16 static void json_escape_unicode(std::string& res, std::string_view str, std::string_view::const_iterator& it) {
20 std::istringstream iss( std::string(str.substr(it-str.begin(), 4)));
23 unsigned int codePoint;
24 iss >> std::hex >> codePoint;
26 if (iss.fail() || codePoint > 0xFFFF) {
32 if (codePoint >= 0xD800 && codePoint <= 0xDFFF) {
36 if (codePoint >= 0xDC00) {
42 if (str.end() - it < 7 || *(it+1) !=
'\\' || *(it+2) !=
'u') {
49 std::istringstream lowIss( std::string(str.substr(it-str.begin(), 4) ));
52 unsigned int lowCodePoint;
53 lowIss >> std::hex >> lowCodePoint;
55 if (lowIss.fail() || lowCodePoint < 0xDC00 || lowCodePoint > 0xDFFF) {
61 codePoint = 0x10000 + ((codePoint - 0xD800) << 10) + (lowCodePoint - 0xDC00);
65 if (codePoint <= 0x7F) {
66 res +=
static_cast<char>(codePoint);
68 else if (codePoint <= 0x7FF) {
69 res +=
static_cast<char>(0xC0 | (codePoint >> 6));
70 res +=
static_cast<char>(0x80 | (codePoint & 0x3F));
72 else if (codePoint <= 0xFFFF) {
73 res +=
static_cast<char>(0xE0 | (codePoint >> 12));
74 res +=
static_cast<char>(0x80 | ((codePoint >> 6) & 0x3F));
75 res +=
static_cast<char>(0x80 | (codePoint & 0x3F));
77 else if (codePoint <= 0x10FFFF) {
78 res +=
static_cast<char>(0xF0 | (codePoint >> 18));
79 res +=
static_cast<char>(0x80 | ((codePoint >> 12) & 0x3F));
80 res +=
static_cast<char>(0x80 | ((codePoint >> 6) & 0x3F));
81 res +=
static_cast<char>(0x80 | (codePoint & 0x3F));
295 while(it != str.end() && std::isspace(*it)) ++it;
300 type_ = JsonType::OBJECT;
302 auto& jsonObject = std::get<JsonObject>(
content_);
305 while(it != str.end()){
306 while (it!=str.end() && std::isspace(*it)) ++it;
307 if(it == str.end() || *it ==
'}')
break;
312 while (it != str.end() && std::isspace(*it)) ++it;
314 if (*it ==
':') ++it;
317 while (it != str.end() && std::isspace(*it)) ++it;
318 jsonObject[std::move(key)] =
JsonValue ( str, it );
320 while (it != str.end() && std::isspace(*it)) ++it;
321 if (it != str.end() && *it ==
',') ++it;
329 type_ = JsonType::ARRAY;
331 auto& jsonArray = std::get<JsonArray>(
content_);
333 while(it!=str.end()){
334 while (it!=str.end() && std::isspace(*it)) ++it;
335 if(it == str.end() || *it ==
']')
break;
337 jsonArray.emplace_back( str, it );
339 while (it != str.end() && std::isspace(*it)) ++it;
340 if (it != str.end() && *it ==
',') ++it;
348 type_ = JsonType::STRING;
351 while(it != str.end() && *it !=
'\"'){
354 if(it == str.end())
break;
359 content_ = std::string (left, ++it);
364 type_ = JsonType::BOOL;
370 type_ = JsonType::BOOL;
379 type_ = JsonType::NUMBER;
380 bool have_not_point =
true;
381 bool have_not_e =
true;
386 while (it != str.end()) {
387 if (std::isdigit(*it)) ++it;
388 else if (*it ==
'.' && have_not_point && have_not_e) {
389 have_not_point =
false;
392 else if ((*it ==
'e' || *it ==
'E') && have_not_e) {
395 if (it != str.end() && (*it ==
'-' || *it ==
'+')) ++it;
433 if (init_list.size() == 0)
return;
434 if (init_list.size() == 2 && init_list.begin()->is_string()){
435 type_ = JsonType::OBJECT;
437 auto& map = std::get<JsonObject>(
content_);
438 map[init_list.begin()->as_string()] = init_list.begin()[1];
441 type_ = JsonType::ARRAY;
443 auto& list = std::get<JsonArray>(
content_);
444 list.reserve(init_list.size());
445 for (
const auto& it : init_list) {
644 case JsonType::OBJECT:
647 std::string res{
"{" };
648 int tabs = depth * space_num + space_num;
649 const auto& map = std::get<JsonObject>(content_);
650 for (
const auto& [fst, snd] : map) {
652 res.append(tabs,
' ');
656 res += snd.serialize_pretty(space_num, depth + 1);
659 if (*res.rbegin() ==
',') *res.rbegin() =
'\n';
661 res.append(tabs - space_num,
' ');
667 case JsonType::ARRAY:
670 std::string res{
"[" };
671 int tabs = depth * space_num + space_num;
672 const auto& list = std::get<JsonArray>(content_);
675 res.append(tabs,
' ');
676 res += it.serialize_pretty(space_num, depth + 1);
679 if (*res.rbegin() ==
',') *res.rbegin() =
'\n';
681 res.append(tabs - space_num,
' ');
688 return std::get<bool>(content_) ?
"true" :
"false";
689 case JsonType::ISNULL:
693 return std::get<std::string>(content_);