From fc488959ea0e451dff572298208cb23f6ee8d62d Mon Sep 17 00:00:00 2001 From: Lirusaito Date: Thu, 7 Mar 2019 03:38:27 -0500 Subject: [PATCH] Switch out jsoncpp for nlohmann json Add llsdjson.* too! --- autobuild.xml | 118 ++++++++-------------------- indra/cmake/CMakeLists.txt | 3 +- indra/cmake/FindJsonCpp.cmake | 39 --------- indra/cmake/Json.cmake | 6 ++ indra/cmake/JsonCpp.cmake | 22 ------ indra/llcommon/CMakeLists.txt | 4 + indra/llcommon/llsdjson.cpp | 126 ++++++++++++++++++++++++++++++ indra/llcommon/llsdjson.h | 77 ++++++++++++++++++ indra/newview/CMakeLists.txt | 5 +- indra/newview/llwebprofile.cpp | 39 +++------ indra/newview/shupdatechecker.cpp | 21 ++--- 11 files changed, 267 insertions(+), 193 deletions(-) delete mode 100644 indra/cmake/FindJsonCpp.cmake create mode 100644 indra/cmake/Json.cmake delete mode 100644 indra/cmake/JsonCpp.cmake create mode 100644 indra/llcommon/llsdjson.cpp create mode 100644 indra/llcommon/llsdjson.h diff --git a/autobuild.xml b/autobuild.xml index 3108aac0d..78e8aa34f 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -1351,92 +1351,6 @@ version 1.5.3 - jsoncpp - - copyright - Copyright (c) 2007-2010 by Baptiste Lepilleur - description - JsonCpp is an implementation of a JSON (http://json.org) reader and writer in C++. - license - Public Domain - license_file - LICENSES/jsoncpp.txt - name - jsoncpp - platforms - - darwin - - archive - - hash - 3243745940e8419f93abf39fd3358158 - hash_algorithm - md5 - url - https://bitbucket.org/alchemyviewer/publiclibs-darwin/downloads/jsoncpp-1.6.5-darwin-201511222000.tar.bz2 - - name - darwin - - linux - - archive - - hash - 840cd9455638c0ea52c613cfddd07d5b - url - http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/jsoncpp-0.5.0-linux-20110315.tar.bz2 - - name - linux - - linux64 - - archive - - hash - 3ebbace19eb931d9236432ba537c3727 - hash_algorithm - md5 - url - http://depot.alchemyviewer.org/pub/linux64/lib-trusty/jsoncpp-1.6.5-linux64-201603232323.tar.bz2 - - name - linux64 - - windows - - archive - - hash - de7bd51771d3d45185c4977e6aec3a37 - hash_algorithm - md5 - url - http://depot.alchemyviewer.org/pub/windows/lib-vc14/jsoncpp-1.6.5-windows-201601151019.tar.bz2 - - name - windows - - windows64 - - archive - - hash - 592a4145fcc71be4ddae58b265885382 - hash_algorithm - md5 - url - https://depot.alchemyviewer.org/pub/windows64/lib-vc142/jsoncpp-1.8.4-windows64-201712251058.tar.bz2 - - name - windows64 - - - version - 1.8.4 - libhunspell copyright @@ -2013,6 +1927,38 @@ version 7.11.1.297294 + modernjson + + copyright + Copyright (c) 2013-2018 Niels Lohmann + description + JSON for Modern C++ + license + MIT + license_file + LICENSES/modernjson.txt + name + modernjson + platforms + + common + + archive + + hash + 6f11eca7e2a6ca61f9217e949a64f026 + hash_algorithm + md5 + url + https://depot.alchemyviewer.org/pub/common/lib/modernjson-3.2.0-common-201809210551.tar.bz2 + + name + common + + + version + 3.2.0 + nvapi copyright diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index df2b56672..cacb7fd05 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -36,7 +36,6 @@ set(cmake_SOURCE_FILES FindGoogleBreakpad.cmake FindGooglePerfTools.cmake FindHunSpell.cmake - FindJsonCpp.cmake FindNDOF.cmake FindOpenJPEG.cmake FindTut.cmake @@ -51,7 +50,7 @@ set(cmake_SOURCE_FILES GooglePerfTools.cmake Hunspell.cmake JPEG.cmake - JsonCpp.cmake + Json.cmake LLAddBuildTest.cmake LLAppearance.cmake LLAudio.cmake diff --git a/indra/cmake/FindJsonCpp.cmake b/indra/cmake/FindJsonCpp.cmake deleted file mode 100644 index a48c97396..000000000 --- a/indra/cmake/FindJsonCpp.cmake +++ /dev/null @@ -1,39 +0,0 @@ -# -*- cmake -*- - -# - Find JSONCpp -# Find the JSONCpp includes and library -# This module defines -# JSONCPP_FOUND, System has libjsoncpp. -# JSONCPP_INCLUDE_DIRS - The libjsoncpp include directories. -# JSONCPP_LIBRARIES - The libraries needed to use libjsoncpp. -# JSONCPP_DEFINITIONS - Compiler switches required for using libjsoncpp. - -FIND_PACKAGE(PkgConfig) -PKG_CHECK_MODULES(PC_JSONCPP jsoncpp) -SET(JSONCPP_DEFINITIONS ${PC_JSONCPP_CFLAGS_OTHER}) - -FIND_PATH(JSONCPP_INCLUDE_DIR json/reader.h - HINTS ${PC_JSONCPP_INCLUDE_DIR} ${PC_JSONCPP_INCLUDE_DIRS} - PATH_SUFFIXES jsoncpp) - -# Get the GCC compiler version -EXEC_PROGRAM(${CMAKE_CXX_COMPILER} - ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion - OUTPUT_VARIABLE _gcc_COMPILER_VERSION - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - -# Try to find a library that was compiled with the same compiler version as we currently use. -FIND_LIBRARY(JSONCPP_LIBRARY - NAMES libjson_linux-gcc-${_gcc_COMPILER_VERSION}_libmt.so libjsoncpp.so - HINTS ${PC_JSONCPP_LIBDIR} ${PC_JSONCPP_LIBRARY_DIRS} - PATHS /usr/lib /usr/local/lib) - -SET(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY}) -SET(JSONCPP_INCLUDE_DIRS ${JSONCPP_INCLUDE_DIR}) - -include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(JSONCPP DEFAULT_MSG - JSONCPP_LIBRARY JSONCPP_INCLUDE_DIR) - -MARK_AS_ADVANCED(JSONCPP_LIBRARY JSONCPP_INCLUDE_DIR) diff --git a/indra/cmake/Json.cmake b/indra/cmake/Json.cmake new file mode 100644 index 000000000..5c9837047 --- /dev/null +++ b/indra/cmake/Json.cmake @@ -0,0 +1,6 @@ +# -*- cmake -*- + +include(Prebuilt) + +use_prebuilt_binary(modernjson) +set(JSON_INCLUDE_DIR "${LIBS_PREBUILT_DIR}/include") diff --git a/indra/cmake/JsonCpp.cmake b/indra/cmake/JsonCpp.cmake deleted file mode 100644 index 4bde364ce..000000000 --- a/indra/cmake/JsonCpp.cmake +++ /dev/null @@ -1,22 +0,0 @@ -# -*- cmake -*- - -include(Prebuilt) - -set(JSONCPP_FIND_QUIETLY OFF) -set(JSONCPP_FIND_REQUIRED ON) - -if (STANDALONE) - include(FindJsonCpp) -else (STANDALONE) - use_prebuilt_binary(jsoncpp) - if (WINDOWS) - set(JSONCPP_LIBRARIES - debug jsoncppd.lib - optimized jsoncpp.lib) - elseif (DARWIN) - set(JSONCPP_LIBRARIES json_linux-gcc-4.0.1_libmt) - elseif (LINUX) - set(JSONCPP_LIBRARIES jsoncpp) - endif (WINDOWS) - set(JSONCPP_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/) -endif (STANDALONE) diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 0f41e254d..b59485a06 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -10,6 +10,7 @@ include(Linking) include(Boost) include(OpenSSL) include(LLSharedLibs) +include(Json) include(GoogleBreakpad) include(Copy3rdPartyLibs) include(ZLIB) @@ -19,6 +20,7 @@ include_directories( ${EXPAT_INCLUDE_DIRS} ${LLCOMMON_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIRS} + ${JSON_INCLUDE_DIR} ${ZLIB_INCLUDE_DIRS} ${BREAKPAD_INCLUDE_DIRECTORIES} ) @@ -85,6 +87,7 @@ set(llcommon_SOURCE_FILES llrun.cpp llscopedvolatileaprpool.h llsd.cpp + llsdjson.cpp llsdparam.cpp llsdserialize.cpp llsdserialize_xml.cpp @@ -210,6 +213,7 @@ set(llcommon_HEADER_FILES llrun.h llsafehandle.h llsd.h + llsdjson.h llsdparam.h llsdserialize.h llsdserialize_xml.h diff --git a/indra/llcommon/llsdjson.cpp b/indra/llcommon/llsdjson.cpp new file mode 100644 index 000000000..5b49f247a --- /dev/null +++ b/indra/llcommon/llsdjson.cpp @@ -0,0 +1,126 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +/** + * @file llsdjson.cpp + * @brief LLSD flexible data system + * + * $LicenseInfo:firstyear=2015&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2015, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Must turn on conditional declarations in header file so definitions end up +// with proper linkage. +#define LLSD_DEBUG_INFO +#include "linden_common.h" + +#include "llsdjson.h" + +#include "llerror.h" + + +//========================================================================= +LLSD LlsdFromJson(const nlohmann::json &val) +{ + LLSD result; + + switch (val.type()) + { + default: + case nlohmann::json::value_t::null: + break; + case nlohmann::json::value_t::number_integer: + result = LLSD(val.get()); + break; + case nlohmann::json::value_t::number_unsigned: + result = LLSD(val.get()); + break; + case nlohmann::json::value_t::number_float: + result = LLSD(val.get()); + break; + case nlohmann::json::value_t::string: + result = LLSD(val.get()); + break; + case nlohmann::json::value_t::boolean: + result = LLSD(val.get()); + break; + case nlohmann::json::value_t::array: + result = LLSD::emptyArray(); + for (const auto &element : val) + { + result.append(LlsdFromJson(element)); + } + break; + case nlohmann::json::value_t::object: + result = LLSD::emptyMap(); + for (auto it = val.cbegin(); it != val.cend(); ++it) + { + result[it.key()] = LlsdFromJson(it.value()); + } + break; + } + return result; +} + +//========================================================================= +nlohmann::json LlsdToJson(const LLSD &val) +{ + nlohmann::json result; + + switch (val.type()) + { + case LLSD::TypeUndefined: + result = nullptr; + break; + case LLSD::TypeBoolean: + result = val.asBoolean(); + break; + case LLSD::TypeInteger: + result = val.asInteger(); + break; + case LLSD::TypeReal: + result = val.asReal(); + break; + case LLSD::TypeURI: + case LLSD::TypeDate: + case LLSD::TypeUUID: + case LLSD::TypeString: + result = val.asString(); + break; + case LLSD::TypeMap: + for (LLSD::map_const_iterator it = val.beginMap(); it != val.endMap(); ++it) + { + result[it->first] = LlsdToJson(it->second); + } + break; + case LLSD::TypeArray: + for (LLSD::array_const_iterator it = val.beginArray(); it != val.endArray(); ++it) + { + result.push_back(LlsdToJson(*it)); + } + break; + case LLSD::TypeBinary: + default: + LL_ERRS("LlsdToJson") << "Unsupported conversion to JSON from LLSD type (" << val.type() << ")." << LL_ENDL; + break; + } + + return result; +} diff --git a/indra/llcommon/llsdjson.h b/indra/llcommon/llsdjson.h new file mode 100644 index 000000000..bc76acbc8 --- /dev/null +++ b/indra/llcommon/llsdjson.h @@ -0,0 +1,77 @@ +/** + * @file llsdjson.cpp + * @brief LLSD flexible data system + * + * $LicenseInfo:firstyear=2015&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2015, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLSDJSON_H +#define LL_LLSDJSON_H + +#include +#include +#include + +#include "stdtypes.h" + +#include "llsd.h" +#include + +/// Convert a parsed JSON structure into LLSD maintaining member names and +/// array indexes. +/// JSON/JavaScript types are converted as follows: +/// +/// JSON Type | LLSD Type +/// --------------+-------------- +/// null | undefined +/// integer | LLSD::Integer +/// unsigned | LLSD::Integer +/// real/numeric | LLSD::Real +/// string | LLSD::String +/// boolean | LLSD::Boolean +/// array | LLSD::Array +/// object | LLSD::Map +/// +/// 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 nlohmann::json &val); + +/// Convert an LLSD object into Parsed JSON object maintaining member names and +/// array indexs. +/// +/// Types are converted as follows: +/// LLSD Type | JSON Type +/// --------------+---------------- +/// TypeUndefined | null +/// TypeBoolean | boolean +/// TypeInteger | integer +/// TypeReal | real/numeric +/// TypeString | string +/// TypeURI | string +/// TypeDate | string +/// TypeUUID | string +/// TypeMap | object +/// TypeArray | array +/// TypeBinary | unsupported +nlohmann::json LlsdToJson(const LLSD &val); + +#endif // LL_LLSDJSON_H diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index e24fa700b..01e507871 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -13,7 +13,7 @@ include(FMODSTUDIO) include(GLOD) include(FindOpenGL) include(Hunspell) -include(JsonCpp) +include(Json) include(LLAddBuildTest) include(LLAppearance) include(LLAudio) @@ -53,7 +53,7 @@ include_directories( ${STATEMACHINE_INCLUDE_DIRS} ${DBUSGLIB_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS} - ${JSONCPP_INCLUDE_DIR} + ${JSON_INCLUDE_DIR} ${GLOD_INCLUDE_DIR} ${LLAUDIO_INCLUDE_DIRS} ${LLCHARACTER_INCLUDE_DIRS} @@ -1652,7 +1652,6 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${GLOD_LIBRARIES} ${APRUTIL_LIBRARIES} ${OPENGL_LIBRARIES} - ${JSONCPP_LIBRARIES} ${SDL_LIBRARY} ${SMARTHEAP_LIBRARY} ${UI_LIBRARIES} diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp index 577dca897..92df639a6 100644 --- a/indra/newview/llwebprofile.cpp +++ b/indra/newview/llwebprofile.cpp @@ -38,8 +38,7 @@ #include "llpanelprofile.h" // getProfileURL (this is the original location LL put it). #include "llviewermedia.h" // FIXME: don't use LLViewerMedia internals -// third-party JSONCPP -#include // JSONCPP +#include "llsdjson.h" /* * Workflow: @@ -78,39 +77,25 @@ public: if (mStatus != HTTP_OK) { - LL_WARNS() << "Failed to get upload config (" << mStatus << ")" << LL_ENDL; + LL_WARNS() << "Failed to get upload config (" << mStatus << ')' << LL_ENDL; LLWebProfile::reportImageUploadStatus(false); return; } - Json::Value root; - Json::Reader reader; - if (!reader.parse(body, root)) - { - LL_WARNS() << "Failed to parse upload config: " << reader.getFormattedErrorMessages() << LL_ENDL; - LLWebProfile::reportImageUploadStatus(false); - return; - } + auto root = LlsdFromJson(nlohmann::json::parse(body)); // *TODO: 404 = not supported by the grid // *TODO: increase timeout or handle HTTP_INTERNAL_ERROR_* time errors. // Convert config to LLSD. - const Json::Value data = root["data"]; + const auto data = root["data"]; const std::string upload_url = root["url"].asString(); - LLSD config; - config["acl"] = data["acl"].asString(); - config["AWSAccessKeyId"] = data["AWSAccessKeyId"].asString(); - config["Content-Type"] = data["Content-Type"].asString(); - config["key"] = data["key"].asString(); - config["policy"] = data["policy"].asString(); - config["success_action_redirect"] = data["success_action_redirect"].asString(); - config["signature"] = data["signature"].asString(); - config["add_loc"] = data.get("add_loc", "0").asString(); - config["caption"] = data.get("caption", "").asString(); + LLSD config = data; + if (!data.has("add_loc")) config["add_loc"] = "0"; + if (!data.has("caption")) config["caption"] = LLStringUtil::null; // Do the actual image upload using the configuration. - LL_DEBUGS("Snapshots") << "Got upload config, POSTing image to " << upload_url << ", config=[" << config << "]" << LL_ENDL; + LL_DEBUGS("Snapshots") << "Got upload config, POSTing image to " << upload_url << ", config=[" << config << ']' << LL_ENDL; LLWebProfile::post(mImagep, config, upload_url); } @@ -133,7 +118,7 @@ public: { if (mStatus != HTTP_OK) { - LL_WARNS() << "Failed to upload image: " << mStatus << " " << mReason << LL_ENDL; + LL_WARNS() << "Failed to upload image: " << mStatus << ' ' << mReason << LL_ENDL; LLWebProfile::reportImageUploadStatus(false); return; } @@ -143,7 +128,7 @@ public: strstrm << istr.rdbuf(); const std::string body = strstrm.str(); LL_INFOS() << "Image uploaded." << LL_ENDL; - LL_DEBUGS("Snapshots") << "Uploading image succeeded. Response: [" << body << "]" << LL_ENDL; + LL_DEBUGS("Snapshots") << "Uploading image succeeded. Response: [" << body << ']' << LL_ENDL; LLWebProfile::reportImageUploadStatus(true); } @@ -184,8 +169,8 @@ public: } else { - LL_WARNS() << "Unexpected POST status: " << mStatus << " " << mReason << LL_ENDL; - LL_DEBUGS("Snapshots") << "received_headers: [" << mReceivedHeaders << "]" << LL_ENDL; + LL_WARNS() << "Unexpected POST status: " << mStatus << ' ' << mReason << LL_ENDL; + LL_DEBUGS("Snapshots") << "received_headers: [" << mReceivedHeaders << ']' << LL_ENDL; LLWebProfile::reportImageUploadStatus(false); } } diff --git a/indra/newview/shupdatechecker.cpp b/indra/newview/shupdatechecker.cpp index 0d415f66c..a30fc03db 100644 --- a/indra/newview/shupdatechecker.cpp +++ b/indra/newview/shupdatechecker.cpp @@ -16,8 +16,7 @@ #include "llbufferstream.h" #include "llweb.h" - -#include +#include extern AIHTTPTimeoutPolicy getUpdateInfoResponder_timeout; /////////////////////////////////////////////////////////////////////////////// @@ -57,20 +56,14 @@ public: return; } - Json::Value root; - Json::Reader reader; - if (!reader.parse(body, root)) - { - LL_WARNS() << "Failed to parse update info: " << reader.getFormattedErrorMessages() << LL_ENDL; - return; - } + auto root = nlohmann::json::parse(body); std::string viewer_version = llformat("%s (%i)", LLVersionInfo::getShortVersion().c_str(), LLVersionInfo::getBuild()); - const Json::Value data = root[mType]; + const auto data = root[mType]; #if LL_WINDOWS - std::string recommended_version = data["recommended"]["windows"].asString(); - std::string minimum_version = data["minimum"]["windows"].asString(); + std::string recommended_version = data["recommended"]["windows"]; + std::string minimum_version = data["minimum"]["windows"]; #elif LL_LINUX std::string recommended_version = data["recommended"]["linux"].asString(); std::string minimum_version = data["minimum"]["linux"].asString(); @@ -88,7 +81,7 @@ public: args["CURRENT_VER"] = viewer_version; args["RECOMMENDED_VER"] = recommended_version; args["MINIMUM_VER"] = minimum_version; - args["URL"] = data["url"].asString(); + args["URL"] = data["url"].get(); args["TYPE"] = mType == "release" ? "Viewer" : "Alpha"; static LLCachedControl sLastKnownReleaseBuild("SinguLastKnownReleaseBuild", 0); @@ -123,7 +116,7 @@ public: } if (!notificaiton.empty()) { - LLNotificationsUtil::add(notificaiton, args, LLSD(), boost::bind(&GetUpdateInfoResponder::onNotifyButtonPress, this, _1, _2, notificaiton, data["url"].asString())); + LLNotificationsUtil::add(notificaiton, args, LLSD(), boost::bind(&GetUpdateInfoResponder::onNotifyButtonPress, this, _1, _2, notificaiton, data["url"])); } } }