json_sax.hpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. #pragma once
  2. #include <cstddef>
  3. #include <string>
  4. #include <vector>
  5. #include <nlohmann/detail/input/parser.hpp>
  6. #include <nlohmann/detail/exceptions.hpp>
  7. namespace nlohmann
  8. {
  9. /*!
  10. @brief SAX interface
  11. */
  12. template<typename BasicJsonType>
  13. struct json_sax
  14. {
  15. /// type for (signed) integers
  16. using number_integer_t = typename BasicJsonType::number_integer_t;
  17. /// type for unsigned integers
  18. using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
  19. /// type for floating-point numbers
  20. using number_float_t = typename BasicJsonType::number_float_t;
  21. /// type for strings
  22. using string_t = typename BasicJsonType::string_t;
  23. /// constant to indicate that no size limit is given for array or object
  24. static constexpr auto no_limit = std::size_t(-1);
  25. /*!
  26. @brief a null value was read
  27. @return whether parsing should proceed
  28. */
  29. virtual bool null() = 0;
  30. /*!
  31. @brief a boolean value was read
  32. @param[in] val boolean value
  33. @return whether parsing should proceed
  34. */
  35. virtual bool boolean(bool val) = 0;
  36. /*!
  37. @brief an integer number was read
  38. @param[in] val integer value
  39. @return whether parsing should proceed
  40. */
  41. virtual bool number_integer(number_integer_t val) = 0;
  42. /*!
  43. @brief an unsigned integer number was read
  44. @param[in] val unsigned integer value
  45. @return whether parsing should proceed
  46. */
  47. virtual bool number_unsigned(number_unsigned_t val) = 0;
  48. /*!
  49. @brief an floating-point number was read
  50. @param[in] val floating-point value
  51. @param[in] s raw token value
  52. @return whether parsing should proceed
  53. */
  54. virtual bool number_float(number_float_t val, const string_t& s) = 0;
  55. /*!
  56. @brief a string was read
  57. @param[in] val string value
  58. @return whether parsing should proceed
  59. */
  60. virtual bool string(string_t& val) = 0;
  61. /*!
  62. @brief the beginning of an object was read
  63. @param[in] elements number of object elements or no_limit if unknown
  64. @return whether parsing should proceed
  65. @note binary formats may report the number of elements
  66. */
  67. virtual bool start_object(std::size_t elements = no_limit) = 0;
  68. /*!
  69. @brief an object key was read
  70. @param[in] val object key
  71. @return whether parsing should proceed
  72. */
  73. virtual bool key(string_t& val) = 0;
  74. /*!
  75. @brief the end of an object was read
  76. @return whether parsing should proceed
  77. */
  78. virtual bool end_object() = 0;
  79. /*!
  80. @brief the beginning of an array was read
  81. @param[in] elements number of array elements or no_limit if unknown
  82. @return whether parsing should proceed
  83. @note binary formats may report the number of elements
  84. */
  85. virtual bool start_array(std::size_t elements = no_limit) = 0;
  86. /*!
  87. @brief the end of an array was read
  88. @return whether parsing should proceed
  89. */
  90. virtual bool end_array() = 0;
  91. /*!
  92. @brief a parse error occurred
  93. @param[in] position the position in the input where the error occurs
  94. @param[in] last_token the last read token
  95. @param[in] error_msg a detailed error message
  96. @return whether parsing should proceed (must return false)
  97. */
  98. virtual bool parse_error(std::size_t position,
  99. const std::string& last_token,
  100. const detail::exception& ex) = 0;
  101. virtual ~json_sax() = default;
  102. };
  103. namespace detail
  104. {
  105. /*!
  106. @brief SAX implementation to create a JSON value from SAX events
  107. This class implements the @ref json_sax interface and processes the SAX events
  108. to create a JSON value which makes it basically a DOM parser. The structure or
  109. hierarchy of the JSON value is managed by the stack `ref_stack` which contains
  110. a pointer to the respective array or object for each recursion depth.
  111. After successful parsing, the value that is passed by reference to the
  112. constructor contains the parsed value.
  113. @tparam BasicJsonType the JSON type
  114. */
  115. template<typename BasicJsonType>
  116. class json_sax_dom_parser : public json_sax<BasicJsonType>
  117. {
  118. public:
  119. using number_integer_t = typename BasicJsonType::number_integer_t;
  120. using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
  121. using number_float_t = typename BasicJsonType::number_float_t;
  122. using string_t = typename BasicJsonType::string_t;
  123. /*!
  124. @param[in, out] r reference to a JSON value that is manipulated while
  125. parsing
  126. @param[in] allow_exceptions_ whether parse errors yield exceptions
  127. */
  128. json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
  129. : root(r), allow_exceptions(allow_exceptions_)
  130. {}
  131. bool null() override
  132. {
  133. handle_value(nullptr);
  134. return true;
  135. }
  136. bool boolean(bool val) override
  137. {
  138. handle_value(val);
  139. return true;
  140. }
  141. bool number_integer(number_integer_t val) override
  142. {
  143. handle_value(val);
  144. return true;
  145. }
  146. bool number_unsigned(number_unsigned_t val) override
  147. {
  148. handle_value(val);
  149. return true;
  150. }
  151. bool number_float(number_float_t val, const string_t&) override
  152. {
  153. handle_value(val);
  154. return true;
  155. }
  156. bool string(string_t& val) override
  157. {
  158. handle_value(val);
  159. return true;
  160. }
  161. bool start_object(std::size_t len) override
  162. {
  163. ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
  164. if (JSON_UNLIKELY(len != json_sax<BasicJsonType>::no_limit and len > ref_stack.back()->max_size()))
  165. {
  166. JSON_THROW(out_of_range::create(408,
  167. "excessive object size: " + std::to_string(len)));
  168. }
  169. return true;
  170. }
  171. bool key(string_t& val) override
  172. {
  173. // add null at given key and store the reference for later
  174. object_element = &(ref_stack.back()->m_value.object->operator[](val));
  175. return true;
  176. }
  177. bool end_object() override
  178. {
  179. ref_stack.pop_back();
  180. return true;
  181. }
  182. bool start_array(std::size_t len) override
  183. {
  184. ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
  185. if (JSON_UNLIKELY(len != json_sax<BasicJsonType>::no_limit and len > ref_stack.back()->max_size()))
  186. {
  187. JSON_THROW(out_of_range::create(408,
  188. "excessive array size: " + std::to_string(len)));
  189. }
  190. return true;
  191. }
  192. bool end_array() override
  193. {
  194. ref_stack.pop_back();
  195. return true;
  196. }
  197. bool parse_error(std::size_t, const std::string&,
  198. const detail::exception& ex) override
  199. {
  200. errored = true;
  201. if (allow_exceptions)
  202. {
  203. // determine the proper exception type from the id
  204. switch ((ex.id / 100) % 100)
  205. {
  206. case 1:
  207. JSON_THROW(*reinterpret_cast<const detail::parse_error*>(&ex));
  208. case 2:
  209. JSON_THROW(*reinterpret_cast<const detail::invalid_iterator*>(&ex)); // LCOV_EXCL_LINE
  210. case 3:
  211. JSON_THROW(*reinterpret_cast<const detail::type_error*>(&ex)); // LCOV_EXCL_LINE
  212. case 4:
  213. JSON_THROW(*reinterpret_cast<const detail::out_of_range*>(&ex));
  214. case 5:
  215. JSON_THROW(*reinterpret_cast<const detail::other_error*>(&ex)); // LCOV_EXCL_LINE
  216. default:
  217. assert(false); // LCOV_EXCL_LINE
  218. }
  219. }
  220. return false;
  221. }
  222. constexpr bool is_errored() const
  223. {
  224. return errored;
  225. }
  226. private:
  227. /*!
  228. @invariant If the ref stack is empty, then the passed value will be the new
  229. root.
  230. @invariant If the ref stack contains a value, then it is an array or an
  231. object to which we can add elements
  232. */
  233. template<typename Value>
  234. BasicJsonType* handle_value(Value&& v)
  235. {
  236. if (ref_stack.empty())
  237. {
  238. root = BasicJsonType(std::forward<Value>(v));
  239. return &root;
  240. }
  241. else
  242. {
  243. assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
  244. if (ref_stack.back()->is_array())
  245. {
  246. ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
  247. return &(ref_stack.back()->m_value.array->back());
  248. }
  249. else
  250. {
  251. assert(object_element);
  252. *object_element = BasicJsonType(std::forward<Value>(v));
  253. return object_element;
  254. }
  255. }
  256. }
  257. /// the parsed JSON value
  258. BasicJsonType& root;
  259. /// stack to model hierarchy of values
  260. std::vector<BasicJsonType*> ref_stack;
  261. /// helper to hold the reference for the next object element
  262. BasicJsonType* object_element = nullptr;
  263. /// whether a syntax error occurred
  264. bool errored = false;
  265. /// whether to throw exceptions in case of errors
  266. const bool allow_exceptions = true;
  267. };
  268. template<typename BasicJsonType>
  269. class json_sax_dom_callback_parser : public json_sax<BasicJsonType>
  270. {
  271. public:
  272. using number_integer_t = typename BasicJsonType::number_integer_t;
  273. using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
  274. using number_float_t = typename BasicJsonType::number_float_t;
  275. using string_t = typename BasicJsonType::string_t;
  276. using parser_callback_t = typename BasicJsonType::parser_callback_t;
  277. using parse_event_t = typename BasicJsonType::parse_event_t;
  278. json_sax_dom_callback_parser(BasicJsonType& r,
  279. const parser_callback_t cb,
  280. const bool allow_exceptions_ = true)
  281. : root(r), callback(cb), allow_exceptions(allow_exceptions_)
  282. {
  283. keep_stack.push_back(true);
  284. }
  285. bool null() override
  286. {
  287. handle_value(nullptr);
  288. return true;
  289. }
  290. bool boolean(bool val) override
  291. {
  292. handle_value(val);
  293. return true;
  294. }
  295. bool number_integer(number_integer_t val) override
  296. {
  297. handle_value(val);
  298. return true;
  299. }
  300. bool number_unsigned(number_unsigned_t val) override
  301. {
  302. handle_value(val);
  303. return true;
  304. }
  305. bool number_float(number_float_t val, const string_t&) override
  306. {
  307. handle_value(val);
  308. return true;
  309. }
  310. bool string(string_t& val) override
  311. {
  312. handle_value(val);
  313. return true;
  314. }
  315. bool start_object(std::size_t len) override
  316. {
  317. // check callback for object start
  318. const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
  319. keep_stack.push_back(keep);
  320. auto val = handle_value(BasicJsonType::value_t::object, true);
  321. ref_stack.push_back(val.second);
  322. // check object limit
  323. if (ref_stack.back())
  324. {
  325. if (JSON_UNLIKELY(len != json_sax<BasicJsonType>::no_limit and len > ref_stack.back()->max_size()))
  326. {
  327. JSON_THROW(out_of_range::create(408,
  328. "excessive object size: " + std::to_string(len)));
  329. }
  330. }
  331. return true;
  332. }
  333. bool key(string_t& val) override
  334. {
  335. BasicJsonType k = BasicJsonType(val);
  336. // check callback for key
  337. const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
  338. key_keep_stack.push_back(keep);
  339. // add discarded value at given key and store the reference for later
  340. if (keep and ref_stack.back())
  341. {
  342. object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
  343. }
  344. return true;
  345. }
  346. bool end_object() override
  347. {
  348. if (ref_stack.back())
  349. {
  350. if (not callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
  351. {
  352. // discard object
  353. *ref_stack.back() = discarded;
  354. }
  355. }
  356. assert(not ref_stack.empty());
  357. assert(not keep_stack.empty());
  358. ref_stack.pop_back();
  359. keep_stack.pop_back();
  360. if (not ref_stack.empty() and ref_stack.back())
  361. {
  362. // remove discarded value
  363. if (ref_stack.back()->is_object())
  364. {
  365. for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
  366. {
  367. if (it->is_discarded())
  368. {
  369. ref_stack.back()->erase(it);
  370. break;
  371. }
  372. }
  373. }
  374. }
  375. return true;
  376. }
  377. bool start_array(std::size_t len) override
  378. {
  379. const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
  380. keep_stack.push_back(keep);
  381. auto val = handle_value(BasicJsonType::value_t::array, true);
  382. ref_stack.push_back(val.second);
  383. // check array limit
  384. if (ref_stack.back())
  385. {
  386. if (JSON_UNLIKELY(len != json_sax<BasicJsonType>::no_limit and len > ref_stack.back()->max_size()))
  387. {
  388. JSON_THROW(out_of_range::create(408,
  389. "excessive array size: " + std::to_string(len)));
  390. }
  391. }
  392. return true;
  393. }
  394. bool end_array() override
  395. {
  396. bool keep = true;
  397. if (ref_stack.back())
  398. {
  399. keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
  400. if (not keep)
  401. {
  402. // discard array
  403. *ref_stack.back() = discarded;
  404. }
  405. }
  406. assert(not ref_stack.empty());
  407. assert(not keep_stack.empty());
  408. ref_stack.pop_back();
  409. keep_stack.pop_back();
  410. // remove discarded value
  411. if (not keep and not ref_stack.empty())
  412. {
  413. if (ref_stack.back()->is_array())
  414. {
  415. ref_stack.back()->m_value.array->pop_back();
  416. }
  417. }
  418. return true;
  419. }
  420. bool parse_error(std::size_t, const std::string&,
  421. const detail::exception& ex) override
  422. {
  423. errored = true;
  424. if (allow_exceptions)
  425. {
  426. // determine the proper exception type from the id
  427. switch ((ex.id / 100) % 100)
  428. {
  429. case 1:
  430. JSON_THROW(*reinterpret_cast<const detail::parse_error*>(&ex));
  431. case 2:
  432. JSON_THROW(*reinterpret_cast<const detail::invalid_iterator*>(&ex)); // LCOV_EXCL_LINE
  433. case 3:
  434. JSON_THROW(*reinterpret_cast<const detail::type_error*>(&ex)); // LCOV_EXCL_LINE
  435. case 4:
  436. JSON_THROW(*reinterpret_cast<const detail::out_of_range*>(&ex));
  437. case 5:
  438. JSON_THROW(*reinterpret_cast<const detail::other_error*>(&ex)); // LCOV_EXCL_LINE
  439. default:
  440. assert(false); // LCOV_EXCL_LINE
  441. }
  442. }
  443. return false;
  444. }
  445. constexpr bool is_errored() const
  446. {
  447. return errored;
  448. }
  449. private:
  450. /*!
  451. @param[in] v value to add to the JSON value we build during parsing
  452. @param[in] skip_callback whether we should skip calling the callback
  453. function; this is required after start_array() and
  454. start_object() SAX events, because otherwise we would call the
  455. callback function with an empty array or object, respectively.
  456. @invariant If the ref stack is empty, then the passed value will be the new
  457. root.
  458. @invariant If the ref stack contains a value, then it is an array or an
  459. object to which we can add elements
  460. @return pair of boolean (whether value should be kept) and pointer (to the
  461. passed value in the ref_stack hierarchy; nullptr if not kept)
  462. */
  463. template<typename Value>
  464. std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
  465. {
  466. assert(not keep_stack.empty());
  467. // do not handle this value if we know it would be added to a discarded
  468. // container
  469. if (not keep_stack.back())
  470. {
  471. return {false, nullptr};
  472. }
  473. // create value
  474. auto value = BasicJsonType(std::forward<Value>(v));
  475. // check callback
  476. const bool keep = skip_callback or callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
  477. // do not handle this value if we just learnt it shall be discarded
  478. if (not keep)
  479. {
  480. return {false, nullptr};
  481. }
  482. if (ref_stack.empty())
  483. {
  484. root = std::move(value);
  485. return {true, &root};
  486. }
  487. else
  488. {
  489. assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
  490. if (ref_stack.back()->is_array())
  491. {
  492. ref_stack.back()->m_value.array->push_back(std::move(value));
  493. return {true, &(ref_stack.back()->m_value.array->back())};
  494. }
  495. else
  496. {
  497. // check if we should store an element for the current key
  498. assert(not key_keep_stack.empty());
  499. const bool store_element = key_keep_stack.back();
  500. key_keep_stack.pop_back();
  501. if (not store_element)
  502. {
  503. return {false, nullptr};
  504. }
  505. assert(object_element);
  506. *object_element = std::move(value);
  507. return {true, object_element};
  508. }
  509. }
  510. }
  511. /// the parsed JSON value
  512. BasicJsonType& root;
  513. /// stack to model hierarchy of values
  514. std::vector<BasicJsonType*> ref_stack;
  515. /// stack to manage which values to keep
  516. std::vector<bool> keep_stack;
  517. /// stack to manage which object keys to keep
  518. std::vector<bool> key_keep_stack;
  519. /// helper to hold the reference for the next object element
  520. BasicJsonType* object_element = nullptr;
  521. /// whether a syntax error occurred
  522. bool errored = false;
  523. /// callback function
  524. const parser_callback_t callback = nullptr;
  525. /// whether to throw exceptions in case of errors
  526. const bool allow_exceptions = true;
  527. /// a discarded value for the callback
  528. BasicJsonType discarded = BasicJsonType::value_t::discarded;
  529. };
  530. template<typename BasicJsonType>
  531. class json_sax_acceptor : public json_sax<BasicJsonType>
  532. {
  533. public:
  534. using number_integer_t = typename BasicJsonType::number_integer_t;
  535. using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
  536. using number_float_t = typename BasicJsonType::number_float_t;
  537. using string_t = typename BasicJsonType::string_t;
  538. bool null() override
  539. {
  540. return true;
  541. }
  542. bool boolean(bool) override
  543. {
  544. return true;
  545. }
  546. bool number_integer(number_integer_t) override
  547. {
  548. return true;
  549. }
  550. bool number_unsigned(number_unsigned_t) override
  551. {
  552. return true;
  553. }
  554. bool number_float(number_float_t, const string_t&) override
  555. {
  556. return true;
  557. }
  558. bool string(string_t&) override
  559. {
  560. return true;
  561. }
  562. bool start_object(std::size_t) override
  563. {
  564. return true;
  565. }
  566. bool key(string_t&) override
  567. {
  568. return true;
  569. }
  570. bool end_object() override
  571. {
  572. return true;
  573. }
  574. bool start_array(std::size_t) override
  575. {
  576. return true;
  577. }
  578. bool end_array() override
  579. {
  580. return true;
  581. }
  582. bool parse_error(std::size_t, const std::string&, const detail::exception&) override
  583. {
  584. return false;
  585. }
  586. };
  587. }
  588. }