58 #include <initializer_list>
64 #include <type_traits>
69 #pragma warning(disable : 4244)
70 #if _MSC_VER <= 1800 // VS 2013
72 #define noexcept throw()
76 #define snprintf _snprintf_s
93 using array = std::vector<Json>;
94 using object = std::map<std::string, Json>;
100 Json(
long long value);
102 Json(const
std::
string& value);
104 Json(const
char* value);
107 Json(const
object& values);
108 Json(
object&& values);
111 template <class T, class = decltype(&T::to_json)>
116 typename std::enable_if<
117 std::is_constructible<std::string, decltype(std::declval<M>().begin()->first)>::value &&
118 std::is_constructible<
Json, decltype(std::declval<M>().begin()->second)>::value,
124 typename std::enable_if<std::is_constructible<Json, decltype(*std::declval<V>().begin())>::value,
130 Json(
void*) =
delete;
176 void dump(std::string& out)
const;
194 static std::vector<Json>
parse_multi(
const std::string& in, std::string::size_type& parser_stop_pos,
199 std::string::size_type parser_stop_pos;
206 return !(*
this ==
rhs);
209 return !(
rhs < *
this);
212 return (
rhs < *
this);
215 return !(*
this <
rhs);
223 using shape = std::initializer_list<std::pair<std::string, Type>>;
226 err =
"expected JSON object, got " +
dump();
230 for (
auto& item :
types) {
231 if ((*
this)[item.first].type() != item.second) {
232 err =
"bad type for " + item.first +
" in " +
dump();
251 virtual bool equals(
const JsonValue* other)
const = 0;
252 virtual bool less(
const JsonValue* other)
const = 0;
253 virtual void dump(std::string& out)
const = 0;
254 virtual double number_value()
const;
255 virtual int int_value()
const;
256 virtual long long long_value()
const;
257 virtual bool bool_value()
const;
258 virtual const std::string& string_value()
const;
260 virtual const Json& operator[](
size_t i)
const;
262 virtual const Json& operator[](
const std::string& key)
const;
289 static void dump(
double value, std::string& out) {
290 if (std::isfinite(value)) {
292 snprintf(buf,
sizeof buf,
"%.17g", value);
299 static void dump(
long long value, std::string& out) {
301 snprintf(buf,
sizeof buf,
"%lld", value);
305 static void dump(
bool value, std::string& out) {
306 out += value ?
"true" :
"false";
309 static void dump(
const std::string& value, std::string& out) {
311 for (
size_t i = 0;
i < value.length();
i++) {
312 const char ch = value[
i];
315 }
else if (ch ==
'"') {
317 }
else if (ch ==
'\b') {
319 }
else if (ch ==
'\f') {
321 }
else if (ch ==
'\n') {
323 }
else if (ch ==
'\r') {
325 }
else if (ch ==
'\t') {
327 }
else if (
static_cast<uint8_t
>(ch) <= 0x1f) {
329 snprintf(buf,
sizeof buf,
"\\u%04x", ch);
331 }
else if (
static_cast<uint8_t
>(ch) == 0xe2 &&
static_cast<uint8_t
>(value[
i + 1]) == 0x80 &&
332 static_cast<uint8_t
>(value[
i + 2]) == 0xa8) {
335 }
else if (
static_cast<uint8_t
>(ch) == 0xe2 &&
static_cast<uint8_t
>(value[
i + 1]) == 0x80 &&
336 static_cast<uint8_t
>(value[
i + 2]) == 0xa9) {
349 for (
const auto& value : values) {
350 if (!first) out +=
", ";
360 for (
const auto& kv : values) {
361 if (!first) out +=
", ";
378 template <Json::Type tag,
typename T>
382 explicit Value(T value) : m_value(
std::move(value)) {}
391 return m_value ==
static_cast<const Value<tag, T>*
>(other)->m_value;
394 return m_value < static_cast<const Value<tag, T>*>(other)->m_value;
398 void dump(std::string& out)
const override {
408 return static_cast<int>(
m_value);
411 return static_cast<long long>(
m_value);
432 return static_cast<long long>(
m_value);
495 const std::shared_ptr<JsonValue>
null = std::make_shared<JsonNull>();
496 const std::shared_ptr<JsonValue>
t = std::make_shared<JsonBoolean>(
true);
497 const std::shared_ptr<JsonValue>
f = std::make_shared<JsonBoolean>(
false);
511 static const Json json_null;
537 return m_ptr->type();
540 return m_ptr->number_value();
543 return m_ptr->int_value();
546 return m_ptr->long_value();
549 return m_ptr->bool_value();
552 return m_ptr->string_value();
555 return m_ptr->array_items();
558 return m_ptr->object_items();
564 return (*
m_ptr)[key];
640 static inline std::string
esc(
char c) {
642 if (
static_cast<uint8_t
>(c) >= 0x20 &&
static_cast<uint8_t
>(c) <= 0x7f) {
643 snprintf(buf,
sizeof buf,
"'%c' (%d)", c, c);
645 snprintf(buf,
sizeof buf,
"(%d)", c);
647 return std::string(buf);
650 static inline bool in_range(
long x,
long lower,
long upper) {
651 return (x >= lower && x <= upper);
659 struct JsonParser final {
672 Json fail(std::string&& msg) {
673 return fail(std::move(msg), Json());
676 template <
typename T>
677 T fail(std::string&& msg, T err_ret) {
679 err = std::move(msg);
689 void consume_whitespace() {
690 while (
str[
i] ==
' ' ||
str[
i] ==
'\r' ||
str[
i] ==
'\n' ||
str[
i] ==
'\t') {
699 bool consume_comment() {
700 bool comment_found =
false;
703 if (
i ==
str.size()) {
704 return fail(
"unexpected end of input after start of comment",
false);
709 while (
i <
str.size() &&
str[
i] !=
'\n') {
712 comment_found =
true;
713 }
else if (
str[
i] ==
'*') {
715 if (
i >
str.size() - 2)
716 return fail(
"unexpected end of input inside multi-line comment",
false);
718 while (!(
str[
i] ==
'*' &&
str[
i + 1] ==
'/')) {
720 if (
i >
str.size() - 2)
721 return fail(
"unexpected end of input inside multi-line comment",
false);
724 comment_found =
true;
726 return fail(
"malformed comment",
false);
729 return comment_found;
736 void consume_garbage() {
737 consume_whitespace();
739 bool comment_found =
false;
741 comment_found = consume_comment();
745 consume_whitespace();
746 }
while (comment_found);
755 char get_next_token() {
758 return static_cast<char>(0);
760 if (
i ==
str.size()) {
761 return fail(
"unexpected end of input",
static_cast<char>(0));
771 void encode_utf8(
long pt, std::string& out) {
777 out +=
static_cast<char>(pt);
778 }
else if (pt < 0x800) {
779 out +=
static_cast<char>((pt >> 6) | 0xC0);
780 out +=
static_cast<char>((pt & 0x3F) | 0x80);
781 }
else if (pt < 0x10000) {
782 out +=
static_cast<char>((pt >> 12) | 0xE0);
783 out +=
static_cast<char>(((pt >> 6) & 0x3F) | 0x80);
784 out +=
static_cast<char>((pt & 0x3F) | 0x80);
786 out +=
static_cast<char>((pt >> 18) | 0xF0);
787 out +=
static_cast<char>(((pt >> 12) & 0x3F) | 0x80);
788 out +=
static_cast<char>(((pt >> 6) & 0x3F) | 0x80);
789 out +=
static_cast<char>((pt & 0x3F) | 0x80);
797 std::string parse_string() {
799 long last_escaped_codepoint = -1;
801 if (
i ==
str.size())
return fail(
"unexpected end of input in std::string",
"");
806 encode_utf8(last_escaped_codepoint, out);
811 return fail(
"unescaped " +
esc(ch) +
" in std::string",
"");
816 encode_utf8(last_escaped_codepoint, out);
817 last_escaped_codepoint = -1;
823 if (
i ==
str.size()) {
824 return fail(
"unexpected end of input in std::string",
"");
831 std::string
esc =
str.substr(
i, 4);
835 if (
esc.length() < 4) {
836 return fail(
"bad \\u escape: " +
esc,
"");
838 for (
size_t j = 0;
j < 4;
j++) {
841 return fail(
"bad \\u escape: " +
esc,
"");
844 long codepoint = strtol(
esc.data(),
nullptr, 16);
850 if (
in_range(last_escaped_codepoint, 0xD800, 0xDBFF) &&
in_range(codepoint, 0xDC00, 0xDFFF)) {
853 encode_utf8((((last_escaped_codepoint - 0xD800) << 10) | (codepoint - 0xDC00)) + 0x10000,
855 last_escaped_codepoint = -1;
857 encode_utf8(last_escaped_codepoint, out);
858 last_escaped_codepoint = codepoint;
865 encode_utf8(last_escaped_codepoint, out);
866 last_escaped_codepoint = -1;
870 }
else if (ch ==
'f') {
872 }
else if (ch ==
'n') {
874 }
else if (ch ==
'r') {
876 }
else if (ch ==
't') {
878 }
else if (ch ==
'"' || ch ==
'\\' || ch ==
'/') {
881 return fail(
"invalid escape character " +
esc(ch),
"");
890 Json parse_number() {
891 size_t start_pos =
i;
901 return fail(
"leading 0s not permitted in numbers");
909 return fail(
"invalid " +
esc(
str[
i]) +
" in number");
913 (
i - start_pos) <=
static_cast<size_t>(std::numeric_limits<int>::digits10)) {
914 return std::atoll(
str.c_str() + start_pos);
921 return fail(
"at least one digit required in fractional part");
930 if (
str[
i] ==
'e' ||
str[
i] ==
'E') {
933 if (
str[
i] ==
'+' ||
str[
i] ==
'-') {
938 return fail(
"at least one digit required in exponent");
946 return std::strtod(
str.c_str() + start_pos,
nullptr);
954 Json expect(
const std::string& expected, Json res) {
957 if (
str.compare(
i, expected.length(), expected) == 0) {
958 i += expected.length();
961 return fail(
"parse error: expected " + expected +
", got " +
str.substr(
i, expected.length()));
969 Json parse_json(
int depth) {
971 return fail(
"exceeded maximum nesting depth");
974 char ch = get_next_token();
979 if (ch ==
'-' || (ch >=
'0' && ch <=
'9')) {
981 return parse_number();
985 return expect(
"true",
true);
989 return expect(
"false",
false);
993 return expect(
"null", Json());
997 return parse_string();
1001 std::map<std::string, Json>
data;
1002 ch = get_next_token();
1008 if (ch !=
'"')
return fail(
"expected '\"' in object, got " +
esc(ch));
1010 std::string key = parse_string();
1015 ch = get_next_token();
1017 return fail(
"expected ':' in object, got " +
esc(ch));
1020 data[std::move(key)] = parse_json(depth + 1);
1025 ch = get_next_token();
1030 return fail(
"expected ',' in object, got " +
esc(ch));
1033 ch = get_next_token();
1039 std::vector<Json>
data;
1040 ch = get_next_token();
1047 data.push_back(parse_json(depth + 1));
1052 ch = get_next_token();
1057 return fail(
"expected ',' in list, got " +
esc(ch));
1060 ch = get_next_token();
1066 return fail(
"expected value, got " +
esc(ch));
1073 Json result = parser.parse_json(0);
1076 parser.consume_garbage();
1077 if (parser.failed) {
1080 if (parser.i != in.size()) {
1081 return parser.fail(
"unexpected trailing " +
esc(in[parser.i]));
1087 inline std::vector<Json>
parse_multi(
const std::string& in, std::string::size_type& parser_stop_pos,
1090 parser_stop_pos = 0;
1091 std::vector<Json> json_vec;
1092 while (parser.i != in.size() && !parser.failed) {
1093 json_vec.push_back(parser.parse_json(0));
1094 if (parser.failed) {
1099 parser.consume_garbage();
1100 if (parser.failed) {
1103 parser_stop_pos = parser.i;
1109 #pragma warning(default : 4244)