31 #ifndef HELPER_JSON_HPP_ 32 #define HELPER_JSON_HPP_ 36 #include "../Main/Exception.hpp" 37 #include "../Struct/TextMap.hpp" 39 #include "../_extern/jsoncons/include/jsoncons/json.hpp" 45 #include "../_extern/rapidjson/include/rapidjson/document.h" 46 #include "../_extern/rapidjson/include/rapidjson/error/en.h" 47 #include "../_extern/rapidjson/include/rapidjson/error/error.h" 48 #include "../_extern/rapidjson/include/rapidjson/stringbuffer.h" 49 #include "../_extern/rapidjson/include/rapidjson/writer.h" 93 [[nodiscard]] std::string
stringify(
const std::vector<std::string>& vectorToStringify);
94 [[nodiscard]] std::string
stringify(
const std::string& stringToStringify);
95 [[nodiscard]] std::string
stringify(
const char * stringToStringify);
97 const std::vector<std::vector<std::pair<std::string, std::string>>>& vectorToStringify
100 [[nodiscard]] std::string
stringify(
const rapidjson::Value& value);
101 [[nodiscard]] std::string
stringify(
const jsoncons::json& json);
107 [[nodiscard]] std::string
cleanCopy(std::string_view json);
108 [[nodiscard]] rapidjson::Document
parseRapid(std::string_view json);
109 [[nodiscard]] jsoncons::json
parseCons(std::string_view json);
112 std::string_view json
119 static void free(rapidjson::Document& target);
158 inline std::string
stringify(
const std::vector<std::string>& vectorToStringify) {
160 rapidjson::Document document;
164 rapidjson::Document::AllocatorType& allocator{document.GetAllocator()};
167 document.Reserve(vectorToStringify.size(), allocator);
170 for(
const auto& element : vectorToStringify) {
171 rapidjson::Value stringValue;
173 stringValue.SetString(element, allocator);
175 document.PushBack(stringValue, allocator);
179 rapidjson::StringBuffer buffer;
180 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
183 document.Accept(writer);
186 return std::string(buffer.GetString(), buffer.GetSize());
210 inline std::string
stringify(
const std::string& stringToStringify) {
212 rapidjson::Document document;
216 rapidjson::Document::AllocatorType& allocator{document.GetAllocator()};
219 rapidjson::Value stringValue;
221 stringValue.SetString(stringToStringify, allocator);
223 document.PushBack(stringValue, allocator);
226 rapidjson::StringBuffer buffer;
227 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
230 document.Accept(writer);
233 return std::string(buffer.GetString(), buffer.GetSize());
257 inline std::string
stringify(
const char * stringToStringify) {
258 return stringify(std::string(stringToStringify));
279 inline std::string
stringify(
const std::vector<std::vector<std::pair<std::string, std::string>>>& vectorToStringify) {
281 rapidjson::Document document;
285 rapidjson::Document::AllocatorType& allocator{document.GetAllocator()};
288 document.Reserve(vectorToStringify.size(), allocator);
291 for(
const auto& element : vectorToStringify) {
293 rapidjson::Value objectValue;
295 objectValue.SetObject();
298 for(
const auto& pair : element) {
300 rapidjson::Value key;
302 key.SetString(pair.first, allocator);
305 rapidjson::Value value;
307 value.SetString(pair.second, allocator);
310 objectValue.AddMember(key, value, allocator);
314 document.PushBack(objectValue, allocator);
318 rapidjson::StringBuffer buffer;
319 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
322 document.Accept(writer);
325 return std::string(buffer.GetString(), buffer.GetSize());
349 rapidjson::Document document;
353 rapidjson::Document::AllocatorType& allocator{document.GetAllocator()};
356 document.Reserve(textMapToStringify.size(), allocator);
359 for(
const auto& textMapEntry : textMapToStringify) {
361 rapidjson::Value objectValue;
363 objectValue.SetObject();
366 rapidjson::Value keyPos;
368 keyPos.SetString(
"p", 1, allocator);
370 rapidjson::Value valuePos;
372 valuePos.SetUint64(Struct::TextMapEntry::pos(textMapEntry));
374 objectValue.AddMember(keyPos, valuePos, allocator);
377 rapidjson::Value keyLength;
379 keyLength.SetString(
"l", 1, allocator);
381 rapidjson::Value valueLength;
385 objectValue.AddMember(keyLength, valueLength, allocator);
388 rapidjson::Value keyValue;
390 keyValue.SetString(
"v", 1, allocator);
392 rapidjson::Value valueValue;
394 valueValue.SetString(textMapEntry.value, allocator);
396 objectValue.AddMember(keyValue, valueValue, allocator);
399 document.PushBack(objectValue, allocator);
403 rapidjson::StringBuffer buffer;
404 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
407 document.Accept(writer);
410 return std::string(buffer.GetString(), buffer.GetSize());
427 inline std::string
stringify(
const rapidjson::Value& value) {
428 rapidjson::StringBuffer buffer;
429 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
431 value.Accept(writer);
433 return std::string(buffer.GetString(), buffer.GetSize());
449 inline std::string
stringify(
const jsoncons::json& json) {
478 return std::string();
483 for(std::size_t n{}; n < json.length(); ++n) {
485 if(std::iscntrl(json[n]) != 0) {
490 if(json[n] ==
'\\') {
491 bool validEscapeSequence{
false};
493 if(n < json.length() - 1) {
494 switch(std::tolower(json[n + 1])) {
501 result.push_back(
'\\');
503 validEscapeSequence =
true;
516 validEscapeSequence =
true;
523 validEscapeSequence =
537 if(!validEscapeSequence) {
539 result.push_back(
'\\');
542 result.push_back(
'\\');
545 result.push_back(json[n]);
575 inline rapidjson::Document
parseRapid(std::string_view json) {
579 rapidjson::Document doc;
581 doc.Parse(cleanJson);
583 if(doc.HasParseError() && cleanJson.find(
'\\') != std::string::npos) {
587 doc.Parse(cleanJson);
590 if(doc.HasParseError()) {
591 std::string exceptionStr{
592 "Json::parseRapid(): " 595 exceptionStr += rapidjson::GetParseError_En(doc.GetParseError());
596 exceptionStr +=
" at '";
601 else if(doc.GetErrorOffset() > 0) {
602 exceptionStr += cleanJson.substr(0, doc.GetErrorOffset());
605 exceptionStr +=
"[!]";
607 if(cleanJson.size() > doc.GetErrorOffset() +
numDebugChars) {
608 exceptionStr += cleanJson.substr(doc.GetErrorOffset(),
numDebugChars);
610 else if(cleanJson.size() > doc.GetErrorOffset()) {
611 exceptionStr += cleanJson.substr(doc.GetErrorOffset());
645 inline jsoncons::json
parseCons(std::string_view json) {
650 jsoncons::json result{jsoncons::json::parse(cleanJson)};
654 catch(
const jsoncons::json_exception&) {
656 if(cleanJson.find(
'\\') == std::string::npos) {
663 jsoncons::json result{jsoncons::json::parse(cleanJson)};
667 catch(
const jsoncons::json_exception& e2) {
669 "Json::parseCons(): " 670 + std::string(e2.what())
706 rapidjson::Document document{
parseRapid(json)};
708 if(!document.IsArray()) {
710 "Json::parseTextMapJson():" 718 for(
const auto& element : document.GetArray()) {
719 if(!element.IsObject()) {
721 "Json::parseTextMapJson():" 723 " (an array element is not an object" 727 const auto p{element.FindMember(
"p")};
728 const auto l{element.FindMember(
"l")};
729 const auto v{element.FindMember(
"v")};
731 if(p == element.MemberEnd() || !(p->value.IsUint64())) {
733 "Json::parseTextMapJson():" 735 " (could not find valid position)" 739 if(l == element.MemberEnd() || !(l->value.IsUint64())) {
741 "Json::parseTextMapJson():" 743 " (could not find valid length)" 747 if(v == element.MemberEnd() || !(v->value.IsString())) {
749 "Json::parseTextMapJson():" 751 " (could not find valid value)" 756 p->value.GetUint64(),
757 l->value.GetUint64(),
759 v->value.GetString(),
760 v->value.GetStringLength()
794 std::string_view json
801 rapidjson::Document document{
parseRapid(json)};
803 if(!document.IsArray()) {
805 "Json::parsePosLenPairsJson():" 806 " Invalid array of [pos;length] pairs" 811 std::vector<std::pair<std::size_t, std::size_t>> result;
813 for(
const auto& element : document.GetArray()) {
814 if(!element.IsArray()) {
816 "Json::parsePosLenPairsJson():" 817 " Invalid array of [pos;length] pairs" 818 " (an array element is not an array)" 822 if(element.Size() != 2) {
824 "Json::parsePosLenPairsJson():" 825 " Invalid array of [pos;length] pairs" 826 " (a pair is not of size 2)" 830 const auto a{element.GetArray()};
832 if(!(a[0].IsUint64())) {
834 "Json::parsePosLenPairsJson():" 835 " Invalid array of [pos;length] pairs" 836 " (could not find valid position)" 840 if(!(a[1].IsUint64())) {
842 "Json::parsePosLenPairsJson():" 843 " Invalid array of [pos;length] pairs" 844 " (could not find valid length)" 862 inline void free(rapidjson::Document& target) {
863 rapidjson::Value(rapidjson::kObjectType).Swap(target);
constexpr auto unicodeEscapeDigit4
The offset of the fourth Unicode character digit in JSON code (from the '\').
Definition: Json.hpp:79
constexpr auto unicodeEscapeDigit1
The offset of the first Unicode character digit in JSON code (from the '\').
Definition: Json.hpp:70
constexpr auto unicodeEscapeDigit3
The offset of the third Unicode character digit in JSON code (from the '\').
Definition: Json.hpp:76
std::vector< std::pair< std::size_t, std::size_t > > parsePosLenPairsJson(std::string_view json)
Parses JSON code using RapidJSON and converts it into [pos;length] pairs.
Definition: Json.hpp:793
Namespace for global JSON helper functions.
Definition: Json.hpp:57
constexpr auto numDebugChars
The number of characters to show before and behind a JSON error.
Definition: Json.hpp:82
rapidjson::Document parseRapid(std::string_view json)
Parses JSON code using RapidJSON.
Definition: Json.hpp:575
#define MAIN_EXCEPTION_CLASS()
Macro used to easily define classes for general exceptions.
Definition: Exception.hpp:50
Class for JSON exceptions.
Definition: Json.hpp:136
constexpr auto unicodeEscapeLength
The length of an escaped Unicode character in JSON code (including the '\u').
Definition: Json.hpp:67
Struct::TextMap parseTextMapJson(std::string_view json)
Parses JSON code using RapidJSON and converts it into a text map.
Definition: Json.hpp:700
void replaceAll(std::string &strInOut, std::string_view needle, std::string_view replacement)
Replaces all occurences within a string with another string.
Definition: Strings.hpp:246
std::vector< TextMapEntry > TextMap
A text map is defined as a vector of text map entries.
Definition: TextMap.hpp:280
std::string cleanCopy(std::string_view json)
Copies and cleans the given JSON code to prepare it for parsing.
Definition: Json.hpp:476
std::size_t length(std::string_view str)
Definition: Utf8.hpp:327
std::string stringify(const jsoncons::json &json)
Stringifies a JSON value using jsoncons.
Definition: Json.hpp:449
::std::size_t SizeType
Definition: Json.hpp:43
jsoncons::json parseCons(std::string_view json)
Parses JSON code using jsoncons.
Definition: Json.hpp:645
static void free(rapidjson::Document &target)
Frees memory by swapping.
Definition: Json.hpp:862
constexpr auto unicodeEscapeDigit2
The offset of the second Unicode character digit in JSON code (from the '\').
Definition: Json.hpp:73