comparison OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp @ 4394:f7104e9d044c

functions to read/write JSON in OrthancPluginCppWrapper.h
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 22 Dec 2020 08:11:37 +0100
parents 4bb7522a63e0
children d07a65100a95
comparison
equal deleted inserted replaced
4393:e8e95b80194f 4394:f7104e9d044c
22 #include "OrthancPluginCppWrapper.h" 22 #include "OrthancPluginCppWrapper.h"
23 23
24 #include <boost/algorithm/string/predicate.hpp> 24 #include <boost/algorithm/string/predicate.hpp>
25 #include <boost/move/unique_ptr.hpp> 25 #include <boost/move/unique_ptr.hpp>
26 #include <boost/thread.hpp> 26 #include <boost/thread.hpp>
27
28
27 #include <json/reader.h> 29 #include <json/reader.h>
30 #include <json/version.h>
28 #include <json/writer.h> 31 #include <json/writer.h>
32
33 #if !defined(JSONCPP_VERSION_MAJOR) || !defined(JSONCPP_VERSION_MINOR)
34 # error Cannot access the version of JsonCpp
35 #endif
36
37
38 /**
39 * We use deprecated "Json::Reader", "Json::StyledWriter" and
40 * "Json::StyledReader" if JsonCpp < 1.7.0. This choice is rather
41 * arbitrary, but if Json >= 1.9.0, gcc generates explicit deprecation
42 * warnings (clang was warning in earlier versions). For reference,
43 * these classes seem to have been deprecated since JsonCpp 1.4.0 (on
44 * February 2015) by the following changeset:
45 * https://github.com/open-source-parsers/jsoncpp/commit/8df98f6112890d6272734975dd6d70cf8999bb22
46 **/
47 #if (JSONCPP_VERSION_MAJOR >= 2 || \
48 (JSONCPP_VERSION_MAJOR == 1 && JSONCPP_VERSION_MINOR >= 8))
49 # define JSONCPP_USE_DEPRECATED 0
50 #else
51 # define JSONCPP_USE_DEPRECATED 1
52 #endif
29 53
30 54
31 #if !ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 2, 0) 55 #if !ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 2, 0)
32 static const OrthancPluginErrorCode OrthancPluginErrorCode_NullPointer = OrthancPluginErrorCode_Plugin; 56 static const OrthancPluginErrorCode OrthancPluginErrorCode_NullPointer = OrthancPluginErrorCode_Plugin;
33 #endif 57 #endif
200 buffer_.size == 0) 224 buffer_.size == 0)
201 { 225 {
202 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); 226 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
203 } 227 }
204 228
205 const char* tmp = reinterpret_cast<const char*>(buffer_.data); 229 if (!ReadJson(target, buffer_.data, buffer_.size))
206
207 Json::Reader reader;
208 if (!reader.parse(tmp, tmp + buffer_.size, target))
209 { 230 {
210 LogError("Cannot convert some memory buffer to JSON"); 231 LogError("Cannot convert some memory buffer to JSON");
211 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); 232 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
212 } 233 }
213 } 234 }
290 return CheckHttp(OrthancPluginRestApiPut(GetGlobalContext(), &buffer_, uri.c_str(), b, bodySize)); 311 return CheckHttp(OrthancPluginRestApiPut(GetGlobalContext(), &buffer_, uri.c_str(), b, bodySize));
291 } 312 }
292 } 313 }
293 314
294 315
316 bool ReadJson(Json::Value& target,
317 const std::string& source)
318 {
319 #if JSONCPP_USE_DEPRECATED == 1
320 Json::Reader reader;
321 return reader.parse(source, target);
322 #else
323 return ReadJson(target, source.c_str(), source.size());
324 #endif
325 }
326
327
328 bool ReadJson(Json::Value& target,
329 const void* buffer,
330 size_t size)
331 {
332 #if JSONCPP_USE_DEPRECATED == 1
333 Json::Reader reader;
334 return reader.parse(reinterpret_cast<const char*>(buffer),
335 reinterpret_cast<const char*>(buffer) + size, target);
336 #else
337 Json::CharReaderBuilder builder;
338 const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
339 assert(reader.get() != NULL);
340 JSONCPP_STRING err;
341 if (reader->parse(reinterpret_cast<const char*>(buffer),
342 reinterpret_cast<const char*>(buffer) + size, &target, &err))
343 {
344 return true;
345 }
346 else
347 {
348 LogError("Cannot parse JSON: " + err);
349 return false;
350 }
351 #endif
352 }
353
354
355 void WriteFastJson(std::string& target,
356 const Json::Value& source)
357 {
358 #if JSONCPP_USE_DEPRECATED == 1
359 Json::FastWriter writer;
360 target = writer.write(source);
361 #else
362 Json::StreamWriterBuilder builder;
363 builder.settings_["indentation"] = "";
364 target = Json::writeString(builder, source);
365 #endif
366 }
367
368
369 void WriteStyledJson(std::string& target,
370 const Json::Value& source)
371 {
372 #if JSONCPP_USE_DEPRECATED == 1
373 Json::StyledWriter writer;
374 target = writer.write(source);
375 #else
376 Json::StreamWriterBuilder builder;
377 builder.settings_["indentation"] = " ";
378 target = Json::writeString(builder, source);
379 #endif
380 }
381
382
295 bool MemoryBuffer::RestApiPost(const std::string& uri, 383 bool MemoryBuffer::RestApiPost(const std::string& uri,
296 const Json::Value& body, 384 const Json::Value& body,
297 bool applyPlugins) 385 bool applyPlugins)
298 { 386 {
299 Json::FastWriter writer; 387 std::string s;
300 return RestApiPost(uri, writer.write(body), applyPlugins); 388 WriteFastJson(s, body);
389 return RestApiPost(uri, s, applyPlugins);
301 } 390 }
302 391
303 392
304 bool MemoryBuffer::RestApiPut(const std::string& uri, 393 bool MemoryBuffer::RestApiPut(const std::string& uri,
305 const Json::Value& body, 394 const Json::Value& body,
306 bool applyPlugins) 395 bool applyPlugins)
307 { 396 {
308 Json::FastWriter writer; 397 std::string s;
309 return RestApiPut(uri, writer.write(body), applyPlugins); 398 WriteFastJson(s, body);
399 return RestApiPut(uri, s, applyPlugins);
310 } 400 }
311 401
312 402
313 void MemoryBuffer::CreateDicom(const Json::Value& tags, 403 void MemoryBuffer::CreateDicom(const Json::Value& tags,
314 OrthancPluginCreateDicomFlags flags) 404 OrthancPluginCreateDicomFlags flags)
315 { 405 {
316 Clear(); 406 Clear();
317 407
318 Json::FastWriter writer; 408 std::string s;
319 std::string s = writer.write(tags); 409 WriteFastJson(s, tags);
320 410
321 Check(OrthancPluginCreateDicom(GetGlobalContext(), &buffer_, s.c_str(), NULL, flags)); 411 Check(OrthancPluginCreateDicom(GetGlobalContext(), &buffer_, s.c_str(), NULL, flags));
322 } 412 }
323 413
324 void MemoryBuffer::CreateDicom(const Json::Value& tags, 414 void MemoryBuffer::CreateDicom(const Json::Value& tags,
325 const OrthancImage& pixelData, 415 const OrthancImage& pixelData,
326 OrthancPluginCreateDicomFlags flags) 416 OrthancPluginCreateDicomFlags flags)
327 { 417 {
328 Clear(); 418 Clear();
329 419
330 Json::FastWriter writer; 420 std::string s;
331 std::string s = writer.write(tags); 421 WriteFastJson(s, tags);
332 422
333 Check(OrthancPluginCreateDicom(GetGlobalContext(), &buffer_, s.c_str(), pixelData.GetObject(), flags)); 423 Check(OrthancPluginCreateDicom(GetGlobalContext(), &buffer_, s.c_str(), pixelData.GetObject(), flags));
334 } 424 }
335 425
336 426
388 { 478 {
389 LogError("Cannot convert an empty memory buffer to JSON"); 479 LogError("Cannot convert an empty memory buffer to JSON");
390 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); 480 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
391 } 481 }
392 482
393 Json::Reader reader; 483 if (!ReadJson(target, str_))
394 if (!reader.parse(str_, target))
395 { 484 {
396 LogError("Cannot convert some memory buffer to JSON"); 485 LogError("Cannot convert some memory buffer to JSON");
397 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); 486 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
398 } 487 }
399 } 488 }
1188 } 1277 }
1189 1278
1190 #endif /* HAS_ORTHANC_PLUGIN_FIND_MATCHER == 1 */ 1279 #endif /* HAS_ORTHANC_PLUGIN_FIND_MATCHER == 1 */
1191 1280
1192 void AnswerJson(const Json::Value& value, 1281 void AnswerJson(const Json::Value& value,
1193 OrthancPluginRestOutput* output 1282 OrthancPluginRestOutput* output)
1194 ) 1283 {
1195 { 1284 std::string bodyString;
1196 Json::StyledWriter writer; 1285 WriteStyledJson(bodyString, value);
1197 std::string bodyString = writer.write(value);
1198
1199 OrthancPluginAnswerBuffer(GetGlobalContext(), output, bodyString.c_str(), bodyString.size(), "application/json"); 1286 OrthancPluginAnswerBuffer(GetGlobalContext(), output, bodyString.c_str(), bodyString.size(), "application/json");
1200 } 1287 }
1201 1288
1202 void AnswerString(const std::string& answer, 1289 void AnswerString(const std::string& answer,
1203 const char* mimeType, 1290 const char* mimeType,
1204 OrthancPluginRestOutput* output 1291 OrthancPluginRestOutput* output)
1205 )
1206 { 1292 {
1207 OrthancPluginAnswerBuffer(GetGlobalContext(), output, answer.c_str(), answer.size(), mimeType); 1293 OrthancPluginAnswerBuffer(GetGlobalContext(), output, answer.c_str(), answer.size(), mimeType);
1208 } 1294 }
1209 1295
1210 void AnswerHttpError(uint16_t httpError, OrthancPluginRestOutput *output) 1296 void AnswerHttpError(uint16_t httpError, OrthancPluginRestOutput *output)
1322 bool RestApiPost(Json::Value& result, 1408 bool RestApiPost(Json::Value& result,
1323 const std::string& uri, 1409 const std::string& uri,
1324 const Json::Value& body, 1410 const Json::Value& body,
1325 bool applyPlugins) 1411 bool applyPlugins)
1326 { 1412 {
1327 Json::FastWriter writer; 1413 std::string s;
1328 return RestApiPost(result, uri, writer.write(body), applyPlugins); 1414 WriteFastJson(s, body);
1415 return RestApiPost(result, uri, s, applyPlugins);
1329 } 1416 }
1330 1417
1331 1418
1332 bool RestApiPut(Json::Value& result, 1419 bool RestApiPut(Json::Value& result,
1333 const std::string& uri, 1420 const std::string& uri,
1355 bool RestApiPut(Json::Value& result, 1442 bool RestApiPut(Json::Value& result,
1356 const std::string& uri, 1443 const std::string& uri,
1357 const Json::Value& body, 1444 const Json::Value& body,
1358 bool applyPlugins) 1445 bool applyPlugins)
1359 { 1446 {
1360 Json::FastWriter writer; 1447 std::string s;
1361 return RestApiPut(result, uri, writer.write(body), applyPlugins); 1448 WriteFastJson(s, body);
1449 return RestApiPut(result, uri, s, applyPlugins);
1362 } 1450 }
1363 1451
1364 1452
1365 bool RestApiDelete(const std::string& uri, 1453 bool RestApiDelete(const std::string& uri,
1366 bool applyPlugins) 1454 bool applyPlugins)
2018 { 2106 {
2019 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_BadFileFormat); 2107 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_BadFileFormat);
2020 } 2108 }
2021 else 2109 else
2022 { 2110 {
2023 Json::FastWriter writer; 2111 WriteFastJson(content_, content);
2024 content_ = writer.write(content);
2025 } 2112 }
2026 } 2113 }
2027 2114
2028 2115
2029 void OrthancJob::ClearSerialized() 2116 void OrthancJob::ClearSerialized()
2039 { 2126 {
2040 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_BadFileFormat); 2127 ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_BadFileFormat);
2041 } 2128 }
2042 else 2129 else
2043 { 2130 {
2044 Json::FastWriter writer; 2131 WriteFastJson(serialized_, serialized);
2045 serialized_ = writer.write(serialized);
2046 hasSerialized_ = true; 2132 hasSerialized_ = true;
2047 } 2133 }
2048 } 2134 }
2049 2135
2050 2136
2900 Json::Value& answerBody /* out */) 2986 Json::Value& answerBody /* out */)
2901 { 2987 {
2902 std::string body; 2988 std::string body;
2903 Execute(answerHeaders, body); 2989 Execute(answerHeaders, body);
2904 2990
2905 Json::Reader reader; 2991 if (!ReadJson(answerBody, body))
2906 if (!reader.parse(body, answerBody))
2907 { 2992 {
2908 LogError("Cannot convert HTTP answer body to JSON"); 2993 LogError("Cannot convert HTTP answer body to JSON");
2909 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); 2994 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
2910 } 2995 }
2911 } 2996 }