value.ipp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. //
  2. // Copyright (c) 2019 Vinnie Falco ([email protected])
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // Official repository: https://github.com/boostorg/json
  8. //
  9. #ifndef BOOST_JSON_IMPL_VALUE_IPP
  10. #define BOOST_JSON_IMPL_VALUE_IPP
  11. #include <boost/container_hash/hash.hpp>
  12. #include <boost/json/value.hpp>
  13. #include <boost/json/parser.hpp>
  14. #include <cstring>
  15. #include <istream>
  16. #include <limits>
  17. #include <new>
  18. #include <utility>
  19. namespace boost {
  20. namespace json {
  21. namespace
  22. {
  23. int parse_depth_xalloc = std::ios::xalloc();
  24. int parse_flags_xalloc = std::ios::xalloc();
  25. struct value_hasher
  26. {
  27. std::size_t& seed;
  28. template< class T >
  29. void operator()( T&& t ) const noexcept
  30. {
  31. boost::hash_combine( seed, t );
  32. }
  33. };
  34. enum class stream_parse_flags
  35. {
  36. allow_comments = 1 << 0,
  37. allow_trailing_commas = 1 << 1,
  38. allow_invalid_utf8 = 1 << 2,
  39. };
  40. long
  41. to_bitmask( parse_options const& opts )
  42. {
  43. using E = stream_parse_flags;
  44. return
  45. (opts.allow_comments ?
  46. static_cast<long>(E::allow_comments) : 0) |
  47. (opts.allow_trailing_commas ?
  48. static_cast<long>(E::allow_trailing_commas) : 0) |
  49. (opts.allow_invalid_utf8 ?
  50. static_cast<long>(E::allow_invalid_utf8) : 0);
  51. }
  52. parse_options
  53. get_parse_options( std::istream& is )
  54. {
  55. long const flags = is.iword(parse_flags_xalloc);
  56. using E = stream_parse_flags;
  57. parse_options opts;
  58. opts.allow_comments =
  59. flags & static_cast<long>(E::allow_comments) ? true : false;
  60. opts.allow_trailing_commas =
  61. flags & static_cast<long>(E::allow_trailing_commas) ? true : false;
  62. opts.allow_invalid_utf8 =
  63. flags & static_cast<long>(E::allow_invalid_utf8) ? true : false;
  64. return opts;
  65. }
  66. } // namespace
  67. value::
  68. ~value() noexcept
  69. {
  70. switch(kind())
  71. {
  72. case json::kind::null:
  73. case json::kind::bool_:
  74. case json::kind::int64:
  75. case json::kind::uint64:
  76. case json::kind::double_:
  77. sca_.~scalar();
  78. break;
  79. case json::kind::string:
  80. str_.~string();
  81. break;
  82. case json::kind::array:
  83. arr_.~array();
  84. break;
  85. case json::kind::object:
  86. obj_.~object();
  87. break;
  88. }
  89. }
  90. value::
  91. value(
  92. value const& other,
  93. storage_ptr sp)
  94. {
  95. switch(other.kind())
  96. {
  97. case json::kind::null:
  98. ::new(&sca_) scalar(
  99. std::move(sp));
  100. break;
  101. case json::kind::bool_:
  102. ::new(&sca_) scalar(
  103. other.sca_.b,
  104. std::move(sp));
  105. break;
  106. case json::kind::int64:
  107. ::new(&sca_) scalar(
  108. other.sca_.i,
  109. std::move(sp));
  110. break;
  111. case json::kind::uint64:
  112. ::new(&sca_) scalar(
  113. other.sca_.u,
  114. std::move(sp));
  115. break;
  116. case json::kind::double_:
  117. ::new(&sca_) scalar(
  118. other.sca_.d,
  119. std::move(sp));
  120. break;
  121. case json::kind::string:
  122. ::new(&str_) string(
  123. other.str_,
  124. std::move(sp));
  125. break;
  126. case json::kind::array:
  127. ::new(&arr_) array(
  128. other.arr_,
  129. std::move(sp));
  130. break;
  131. case json::kind::object:
  132. ::new(&obj_) object(
  133. other.obj_,
  134. std::move(sp));
  135. break;
  136. }
  137. }
  138. value::
  139. value(value&& other) noexcept
  140. {
  141. relocate(this, other);
  142. ::new(&other.sca_) scalar(sp_);
  143. }
  144. value::
  145. value(
  146. value&& other,
  147. storage_ptr sp)
  148. {
  149. switch(other.kind())
  150. {
  151. case json::kind::null:
  152. ::new(&sca_) scalar(
  153. std::move(sp));
  154. break;
  155. case json::kind::bool_:
  156. ::new(&sca_) scalar(
  157. other.sca_.b, std::move(sp));
  158. break;
  159. case json::kind::int64:
  160. ::new(&sca_) scalar(
  161. other.sca_.i, std::move(sp));
  162. break;
  163. case json::kind::uint64:
  164. ::new(&sca_) scalar(
  165. other.sca_.u, std::move(sp));
  166. break;
  167. case json::kind::double_:
  168. ::new(&sca_) scalar(
  169. other.sca_.d, std::move(sp));
  170. break;
  171. case json::kind::string:
  172. ::new(&str_) string(
  173. std::move(other.str_),
  174. std::move(sp));
  175. break;
  176. case json::kind::array:
  177. ::new(&arr_) array(
  178. std::move(other.arr_),
  179. std::move(sp));
  180. break;
  181. case json::kind::object:
  182. ::new(&obj_) object(
  183. std::move(other.obj_),
  184. std::move(sp));
  185. break;
  186. }
  187. }
  188. //----------------------------------------------------------
  189. //
  190. // Conversion
  191. //
  192. //----------------------------------------------------------
  193. value::
  194. value(
  195. std::initializer_list<value_ref> init,
  196. storage_ptr sp)
  197. {
  198. if(value_ref::maybe_object(init))
  199. {
  200. ::new(&obj_) object(
  201. value_ref::make_object(
  202. init, std::move(sp)));
  203. }
  204. else
  205. {
  206. #ifndef BOOST_JSON_LEGACY_INIT_LIST_BEHAVIOR
  207. if( init.size() == 1 )
  208. {
  209. ::new(&sca_) scalar();
  210. value temp = init.begin()->make_value( std::move(sp) );
  211. swap(temp);
  212. }
  213. else
  214. #endif
  215. {
  216. ::new(&arr_) array(
  217. value_ref::make_array(
  218. init, std::move(sp)));
  219. }
  220. }
  221. }
  222. //----------------------------------------------------------
  223. //
  224. // Assignment
  225. //
  226. //----------------------------------------------------------
  227. value&
  228. value::
  229. operator=(value const& other)
  230. {
  231. value(other,
  232. storage()).swap(*this);
  233. return *this;
  234. }
  235. value&
  236. value::
  237. operator=(value&& other)
  238. {
  239. value(std::move(other),
  240. storage()).swap(*this);
  241. return *this;
  242. }
  243. value&
  244. value::
  245. operator=(
  246. std::initializer_list<value_ref> init)
  247. {
  248. value(init,
  249. storage()).swap(*this);
  250. return *this;
  251. }
  252. value&
  253. value::
  254. operator=(string_view s)
  255. {
  256. value(s, storage()).swap(*this);
  257. return *this;
  258. }
  259. value&
  260. value::
  261. operator=(char const* s)
  262. {
  263. value(s, storage()).swap(*this);
  264. return *this;
  265. }
  266. value&
  267. value::
  268. operator=(string const& str)
  269. {
  270. value(str, storage()).swap(*this);
  271. return *this;
  272. }
  273. value&
  274. value::
  275. operator=(string&& str)
  276. {
  277. value(std::move(str),
  278. storage()).swap(*this);
  279. return *this;
  280. }
  281. value&
  282. value::
  283. operator=(array const& arr)
  284. {
  285. value(arr, storage()).swap(*this);
  286. return *this;
  287. }
  288. value&
  289. value::
  290. operator=(array&& arr)
  291. {
  292. value(std::move(arr),
  293. storage()).swap(*this);
  294. return *this;
  295. }
  296. value&
  297. value::
  298. operator=(object const& obj)
  299. {
  300. value(obj, storage()).swap(*this);
  301. return *this;
  302. }
  303. value&
  304. value::
  305. operator=(object&& obj)
  306. {
  307. value(std::move(obj),
  308. storage()).swap(*this);
  309. return *this;
  310. }
  311. //----------------------------------------------------------
  312. //
  313. // Modifiers
  314. //
  315. //----------------------------------------------------------
  316. string&
  317. value::
  318. emplace_string() noexcept
  319. {
  320. return *::new(&str_) string(destroy());
  321. }
  322. array&
  323. value::
  324. emplace_array() noexcept
  325. {
  326. return *::new(&arr_) array(destroy());
  327. }
  328. object&
  329. value::
  330. emplace_object() noexcept
  331. {
  332. return *::new(&obj_) object(destroy());
  333. }
  334. void
  335. value::
  336. swap(value& other)
  337. {
  338. if(*storage() == *other.storage())
  339. {
  340. // fast path
  341. union U
  342. {
  343. value tmp;
  344. U(){}
  345. ~U(){}
  346. };
  347. U u;
  348. relocate(&u.tmp, *this);
  349. relocate(this, other);
  350. relocate(&other, u.tmp);
  351. return;
  352. }
  353. // copy
  354. value temp1(
  355. std::move(*this),
  356. other.storage());
  357. value temp2(
  358. std::move(other),
  359. this->storage());
  360. other.~value();
  361. ::new(&other) value(pilfer(temp1));
  362. this->~value();
  363. ::new(this) value(pilfer(temp2));
  364. }
  365. std::istream&
  366. operator>>(
  367. std::istream& is,
  368. value& jv)
  369. {
  370. using Traits = std::istream::traits_type;
  371. // sentry prepares the stream for reading and finalizes it in destructor
  372. std::istream::sentry sentry(is);
  373. if( !sentry )
  374. return is;
  375. parse_options opts = get_parse_options( is );
  376. if( auto depth = static_cast<std::size_t>( is.iword(parse_depth_xalloc) ) )
  377. opts.max_depth = depth;
  378. unsigned char parser_buf[BOOST_JSON_STACK_BUFFER_SIZE / 2];
  379. stream_parser p( {}, opts, parser_buf );
  380. p.reset( jv.storage() );
  381. char read_buf[BOOST_JSON_STACK_BUFFER_SIZE / 2];
  382. std::streambuf& buf = *is.rdbuf();
  383. std::ios::iostate err = std::ios::goodbit;
  384. #ifndef BOOST_NO_EXCEPTIONS
  385. try
  386. #endif
  387. {
  388. while( true )
  389. {
  390. system::error_code ec;
  391. // we peek the buffer; this either makes sure that there's no
  392. // more input, or makes sure there's something in the internal
  393. // buffer (so in_avail will return a positive number)
  394. std::istream::int_type c = is.rdbuf()->sgetc();
  395. // if we indeed reached EOF, we check if we parsed a full JSON
  396. // document; if not, we error out
  397. if( Traits::eq_int_type(c, Traits::eof()) )
  398. {
  399. err |= std::ios::eofbit;
  400. p.finish(ec);
  401. if( ec.failed() )
  402. break;
  403. }
  404. // regardless of reaching EOF, we might have parsed a full JSON
  405. // document; if so, we successfully finish
  406. if( p.done() )
  407. {
  408. jv = p.release();
  409. return is;
  410. }
  411. // at this point we definitely have more input, specifically in
  412. // buf's internal buffer; we also definitely haven't parsed a whole
  413. // document
  414. std::streamsize available = buf.in_avail();
  415. // if this assert fails, the streambuf is buggy
  416. BOOST_ASSERT( available > 0 );
  417. available = ( std::min )(
  418. static_cast<std::size_t>(available), sizeof(read_buf) );
  419. // we read from the internal buffer of buf into our buffer
  420. available = buf.sgetn( read_buf, available );
  421. std::size_t consumed = p.write_some(
  422. read_buf, static_cast<std::size_t>(available), ec );
  423. // if the parser hasn't consumed the entire input we've took from
  424. // buf, we put the remaining data back; this should succeed,
  425. // because we only read data from buf's internal buffer
  426. while( consumed++ < static_cast<std::size_t>(available) )
  427. {
  428. std::istream::int_type const status = buf.sungetc();
  429. BOOST_ASSERT( status != Traits::eof() );
  430. (void)status;
  431. }
  432. if( ec.failed() )
  433. break;
  434. }
  435. }
  436. #ifndef BOOST_NO_EXCEPTIONS
  437. catch(...)
  438. {
  439. try
  440. {
  441. is.setstate(std::ios::badbit);
  442. }
  443. // we ignore the exception, because we need to throw the original
  444. // exception instead
  445. catch( std::ios::failure const& ) { }
  446. if( is.exceptions() & std::ios::badbit )
  447. throw;
  448. }
  449. #endif
  450. is.setstate(err | std::ios::failbit);
  451. return is;
  452. }
  453. std::istream&
  454. operator>>(
  455. std::istream& is,
  456. parse_options const& opts)
  457. {
  458. is.iword(parse_flags_xalloc) = to_bitmask(opts);
  459. is.iword(parse_depth_xalloc) = static_cast<long>(opts.max_depth);
  460. return is;
  461. }
  462. //----------------------------------------------------------
  463. //
  464. // private
  465. //
  466. //----------------------------------------------------------
  467. storage_ptr
  468. value::
  469. destroy() noexcept
  470. {
  471. switch(kind())
  472. {
  473. case json::kind::null:
  474. case json::kind::bool_:
  475. case json::kind::int64:
  476. case json::kind::uint64:
  477. case json::kind::double_:
  478. break;
  479. case json::kind::string:
  480. {
  481. auto sp = str_.storage();
  482. str_.~string();
  483. return sp;
  484. }
  485. case json::kind::array:
  486. {
  487. auto sp = arr_.storage();
  488. arr_.~array();
  489. return sp;
  490. }
  491. case json::kind::object:
  492. {
  493. auto sp = obj_.storage();
  494. obj_.~object();
  495. return sp;
  496. }
  497. }
  498. return std::move(sp_);
  499. }
  500. bool
  501. value::
  502. equal(value const& other) const noexcept
  503. {
  504. switch(kind())
  505. {
  506. default: // unreachable()?
  507. case json::kind::null:
  508. return other.kind() == json::kind::null;
  509. case json::kind::bool_:
  510. return
  511. other.kind() == json::kind::bool_ &&
  512. get_bool() == other.get_bool();
  513. case json::kind::int64:
  514. switch(other.kind())
  515. {
  516. case json::kind::int64:
  517. return get_int64() == other.get_int64();
  518. case json::kind::uint64:
  519. if(get_int64() < 0)
  520. return false;
  521. return static_cast<std::uint64_t>(
  522. get_int64()) == other.get_uint64();
  523. default:
  524. return false;
  525. }
  526. case json::kind::uint64:
  527. switch(other.kind())
  528. {
  529. case json::kind::uint64:
  530. return get_uint64() == other.get_uint64();
  531. case json::kind::int64:
  532. if(other.get_int64() < 0)
  533. return false;
  534. return static_cast<std::uint64_t>(
  535. other.get_int64()) == get_uint64();
  536. default:
  537. return false;
  538. }
  539. case json::kind::double_:
  540. return
  541. other.kind() == json::kind::double_ &&
  542. get_double() == other.get_double();
  543. case json::kind::string:
  544. return
  545. other.kind() == json::kind::string &&
  546. get_string() == other.get_string();
  547. case json::kind::array:
  548. return
  549. other.kind() == json::kind::array &&
  550. get_array() == other.get_array();
  551. case json::kind::object:
  552. return
  553. other.kind() == json::kind::object &&
  554. get_object() == other.get_object();
  555. }
  556. }
  557. //----------------------------------------------------------
  558. //
  559. // key_value_pair
  560. //
  561. //----------------------------------------------------------
  562. // empty keys point here
  563. BOOST_JSON_REQUIRE_CONST_INIT
  564. char const
  565. key_value_pair::empty_[1] = { 0 };
  566. key_value_pair::
  567. key_value_pair(
  568. pilfered<json::value> key,
  569. pilfered<json::value> value) noexcept
  570. : value_(value)
  571. {
  572. std::size_t len;
  573. key_ = access::release_key(key.get(), len);
  574. len_ = static_cast<std::uint32_t>(len);
  575. }
  576. key_value_pair::
  577. key_value_pair(
  578. key_value_pair const& other,
  579. storage_ptr sp)
  580. : value_(other.value_, std::move(sp))
  581. {
  582. auto p = reinterpret_cast<
  583. char*>(value_.storage()->
  584. allocate(other.len_ + 1,
  585. alignof(char)));
  586. std::memcpy(
  587. p, other.key_, other.len_);
  588. len_ = other.len_;
  589. p[len_] = 0;
  590. key_ = p;
  591. }
  592. //----------------------------------------------------------
  593. namespace detail
  594. {
  595. std::size_t
  596. hash_value_impl( value const& jv ) noexcept
  597. {
  598. std::size_t seed = 0;
  599. kind const k = jv.kind();
  600. boost::hash_combine( seed, k != kind::int64 ? k : kind::uint64 );
  601. visit( value_hasher{seed}, jv );
  602. return seed;
  603. }
  604. } // namespace detail
  605. } // namespace json
  606. } // namespace boost
  607. //----------------------------------------------------------
  608. //
  609. // std::hash specialization
  610. //
  611. //----------------------------------------------------------
  612. std::size_t
  613. std::hash<::boost::json::value>::operator()(
  614. ::boost::json::value const& jv) const noexcept
  615. {
  616. return ::boost::hash< ::boost::json::value >()( jv );
  617. }
  618. //----------------------------------------------------------
  619. #endif