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;
1318#ifdef CROW_JSON_USE_MAP
1319 std::map<std::string, wvalue>;
1321 std::unordered_map<std::string, wvalue>;
1324 using list = std::vector<wvalue>;
1326 type t()
const {
return t_; }
1332 type t_{type::Null};
1333 num_type nt{num_type::Null};
1341 constexpr number() noexcept:
1343 constexpr number(std::uint64_t value)
noexcept:
1345 constexpr number(std::int64_t value)
noexcept:
1347 explicit constexpr number(
double value)
noexcept:
1349 explicit constexpr number(
float value)
noexcept:
1353 std::unique_ptr<list> l;
1354 std::unique_ptr<object> o;
1355 std::function<std::string(std::string&)> f;
1359 returnable(
"application/json") {}
1361 wvalue(std::nullptr_t):
1362 returnable(
"application/json"), t_(type::Null) {}
1365 returnable(
"application/json"), t_(value ? type::True : type::False) {}
1367 wvalue(std::uint8_t value):
1368 returnable(
"application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
1369 wvalue(std::uint16_t value):
1370 returnable(
"application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
1371 wvalue(std::uint32_t value):
1372 returnable(
"application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
1373 wvalue(std::uint64_t value):
1374 returnable(
"application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
1376 wvalue(std::int8_t value):
1377 returnable(
"application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
1378 wvalue(std::int16_t value):
1379 returnable(
"application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
1380 wvalue(std::int32_t value):
1381 returnable(
"application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
1382 wvalue(std::int64_t value):
1383 returnable(
"application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
1385 wvalue(
float value):
1386 returnable(
"application/json"), t_(type::Number), nt(num_type::Floating_point), num(static_cast<double>(value)) {}
1387 wvalue(
double value):
1388 returnable(
"application/json"), t_(type::Number), nt(num_type::Double_precision_floating_point), num(static_cast<double>(value)) {}
1390 wvalue(
char const* value):
1391 returnable(
"application/json"), t_(type::String), s(value) {}
1393 wvalue(std::string
const& value):
1394 returnable(
"application/json"), t_(type::String), s(value) {}
1395 wvalue(std::string&& value):
1396 returnable(
"application/json"), t_(type::String), s(std::move(value)) {}
1398 wvalue(std::initializer_list<std::pair<std::string const, wvalue>> initializer_list):
1399 returnable(
"application/json"), t_(type::Object), o(new object(initializer_list)) {}
1401 wvalue(
object const& value):
1402 returnable(
"application/json"), t_(type::Object), o(new object(value)) {}
1403 wvalue(
object&& value):
1404 returnable(
"application/json"), t_(type::Object), o(new object(std::move(value))) {}
1406 wvalue(
const list& r):
1407 returnable(
"application/json")
1410 l = std::unique_ptr<list>(
new list{});
1411 l->reserve(r.size());
1412 for (
auto it = r.begin(); it != r.end(); ++it)
1413 l->emplace_back(*it);
1416 returnable(
"application/json")
1419 l = std::unique_ptr<list>(
new list{});
1420 l->reserve(r.size());
1421 for (
auto it = r.begin(); it != r.end(); ++it)
1422 l->emplace_back(*it);
1435 case type::Function:
1439 if (nt == num_type::Floating_point || nt == num_type::Double_precision_floating_point)
1441 else if (nt == num_type::Signed_integer)
1450 l = std::unique_ptr<list>(
new list{});
1451 l->reserve(r.size());
1452 for (
auto it = r.begin(); it != r.end(); ++it)
1453 l->emplace_back(*it);
1456 o = std::unique_ptr<object>(
new object{});
1457 for (
auto it = r.begin(); it != r.end(); ++it)
1458 o->emplace(it->key(), *it);
1475 if (nt == num_type::Floating_point || nt == num_type::Double_precision_floating_point)
1477 else if (nt == num_type::Signed_integer)
1486 l = std::unique_ptr<list>(
new list{});
1487 l->reserve(r.
size());
1488 for (
auto it = r.l->begin(); it != r.l->end(); ++it)
1489 l->emplace_back(*it);
1492 o = std::unique_ptr<object>(
new object{});
1493 o->insert(r.o->begin(), r.o->end());
1495 case type::Function:
1501 returnable(
"application/json")
1503 *
this = std::move(r);
1506 wvalue& operator=(wvalue&& r)
1530 wvalue& operator=(std::nullptr_t)
1535 wvalue& operator=(
bool value)
1545 wvalue& operator=(
float value)
1550 nt = num_type::Floating_point;
1554 wvalue& operator=(
double value)
1559 nt = num_type::Double_precision_floating_point;
1563 wvalue& operator=(
unsigned short value)
1568 nt = num_type::Unsigned_integer;
1572 wvalue& operator=(
short value)
1577 nt = num_type::Signed_integer;
1581 wvalue& operator=(
long long value)
1586 nt = num_type::Signed_integer;
1590 wvalue& operator=(
long value)
1595 nt = num_type::Signed_integer;
1599 wvalue& operator=(
int value)
1604 nt = num_type::Signed_integer;
1608 wvalue& operator=(
unsigned long long value)
1613 nt = num_type::Unsigned_integer;
1617 wvalue& operator=(
unsigned long value)
1622 nt = num_type::Unsigned_integer;
1626 wvalue& operator=(
unsigned int value)
1631 nt = num_type::Unsigned_integer;
1635 wvalue& operator=(
const char* str)
1643 wvalue& operator=(
const std::string& str)
1651 wvalue& operator=(list&& v)
1653 if (t_ != type::List)
1657 l = std::unique_ptr<list>(
new list{});
1659 l->resize(v.size());
1663 (*l)[idx++] = std::move(x);
1668 template<
typename T>
1669 wvalue& operator=(
const std::vector<T>& v)
1671 if (t_ != type::List)
1675 l = std::unique_ptr<list>(
new list{});
1677 l->resize(v.size());
1686 wvalue& operator=(std::initializer_list<std::pair<std::string const, wvalue>> initializer_list)
1688 if (t_ != type::Object)
1692 o = std::unique_ptr<object>(
new object(initializer_list));
1696#if defined(__APPLE__) || defined(__MACH__) || defined(__FreeBSD__) || defined(__ANDROID__) || defined(_LIBCPP_VERSION)
1697 o = std::unique_ptr<object>(
new object(initializer_list));
1699 (*o) = initializer_list;
1705 wvalue& operator=(
object const& value)
1707 if (t_ != type::Object)
1711 o = std::unique_ptr<object>(
new object(value));
1715#if defined(__APPLE__) || defined(__MACH__) || defined(__FreeBSD__) || defined(__ANDROID__) || defined(_LIBCPP_VERSION)
1716 o = std::unique_ptr<object>(
new object(value));
1724 wvalue& operator=(
object&& value)
1726 if (t_ != type::Object)
1730 o = std::unique_ptr<object>(
new object(std::move(value)));
1734 (*o) = std::move(value);
1739 wvalue& operator=(std::function<std::string(std::string&)>&& func)
1742 t_ = type::Function;
1743 f = std::move(func);
1747 wvalue& operator[](
unsigned index)
1749 if (t_ != type::List)
1753 l = std::unique_ptr<list>(
new list{});
1754 if (l->size() < index + 1)
1755 l->resize(index + 1);
1759 const wvalue& operator[](
unsigned index)
const
1761 return const_cast<wvalue*
>(
this)->
operator[](index);
1765 bool has(
const char* key)
const
1767 return has(std::string(key));
1771 bool has(
const std::string& key)
const
1773 if (t_ != type::Object)
1777#if (__cplusplus>=202002L)
1778 return o->contains(key);
1780 return o->count(key)>0;
1784 int count(
const std::string& str)
const
1786 if (t_ != type::Object)
1790 return o->count(str);
1793 wvalue& operator[](
const std::string& str)
1795 if (t_ != type::Object)
1799 o = std::unique_ptr<object>(
new object{});
1803 const wvalue& operator[](
const std::string& str)
const
1805 return const_cast<wvalue*
>(
this)->
operator[](str);
1808 std::vector<std::string> keys()
const
1810 if (t_ != type::Object)
1812 std::vector<std::string> result;
1815 result.push_back(kv.first);
1820 std::string execute(std::string txt =
"") const
1822 if (t_ != type::Function)
1830 if (t_ != type::List)
1840 case type::Null:
return 4;
1841 case type::False:
return 5;
1842 case type::True:
return 4;
1843 case type::Number:
return 30;
1844 case type::String:
return 2 + s.size() + s.size() / 2;
1853 sum += x.estimate_length();
1866 sum += 2 + kv.first.size() + kv.first.size() / 2;
1867 sum += kv.second.estimate_length();
1872 case type::Function:
1879 inline void dump_string(
const std::string& str, std::string& out)
const
1886 inline void dump_indentation_part(std::string& out,
const size_t indent,
const char separator,
const int indent_level)
const
1888 out.push_back(
'\n');
1889 out.append(indent_level * indent, separator);
1893 inline void dump_internal(
const wvalue& v, std::string& out,
const size_t indent,
const char separator,
const int indent_level = 0)
const
1897 case type::Null: out +=
"null";
break;
1898 case type::False: out +=
"false";
break;
1899 case type::True: out +=
"true";
break;
1902 if (v.nt == num_type::Floating_point || v.nt == num_type::Double_precision_floating_point)
1904 if (isnan(v.num.d) || isinf(v.num.d))
1907 CROW_LOG_WARNING <<
"Invalid JSON value detected (" << v.num.d <<
"), value set to null";
1918 if (v.nt == num_type::Double_precision_floating_point)
1921 sprintf_s(outbuf,
sizeof(outbuf),
"%.*g", std::numeric_limits<double>::max_digits10, v.num.d);
1923 snprintf(outbuf,
sizeof(outbuf),
"%.*g", std::numeric_limits<double>::max_digits10, v.num.d);
1929 sprintf_s(outbuf,
sizeof(outbuf),
"%f", v.num.d);
1931 snprintf(outbuf,
sizeof(outbuf),
"%f", v.num.d);
1934 char* p = &outbuf[0];
1935 char* pos_first_trailing_0 =
nullptr;
1936 char* pos_exponent =
nullptr;
1947 char fch = *(p + 1);
1949 if (fch !=
'\0' && fch ==
'0') p++;
1958 pos_first_trailing_0 = p;
1975 pos_first_trailing_0 =
nullptr;
1985 if (pos_first_trailing_0 !=
nullptr)
1987 *pos_first_trailing_0 =
'\0';
1988 if (pos_exponent !=
nullptr)
1990 strcpy(pos_first_trailing_0, pos_exponent);
1995 else if (v.nt == num_type::Signed_integer)
1997 out += std::to_string(v.num.si);
2001 out += std::to_string(v.num.ui);
2005 case type::String: dump_string(v.s, out);
break;
2010 if (indent !=std::string::npos)
2012 dump_indentation_part(out, indent, separator, indent_level + 1);
2018 for (
auto& x : *v.l)
2024 if (indent != std::string::npos)
2026 dump_indentation_part(out, indent, separator, indent_level + 1);
2030 dump_internal(x, out, indent, separator, indent_level + 1);
2034 if (indent !=std::string::npos)
2036 dump_indentation_part(out, indent, separator, indent_level);
2046 if (indent != std::string::npos)
2048 dump_indentation_part(out, indent, separator, indent_level + 1);
2054 for (
auto& kv : *v.o)
2059 if (indent != std::string::npos)
2061 dump_indentation_part(out, indent, separator, indent_level + 1);
2065 dump_string(kv.first, out);
2068 if (indent != std::string::npos)
2073 dump_internal(kv.second, out, indent, separator, indent_level + 1);
2077 if (indent != std::string::npos)
2079 dump_indentation_part(out, indent, separator, indent_level);
2086 case type::Function:
2087 out +=
"custom function";
2093 std::string dump(
const size_t indent,
const char separator =
' ')
const
2097 dump_internal(*
this, ret, indent, separator);
2101 std::string dump()
const override
2103 static constexpr size_t DontIndent = std::string::npos;
2105 return dump(DontIndent);
2109 explicit operator std::string()
const