json11.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  1. /* Copyright (c) 2013 Dropbox, Inc.
  2. *
  3. * Permission is hereby granted, free of charge, to any person obtaining a copy
  4. * of this software and associated documentation files (the "Software"), to deal
  5. * in the Software without restriction, including without limitation the rights
  6. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. * copies of the Software, and to permit persons to whom the Software is
  8. * furnished to do so, subject to the following conditions:
  9. *
  10. * The above copyright notice and this permission notice shall be included in
  11. * all copies or substantial portions of the Software.
  12. *
  13. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. * THE SOFTWARE.
  20. */
  21. #include "json11.hpp"
  22. #include <cassert>
  23. #include <cmath>
  24. #include <cstdlib>
  25. #include <cstdio>
  26. #include <limits>
  27. namespace json11 {
  28. static const int max_depth = 200;
  29. using std::string;
  30. using std::vector;
  31. using std::map;
  32. using std::make_shared;
  33. using std::initializer_list;
  34. using std::move;
  35. /* Helper for representing null - just a do-nothing struct, plus comparison
  36. * operators so the helpers in JsonValue work. We can't use nullptr_t because
  37. * it may not be orderable.
  38. */
  39. struct NullStruct {
  40. bool operator==(NullStruct) const { return true; }
  41. bool operator<(NullStruct) const { return false; }
  42. };
  43. /* * * * * * * * * * * * * * * * * * * *
  44. * Serialization
  45. */
  46. static void dump(NullStruct, string &out) {
  47. out += "null";
  48. }
  49. static void dump(double value, string &out) {
  50. if (std::isfinite(value)) {
  51. char buf[32];
  52. snprintf(buf, sizeof buf, "%.17g", value);
  53. out += buf;
  54. } else {
  55. out += "null";
  56. }
  57. }
  58. static void dump(int value, string &out) {
  59. char buf[32];
  60. snprintf(buf, sizeof buf, "%d", value);
  61. out += buf;
  62. }
  63. static void dump(bool value, string &out) {
  64. out += value ? "true" : "false";
  65. }
  66. static void dump(const string &value, string &out) {
  67. out += '"';
  68. for (size_t i = 0; i < value.length(); i++) {
  69. const char ch = value[i];
  70. if (ch == '\\') {
  71. out += "\\\\";
  72. } else if (ch == '"') {
  73. out += "\\\"";
  74. } else if (ch == '\b') {
  75. out += "\\b";
  76. } else if (ch == '\f') {
  77. out += "\\f";
  78. } else if (ch == '\n') {
  79. out += "\\n";
  80. } else if (ch == '\r') {
  81. out += "\\r";
  82. } else if (ch == '\t') {
  83. out += "\\t";
  84. } else if (static_cast<uint8_t>(ch) <= 0x1f) {
  85. char buf[8];
  86. snprintf(buf, sizeof buf, "\\u%04x", ch);
  87. out += buf;
  88. } else if (static_cast<uint8_t>(ch) == 0xe2 && static_cast<uint8_t>(value[i+1]) == 0x80
  89. && static_cast<uint8_t>(value[i+2]) == 0xa8) {
  90. out += "\\u2028";
  91. i += 2;
  92. } else if (static_cast<uint8_t>(ch) == 0xe2 && static_cast<uint8_t>(value[i+1]) == 0x80
  93. && static_cast<uint8_t>(value[i+2]) == 0xa9) {
  94. out += "\\u2029";
  95. i += 2;
  96. } else {
  97. out += ch;
  98. }
  99. }
  100. out += '"';
  101. }
  102. static void dump(const Json::array &values, string &out) {
  103. bool first = true;
  104. out += "[";
  105. for (const auto &value : values) {
  106. if (!first)
  107. out += ",";
  108. value.dump(out);
  109. first = false;
  110. }
  111. out += "]";
  112. }
  113. static void dump(const Json::object &values, string &out) {
  114. bool first = true;
  115. out += "{";
  116. for (const auto &kv : values) {
  117. if (!first)
  118. out += ",";
  119. dump(kv.first, out);
  120. out += ":";
  121. kv.second.dump(out);
  122. first = false;
  123. }
  124. out += "}";
  125. }
  126. void Json::dump(string &out) const {
  127. m_ptr->dump(out);
  128. }
  129. /* * * * * * * * * * * * * * * * * * * *
  130. * Value wrappers
  131. */
  132. template <Json::Type tag, typename T>
  133. class Value : public JsonValue {
  134. protected:
  135. // Constructors
  136. explicit Value(const T &value) : m_value(value) {}
  137. explicit Value(T &&value) : m_value(move(value)) {}
  138. // Get type tag
  139. Json::Type type() const override {
  140. return tag;
  141. }
  142. // Comparisons
  143. bool equals(const JsonValue * other) const override {
  144. return m_value == static_cast<const Value<tag, T> *>(other)->m_value;
  145. }
  146. bool less(const JsonValue * other) const override {
  147. return m_value < static_cast<const Value<tag, T> *>(other)->m_value;
  148. }
  149. const T m_value;
  150. void dump(string &out) const override { json11::dump(m_value, out); }
  151. };
  152. class JsonDouble final : public Value<Json::NUMBER, double> {
  153. double number_value() const override { return m_value; }
  154. int int_value() const override { return static_cast<int>(m_value); }
  155. bool equals(const JsonValue * other) const override { return m_value == other->number_value(); }
  156. bool less(const JsonValue * other) const override { return m_value < other->number_value(); }
  157. public:
  158. explicit JsonDouble(double value) : Value(value) {}
  159. };
  160. class JsonInt final : public Value<Json::NUMBER, int> {
  161. double number_value() const override { return m_value; }
  162. int int_value() const override { return m_value; }
  163. bool equals(const JsonValue * other) const override { return m_value == other->number_value(); }
  164. bool less(const JsonValue * other) const override { return m_value < other->number_value(); }
  165. public:
  166. explicit JsonInt(int value) : Value(value) {}
  167. };
  168. class JsonBoolean final : public Value<Json::BOOL, bool> {
  169. bool bool_value() const override { return m_value; }
  170. public:
  171. explicit JsonBoolean(bool value) : Value(value) {}
  172. };
  173. class JsonString final : public Value<Json::STRING, string> {
  174. const string &string_value() const override { return m_value; }
  175. public:
  176. explicit JsonString(const string &value) : Value(value) {}
  177. explicit JsonString(string &&value) : Value(move(value)) {}
  178. };
  179. class JsonArray final : public Value<Json::ARRAY, Json::array> {
  180. const Json::array &array_items() const override { return m_value; }
  181. const Json & operator[](size_t i) const override;
  182. public:
  183. explicit JsonArray(const Json::array &value) : Value(value) {}
  184. explicit JsonArray(Json::array &&value) : Value(move(value)) {}
  185. };
  186. class JsonObject final : public Value<Json::OBJECT, Json::object> {
  187. const Json::object &object_items() const override { return m_value; }
  188. const Json & operator[](const string &key) const override;
  189. public:
  190. explicit JsonObject(const Json::object &value) : Value(value) {}
  191. explicit JsonObject(Json::object &&value) : Value(move(value)) {}
  192. };
  193. class JsonNull final : public Value<Json::NUL, NullStruct> {
  194. public:
  195. JsonNull() : Value({}) {}
  196. };
  197. /* * * * * * * * * * * * * * * * * * * *
  198. * Static globals - static-init-safe
  199. */
  200. struct Statics {
  201. const std::shared_ptr<JsonValue> null = make_shared<JsonNull>();
  202. const std::shared_ptr<JsonValue> t = make_shared<JsonBoolean>(true);
  203. const std::shared_ptr<JsonValue> f = make_shared<JsonBoolean>(false);
  204. const string empty_string;
  205. const vector<Json> empty_vector;
  206. const map<string, Json> empty_map;
  207. Statics() {}
  208. };
  209. static const Statics & statics() {
  210. static const Statics s {};
  211. return s;
  212. }
  213. static const Json & static_null() {
  214. // This has to be separate, not in Statics, because Json() accesses statics().null.
  215. static const Json json_null;
  216. return json_null;
  217. }
  218. /* * * * * * * * * * * * * * * * * * * *
  219. * Constructors
  220. */
  221. Json::Json() noexcept : m_ptr(statics().null) {}
  222. Json::Json(std::nullptr_t) noexcept : m_ptr(statics().null) {}
  223. Json::Json(double value) : m_ptr(make_shared<JsonDouble>(value)) {}
  224. Json::Json(int value) : m_ptr(make_shared<JsonInt>(value)) {}
  225. Json::Json(bool value) : m_ptr(value ? statics().t : statics().f) {}
  226. Json::Json(const string &value) : m_ptr(make_shared<JsonString>(value)) {}
  227. Json::Json(string &&value) : m_ptr(make_shared<JsonString>(move(value))) {}
  228. Json::Json(const char * value) : m_ptr(make_shared<JsonString>(value)) {}
  229. Json::Json(const Json::array &values) : m_ptr(make_shared<JsonArray>(values)) {}
  230. Json::Json(Json::array &&values) : m_ptr(make_shared<JsonArray>(move(values))) {}
  231. Json::Json(const Json::object &values) : m_ptr(make_shared<JsonObject>(values)) {}
  232. Json::Json(Json::object &&values) : m_ptr(make_shared<JsonObject>(move(values))) {}
  233. /* * * * * * * * * * * * * * * * * * * *
  234. * Accessors
  235. */
  236. Json::Type Json::type() const { return m_ptr->type(); }
  237. double Json::number_value() const { return m_ptr->number_value(); }
  238. int Json::int_value() const { return m_ptr->int_value(); }
  239. bool Json::bool_value() const { return m_ptr->bool_value(); }
  240. const string & Json::string_value() const { return m_ptr->string_value(); }
  241. const vector<Json> & Json::array_items() const { return m_ptr->array_items(); }
  242. const map<string, Json> & Json::object_items() const { return m_ptr->object_items(); }
  243. const Json & Json::operator[] (size_t i) const { return (*m_ptr)[i]; }
  244. const Json & Json::operator[] (const string &key) const { return (*m_ptr)[key]; }
  245. double JsonValue::number_value() const { return 0; }
  246. int JsonValue::int_value() const { return 0; }
  247. bool JsonValue::bool_value() const { return false; }
  248. const string & JsonValue::string_value() const { return statics().empty_string; }
  249. const vector<Json> & JsonValue::array_items() const { return statics().empty_vector; }
  250. const map<string, Json> & JsonValue::object_items() const { return statics().empty_map; }
  251. const Json & JsonValue::operator[] (size_t) const { return static_null(); }
  252. const Json & JsonValue::operator[] (const string &) const { return static_null(); }
  253. const Json & JsonObject::operator[] (const string &key) const {
  254. auto iter = m_value.find(key);
  255. return (iter == m_value.end()) ? static_null() : iter->second;
  256. }
  257. const Json & JsonArray::operator[] (size_t i) const {
  258. if (i >= m_value.size()) return static_null();
  259. else return m_value[i];
  260. }
  261. /* * * * * * * * * * * * * * * * * * * *
  262. * Comparison
  263. */
  264. bool Json::operator== (const Json &other) const {
  265. if (m_ptr == other.m_ptr)
  266. return true;
  267. if (m_ptr->type() != other.m_ptr->type())
  268. return false;
  269. return m_ptr->equals(other.m_ptr.get());
  270. }
  271. bool Json::operator< (const Json &other) const {
  272. if (m_ptr == other.m_ptr)
  273. return false;
  274. if (m_ptr->type() != other.m_ptr->type())
  275. return m_ptr->type() < other.m_ptr->type();
  276. return m_ptr->less(other.m_ptr.get());
  277. }
  278. /* * * * * * * * * * * * * * * * * * * *
  279. * Parsing
  280. */
  281. /* esc(c)
  282. *
  283. * Format char c suitable for printing in an error message.
  284. */
  285. static inline string esc(char c) {
  286. char buf[12];
  287. if (static_cast<uint8_t>(c) >= 0x20 && static_cast<uint8_t>(c) <= 0x7f) {
  288. snprintf(buf, sizeof buf, "'%c' (%d)", c, c);
  289. } else {
  290. snprintf(buf, sizeof buf, "(%d)", c);
  291. }
  292. return string(buf);
  293. }
  294. static inline bool in_range(long x, long lower, long upper) {
  295. return (x >= lower && x <= upper);
  296. }
  297. namespace {
  298. /* JsonParser
  299. *
  300. * Object that tracks all state of an in-progress parse.
  301. */
  302. struct JsonParser final {
  303. /* State
  304. */
  305. const string &str;
  306. size_t i;
  307. string &err;
  308. bool failed;
  309. const JsonParse strategy;
  310. /* fail(msg, err_ret = Json())
  311. *
  312. * Mark this parse as failed.
  313. */
  314. Json fail(string &&msg) {
  315. return fail(move(msg), Json());
  316. }
  317. template <typename T>
  318. T fail(string &&msg, const T err_ret) {
  319. if (!failed)
  320. err = std::move(msg);
  321. failed = true;
  322. return err_ret;
  323. }
  324. /* consume_whitespace()
  325. *
  326. * Advance until the current character is non-whitespace.
  327. */
  328. void consume_whitespace() {
  329. while (str[i] == ' ' || str[i] == '\r' || str[i] == '\n' || str[i] == '\t')
  330. i++;
  331. }
  332. /* consume_comment()
  333. *
  334. * Advance comments (c-style inline and multiline).
  335. */
  336. bool consume_comment() {
  337. bool comment_found = false;
  338. if (str[i] == '/') {
  339. i++;
  340. if (i == str.size())
  341. return fail("unexpected end of input after start of comment", false);
  342. if (str[i] == '/') { // inline comment
  343. i++;
  344. // advance until next line, or end of input
  345. while (i < str.size() && str[i] != '\n') {
  346. i++;
  347. }
  348. comment_found = true;
  349. }
  350. else if (str[i] == '*') { // multiline comment
  351. i++;
  352. if (i > str.size()-2)
  353. return fail("unexpected end of input inside multi-line comment", false);
  354. // advance until closing tokens
  355. while (!(str[i] == '*' && str[i+1] == '/')) {
  356. i++;
  357. if (i > str.size()-2)
  358. return fail(
  359. "unexpected end of input inside multi-line comment", false);
  360. }
  361. i += 2;
  362. comment_found = true;
  363. }
  364. else
  365. return fail("malformed comment", false);
  366. }
  367. return comment_found;
  368. }
  369. /* consume_garbage()
  370. *
  371. * Advance until the current character is non-whitespace and non-comment.
  372. */
  373. void consume_garbage() {
  374. consume_whitespace();
  375. if(strategy == JsonParse::COMMENTS) {
  376. bool comment_found = false;
  377. do {
  378. comment_found = consume_comment();
  379. if (failed) return;
  380. consume_whitespace();
  381. }
  382. while(comment_found);
  383. }
  384. }
  385. /* get_next_token()
  386. *
  387. * Return the next non-whitespace character. If the end of the input is reached,
  388. * flag an error and return 0.
  389. */
  390. char get_next_token() {
  391. consume_garbage();
  392. if (failed) return (char)0;
  393. if (i == str.size())
  394. return fail("unexpected end of input", (char)0);
  395. return str[i++];
  396. }
  397. /* encode_utf8(pt, out)
  398. *
  399. * Encode pt as UTF-8 and add it to out.
  400. */
  401. void encode_utf8(long pt, string & out) {
  402. if (pt < 0)
  403. return;
  404. if (pt < 0x80) {
  405. out += static_cast<char>(pt);
  406. } else if (pt < 0x800) {
  407. out += static_cast<char>((pt >> 6) | 0xC0);
  408. out += static_cast<char>((pt & 0x3F) | 0x80);
  409. } else if (pt < 0x10000) {
  410. out += static_cast<char>((pt >> 12) | 0xE0);
  411. out += static_cast<char>(((pt >> 6) & 0x3F) | 0x80);
  412. out += static_cast<char>((pt & 0x3F) | 0x80);
  413. } else {
  414. out += static_cast<char>((pt >> 18) | 0xF0);
  415. out += static_cast<char>(((pt >> 12) & 0x3F) | 0x80);
  416. out += static_cast<char>(((pt >> 6) & 0x3F) | 0x80);
  417. out += static_cast<char>((pt & 0x3F) | 0x80);
  418. }
  419. }
  420. /* parse_string()
  421. *
  422. * Parse a string, starting at the current position.
  423. */
  424. string parse_string() {
  425. string out;
  426. long last_escaped_codepoint = -1;
  427. while (true) {
  428. if (i == str.size())
  429. return fail("unexpected end of input in string", "");
  430. char ch = str[i++];
  431. if (ch == '"') {
  432. encode_utf8(last_escaped_codepoint, out);
  433. return out;
  434. }
  435. if (in_range(ch, 0, 0x1f))
  436. return fail("unescaped " + esc(ch) + " in string", "");
  437. // The usual case: non-escaped characters
  438. if (ch != '\\') {
  439. encode_utf8(last_escaped_codepoint, out);
  440. last_escaped_codepoint = -1;
  441. out += ch;
  442. continue;
  443. }
  444. // Handle escapes
  445. if (i == str.size())
  446. return fail("unexpected end of input in string", "");
  447. ch = str[i++];
  448. if (ch == 'u') {
  449. // Extract 4-byte escape sequence
  450. string esc = str.substr(i, 4);
  451. // Explicitly check length of the substring. The following loop
  452. // relies on std::string returning the terminating NUL when
  453. // accessing str[length]. Checking here reduces brittleness.
  454. if (esc.length() < 4) {
  455. return fail("bad \\u escape: " + esc, "");
  456. }
  457. for (size_t j = 0; j < 4; j++) {
  458. if (!in_range(esc[j], 'a', 'f') && !in_range(esc[j], 'A', 'F')
  459. && !in_range(esc[j], '0', '9'))
  460. return fail("bad \\u escape: " + esc, "");
  461. }
  462. long codepoint = strtol(esc.data(), nullptr, 16);
  463. // JSON specifies that characters outside the BMP shall be encoded as a pair
  464. // of 4-hex-digit \u escapes encoding their surrogate pair components. Check
  465. // whether we're in the middle of such a beast: the previous codepoint was an
  466. // escaped lead (high) surrogate, and this is a trail (low) surrogate.
  467. if (in_range(last_escaped_codepoint, 0xD800, 0xDBFF)
  468. && in_range(codepoint, 0xDC00, 0xDFFF)) {
  469. // Reassemble the two surrogate pairs into one astral-plane character, per
  470. // the UTF-16 algorithm.
  471. encode_utf8((((last_escaped_codepoint - 0xD800) << 10)
  472. | (codepoint - 0xDC00)) + 0x10000, out);
  473. last_escaped_codepoint = -1;
  474. } else {
  475. encode_utf8(last_escaped_codepoint, out);
  476. last_escaped_codepoint = codepoint;
  477. }
  478. i += 4;
  479. continue;
  480. }
  481. encode_utf8(last_escaped_codepoint, out);
  482. last_escaped_codepoint = -1;
  483. if (ch == 'b') {
  484. out += '\b';
  485. } else if (ch == 'f') {
  486. out += '\f';
  487. } else if (ch == 'n') {
  488. out += '\n';
  489. } else if (ch == 'r') {
  490. out += '\r';
  491. } else if (ch == 't') {
  492. out += '\t';
  493. } else if (ch == '"' || ch == '\\' || ch == '/') {
  494. out += ch;
  495. } else {
  496. return fail("invalid escape character " + esc(ch), "");
  497. }
  498. }
  499. }
  500. /* parse_number()
  501. *
  502. * Parse a double.
  503. */
  504. Json parse_number() {
  505. size_t start_pos = i;
  506. if (str[i] == '-')
  507. i++;
  508. // Integer part
  509. if (str[i] == '0') {
  510. i++;
  511. if (in_range(str[i], '0', '9'))
  512. return fail("leading 0s not permitted in numbers");
  513. } else if (in_range(str[i], '1', '9')) {
  514. i++;
  515. while (in_range(str[i], '0', '9'))
  516. i++;
  517. } else {
  518. return fail("invalid " + esc(str[i]) + " in number");
  519. }
  520. if (str[i] != '.' && str[i] != 'e' && str[i] != 'E'
  521. && (i - start_pos) <= static_cast<size_t>(std::numeric_limits<int>::digits10)) {
  522. return std::atoi(str.c_str() + start_pos);
  523. }
  524. // Decimal part
  525. if (str[i] == '.') {
  526. i++;
  527. if (!in_range(str[i], '0', '9'))
  528. return fail("at least one digit required in fractional part");
  529. while (in_range(str[i], '0', '9'))
  530. i++;
  531. }
  532. // Exponent part
  533. if (str[i] == 'e' || str[i] == 'E') {
  534. i++;
  535. if (str[i] == '+' || str[i] == '-')
  536. i++;
  537. if (!in_range(str[i], '0', '9'))
  538. return fail("at least one digit required in exponent");
  539. while (in_range(str[i], '0', '9'))
  540. i++;
  541. }
  542. return std::strtod(str.c_str() + start_pos, nullptr);
  543. }
  544. /* expect(str, res)
  545. *
  546. * Expect that 'str' starts at the character that was just read. If it does, advance
  547. * the input and return res. If not, flag an error.
  548. */
  549. Json expect(const string &expected, Json res) {
  550. assert(i != 0);
  551. i--;
  552. if (str.compare(i, expected.length(), expected) == 0) {
  553. i += expected.length();
  554. return res;
  555. } else {
  556. return fail("parse error: expected " + expected + ", got " + str.substr(i, expected.length()));
  557. }
  558. }
  559. /* parse_json()
  560. *
  561. * Parse a JSON object.
  562. */
  563. Json parse_json(int depth) {
  564. if (depth > max_depth) {
  565. return fail("exceeded maximum nesting depth");
  566. }
  567. char ch = get_next_token();
  568. if (failed)
  569. return Json();
  570. if (ch == '-' || (ch >= '0' && ch <= '9')) {
  571. i--;
  572. return parse_number();
  573. }
  574. if (ch == 't')
  575. return expect("true", true);
  576. if (ch == 'f')
  577. return expect("false", false);
  578. if (ch == 'n')
  579. return expect("null", Json());
  580. if (ch == '"')
  581. return parse_string();
  582. if (ch == '{') {
  583. map<string, Json> data;
  584. ch = get_next_token();
  585. if (ch == '}')
  586. return data;
  587. while (1) {
  588. if (ch != '"')
  589. return fail("expected '\"' in object, got " + esc(ch));
  590. string key = parse_string();
  591. if (failed)
  592. return Json();
  593. ch = get_next_token();
  594. if (ch != ':')
  595. return fail("expected ':' in object, got " + esc(ch));
  596. data[std::move(key)] = parse_json(depth + 1);
  597. if (failed)
  598. return Json();
  599. ch = get_next_token();
  600. if (ch == '}')
  601. break;
  602. if (ch != ',')
  603. return fail("expected ',' in object, got " + esc(ch));
  604. ch = get_next_token();
  605. }
  606. return data;
  607. }
  608. if (ch == '[') {
  609. vector<Json> data;
  610. ch = get_next_token();
  611. if (ch == ']')
  612. return data;
  613. while (1) {
  614. i--;
  615. data.push_back(parse_json(depth + 1));
  616. if (failed)
  617. return Json();
  618. ch = get_next_token();
  619. if (ch == ']')
  620. break;
  621. if (ch != ',')
  622. return fail("expected ',' in list, got " + esc(ch));
  623. ch = get_next_token();
  624. (void)ch;
  625. }
  626. return data;
  627. }
  628. return fail("expected value, got " + esc(ch));
  629. }
  630. };
  631. }//namespace {
  632. Json Json::parse(const string &in, string &err, JsonParse strategy) {
  633. JsonParser parser { in, 0, err, false, strategy };
  634. Json result = parser.parse_json(0);
  635. // Check for any trailing garbage
  636. parser.consume_garbage();
  637. if (parser.failed)
  638. return Json();
  639. if (parser.i != in.size())
  640. return parser.fail("unexpected trailing " + esc(in[parser.i]));
  641. return result;
  642. }
  643. // Documented in json11.hpp
  644. vector<Json> Json::parse_multi(const string &in,
  645. std::string::size_type &parser_stop_pos,
  646. string &err,
  647. JsonParse strategy) {
  648. JsonParser parser { in, 0, err, false, strategy };
  649. parser_stop_pos = 0;
  650. vector<Json> json_vec;
  651. while (parser.i != in.size() && !parser.failed) {
  652. json_vec.push_back(parser.parse_json(0));
  653. if (parser.failed)
  654. break;
  655. // Check for another object
  656. parser.consume_garbage();
  657. if (parser.failed)
  658. break;
  659. parser_stop_pos = parser.i;
  660. }
  661. return json_vec;
  662. }
  663. /* * * * * * * * * * * * * * * * * * * *
  664. * Shape-checking
  665. */
  666. bool Json::has_shape(const shape & types, string & err) const {
  667. if (!is_object()) {
  668. err = "expected JSON object, got " + dump();
  669. return false;
  670. }
  671. for (auto & item : types) {
  672. if ((*this)[item.first].type() != item.second) {
  673. err = "bad type for " + item.first + " in " + dump();
  674. return false;
  675. }
  676. }
  677. return true;
  678. }
  679. } // namespace json11