json11.cpp 24 KB

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