json_sax.hpp 21 KB

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