json11.cpp 24 KB

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