Port from JsonCPP to Boost.Json for json parsing and serializing (#1054)
parent
7dbdfda7d6
commit
17e1f3692c
|
|
@ -1021,66 +1021,6 @@
|
|||
<key>description</key>
|
||||
<string>JPEG encoding, decoding library</string>
|
||||
</map>
|
||||
<key>jsoncpp</key>
|
||||
<map>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>darwin64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>07761ab01e61d5d6b40d303ffafd85ec055ec9f7</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/3p-jsoncpp/releases/download/v0.5.0.bc46e62/jsoncpp-0.5.0.bc46e62-darwin64-bc46e62.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
</map>
|
||||
<key>linux64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>97e268754808cb2fbd682c4d3beafd2c598e1ba7</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/3p-jsoncpp/releases/download/v0.5.0.bc46e62/jsoncpp-0.5.0.bc46e62-linux64-bc46e62.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
</map>
|
||||
<key>windows64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>500e455b210d6bc4985185cef2472987ed3034bf</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/3p-jsoncpp/releases/download/v0.5.0.bc46e62/jsoncpp-0.5.0.bc46e62-windows64-bc46e62.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>license</key>
|
||||
<string>public domain</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/jsoncpp.txt</string>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (c) 2007-2010 Baptiste Lepilleur</string>
|
||||
<key>version</key>
|
||||
<string>0.5.0.bc46e62</string>
|
||||
<key>name</key>
|
||||
<string>jsoncpp</string>
|
||||
<key>description</key>
|
||||
<string>jsoncpp is an implementation of a JSON (http://json.org) reader and writer in C++.</string>
|
||||
</map>
|
||||
<key>kdu</key>
|
||||
<map>
|
||||
<key>platforms</key>
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ set(cmake_SOURCE_FILES
|
|||
Havok.cmake
|
||||
Hunspell.cmake
|
||||
ICU4C.cmake
|
||||
JsonCpp.cmake
|
||||
LLAddBuildTest.cmake
|
||||
LLAppearance.cmake
|
||||
LLAudio.cmake
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
# -*- cmake -*-
|
||||
|
||||
include(Prebuilt)
|
||||
include_guard()
|
||||
add_library( ll::jsoncpp INTERFACE IMPORTED )
|
||||
|
||||
use_system_binary(jsoncpp)
|
||||
|
||||
use_prebuilt_binary(jsoncpp)
|
||||
if (WINDOWS)
|
||||
target_link_libraries( ll::jsoncpp INTERFACE json_libmd.lib )
|
||||
elseif (DARWIN)
|
||||
target_link_libraries( ll::jsoncpp INTERFACE libjson_darwin_libmt.a )
|
||||
elseif (LINUX)
|
||||
target_link_libraries( ll::jsoncpp INTERFACE libjson_linux-gcc-4.1.3_libmt.a )
|
||||
endif (WINDOWS)
|
||||
target_include_directories( ll::jsoncpp SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include)
|
||||
|
|
@ -6,6 +6,5 @@ include(EXPAT)
|
|||
include(Tracy)
|
||||
include(xxHash)
|
||||
include(ZLIBNG)
|
||||
include(JsonCpp)
|
||||
|
||||
include(XmlRpcEpi)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ include(bugsplat)
|
|||
include(Linking)
|
||||
include(Boost)
|
||||
include(LLSharedLibs)
|
||||
include(JsonCpp)
|
||||
include(Copy3rdPartyLibs)
|
||||
include(ZLIBNG)
|
||||
include(URIPARSER)
|
||||
|
|
@ -278,7 +277,6 @@ target_link_libraries(
|
|||
llcommon
|
||||
ll::apr
|
||||
ll::expat
|
||||
ll::jsoncpp
|
||||
ll::zlib-ng
|
||||
ll::boost
|
||||
ll::uriparser
|
||||
|
|
|
|||
|
|
@ -31,46 +31,56 @@
|
|||
|
||||
#include "llsdjson.h"
|
||||
|
||||
#include "llsdutil.h"
|
||||
#include "llerror.h"
|
||||
#include "../llmath/llmath.h"
|
||||
|
||||
#if LL_WINDOWS
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable : 4702) // compiler thinks unreachable code
|
||||
#endif
|
||||
#include <boost/json/src.hpp>
|
||||
#if LL_WINDOWS
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//=========================================================================
|
||||
LLSD LlsdFromJson(const Json::Value &val)
|
||||
LLSD LlsdFromJson(const boost::json::value& val)
|
||||
{
|
||||
LLSD result;
|
||||
|
||||
switch (val.type())
|
||||
switch (val.kind())
|
||||
{
|
||||
default:
|
||||
case Json::nullValue:
|
||||
case boost::json::kind::null:
|
||||
break;
|
||||
case Json::intValue:
|
||||
result = LLSD(static_cast<LLSD::Integer>(val.asInt()));
|
||||
case boost::json::kind::int64:
|
||||
case boost::json::kind::uint64:
|
||||
result = LLSD(val.to_number<int64_t>());
|
||||
break;
|
||||
case Json::uintValue:
|
||||
result = LLSD(static_cast<LLSD::Integer>(val.asUInt()));
|
||||
case boost::json::kind::double_:
|
||||
result = LLSD(val.to_number<double>());
|
||||
break;
|
||||
case Json::realValue:
|
||||
result = LLSD(static_cast<LLSD::Real>(val.asDouble()));
|
||||
case boost::json::kind::string:
|
||||
result = LLSD(boost::json::value_to<std::string>(val));
|
||||
break;
|
||||
case Json::stringValue:
|
||||
result = LLSD(static_cast<LLSD::String>(val.asString()));
|
||||
case boost::json::kind::bool_:
|
||||
result = LLSD(val.as_bool());
|
||||
break;
|
||||
case Json::booleanValue:
|
||||
result = LLSD(static_cast<LLSD::Boolean>(val.asBool()));
|
||||
break;
|
||||
case Json::arrayValue:
|
||||
case boost::json::kind::array:
|
||||
result = LLSD::emptyArray();
|
||||
for (Json::ValueConstIterator it = val.begin(); it != val.end(); ++it)
|
||||
for (const auto &element : val.as_array())
|
||||
{
|
||||
result.append(LlsdFromJson((*it)));
|
||||
result.append(LlsdFromJson(element));
|
||||
}
|
||||
break;
|
||||
case Json::objectValue:
|
||||
case boost::json::kind::object:
|
||||
result = LLSD::emptyMap();
|
||||
for (Json::ValueConstIterator it = val.begin(); it != val.end(); ++it)
|
||||
for (const auto& element : val.as_object())
|
||||
{
|
||||
result[it.memberName()] = LlsdFromJson((*it));
|
||||
result[element.key()] = LlsdFromJson(element.value());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -78,44 +88,48 @@ LLSD LlsdFromJson(const Json::Value &val)
|
|||
}
|
||||
|
||||
//=========================================================================
|
||||
Json::Value LlsdToJson(const LLSD &val)
|
||||
boost::json::value LlsdToJson(const LLSD &val)
|
||||
{
|
||||
Json::Value result;
|
||||
boost::json::value result;
|
||||
|
||||
switch (val.type())
|
||||
{
|
||||
case LLSD::TypeUndefined:
|
||||
result = Json::Value::null;
|
||||
result = nullptr;
|
||||
break;
|
||||
case LLSD::TypeBoolean:
|
||||
result = Json::Value(static_cast<bool>(val.asBoolean()));
|
||||
result = val.asBoolean();
|
||||
break;
|
||||
case LLSD::TypeInteger:
|
||||
result = Json::Value(static_cast<int>(val.asInteger()));
|
||||
result = val.asInteger();
|
||||
break;
|
||||
case LLSD::TypeReal:
|
||||
result = Json::Value(static_cast<double>(val.asReal()));
|
||||
result = val.asReal();
|
||||
break;
|
||||
case LLSD::TypeURI:
|
||||
case LLSD::TypeDate:
|
||||
case LLSD::TypeUUID:
|
||||
case LLSD::TypeString:
|
||||
result = Json::Value(val.asString());
|
||||
result = val.asString();
|
||||
break;
|
||||
case LLSD::TypeMap:
|
||||
result = Json::Value(Json::objectValue);
|
||||
for (LLSD::map_const_iterator it = val.beginMap(); it != val.endMap(); ++it)
|
||||
{
|
||||
boost::json::object& obj = result.emplace_object();
|
||||
for (const auto& llsd_dat : llsd::inMap(val))
|
||||
{
|
||||
result[it->first] = LlsdToJson(it->second);
|
||||
obj[llsd_dat.first] = LlsdToJson(llsd_dat.second);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LLSD::TypeArray:
|
||||
result = Json::Value(Json::arrayValue);
|
||||
for (LLSD::array_const_iterator it = val.beginArray(); it != val.endArray(); ++it)
|
||||
{
|
||||
boost::json::array& json_array = result.emplace_array();
|
||||
for (const auto& llsd_dat : llsd::inArray(val))
|
||||
{
|
||||
result.append(LlsdToJson(*it));
|
||||
json_array.push_back(LlsdToJson(llsd_dat));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LLSD::TypeBinary:
|
||||
default:
|
||||
LL_ERRS("LlsdToJson") << "Unsupported conversion to JSON from LLSD type (" << val.type() << ")." << LL_ENDL;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
#include "stdtypes.h"
|
||||
|
||||
#include "llsd.h"
|
||||
#include "json/value.h"
|
||||
#include <boost/json.hpp>
|
||||
|
||||
/// Convert a parsed JSON structure into LLSD maintaining member names and
|
||||
/// array indexes.
|
||||
|
|
@ -53,7 +53,7 @@
|
|||
///
|
||||
/// For maps and arrays child entries will be converted and added to the structure.
|
||||
/// Order is preserved for an array but not for objects.
|
||||
LLSD LlsdFromJson(const Json::Value &val);
|
||||
LLSD LlsdFromJson(const boost::json::value &val);
|
||||
|
||||
/// Convert an LLSD object into Parsed JSON object maintaining member names and
|
||||
/// array indexs.
|
||||
|
|
@ -72,6 +72,6 @@ LLSD LlsdFromJson(const Json::Value &val);
|
|||
/// TypeMap | object
|
||||
/// TypeArray | array
|
||||
/// TypeBinary | unsupported
|
||||
Json::Value LlsdToJson(const LLSD &val);
|
||||
boost::json::value LlsdToJson(const LLSD &val);
|
||||
|
||||
#endif // LL_LLSDJSON_H
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ include(LLAddBuildTest)
|
|||
include(Python)
|
||||
include(Tut)
|
||||
include(Python)
|
||||
include(JsonCpp)
|
||||
|
||||
set(llmessage_SOURCE_FILES
|
||||
llassetstorage.cpp
|
||||
|
|
|
|||
|
|
@ -35,8 +35,7 @@
|
|||
#include "llsd.h"
|
||||
#include "llsdjson.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "json/reader.h" // JSON
|
||||
#include "json/writer.h" // JSON
|
||||
#include "boost/json.hpp" // Boost.Json
|
||||
#include "llfilesystem.h"
|
||||
|
||||
#include "message.h" // for getting the port
|
||||
|
|
@ -585,15 +584,12 @@ LLSD HttpCoroJSONHandler::handleSuccess(LLCore::HttpResponse * response, LLCore:
|
|||
}
|
||||
|
||||
LLCore::BufferArrayStream bas(body);
|
||||
Json::Value jsonRoot;
|
||||
|
||||
try
|
||||
{
|
||||
bas >> jsonRoot;
|
||||
}
|
||||
catch (std::runtime_error& e)
|
||||
boost::json::error_code ec;
|
||||
boost::json::value jsonRoot = boost::json::parse(bas, ec);
|
||||
if(ec.failed())
|
||||
{ // deserialization failed. Record the reason and pass back an empty map for markup.
|
||||
status = LLCore::HttpStatus(499, std::string(e.what()));
|
||||
status = LLCore::HttpStatus(499, std::string(ec.what()));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -613,14 +609,11 @@ LLSD HttpCoroJSONHandler::parseBody(LLCore::HttpResponse *response, bool &succes
|
|||
}
|
||||
|
||||
LLCore::BufferArrayStream bas(body);
|
||||
Json::Value jsonRoot;
|
||||
|
||||
try
|
||||
boost::json::error_code ec;
|
||||
boost::json::value jsonRoot = boost::json::parse(bas, ec);
|
||||
if (ec.failed())
|
||||
{
|
||||
bas >> jsonRoot;
|
||||
}
|
||||
catch (std::runtime_error&)
|
||||
{
|
||||
success = false;
|
||||
return LLSD();
|
||||
}
|
||||
|
|
@ -802,12 +795,12 @@ LLSD HttpCoroutineAdapter::postJsonAndSuspend(LLCore::HttpRequest::ptr_t request
|
|||
|
||||
{
|
||||
LLCore::BufferArrayStream outs(rawbody.get());
|
||||
Json::Value root = LlsdToJson(body);
|
||||
Json::FastWriter writer;
|
||||
auto root = LlsdToJson(body);
|
||||
std::string value = boost::json::serialize(root);
|
||||
|
||||
LL_WARNS("Http::post") << "JSON Generates: \"" << writer.write(root) << "\"" << LL_ENDL;
|
||||
LL_WARNS("Http::post") << "JSON Generates: \"" << value << "\"" << LL_ENDL;
|
||||
|
||||
outs << writer.write(root);
|
||||
outs << value;
|
||||
}
|
||||
|
||||
return postAndSuspend_(request, url, rawbody, options, headers, httpHandler);
|
||||
|
|
@ -861,11 +854,11 @@ LLSD HttpCoroutineAdapter::putJsonAndSuspend(LLCore::HttpRequest::ptr_t request,
|
|||
|
||||
{
|
||||
LLCore::BufferArrayStream outs(rawbody.get());
|
||||
Json::Value root = LlsdToJson(body);
|
||||
Json::FastWriter writer;
|
||||
auto root = LlsdToJson(body);
|
||||
std::string value = boost::json::serialize(root);
|
||||
|
||||
LL_WARNS("Http::put") << "JSON Generates: \"" << writer.write(root) << "\"" << LL_ENDL;
|
||||
outs << writer.write(root);
|
||||
LL_WARNS("Http::put") << "JSON Generates: \"" << value << "\"" << LL_ENDL;
|
||||
outs << value;
|
||||
}
|
||||
|
||||
return putAndSuspend_(request, url, rawbody, options, headers, httpHandler);
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ include(EXPAT)
|
|||
include(Hunspell)
|
||||
include(ICU4C)
|
||||
include(JPEGEncoderBasic)
|
||||
include(JsonCpp)
|
||||
include(LLAppearance)
|
||||
include(LLAudio)
|
||||
include(LLCA)
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@
|
|||
// Bugsplat (http://bugsplat.com) crash reporting tool
|
||||
#ifdef LL_BUGSPLAT
|
||||
#include "BugSplat.h"
|
||||
#include "json/reader.h" // JsonCpp
|
||||
#include "boost/json.hpp" // Boost.Json
|
||||
#include "llagent.h" // for agent location
|
||||
#include "llviewerregion.h"
|
||||
#include "llvoavatarself.h" // for agent name
|
||||
|
|
@ -722,24 +722,25 @@ bool LLAppViewerWin32::init()
|
|||
}
|
||||
else
|
||||
{
|
||||
Json::Reader reader;
|
||||
Json::Value build_data;
|
||||
if (!reader.parse(inf, build_data, false)) // don't collect comments
|
||||
boost::json::error_code ec;
|
||||
boost::json::value build_data = boost::json::parse(inf, ec);
|
||||
if(ec.failed())
|
||||
{
|
||||
// gah, the typo is baked into Json::Reader API
|
||||
LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, can't parse '" << build_data_fname
|
||||
<< "': " << reader.getFormatedErrorMessages() << LL_ENDL;
|
||||
<< "': " << ec.what() << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
Json::Value BugSplat_DB = build_data["BugSplat DB"];
|
||||
if (!BugSplat_DB)
|
||||
if (!build_data.is_object() || !build_data.as_object().contains("BugSplat DB"))
|
||||
{
|
||||
LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, no 'BugSplat DB' entry in '"
|
||||
<< build_data_fname << "'" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::json::value BugSplat_DB = build_data.at("BugSplat DB");
|
||||
|
||||
// Got BugSplat_DB, onward!
|
||||
std::wstring version_string(WSTRINGIZE(LL_VIEWER_VERSION_MAJOR << '.' <<
|
||||
LL_VIEWER_VERSION_MINOR << '.' <<
|
||||
|
|
@ -761,7 +762,7 @@ bool LLAppViewerWin32::init()
|
|||
|
||||
// have to convert normal wide strings to strings of __wchar_t
|
||||
sBugSplatSender = new MiniDmpSender(
|
||||
WCSTR(BugSplat_DB.asString()),
|
||||
WCSTR(boost::json::value_to<std::string>(BugSplat_DB)),
|
||||
WCSTR(LL_TO_WSTRING(LL_VIEWER_CHANNEL)),
|
||||
WCSTR(version_string),
|
||||
nullptr, // szAppIdentifier -- set later
|
||||
|
|
|
|||
|
|
@ -47,9 +47,6 @@
|
|||
#include "tinygltf/tiny_gltf.h"
|
||||
#include <strstream>
|
||||
|
||||
#include "json/reader.h"
|
||||
#include "json/value.h"
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
LLGLTFMaterialList gGLTFMaterialList;
|
||||
|
|
|
|||
|
|
@ -42,8 +42,6 @@
|
|||
#include "llviewermedia.h"
|
||||
#include "llviewernetwork.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "json/reader.h" // JSON
|
||||
#include "json/writer.h" // JSON
|
||||
#include "lleventcoro.h"
|
||||
#include "llcoros.h"
|
||||
#include "llcorehttputil.h"
|
||||
|
|
|
|||
|
|
@ -36,11 +36,11 @@
|
|||
#include "llversioninfo.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llcoros.h"
|
||||
#include "json/reader.h"
|
||||
#include "llcorehttputil.h"
|
||||
#include "llurlregistry.h"
|
||||
#include "stringize.h"
|
||||
|
||||
#include <boost/json.hpp>
|
||||
|
||||
static const std::string AZURE_NOTRANSLATE_OPENING_TAG("<div translate=\"no\">");
|
||||
static const std::string AZURE_NOTRANSLATE_CLOSING_TAG("</div>");
|
||||
|
|
@ -346,11 +346,11 @@ public:
|
|||
|
||||
private:
|
||||
static void parseErrorResponse(
|
||||
const Json::Value& root,
|
||||
const boost::json::value& root,
|
||||
int& status,
|
||||
std::string& err_msg);
|
||||
static bool parseTranslation(
|
||||
const Json::Value& root,
|
||||
const boost::json::value& root,
|
||||
std::string& translation,
|
||||
std::string& detected_lang);
|
||||
static std::string getAPIKey();
|
||||
|
|
@ -399,19 +399,13 @@ bool LLGoogleTranslationHandler::parseResponse(
|
|||
std::string& detected_lang,
|
||||
std::string& err_msg) const
|
||||
{
|
||||
Json::Value root;
|
||||
Json::Reader reader;
|
||||
|
||||
if (!reader.parse(body, root))
|
||||
{
|
||||
err_msg = reader.getFormatedErrorMessages();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!root.isObject()) // empty response? should not happen
|
||||
{
|
||||
return false;
|
||||
}
|
||||
boost::json::error_code ec;
|
||||
boost::json::value root = boost::json::parse(body, ec);
|
||||
if (ec.failed())
|
||||
{
|
||||
err_msg = ec.what();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (status != HTTP_OK)
|
||||
{
|
||||
|
|
@ -432,48 +426,55 @@ bool LLGoogleTranslationHandler::isConfigured() const
|
|||
|
||||
// static
|
||||
void LLGoogleTranslationHandler::parseErrorResponse(
|
||||
const Json::Value& root,
|
||||
const boost::json::value& root,
|
||||
int& status,
|
||||
std::string& err_msg)
|
||||
{
|
||||
const Json::Value& error = root.get("error", 0);
|
||||
if (!error.isObject() || !error.isMember("message") || !error.isMember("code"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
boost::json::error_code ec;
|
||||
auto message = root.find_pointer("/data/message", ec);
|
||||
auto code = root.find_pointer("/data/code", ec);
|
||||
if (!message || !code)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
err_msg = error["message"].asString();
|
||||
status = error["code"].asInt();
|
||||
auto message_val = boost::json::try_value_to<std::string>(*message);
|
||||
auto code_val = boost::json::try_value_to<int>(*code);
|
||||
if (!message_val || !code_val)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
err_msg = message_val.value();
|
||||
status = code_val.value();
|
||||
}
|
||||
|
||||
// static
|
||||
bool LLGoogleTranslationHandler::parseTranslation(
|
||||
const Json::Value& root,
|
||||
const boost::json::value& root,
|
||||
std::string& translation,
|
||||
std::string& detected_lang)
|
||||
{
|
||||
// JsonCpp is prone to aborting the program on failed assertions,
|
||||
// so be super-careful and verify the response format.
|
||||
const Json::Value& data = root.get("data", 0);
|
||||
if (!data.isObject() || !data.isMember("translations"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
boost::json::error_code ec;
|
||||
auto translated_text = root.find_pointer("/data/translations/0/translatedText", ec);
|
||||
if (!translated_text) return false;
|
||||
|
||||
const Json::Value& translations = data["translations"];
|
||||
if (!translations.isArray() || translations.size() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
auto text_val = boost::json::try_value_to<std::string>(*translated_text);
|
||||
if (!text_val)
|
||||
{
|
||||
LL_WARNS() << "Failed to parse translation" << text_val.error() << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
const Json::Value& first = translations[0U];
|
||||
if (!first.isObject() || !first.isMember("translatedText"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
translation = text_val.value();
|
||||
|
||||
auto language = root.find_pointer("/data/translations/0/detectedSourceLanguage", ec);
|
||||
if (language)
|
||||
{
|
||||
auto lang_val = boost::json::try_value_to<std::string>(*language);
|
||||
detected_lang = lang_val ? lang_val.value() : "";
|
||||
}
|
||||
|
||||
translation = first["translatedText"].asString();
|
||||
detected_lang = first.get("detectedSourceLanguage", "").asString();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -655,12 +656,11 @@ bool LLAzureTranslationHandler::checkVerificationResponse(
|
|||
// Expected: "{\"error\":{\"code\":400000,\"message\":\"One of the request inputs is not valid.\"}}"
|
||||
// But for now just verify response is a valid json
|
||||
|
||||
Json::Value root;
|
||||
Json::Reader reader;
|
||||
|
||||
if (!reader.parse(response["error_body"].asString(), root))
|
||||
boost::json::error_code ec;
|
||||
boost::json::value root = boost::json::parse(response["error_body"].asString(), ec);
|
||||
if (ec.failed())
|
||||
{
|
||||
LL_DEBUGS("Translate") << "Failed to parse error_body:" << reader.getFormatedErrorMessages() << LL_ENDL;
|
||||
LL_DEBUGS("Translate") << "Failed to parse error_body:" << ec.what() << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -679,57 +679,36 @@ bool LLAzureTranslationHandler::parseResponse(
|
|||
if (status != HTTP_OK)
|
||||
{
|
||||
if (http_response.has("error_body"))
|
||||
err_msg = parseErrorResponse(http_response["error_body"].asString());
|
||||
err_msg = parseErrorResponse(http_response["error_body"].asString());
|
||||
return false;
|
||||
}
|
||||
|
||||
//Example:
|
||||
// "[{\"detectedLanguage\":{\"language\":\"en\",\"score\":1.0},\"translations\":[{\"text\":\"Hello, what is your name?\",\"to\":\"en\"}]}]"
|
||||
|
||||
Json::Value root;
|
||||
Json::Reader reader;
|
||||
|
||||
if (!reader.parse(body, root))
|
||||
boost::json::error_code ec;
|
||||
boost::json::value root = boost::json::parse(body, ec);
|
||||
if (ec.failed())
|
||||
{
|
||||
err_msg = reader.getFormatedErrorMessages();
|
||||
err_msg = ec.what();
|
||||
return false;
|
||||
}
|
||||
auto language = root.find_pointer("/0/detectedLanguage/language", ec);
|
||||
if (!language) return false;
|
||||
|
||||
auto translated_text = root.find_pointer("/0/translations/0/text", ec);
|
||||
if (!translated_text) return false;
|
||||
|
||||
auto lang_val = boost::json::try_value_to<std::string>(*language);
|
||||
auto text_val = boost::json::try_value_to<std::string>(*translated_text);
|
||||
if (!lang_val || !text_val)
|
||||
{
|
||||
LL_WARNS() << "Failed to parse translation" << lang_val.error() << text_val.error() << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!root.isArray()) // empty response? should not happen
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Request succeeded, extract translation from the response.
|
||||
|
||||
const Json::Value& data = root[0U];
|
||||
if (!data.isObject()
|
||||
|| !data.isMember("detectedLanguage")
|
||||
|| !data.isMember("translations"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const Json::Value& detectedLanguage = data["detectedLanguage"];
|
||||
if (!detectedLanguage.isObject() || !detectedLanguage.isMember("language"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
detected_lang = detectedLanguage["language"].asString();
|
||||
|
||||
const Json::Value& translations = data["translations"];
|
||||
if (!translations.isArray() || translations.size() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const Json::Value& first = translations[0U];
|
||||
if (!first.isObject() || !first.isMember("text"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
translation = first["text"].asString();
|
||||
detected_lang = lang_val.value();
|
||||
translation = text_val.value();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -747,27 +726,25 @@ std::string LLAzureTranslationHandler::parseErrorResponse(
|
|||
// Expected: "{\"error\":{\"code\":400000,\"message\":\"One of the request inputs is not valid.\"}}"
|
||||
// But for now just verify response is a valid json with an error
|
||||
|
||||
Json::Value root;
|
||||
Json::Reader reader;
|
||||
|
||||
if (!reader.parse(body, root))
|
||||
boost::json::error_code ec;
|
||||
boost::json::value root = boost::json::parse(body, ec);
|
||||
if (ec.failed())
|
||||
{
|
||||
return std::string();
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!root.isObject() || !root.isMember("error"))
|
||||
auto err_msg = root.find_pointer("/error/message", ec);
|
||||
if (!err_msg)
|
||||
{
|
||||
return std::string();
|
||||
return {};
|
||||
}
|
||||
|
||||
const Json::Value& error_map = root["error"];
|
||||
|
||||
if (!error_map.isObject() || !error_map.isMember("message"))
|
||||
auto err_msg_val = boost::json::try_value_to<std::string>(*err_msg);
|
||||
if (!err_msg_val)
|
||||
{
|
||||
return std::string();
|
||||
return {};
|
||||
}
|
||||
|
||||
return error_map["message"].asString();
|
||||
return err_msg_val.value();
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -974,39 +951,39 @@ bool LLDeepLTranslationHandler::parseResponse(
|
|||
//Example:
|
||||
// "{\"translations\":[{\"detected_source_language\":\"EN\",\"text\":\"test\"}]}"
|
||||
|
||||
Json::Value root;
|
||||
Json::Reader reader;
|
||||
|
||||
if (!reader.parse(body, root))
|
||||
boost::json::error_code ec;
|
||||
boost::json::value root = boost::json::parse(body, ec);
|
||||
if (ec.failed())
|
||||
{
|
||||
err_msg = reader.getFormatedErrorMessages();
|
||||
err_msg = ec.message();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!root.isObject()
|
||||
|| !root.isMember("translations")) // empty response? should not happen
|
||||
auto detected_langp = root.find_pointer("/translations/0/detected_source_language", ec);
|
||||
if (!detected_langp || ec.failed()) // empty response? should not happen
|
||||
{
|
||||
err_msg = ec.message();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Request succeeded, extract translation from the response.
|
||||
const Json::Value& translations = root["translations"];
|
||||
if (!translations.isArray() || translations.size() == 0)
|
||||
auto text_valp = root.find_pointer("/translations/0/text", ec);
|
||||
if (!text_valp || ec.failed())
|
||||
{
|
||||
err_msg = ec.message();
|
||||
return false;
|
||||
}
|
||||
|
||||
auto lang_result = boost::json::try_value_to<std::string>(*detected_langp);
|
||||
auto text_result = boost::json::try_value_to<std::string>(*text_valp);
|
||||
if (!lang_result || !text_result)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const Json::Value& data= translations[0U];
|
||||
if (!data.isObject()
|
||||
|| !data.isMember("detected_source_language")
|
||||
|| !data.isMember("text"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
detected_lang = data["detected_source_language"].asString();
|
||||
detected_lang = lang_result.value();
|
||||
LLStringUtil::toLower(detected_lang);
|
||||
translation = data["text"].asString();
|
||||
translation = text_result.value();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1022,21 +999,24 @@ std::string LLDeepLTranslationHandler::parseErrorResponse(
|
|||
const std::string& body)
|
||||
{
|
||||
// Example: "{\"message\":\"One of the request inputs is not valid.\"}"
|
||||
|
||||
Json::Value root;
|
||||
Json::Reader reader;
|
||||
|
||||
if (!reader.parse(body, root))
|
||||
{
|
||||
return std::string();
|
||||
boost::json::error_code ec;
|
||||
boost::json::value root = boost::json::parse(body, ec);
|
||||
if (ec.failed())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!root.isObject() || !root.isMember("message"))
|
||||
auto message_ptr = root.find_pointer("/message", ec);
|
||||
if (!message_ptr || ec.failed())
|
||||
{
|
||||
return std::string();
|
||||
return {};
|
||||
}
|
||||
|
||||
return root["message"].asString();
|
||||
auto message_val = boost::json::try_value_to<std::string>(*message_ptr);
|
||||
if (!message_val)
|
||||
return {};
|
||||
|
||||
return message_val.value();
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
|||
|
|
@ -32,11 +32,6 @@
|
|||
|
||||
#include "llsingleton.h"
|
||||
|
||||
namespace Json
|
||||
{
|
||||
class Value;
|
||||
}
|
||||
|
||||
class LLTranslationAPIHandler;
|
||||
/**
|
||||
* Entry point for machine translation services.
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
#include "llcorehttputil.h"
|
||||
|
||||
// third-party
|
||||
#include "json/reader.h" // JSON
|
||||
|
||||
|
||||
/*
|
||||
* Workflow:
|
||||
|
|
|
|||
Loading…
Reference in New Issue