changeset 4393:e8e95b80194f

removing usage of deprecated JsonCpp classes
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 21 Dec 2020 18:55:32 +0100
parents 3af1d763763a
children f7104e9d044c
files OrthancFramework/Sources/Toolbox.cpp OrthancFramework/UnitTestsSources/ToolboxTests.cpp
diffstat 2 files changed, 91 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancFramework/Sources/Toolbox.cpp	Mon Dec 21 18:09:47 2020 +0100
+++ b/OrthancFramework/Sources/Toolbox.cpp	Mon Dec 21 18:55:32 2020 +0100
@@ -27,7 +27,31 @@
 #include "OrthancException.h"
 #include "Logging.h"
 
-#include <json/json.h>
+#include <json/reader.h>
+#include <json/version.h>
+#include <json/writer.h>
+
+#if !defined(JSONCPP_VERSION_MAJOR) || !defined(JSONCPP_VERSION_MINOR)
+#  error Cannot access the version of JsonCpp
+#endif
+
+
+/**
+ * We use deprecated "Json::Reader", "Json::StyledWriter" and
+ * "Json::StyledReader" if JsonCpp < 1.7.0. This choice is rather
+ * arbitrary, but if Json >= 1.9.0, gcc generates explicit deprecation
+ * warnings (clang was warning in earlier versions). For reference,
+ * these classes seem to have been deprecated since JsonCpp 1.4.0 (on
+ * February 2015) by the following changeset:
+ * https://github.com/open-source-parsers/jsoncpp/commit/8df98f6112890d6272734975dd6d70cf8999bb22
+ **/
+#if (JSONCPP_VERSION_MAJOR >= 2 ||                                      \
+     (JSONCPP_VERSION_MAJOR == 1 && JSONCPP_VERSION_MINOR >= 8))
+#  define JSONCPP_USE_DEPRECATED 0
+#else
+#  define JSONCPP_USE_DEPRECATED 1
+#endif
+
 
 #include <boost/algorithm/string/case_conv.hpp>
 #include <boost/algorithm/string/replace.hpp>
@@ -2276,8 +2300,12 @@
   bool Toolbox::ReadJson(Json::Value& target,
                          const std::string& source)
   {
+#if JSONCPP_USE_DEPRECATED == 1
     Json::Reader reader;
     return reader.parse(source, target);
+#else
+    return ReadJson(target, source.c_str(), source.size());
+#endif
   }
   
 
@@ -2285,9 +2313,26 @@
                          const void* buffer,
                          size_t size)
   {
+#if JSONCPP_USE_DEPRECATED == 1
     Json::Reader reader;
     return reader.parse(reinterpret_cast<const char*>(buffer),
                         reinterpret_cast<const char*>(buffer) + size, target);
+#else
+    Json::CharReaderBuilder builder;
+    const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
+    assert(reader.get() != NULL);
+    JSONCPP_STRING err;
+    if (reader->parse(reinterpret_cast<const char*>(buffer),
+                      reinterpret_cast<const char*>(buffer) + size, &target, &err))
+    {
+      return true;
+    }
+    else
+    {
+      LOG(ERROR) << "Cannot parse JSON: " << err;
+      return false;
+    }
+#endif
   }
   
 
@@ -2295,6 +2340,7 @@
                           const Json::Value& source,
                           bool fast)
   {
+#if JSONCPP_USE_DEPRECATED == 1
     if (fast)
     {
       Json::FastWriter writer;
@@ -2305,6 +2351,20 @@
       Json::StyledWriter writer;
       target = writer.write(source);
     }
+#else
+    if (fast)
+    {
+      Json::StreamWriterBuilder builder;
+      builder.settings_["indentation"] = "";
+      target = Json::writeString(builder, source);
+    }
+    else
+    {
+      Json::StreamWriterBuilder builder;
+      builder.settings_["indentation"] = "   ";
+      target = Json::writeString(builder, source);
+    }
+#endif
   }
 }
 
--- a/OrthancFramework/UnitTestsSources/ToolboxTests.cpp	Mon Dec 21 18:09:47 2020 +0100
+++ b/OrthancFramework/UnitTestsSources/ToolboxTests.cpp	Mon Dec 21 18:55:32 2020 +0100
@@ -34,6 +34,36 @@
 
 using namespace Orthanc;
 
+TEST(Toolbox, Json)
+{
+  Json::Value a = Json::objectValue;
+  a["hello"] = "world";
+
+  std::string b = "{\"hello\"    :   \"world\"}";
+
+  Json::Value c;
+  ASSERT_TRUE(Toolbox::ReadJson(c, b));
+
+  std::string d, e;
+  Toolbox::WriteJson(d, a, true);
+  Toolbox::WriteJson(e, c, true);
+  ASSERT_EQ(d, e);
+
+  std::string f, g;
+  Toolbox::WriteJson(f, a, false);
+  Toolbox::WriteJson(g, c, false);
+  ASSERT_EQ(f, g);
+
+  /**
+   * Check compatibility with the serialized string generated by
+   * JsonCpp 1.7.4 (Ubuntu 18.04). "StripSpaces()" removes the
+   * trailing end-of-line character that was not present in the
+   * deprecated serialization classes of JsonCpp.
+   **/
+  ASSERT_EQ(Toolbox::StripSpaces(d), "{\"hello\":\"world\"}");
+  ASSERT_EQ(Toolbox::StripSpaces(f), "{\n   \"hello\" : \"world\"\n}");
+}
+
 TEST(Toolbox, Base64_allByteValues)
 {
   std::string toEncode;