293 static const int cached_bit = 2;
294 static const int error_bit = 4;
302 lsize_{}, lremain_{}, t_{
t}
305 rvalue(type
t,
char*
s,
char* e)
noexcept:
306 start_{
s}, end_{e}, t_{
t}
308 determine_num_type();
312 start_(r.start_), end_(r.end_), key_(r.key_), t_(r.t_), nt_(r.nt_), option_(r.option_)
319 *
this = std::move(r);
337 key_ = std::move(r.key_);
338 l_ = std::move(r.l_);
340 lremain_ = r.lremain_;
347 explicit operator bool()
const noexcept
349 return (option_ & error_bit) == 0;
352 explicit operator int64_t()
const
357 explicit operator uint64_t()
const
362 explicit operator int()
const
364 return static_cast<int>(
i());
368 explicit operator std::string()
const
370#ifndef CROW_JSON_NO_ERROR_CHECK
371 if (
t() == type::Object ||
t() == type::List)
372 throw std::runtime_error(
"json type container");
377 return std::string(
s());
379 return std::string(
"null");
381 return std::string(
"true");
383 return std::string(
"false");
385 return std::string(start_, end_ - start_);
392#ifndef CROW_JSON_NO_ERROR_CHECK
393 if (option_ & error_bit)
395 throw std::runtime_error(
"invalid json object");
404#ifndef CROW_JSON_NO_ERROR_CHECK
405 if (option_ & error_bit)
407 throw std::runtime_error(
"invalid json object");
416#ifndef CROW_JSON_NO_ERROR_CHECK
421 return utility::lexical_cast<int64_t>(start_, end_ - start_);
423 const std::string msg =
"expected number, got: " + std::string(get_type_str(
t()));
424 throw std::runtime_error(msg);
427 return utility::lexical_cast<int64_t>(start_, end_ - start_);
433#ifndef CROW_JSON_NO_ERROR_CHECK
438 return utility::lexical_cast<uint64_t>(start_, end_ - start_);
440 throw std::runtime_error(std::string(
"expected number, got: ") + get_type_str(
t()));
443 return utility::lexical_cast<uint64_t>(start_, end_ - start_);
449#ifndef CROW_JSON_NO_ERROR_CHECK
450 if (
t() != type::Number)
451 throw std::runtime_error(
"value is not number");
453 return utility::lexical_cast<double>(start_, end_ - start_);
459#ifndef CROW_JSON_NO_ERROR_CHECK
460 if (
t() != type::True &&
t() != type::False)
461 throw std::runtime_error(
"value is not boolean");
463 return t() == type::True;
469#ifndef CROW_JSON_NO_ERROR_CHECK
470 if (
t() != type::String)
471 throw std::runtime_error(
"value is not string");
478 std::vector<rvalue>
lo()
const
480#ifndef CROW_JSON_NO_ERROR_CHECK
481 if (
t() != type::Object &&
t() != type::List)
482 throw std::runtime_error(
"value is not a container");
484 std::vector<rvalue> ret;
486 for (uint32_t
i = 0;
i < lsize_;
i++)
488 ret.emplace_back(l_[
i]);
506 case '"': *tail++ =
'"';
break;
507 case '\\': *tail++ =
'\\';
break;
508 case '/': *tail++ =
'/';
break;
509 case 'b': *tail++ =
'\b';
break;
510 case 'f': *tail++ =
'\f';
break;
511 case 'n': *tail++ =
'\n';
break;
512 case 'r': *tail++ =
'\r';
break;
513 case 't': *tail++ =
'\t';
break;
516 auto from_hex = [](
char c) {
524 (from_hex(head[1]) << 12) +
525 (from_hex(head[2]) << 8) +
526 (from_hex(head[3]) << 4) +
530 *tail++ = 0xE0 | (code >> 12);
531 *tail++ = 0x80 | ((code >> 6) & 0x3F);
532 *tail++ = 0x80 | (code & 0x3F);
534 else if (code >= 0x80)
536 *tail++ = 0xC0 | (code >> 6);
537 *tail++ = 0x80 | (code & 0x3F);
559 bool has(
const char* str)
const
561 return has(std::string(str));
564 bool has(
const std::string& str)
const
570 return l.key_ < r.key_;
572 bool operator()(
const rvalue& l,
const std::string& r)
const
576 bool operator()(
const std::string& l,
const rvalue& r)
const
583 std::sort(begin(), end(), Pred());
586 auto it = lower_bound(begin(), end(), str, Pred());
587 return it != end() && it->key_ == str;
590 int count(
const std::string& str)
const
592 return has(str) ? 1 : 0;
595 rvalue* begin()
const
597#ifndef CROW_JSON_NO_ERROR_CHECK
598 if (
t() != type::Object &&
t() != type::List)
599 throw std::runtime_error(
"value is not a container");
605#ifndef CROW_JSON_NO_ERROR_CHECK
606 if (
t() != type::Object &&
t() != type::List)
607 throw std::runtime_error(
"value is not a container");
609 return l_.get() + lsize_;
612 const detail::r_string& key()
const
619 if (
t() == type::String)
621#ifndef CROW_JSON_NO_ERROR_CHECK
622 if (
t() != type::Object &&
t() != type::List)
623 throw std::runtime_error(
"value is not a container");
628 const rvalue& operator[](
int index)
const
630#ifndef CROW_JSON_NO_ERROR_CHECK
631 if (
t() != type::List)
632 throw std::runtime_error(
"value is not a list");
633 if (index >=
static_cast<int>(lsize_) || index < 0)
634 throw std::runtime_error(
"list out of bound");
639 const rvalue& operator[](
size_t index)
const
641#ifndef CROW_JSON_NO_ERROR_CHECK
642 if (
t() != type::List)
643 throw std::runtime_error(
"value is not a list");
645 throw std::runtime_error(
"list out of bound");
650 const rvalue& operator[](
const char* str)
const
652 return this->operator[](std::string(str));
655 const rvalue& operator[](
const std::string& str)
const
657#ifndef CROW_JSON_NO_ERROR_CHECK
658 if (
t() != type::Object)
659 throw std::runtime_error(
"value is not an object");
663 bool operator()(
const rvalue& l,
const rvalue& r)
const
665 return l.key_ < r.key_;
667 bool operator()(
const rvalue& l,
const std::string& r)
const
671 bool operator()(
const std::string& l,
const rvalue& r)
const
678 std::sort(begin(), end(), Pred());
681 auto it = lower_bound(begin(), end(), str, Pred());
682 if (it != end() && it->key_ == str)
684#ifndef CROW_JSON_NO_ERROR_CHECK
685 throw std::runtime_error(
"cannot find key: " + str);
687 static rvalue nullValue;
694 option_ |= error_bit;
699 return (option_ & error_bit) != 0;
702 std::vector<std::string> keys()
const
704#ifndef CROW_JSON_NO_ERROR_CHECK
705 if (
t() != type::Object)
706 throw std::runtime_error(
"value is not an object");
708 std::vector<std::string> ret;
710 for (uint32_t
i = 0;
i < lsize_;
i++)
712 ret.emplace_back(std::string(l_[
i].key()));
718 bool is_cached()
const
720 return (option_ & cached_bit) != 0;
722 void set_cached()
const
724 option_ |= cached_bit;
726 void copy_l(
const rvalue& r)
728 if (r.t() != type::Object && r.t() != type::List)
732 l_.reset(
new rvalue[lsize_]);
733 std::copy(r.begin(), r.end(), begin());
736 void emplace_back(rvalue&& v)
740 int new_size = lsize_ + lsize_;
741 if (new_size - lsize_ > 60000)
742 new_size = lsize_ + 60000;
745 rvalue* p =
new rvalue[new_size];
747 for (
auto& x : *this)
748 *p2++ = std::move(x);
750 lremain_ = new_size - lsize_;
752 l_[lsize_++] = std::move(v);
757 void determine_num_type()
759 if (t_ != type::Number)
761 nt_ = num_type::Null;
765 const std::size_t len = end_ - start_;
766 const bool has_minus = std::memchr(start_,
'-', len) !=
nullptr;
767 const bool has_e = std::memchr(start_,
'e', len) !=
nullptr || std::memchr(start_,
'E', len) !=
nullptr;
768 const bool has_dec_sep = std::memchr(start_,
'.', len) !=
nullptr;
769 if (has_dec_sep || has_e)
770 nt_ = num_type::Floating_point;
772 nt_ = num_type::Signed_integer;
774 nt_ = num_type::Unsigned_integer;
777 mutable char* start_;
779 detail::r_string key_;
780 std::unique_ptr<rvalue[]> l_;
784 num_type nt_{num_type::Null};
785 mutable uint8_t option_{0};
787 friend rvalue load_nocopy_internal(
char* data,
size_t size);
788 friend rvalue load(
const char* data,
size_t size);
789 friend std::ostream& operator<<(std::ostream& os,
const rvalue& r)
794 case type::Null: os <<
"null";
break;
795 case type::False: os <<
"false";
break;
796 case type::True: os <<
"true";
break;
801 case num_type::Floating_point: os << r.d();
break;
802 case num_type::Double_precision_floating_point: os << r.d();
break;
803 case num_type::Signed_integer: os << r.i();
break;
804 case num_type::Unsigned_integer: os << r.u();
break;
805 case num_type::Null:
throw std::runtime_error(
"Number with num_type Null");
809 case type::String: os <<
'"' << r.s() <<
'"';
break;
832 os <<
'"' << escape(x.key_) <<
"\":";
839 case type::Function: os <<
"custom function";
break;
1311#ifdef CROW_JSON_USE_MAP
1312 std::map<std::string, wvalue>;
1314 std::unordered_map<std::string, wvalue>;
1317 using list = std::vector<wvalue>;
1319 type t()
const {
return t_; }
1325 type t_{type::Null};
1326 num_type nt{num_type::Null};
1334 constexpr number() noexcept:
1336 constexpr number(std::uint64_t value)
noexcept:
1338 constexpr number(std::int64_t value)
noexcept:
1340 explicit constexpr number(
double value)
noexcept:
1342 explicit constexpr number(
float value)
noexcept:
1346 std::unique_ptr<list> l;
1347 std::unique_ptr<object> o;
1348 std::function<std::string(std::string&)> f;
1352 returnable(
"application/json") {}
1354 wvalue(std::nullptr_t):
1355 returnable(
"application/json"), t_(type::Null) {}
1358 returnable(
"application/json"), t_(value ? type::True : type::False) {}
1360 wvalue(std::uint8_t value):
1361 returnable(
"application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
1362 wvalue(std::uint16_t value):
1363 returnable(
"application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
1364 wvalue(std::uint32_t value):
1365 returnable(
"application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
1366 wvalue(std::uint64_t value):
1367 returnable(
"application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
1369 wvalue(std::int8_t value):
1370 returnable(
"application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
1371 wvalue(std::int16_t value):
1372 returnable(
"application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
1373 wvalue(std::int32_t value):
1374 returnable(
"application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
1375 wvalue(std::int64_t value):
1376 returnable(
"application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
1378 wvalue(
float value):
1379 returnable(
"application/json"), t_(type::Number), nt(num_type::Floating_point), num(static_cast<double>(value)) {}
1380 wvalue(
double value):
1381 returnable(
"application/json"), t_(type::Number), nt(num_type::Double_precision_floating_point), num(static_cast<double>(value)) {}
1383 wvalue(
char const* value):
1384 returnable(
"application/json"), t_(type::String), s(value) {}
1386 wvalue(std::string
const& value):
1387 returnable(
"application/json"), t_(type::String), s(value) {}
1388 wvalue(std::string&& value):
1389 returnable(
"application/json"), t_(type::String), s(std::move(value)) {}
1391 wvalue(std::initializer_list<std::pair<std::string const, wvalue>> initializer_list):
1392 returnable(
"application/json"), t_(type::Object), o(new object(initializer_list)) {}
1394 wvalue(
object const& value):
1395 returnable(
"application/json"), t_(type::Object), o(new object(value)) {}
1396 wvalue(
object&& value):
1397 returnable(
"application/json"), t_(type::Object), o(new object(std::move(value))) {}
1399 wvalue(
const list& r):
1400 returnable(
"application/json")
1403 l = std::unique_ptr<list>(
new list{});
1404 l->reserve(r.size());
1405 for (
auto it = r.begin(); it != r.end(); ++it)
1406 l->emplace_back(*it);
1409 returnable(
"application/json")
1412 l = std::unique_ptr<list>(
new list{});
1413 l->reserve(r.size());
1414 for (
auto it = r.begin(); it != r.end(); ++it)
1415 l->emplace_back(*it);
1428 case type::Function:
1432 if (nt == num_type::Floating_point || nt == num_type::Double_precision_floating_point)
1434 else if (nt == num_type::Signed_integer)
1443 l = std::unique_ptr<list>(
new list{});
1444 l->reserve(r.size());
1445 for (
auto it = r.begin(); it != r.end(); ++it)
1446 l->emplace_back(*it);
1449 o = std::unique_ptr<object>(
new object{});
1450 for (
auto it = r.begin(); it != r.end(); ++it)
1451 o->emplace(it->key(), *it);
1468 if (nt == num_type::Floating_point || nt == num_type::Double_precision_floating_point)
1470 else if (nt == num_type::Signed_integer)
1479 l = std::unique_ptr<list>(
new list{});
1480 l->reserve(r.
size());
1481 for (
auto it = r.l->begin(); it != r.l->end(); ++it)
1482 l->emplace_back(*it);
1485 o = std::unique_ptr<object>(
new object{});
1486 o->insert(r.o->begin(), r.o->end());
1488 case type::Function:
1494 returnable(
"application/json")
1496 *
this = std::move(r);
1499 wvalue& operator=(wvalue&& r)
1523 wvalue& operator=(std::nullptr_t)
1528 wvalue& operator=(
bool value)
1538 wvalue& operator=(
float value)
1543 nt = num_type::Floating_point;
1547 wvalue& operator=(
double value)
1552 nt = num_type::Double_precision_floating_point;
1556 wvalue& operator=(
unsigned short value)
1561 nt = num_type::Unsigned_integer;
1565 wvalue& operator=(
short value)
1570 nt = num_type::Signed_integer;
1574 wvalue& operator=(
long long value)
1579 nt = num_type::Signed_integer;
1583 wvalue& operator=(
long value)
1588 nt = num_type::Signed_integer;
1592 wvalue& operator=(
int value)
1597 nt = num_type::Signed_integer;
1601 wvalue& operator=(
unsigned long long value)
1606 nt = num_type::Unsigned_integer;
1610 wvalue& operator=(
unsigned long value)
1615 nt = num_type::Unsigned_integer;
1619 wvalue& operator=(
unsigned int value)
1624 nt = num_type::Unsigned_integer;
1628 wvalue& operator=(
const char* str)
1636 wvalue& operator=(
const std::string& str)
1644 wvalue& operator=(list&& v)
1646 if (t_ != type::List)
1650 l = std::unique_ptr<list>(
new list{});
1652 l->resize(v.size());
1656 (*l)[idx++] = std::move(x);
1661 template<
typename T>
1662 wvalue& operator=(
const std::vector<T>& v)
1664 if (t_ != type::List)
1668 l = std::unique_ptr<list>(
new list{});
1670 l->resize(v.size());
1679 wvalue& operator=(std::initializer_list<std::pair<std::string const, wvalue>> initializer_list)
1681 if (t_ != type::Object)
1685 o = std::unique_ptr<object>(
new object(initializer_list));
1689#if defined(__APPLE__) || defined(__MACH__) || defined(__FreeBSD__) || defined(__ANDROID__) || defined(_LIBCPP_VERSION)
1690 o = std::unique_ptr<object>(
new object(initializer_list));
1692 (*o) = initializer_list;
1698 wvalue& operator=(
object const& value)
1700 if (t_ != type::Object)
1704 o = std::unique_ptr<object>(
new object(value));
1708#if defined(__APPLE__) || defined(__MACH__) || defined(__FreeBSD__) || defined(__ANDROID__) || defined(_LIBCPP_VERSION)
1709 o = std::unique_ptr<object>(
new object(value));
1717 wvalue& operator=(
object&& value)
1719 if (t_ != type::Object)
1723 o = std::unique_ptr<object>(
new object(std::move(value)));
1727 (*o) = std::move(value);
1732 wvalue& operator=(std::function<std::string(std::string&)>&& func)
1735 t_ = type::Function;
1736 f = std::move(func);
1740 wvalue& operator[](
unsigned index)
1742 if (t_ != type::List)
1746 l = std::unique_ptr<list>(
new list{});
1747 if (l->size() < index + 1)
1748 l->resize(index + 1);
1752 const wvalue& operator[](
unsigned index)
const
1754 return const_cast<wvalue*
>(
this)->
operator[](index);
1758 bool has(
const char* key)
const
1760 return has(std::string(key));
1764 bool has(
const std::string& key)
const
1766 if (t_ != type::Object)
1770#if (__cplusplus>=202002L)
1771 return o->contains(key);
1773 return o->count(key)>0;
1777 int count(
const std::string& str)
const
1779 if (t_ != type::Object)
1783 return o->count(str);
1786 wvalue& operator[](
const std::string& str)
1788 if (t_ != type::Object)
1792 o = std::unique_ptr<object>(
new object{});
1796 const wvalue& operator[](
const std::string& str)
const
1798 return const_cast<wvalue*
>(
this)->
operator[](str);
1801 std::vector<std::string> keys()
const
1803 if (t_ != type::Object)
1805 std::vector<std::string> result;
1808 result.push_back(kv.first);
1813 std::string execute(std::string txt =
"") const
1815 if (t_ != type::Function)
1823 if (t_ != type::List)
1833 case type::Null:
return 4;
1834 case type::False:
return 5;
1835 case type::True:
return 4;
1836 case type::Number:
return 30;
1837 case type::String:
return 2 + s.size() + s.size() / 2;
1846 sum += x.estimate_length();
1859 sum += 2 + kv.first.size() + kv.first.size() / 2;
1860 sum += kv.second.estimate_length();
1865 case type::Function:
1872 inline void dump_string(
const std::string& str, std::string& out)
const
1879 inline void dump_indentation_part(std::string& out,
const size_t indent,
const char separator,
const int indent_level)
const
1881 out.push_back(
'\n');
1882 out.append(indent_level * indent, separator);
1886 inline void dump_internal(
const wvalue& v, std::string& out,
const size_t indent,
const char separator,
const int indent_level = 0)
const
1890 case type::Null: out +=
"null";
break;
1891 case type::False: out +=
"false";
break;
1892 case type::True: out +=
"true";
break;
1895 if (v.nt == num_type::Floating_point || v.nt == num_type::Double_precision_floating_point)
1897 if (isnan(v.num.d) || isinf(v.num.d))
1900 CROW_LOG_WARNING <<
"Invalid JSON value detected (" << v.num.d <<
"), value set to null";
1911 if (v.nt == num_type::Double_precision_floating_point)
1914 sprintf_s(outbuf,
sizeof(outbuf),
"%.*g", std::numeric_limits<double>::max_digits10, v.num.d);
1916 snprintf(outbuf,
sizeof(outbuf),
"%.*g", std::numeric_limits<double>::max_digits10, v.num.d);
1922 sprintf_s(outbuf,
sizeof(outbuf),
"%f", v.num.d);
1924 snprintf(outbuf,
sizeof(outbuf),
"%f", v.num.d);
1927 char* p = &outbuf[0];
1928 char* pos_first_trailing_0 =
nullptr;
1929 char* pos_exponent =
nullptr;
1940 char fch = *(p + 1);
1942 if (fch !=
'\0' && fch ==
'0') p++;
1951 pos_first_trailing_0 = p;
1968 pos_first_trailing_0 =
nullptr;
1978 if (pos_first_trailing_0 !=
nullptr)
1980 *pos_first_trailing_0 =
'\0';
1981 if (pos_exponent !=
nullptr)
1983 strcpy(pos_first_trailing_0, pos_exponent);
1988 else if (v.nt == num_type::Signed_integer)
1990 out += std::to_string(v.num.si);
1994 out += std::to_string(v.num.ui);
1998 case type::String: dump_string(v.s, out);
break;
2003 if (indent !=std::string::npos)
2005 dump_indentation_part(out, indent, separator, indent_level + 1);
2011 for (
auto& x : *v.l)
2017 if (indent != std::string::npos)
2019 dump_indentation_part(out, indent, separator, indent_level + 1);
2023 dump_internal(x, out, indent, separator, indent_level + 1);
2027 if (indent !=std::string::npos)
2029 dump_indentation_part(out, indent, separator, indent_level);
2039 if (indent != std::string::npos)
2041 dump_indentation_part(out, indent, separator, indent_level + 1);
2047 for (
auto& kv : *v.o)
2052 if (indent != std::string::npos)
2054 dump_indentation_part(out, indent, separator, indent_level + 1);
2058 dump_string(kv.first, out);
2061 if (indent != std::string::npos)
2066 dump_internal(kv.second, out, indent, separator, indent_level + 1);
2070 if (indent != std::string::npos)
2072 dump_indentation_part(out, indent, separator, indent_level);
2079 case type::Function:
2080 out +=
"custom function";
2086 std::string dump(
const size_t indent,
const char separator =
' ')
const
2090 dump_internal(*
this, ret, indent, separator);
2094 std::string dump()
const override
2096 static constexpr size_t DontIndent = std::string::npos;
2098 return dump(DontIndent);
2102 explicit operator std::string()
const