7 #ifdef CROW_JSON_USE_MAP
10 #include <unordered_map>
19 #include "crow/utility.h"
20 #include "crow/settings.h"
21 #include "crow/returnable.h"
22 #include "crow/logging.h"
37 static inline char to_hex(
char c)
45 inline void escape(
const std::string& str, std::string& ret)
47 ret.reserve(ret.size() + str.size() + str.size() / 4);
52 case '"': ret +=
"\\\"";
break;
53 case '\\': ret +=
"\\\\";
break;
54 case '\n': ret +=
"\\n";
break;
55 case '\b': ret +=
"\\b";
break;
56 case '\f': ret +=
"\\f";
break;
57 case '\r': ret +=
"\\r";
break;
58 case '\t': ret +=
"\\t";
break;
60 if (c >= 0 && c < 0x20)
63 ret += to_hex(c / 16);
64 ret += to_hex(c % 16);
72 inline std::string escape(
const std::string& str)
79 enum class type : char
91 inline const char* get_type_str(type t)
95 case type::Number:
return "Number";
96 case type::False:
return "False";
97 case type::True:
return "True";
98 case type::List:
return "List";
99 case type::String:
return "String";
100 case type::Object:
return "Object";
101 case type::Function:
return "Function";
102 default:
return "Unknown";
106 enum class num_type : char
112 Double_precision_floating_point
116 rvalue
load(
const char* data,
size_t size);
160 operator std::string()
const
162 return std::string(
s_,
e_);
166 const char* begin()
const {
return s_; }
167 const char* end()
const {
return e_; }
168 size_t size()
const {
return end() - begin(); }
170 using iterator =
const char*;
171 using const_iterator =
const char*;
176 friend std::ostream& operator<<(std::ostream& os,
const r_string& s)
178 os << static_cast<std::string>(s);
183 void force(
char* s, uint32_t length)
191 friend bool operator==(
const r_string& l,
const r_string& r);
192 friend bool operator==(
const std::string& l,
const r_string& r);
193 friend bool operator==(
const r_string& l,
const std::string& r);
195 template<
typename T,
typename U>
196 inline static bool equals(
const T& l,
const U& r)
198 if (l.size() != r.size())
201 for (
size_t i = 0; i < l.size(); i++)
203 if (*(l.begin() + i) != *(r.begin() + i))
211 inline bool operator<(
const r_string& l,
const r_string& r)
213 return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
216 inline bool operator<(
const r_string& l,
const std::string& r)
218 return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
221 inline bool operator<(
const std::string& l,
const r_string& r)
223 return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
226 inline bool operator>(
const r_string& l,
const r_string& r)
228 return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
231 inline bool operator>(
const r_string& l,
const std::string& r)
233 return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
236 inline bool operator>(
const std::string& l,
const r_string& r)
238 return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
241 inline bool operator==(
const r_string& l,
const r_string& r)
243 return r_string::equals(l, r);
246 inline bool operator==(
const r_string& l,
const std::string& r)
248 return r_string::equals(l, r);
251 inline bool operator==(
const std::string& l,
const r_string& r)
253 return r_string::equals(l, r);
256 inline bool operator!=(
const r_string& l,
const r_string& r)
261 inline bool operator!=(
const r_string& l,
const std::string& r)
266 inline bool operator!=(
const std::string& l,
const r_string& r)
279 static const int cached_bit = 2;
280 static const int error_bit = 4;
288 lsize_{}, lremain_{}, t_{
t}
291 rvalue(type
t,
char*
s,
char* e) noexcept:
292 start_{
s}, end_{e}, t_{
t}
294 determine_num_type();
298 start_(r.start_), end_(r.end_), key_(r.key_), t_(r.t_), nt_(r.nt_), option_(r.option_)
305 *
this = std::move(r);
323 key_ = std::move(r.key_);
324 l_ = std::move(r.l_);
326 lremain_ = r.lremain_;
333 explicit operator bool()
const noexcept
335 return (option_ & error_bit) == 0;
338 explicit operator int64_t()
const
343 explicit operator uint64_t()
const
348 explicit operator int()
const
350 return static_cast<int>(
i());
354 explicit operator std::string()
const
356 #ifndef CROW_JSON_NO_ERROR_CHECK
357 if (
t() == type::Object ||
t() == type::List)
358 throw std::runtime_error(
"json type container");
363 return std::string(
s());
365 return std::string(
"null");
367 return std::string(
"true");
369 return std::string(
"false");
371 return std::string(start_, end_ - start_);
378 #ifndef CROW_JSON_NO_ERROR_CHECK
379 if (option_ & error_bit)
381 throw std::runtime_error(
"invalid json object");
390 #ifndef CROW_JSON_NO_ERROR_CHECK
391 if (option_ & error_bit)
393 throw std::runtime_error(
"invalid json object");
402 #ifndef CROW_JSON_NO_ERROR_CHECK
407 return utility::lexical_cast<int64_t>(start_, end_ - start_);
409 const std::string msg =
"expected number, got: " + std::string(get_type_str(
t()));
410 throw std::runtime_error(msg);
413 return utility::lexical_cast<int64_t>(start_, end_ - start_);
419 #ifndef CROW_JSON_NO_ERROR_CHECK
424 return utility::lexical_cast<uint64_t>(start_, end_ - start_);
426 throw std::runtime_error(std::string(
"expected number, got: ") + get_type_str(
t()));
429 return utility::lexical_cast<uint64_t>(start_, end_ - start_);
435 #ifndef CROW_JSON_NO_ERROR_CHECK
436 if (
t() != type::Number)
437 throw std::runtime_error(
"value is not number");
439 return utility::lexical_cast<double>(start_, end_ - start_);
445 #ifndef CROW_JSON_NO_ERROR_CHECK
446 if (
t() != type::True &&
t() != type::False)
447 throw std::runtime_error(
"value is not boolean");
449 return t() == type::True;
455 #ifndef CROW_JSON_NO_ERROR_CHECK
456 if (
t() != type::String)
457 throw std::runtime_error(
"value is not string");
464 std::vector<rvalue>
lo()
const
466 #ifndef CROW_JSON_NO_ERROR_CHECK
467 if (
t() != type::Object &&
t() != type::List)
468 throw std::runtime_error(
"value is not a container");
470 std::vector<rvalue> ret;
472 for (uint32_t
i = 0;
i < lsize_;
i++)
474 ret.emplace_back(l_[
i]);
492 case '"': *tail++ =
'"';
break;
493 case '\\': *tail++ =
'\\';
break;
494 case '/': *tail++ =
'/';
break;
495 case 'b': *tail++ =
'\b';
break;
496 case 'f': *tail++ =
'\f';
break;
497 case 'n': *tail++ =
'\n';
break;
498 case 'r': *tail++ =
'\r';
break;
499 case 't': *tail++ =
'\t';
break;
502 auto from_hex = [](
char c) {
510 (from_hex(head[1]) << 12) +
511 (from_hex(head[2]) << 8) +
512 (from_hex(head[3]) << 4) +
516 *tail++ = 0xE0 | (code >> 12);
517 *tail++ = 0x80 | ((code >> 6) & 0x3F);
518 *tail++ = 0x80 | (code & 0x3F);
520 else if (code >= 0x80)
522 *tail++ = 0xC0 | (code >> 6);
523 *tail++ = 0x80 | (code & 0x3F);
545 bool has(
const char* str)
const
547 return has(std::string(str));
550 bool has(
const std::string& str)
const
556 return l.key_ < r.key_;
558 bool operator()(
const rvalue& l,
const std::string& r)
const
562 bool operator()(
const std::string& l,
const rvalue& r)
const
569 std::sort(begin(), end(), Pred());
572 auto it = lower_bound(begin(), end(), str, Pred());
573 return it != end() && it->key_ == str;
576 int count(
const std::string& str)
const
578 return has(str) ? 1 : 0;
581 rvalue* begin()
const
583 #ifndef CROW_JSON_NO_ERROR_CHECK
584 if (
t() != type::Object &&
t() != type::List)
585 throw std::runtime_error(
"value is not a container");
591 #ifndef CROW_JSON_NO_ERROR_CHECK
592 if (
t() != type::Object &&
t() != type::List)
593 throw std::runtime_error(
"value is not a container");
595 return l_.get() + lsize_;
598 const detail::r_string& key()
const
605 if (
t() == type::String)
607 #ifndef CROW_JSON_NO_ERROR_CHECK
608 if (
t() != type::Object &&
t() != type::List)
609 throw std::runtime_error(
"value is not a container");
614 const rvalue& operator[](
int index)
const
616 #ifndef CROW_JSON_NO_ERROR_CHECK
617 if (
t() != type::List)
618 throw std::runtime_error(
"value is not a list");
619 if (index >=
static_cast<int>(lsize_) || index < 0)
620 throw std::runtime_error(
"list out of bound");
625 const rvalue& operator[](
size_t index)
const
627 #ifndef CROW_JSON_NO_ERROR_CHECK
628 if (
t() != type::List)
629 throw std::runtime_error(
"value is not a list");
631 throw std::runtime_error(
"list out of bound");
636 const rvalue& operator[](
const char* str)
const
638 return this->operator[](std::string(str));
641 const rvalue& operator[](
const std::string& str)
const
643 #ifndef CROW_JSON_NO_ERROR_CHECK
644 if (
t() != type::Object)
645 throw std::runtime_error(
"value is not an object");
649 bool operator()(
const rvalue& l,
const rvalue& r)
const
651 return l.key_ < r.key_;
653 bool operator()(
const rvalue& l,
const std::string& r)
const
657 bool operator()(
const std::string& l,
const rvalue& r)
const
664 std::sort(begin(), end(), Pred());
667 auto it = lower_bound(begin(), end(), str, Pred());
668 if (it != end() && it->key_ == str)
670 #ifndef CROW_JSON_NO_ERROR_CHECK
671 throw std::runtime_error(
"cannot find key: " + str);
673 static rvalue nullValue;
680 option_ |= error_bit;
685 return (option_ & error_bit) != 0;
688 std::vector<std::string> keys()
const
690 #ifndef CROW_JSON_NO_ERROR_CHECK
691 if (
t() != type::Object)
692 throw std::runtime_error(
"value is not an object");
694 std::vector<std::string> ret;
696 for (uint32_t
i = 0;
i < lsize_;
i++)
698 ret.emplace_back(std::string(l_[
i].key()));
704 bool is_cached()
const
706 return (option_ & cached_bit) != 0;
708 void set_cached()
const
710 option_ |= cached_bit;
712 void copy_l(
const rvalue& r)
714 if (r.t() != type::Object && r.t() != type::List)
718 l_.reset(
new rvalue[lsize_]);
719 std::copy(r.begin(), r.end(), begin());
722 void emplace_back(rvalue&& v)
726 int new_size = lsize_ + lsize_;
727 if (new_size - lsize_ > 60000)
728 new_size = lsize_ + 60000;
731 rvalue* p =
new rvalue[new_size];
733 for (
auto& x : *
this)
734 *p2++ = std::move(x);
736 lremain_ = new_size - lsize_;
738 l_[lsize_++] = std::move(v);
743 void determine_num_type()
745 if (t_ != type::Number)
747 nt_ = num_type::Null;
751 const std::size_t len = end_ - start_;
752 const bool has_minus = std::memchr(start_,
'-', len) !=
nullptr;
753 const bool has_e = std::memchr(start_,
'e', len) !=
nullptr || std::memchr(start_,
'E', len) !=
nullptr;
754 const bool has_dec_sep = std::memchr(start_,
'.', len) !=
nullptr;
755 if (has_dec_sep || has_e)
756 nt_ = num_type::Floating_point;
758 nt_ = num_type::Signed_integer;
760 nt_ = num_type::Unsigned_integer;
763 mutable char* start_;
765 detail::r_string key_;
766 std::unique_ptr<rvalue[]> l_;
770 num_type nt_{num_type::Null};
771 mutable uint8_t option_{0};
773 friend rvalue load_nocopy_internal(
char* data,
size_t size);
774 friend rvalue load(
const char* data,
size_t size);
775 friend std::ostream& operator<<(std::ostream& os,
const rvalue& r)
780 case type::Null: os <<
"null";
break;
781 case type::False: os <<
"false";
break;
782 case type::True: os <<
"true";
break;
787 case num_type::Floating_point: os << r.d();
break;
788 case num_type::Double_precision_floating_point: os << r.d();
break;
789 case num_type::Signed_integer: os << r.i();
break;
790 case num_type::Unsigned_integer: os << r.u();
break;
791 case num_type::Null:
throw std::runtime_error(
"Number with num_type Null");
795 case type::String: os <<
'"' << r.s() <<
'"';
break;
818 os <<
'"' << escape(x.key_) <<
"\":";
825 case type::Function: os <<
"custom function";
break;
834 inline bool operator==(
const rvalue& l,
const std::string& r)
839 inline bool operator==(
const std::string& l,
const rvalue& r)
844 inline bool operator!=(
const rvalue& l,
const std::string& r)
849 inline bool operator!=(
const std::string& l,
const rvalue& r)
854 inline bool operator==(
const rvalue& l,
double r)
859 inline bool operator==(
double l,
const rvalue& r)
864 inline bool operator!=(
const rvalue& l,
double r)
869 inline bool operator!=(
double l,
const rvalue& r)
875 inline rvalue load_nocopy_internal(
char* data,
size_t size)
878 static constexpr
unsigned max_depth = 10000;
883 Parser(
char* data_,
size_t ):
890 if (CROW_UNLIKELY(*data != c))
898 while (*data ==
' ' || *data ==
'\t' || *data ==
'\r' || *data ==
'\n')
902 rvalue decode_string()
904 if (CROW_UNLIKELY(!consume(
'"')))
907 uint8_t has_escaping = 0;
910 if (CROW_LIKELY(*data !=
'"' && *data !=
'\\' && *data !=
'\0'))
914 else if (*data ==
'"')
917 *(start - 1) = has_escaping;
919 return {type::String, start, data - 1};
921 else if (*data ==
'\\')
929 auto check = [](
char c) {
930 return (
'0' <= c && c <=
'9') ||
931 (
'a' <= c && c <=
'f') ||
932 (
'A' <= c && c <=
'F');
934 if (!(check(*(data + 1)) &&
935 check(*(data + 2)) &&
936 check(*(data + 3)) &&
962 rvalue decode_list(
unsigned depth)
964 rvalue ret(type::List);
965 if (CROW_UNLIKELY(!consume(
'[')) || CROW_UNLIKELY(depth > max_depth))
971 if (CROW_UNLIKELY(*data ==
']'))
979 auto v = decode_value(depth + 1);
980 if (CROW_UNLIKELY(!v))
986 ret.emplace_back(std::move(v));
992 if (CROW_UNLIKELY(!consume(
',')))
1002 rvalue decode_number()
1006 enum NumberParsingState
1017 while (CROW_LIKELY(state != Invalid))
1022 state =
static_cast<NumberParsingState
>(
"\2\2\7\3\4\6\6"[state]);
1049 state =
static_cast<NumberParsingState
>(
"\3\3\7\3\4\6\6"[state]);
1050 while (*(data + 1) >=
'0' && *(data + 1) <=
'9')
1070 state =
static_cast<NumberParsingState
>(
"\7\7\4\4\7\7\7"[state]);
1081 state =
static_cast<NumberParsingState
>(
"\1\7\7\7\7\6\7"[state]);
1094 state =
static_cast<NumberParsingState
>(
"\7\7\7\7\7\6\7"[state]);
1104 state =
static_cast<NumberParsingState
>(
"\7\7\7\5\5\7\7"[state]);
1114 if (CROW_LIKELY(state == NumberParsingState::ZeroFirst ||
1115 state == NumberParsingState::Digits ||
1116 state == NumberParsingState::DigitsAfterPoints ||
1117 state == NumberParsingState::DigitsAfterE))
1118 return {type::Number, start, data};
1129 rvalue decode_value(
unsigned depth)
1134 return decode_list(depth + 1);
1136 return decode_object(depth + 1);
1138 return decode_string();
1146 return {type::True};
1158 return {type::False};
1169 return {type::Null};
1178 return decode_number();
1183 rvalue decode_object(
unsigned depth)
1185 rvalue ret(type::Object);
1186 if (CROW_UNLIKELY(!consume(
'{')) || CROW_UNLIKELY(depth > max_depth))
1194 if (CROW_UNLIKELY(*data ==
'}'))
1202 auto t = decode_string();
1203 if (CROW_UNLIKELY(!t))
1210 if (CROW_UNLIKELY(!consume(
':')))
1221 auto v = decode_value(depth + 1);
1222 if (CROW_UNLIKELY(!v))
1229 v.key_ = std::move(key);
1230 ret.emplace_back(std::move(v));
1231 if (CROW_UNLIKELY(*data ==
'}'))
1236 if (CROW_UNLIKELY(!consume(
',')))
1249 auto ret = decode_value(0);
1251 if (ret && *data !=
'\0')
1258 return Parser(data, size).parse();
1260 inline rvalue
load(
const char* data,
size_t size)
1262 char* s =
new char[size + 1];
1263 memcpy(s, data, size);
1265 auto ret = load_nocopy_internal(s, size);
1267 ret.key_.force(s, size);
1273 inline rvalue
load(
const char* data)
1275 return load(data, strlen(data));
1278 inline rvalue
load(
const std::string& str)
1280 return load(str.data(), str.size());
1283 struct wvalue_reader;
1297 #ifdef CROW_JSON_USE_MAP
1298 std::map<std::string, wvalue>;
1300 std::unordered_map<std::string, wvalue>;
1303 using list = std::vector<wvalue>;
1305 type t()
const {
return t_; }
1311 type t_{type::Null};
1312 num_type nt{num_type::Null};
1320 constexpr number() noexcept:
1322 constexpr number(std::uint64_t value) noexcept:
1324 constexpr number(std::int64_t value) noexcept:
1326 explicit constexpr number(
double value) noexcept:
1328 explicit constexpr number(
float value) noexcept:
1332 std::unique_ptr<list> l;
1333 std::unique_ptr<object> o;
1334 std::function<std::string(std::string&)> f;
1338 returnable(
"application/json") {}
1340 wvalue(std::nullptr_t):
1341 returnable(
"application/json"), t_(type::Null) {}
1344 returnable(
"application/json"), t_(value ? type::True : type::False) {}
1346 wvalue(std::uint8_t value):
1347 returnable(
"application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
1348 wvalue(std::uint16_t value):
1349 returnable(
"application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
1350 wvalue(std::uint32_t value):
1351 returnable(
"application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
1352 wvalue(std::uint64_t value):
1353 returnable(
"application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
1355 wvalue(std::int8_t value):
1356 returnable(
"application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
1357 wvalue(std::int16_t value):
1358 returnable(
"application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
1359 wvalue(std::int32_t value):
1360 returnable(
"application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
1361 wvalue(std::int64_t value):
1362 returnable(
"application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
1364 wvalue(
float value):
1365 returnable(
"application/json"), t_(type::Number), nt(num_type::Floating_point), num(static_cast<double>(value)) {}
1366 wvalue(
double value):
1367 returnable(
"application/json"), t_(type::Number), nt(num_type::Double_precision_floating_point), num(static_cast<double>(value)) {}
1369 wvalue(
char const* value):
1370 returnable(
"application/json"), t_(type::String), s(value) {}
1372 wvalue(std::string
const& value):
1373 returnable(
"application/json"), t_(type::String), s(value) {}
1374 wvalue(std::string&& value):
1375 returnable(
"application/json"), t_(type::String), s(std::move(value)) {}
1377 wvalue(std::initializer_list<std::pair<std::string const, wvalue>> initializer_list):
1378 returnable(
"application/json"), t_(type::Object), o(new object(initializer_list)) {}
1380 wvalue(
object const& value):
1381 returnable(
"application/json"), t_(type::Object), o(new object(value)) {}
1382 wvalue(
object&& value):
1383 returnable(
"application/json"), t_(type::Object), o(new object(std::move(value))) {}
1385 wvalue(
const list& r):
1386 returnable(
"application/json")
1389 l = std::unique_ptr<list>(
new list{});
1390 l->reserve(r.size());
1391 for (
auto it = r.begin(); it != r.end(); ++it)
1392 l->emplace_back(*it);
1395 returnable(
"application/json")
1398 l = std::unique_ptr<list>(
new list{});
1399 l->reserve(r.size());
1400 for (
auto it = r.begin(); it != r.end(); ++it)
1401 l->emplace_back(*it);
1414 case type::Function:
1418 if (nt == num_type::Floating_point || nt == num_type::Double_precision_floating_point)
1420 else if (nt == num_type::Signed_integer)
1429 l = std::unique_ptr<list>(
new list{});
1430 l->reserve(r.size());
1431 for (
auto it = r.begin(); it != r.end(); ++it)
1432 l->emplace_back(*it);
1435 o = std::unique_ptr<object>(
new object{});
1436 for (
auto it = r.begin(); it != r.end(); ++it)
1437 o->emplace(it->key(), *it);
1454 if (nt == num_type::Floating_point || nt == num_type::Double_precision_floating_point)
1456 else if (nt == num_type::Signed_integer)
1465 l = std::unique_ptr<list>(
new list{});
1466 l->reserve(r.
size());
1467 for (
auto it = r.l->begin(); it != r.l->end(); ++it)
1468 l->emplace_back(*it);
1471 o = std::unique_ptr<object>(
new object{});
1472 o->insert(r.o->begin(), r.o->end());
1474 case type::Function:
1480 returnable(
"application/json")
1482 *
this = std::move(r);
1485 wvalue& operator=(wvalue&& r)
1509 wvalue& operator=(std::nullptr_t)
1514 wvalue& operator=(
bool value)
1524 wvalue& operator=(
float value)
1529 nt = num_type::Floating_point;
1533 wvalue& operator=(
double value)
1538 nt = num_type::Double_precision_floating_point;
1542 wvalue& operator=(
unsigned short value)
1547 nt = num_type::Unsigned_integer;
1551 wvalue& operator=(
short value)
1556 nt = num_type::Signed_integer;
1560 wvalue& operator=(
long long value)
1565 nt = num_type::Signed_integer;
1569 wvalue& operator=(
long value)
1574 nt = num_type::Signed_integer;
1578 wvalue& operator=(
int value)
1583 nt = num_type::Signed_integer;
1587 wvalue& operator=(
unsigned long long value)
1592 nt = num_type::Unsigned_integer;
1596 wvalue& operator=(
unsigned long value)
1601 nt = num_type::Unsigned_integer;
1605 wvalue& operator=(
unsigned int value)
1610 nt = num_type::Unsigned_integer;
1614 wvalue& operator=(
const char* str)
1622 wvalue& operator=(
const std::string& str)
1630 wvalue& operator=(list&& v)
1632 if (t_ != type::List)
1636 l = std::unique_ptr<list>(
new list{});
1638 l->resize(v.size());
1642 (*l)[idx++] = std::move(x);
1647 template<
typename T>
1648 wvalue& operator=(
const std::vector<T>& v)
1650 if (t_ != type::List)
1654 l = std::unique_ptr<list>(
new list{});
1656 l->resize(v.size());
1665 wvalue& operator=(std::initializer_list<std::pair<std::string const, wvalue>> initializer_list)
1667 if (t_ != type::Object)
1671 o = std::unique_ptr<object>(
new object(initializer_list));
1675 #if defined(__APPLE__) || defined(__MACH__) || defined(__FreeBSD__) || defined(__ANDROID__) || defined(_LIBCPP_VERSION)
1676 o = std::unique_ptr<object>(
new object(initializer_list));
1678 (*o) = initializer_list;
1684 wvalue& operator=(
object const& value)
1686 if (t_ != type::Object)
1690 o = std::unique_ptr<object>(
new object(value));
1694 #if defined(__APPLE__) || defined(__MACH__) || defined(__FreeBSD__) || defined(__ANDROID__) || defined(_LIBCPP_VERSION)
1695 o = std::unique_ptr<object>(
new object(value));
1703 wvalue& operator=(
object&& value)
1705 if (t_ != type::Object)
1709 o = std::unique_ptr<object>(
new object(std::move(value)));
1713 (*o) = std::move(value);
1718 wvalue& operator=(std::function<std::string(std::string&)>&& func)
1721 t_ = type::Function;
1722 f = std::move(func);
1726 wvalue& operator[](
unsigned index)
1728 if (t_ != type::List)
1732 l = std::unique_ptr<list>(
new list{});
1733 if (l->size() < index + 1)
1734 l->resize(index + 1);
1738 const wvalue& operator[](
unsigned index)
const
1740 return const_cast<wvalue*
>(
this)->
operator[](index);
1743 int count(
const std::string& str)
const
1745 if (t_ != type::Object)
1749 return o->count(str);
1752 wvalue& operator[](
const std::string& str)
1754 if (t_ != type::Object)
1758 o = std::unique_ptr<object>(
new object{});
1762 const wvalue& operator[](
const std::string& str)
const
1764 return const_cast<wvalue*
>(
this)->
operator[](str);
1767 std::vector<std::string> keys()
const
1769 if (t_ != type::Object)
1771 std::vector<std::string> result;
1774 result.push_back(kv.first);
1779 std::string execute(std::string txt =
"") const
1781 if (t_ != type::Function)
1789 if (t_ != type::List)
1799 case type::Null:
return 4;
1800 case type::False:
return 5;
1801 case type::True:
return 4;
1802 case type::Number:
return 30;
1803 case type::String:
return 2 + s.size() + s.size() / 2;
1812 sum += x.estimate_length();
1825 sum += 2 + kv.first.size() + kv.first.size() / 2;
1826 sum += kv.second.estimate_length();
1831 case type::Function:
1838 inline void dump_string(
const std::string& str, std::string& out)
const
1845 inline void dump_indentation_part(std::string& out,
const int indent,
const char separator,
const int indent_level)
const
1847 out.push_back(
'\n');
1848 out.append(indent_level * indent, separator);
1852 inline void dump_internal(
const wvalue& v, std::string& out,
const int indent,
const char separator,
const int indent_level = 0)
const
1856 case type::Null: out +=
"null";
break;
1857 case type::False: out +=
"false";
break;
1858 case type::True: out +=
"true";
break;
1861 if (v.nt == num_type::Floating_point || v.nt == num_type::Double_precision_floating_point)
1863 if (isnan(v.num.d) || isinf(v.num.d))
1866 CROW_LOG_WARNING <<
"Invalid JSON value detected (" << v.num.d <<
"), value set to null";
1876 if (v.nt == num_type::Double_precision_floating_point)
1879 sprintf_s(outbuf,
sizeof(outbuf),
"%.*g", DECIMAL_DIG, v.num.d);
1881 snprintf(outbuf,
sizeof(outbuf),
"%.*g", DECIMAL_DIG, v.num.d);
1887 sprintf_s(outbuf,
sizeof(outbuf),
"%f", v.num.d);
1889 snprintf(outbuf,
sizeof(outbuf),
"%f", v.num.d);
1892 char* p = &outbuf[0];
1893 char* pos_first_trailing_0 =
nullptr;
1904 char fch = *(p + 1);
1906 if (fch !=
'\0' && fch ==
'0') p++;
1915 pos_first_trailing_0 = p;
1922 pos_first_trailing_0 =
nullptr;
1929 if (pos_first_trailing_0 !=
nullptr)
1930 *pos_first_trailing_0 =
'\0';
1933 else if (v.nt == num_type::Signed_integer)
1935 out += std::to_string(v.num.si);
1939 out += std::to_string(v.num.ui);
1943 case type::String: dump_string(v.s, out);
break;
1950 dump_indentation_part(out, indent, separator, indent_level + 1);
1956 for (
auto& x : *v.l)
1964 dump_indentation_part(out, indent, separator, indent_level + 1);
1968 dump_internal(x, out, indent, separator, indent_level + 1);
1974 dump_indentation_part(out, indent, separator, indent_level);
1986 dump_indentation_part(out, indent, separator, indent_level + 1);
1992 for (
auto& kv : *v.o)
1999 dump_indentation_part(out, indent, separator, indent_level + 1);
2003 dump_string(kv.first, out);
2011 dump_internal(kv.second, out, indent, separator, indent_level + 1);
2017 dump_indentation_part(out, indent, separator, indent_level);
2024 case type::Function:
2025 out +=
"custom function";
2031 std::string dump(
const int indent,
const char separator =
' ')
const
2035 dump_internal(*
this, ret, indent, separator);
2039 std::string dump()
const override
2041 static constexpr
int DontIndent = -1;
2043 return dump(DontIndent);
2050 int64_t get(int64_t fallback)
2052 if (ref.t() != type::Number || ref.nt == num_type::Floating_point ||
2053 ref.nt == num_type::Double_precision_floating_point)
2058 double get(
double fallback)
2060 if (ref.t() != type::Number || ref.nt != num_type::Floating_point ||
2061 ref.nt == num_type::Double_precision_floating_point)
2066 bool get(
bool fallback)
2068 if (ref.t() == type::True)
return true;
2069 if (ref.t() == type::False)
return false;
2073 std::string get(
const std::string& fallback)
2075 if (ref.t() != type::String)
return fallback;
JSON read value.
Definition: json.h:278
int64_t i() const
The integer value.
Definition: json.h:400
bool has(const char *str) const
Check if the json object has the passed string as a key.
Definition: json.h:545
double d() const
The double precision floating-point number value.
Definition: json.h:433
bool b() const
The boolean value.
Definition: json.h:443
uint64_t u() const
The unsigned integer value.
Definition: json.h:417
std::vector< rvalue > lo() const
The list or object value.
Definition: json.h:464
void unescape() const
Convert escaped string character to their original form ("\\n" -> ' ').
Definition: json.h:480
num_type nt() const
The number type of the JSON value.
Definition: json.h:388
type t() const
The type of the JSON value.
Definition: json.h:376
detail::r_string s() const
The string value.
Definition: json.h:453
JSON write value.
Definition: json.h:1291
wvalue(const rvalue &r)
Create a write value from a read value (useful for editing JSON strings).
Definition: json.h:1405
std::size_t size() const
If the wvalue is a list, it returns the length of the list, otherwise it returns 1.
Definition: json.h:1787
size_t estimate_length() const
Returns an estimated size of the value in bytes.
Definition: json.h:1795
static crow::json::wvalue empty_object()
Create an empty json value (outputs "{}" instead of a "null" string)
Definition: json.h:1308
void clear()
Used for compatibility, same as reset()
Definition: json.h:1497
Compiled mustache template object.
Definition: mustache.h:134
template_t load(const std::string &filename)
Open, read and renders a file using a mustache compiler. It also sanitize the input before compilatio...
Definition: mustache.h:812
The main namespace of the library. In this namespace is defined the most important classes and functi...
A read string implementation with comparison functionality.
Definition: json.h:122
char * s_
Start.
Definition: json.h:173
char * e_
End.
Definition: json.h:174
An abstract class that allows any other class to be returned by a handler.
Definition: returnable.h:9