serializer.ipp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822
  1. //
  2. // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
  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_SERIALIZER_IPP
  10. #define BOOST_JSON_IMPL_SERIALIZER_IPP
  11. #include <boost/json/serializer.hpp>
  12. #include <boost/json/detail/format.hpp>
  13. #include <boost/json/detail/sse2.hpp>
  14. #include <ostream>
  15. #ifdef _MSC_VER
  16. #pragma warning(push)
  17. #pragma warning(disable: 4127) // conditional expression is constant
  18. #endif
  19. BOOST_JSON_NS_BEGIN
  20. enum class serializer::state : char
  21. {
  22. nul1, nul2, nul3, nul4,
  23. tru1, tru2, tru3, tru4,
  24. fal1, fal2, fal3, fal4, fal5,
  25. str1, str2, str3, str4, esc1,
  26. utf1, utf2, utf3, utf4, utf5,
  27. num,
  28. arr1, arr2, arr3, arr4,
  29. obj1, obj2, obj3, obj4, obj5, obj6
  30. };
  31. //----------------------------------------------------------
  32. serializer::
  33. ~serializer() noexcept = default;
  34. bool
  35. serializer::
  36. suspend(state st)
  37. {
  38. st_.push(st);
  39. return false;
  40. }
  41. bool
  42. serializer::
  43. suspend(
  44. state st,
  45. array::const_iterator it,
  46. array const* pa)
  47. {
  48. st_.push(pa);
  49. st_.push(it);
  50. st_.push(st);
  51. return false;
  52. }
  53. bool
  54. serializer::
  55. suspend(
  56. state st,
  57. object::const_iterator it,
  58. object const* po)
  59. {
  60. st_.push(po);
  61. st_.push(it);
  62. st_.push(st);
  63. return false;
  64. }
  65. template<bool StackEmpty>
  66. bool
  67. serializer::
  68. write_null(stream& ss0)
  69. {
  70. local_stream ss(ss0);
  71. if(! StackEmpty && ! st_.empty())
  72. {
  73. state st;
  74. st_.pop(st);
  75. switch(st)
  76. {
  77. default:
  78. case state::nul1: goto do_nul1;
  79. case state::nul2: goto do_nul2;
  80. case state::nul3: goto do_nul3;
  81. case state::nul4: goto do_nul4;
  82. }
  83. }
  84. do_nul1:
  85. if(BOOST_JSON_LIKELY(ss))
  86. ss.append('n');
  87. else
  88. return suspend(state::nul1);
  89. do_nul2:
  90. if(BOOST_JSON_LIKELY(ss))
  91. ss.append('u');
  92. else
  93. return suspend(state::nul2);
  94. do_nul3:
  95. if(BOOST_JSON_LIKELY(ss))
  96. ss.append('l');
  97. else
  98. return suspend(state::nul3);
  99. do_nul4:
  100. if(BOOST_JSON_LIKELY(ss))
  101. ss.append('l');
  102. else
  103. return suspend(state::nul4);
  104. return true;
  105. }
  106. template<bool StackEmpty>
  107. bool
  108. serializer::
  109. write_true(stream& ss0)
  110. {
  111. local_stream ss(ss0);
  112. if(! StackEmpty && ! st_.empty())
  113. {
  114. state st;
  115. st_.pop(st);
  116. switch(st)
  117. {
  118. default:
  119. case state::tru1: goto do_tru1;
  120. case state::tru2: goto do_tru2;
  121. case state::tru3: goto do_tru3;
  122. case state::tru4: goto do_tru4;
  123. }
  124. }
  125. do_tru1:
  126. if(BOOST_JSON_LIKELY(ss))
  127. ss.append('t');
  128. else
  129. return suspend(state::tru1);
  130. do_tru2:
  131. if(BOOST_JSON_LIKELY(ss))
  132. ss.append('r');
  133. else
  134. return suspend(state::tru2);
  135. do_tru3:
  136. if(BOOST_JSON_LIKELY(ss))
  137. ss.append('u');
  138. else
  139. return suspend(state::tru3);
  140. do_tru4:
  141. if(BOOST_JSON_LIKELY(ss))
  142. ss.append('e');
  143. else
  144. return suspend(state::tru4);
  145. return true;
  146. }
  147. template<bool StackEmpty>
  148. bool
  149. serializer::
  150. write_false(stream& ss0)
  151. {
  152. local_stream ss(ss0);
  153. if(! StackEmpty && ! st_.empty())
  154. {
  155. state st;
  156. st_.pop(st);
  157. switch(st)
  158. {
  159. default:
  160. case state::fal1: goto do_fal1;
  161. case state::fal2: goto do_fal2;
  162. case state::fal3: goto do_fal3;
  163. case state::fal4: goto do_fal4;
  164. case state::fal5: goto do_fal5;
  165. }
  166. }
  167. do_fal1:
  168. if(BOOST_JSON_LIKELY(ss))
  169. ss.append('f');
  170. else
  171. return suspend(state::fal1);
  172. do_fal2:
  173. if(BOOST_JSON_LIKELY(ss))
  174. ss.append('a');
  175. else
  176. return suspend(state::fal2);
  177. do_fal3:
  178. if(BOOST_JSON_LIKELY(ss))
  179. ss.append('l');
  180. else
  181. return suspend(state::fal3);
  182. do_fal4:
  183. if(BOOST_JSON_LIKELY(ss))
  184. ss.append('s');
  185. else
  186. return suspend(state::fal4);
  187. do_fal5:
  188. if(BOOST_JSON_LIKELY(ss))
  189. ss.append('e');
  190. else
  191. return suspend(state::fal5);
  192. return true;
  193. }
  194. template<bool StackEmpty>
  195. bool
  196. serializer::
  197. write_string(stream& ss0)
  198. {
  199. local_stream ss(ss0);
  200. local_const_stream cs(cs0_);
  201. if(! StackEmpty && ! st_.empty())
  202. {
  203. state st;
  204. st_.pop(st);
  205. switch(st)
  206. {
  207. default:
  208. case state::str1: goto do_str1;
  209. case state::str2: goto do_str2;
  210. case state::str3: goto do_str3;
  211. case state::str4: goto do_str4;
  212. case state::esc1: goto do_esc1;
  213. case state::utf1: goto do_utf1;
  214. case state::utf2: goto do_utf2;
  215. case state::utf3: goto do_utf3;
  216. case state::utf4: goto do_utf4;
  217. case state::utf5: goto do_utf5;
  218. }
  219. }
  220. static constexpr char hex[] = "0123456789abcdef";
  221. static constexpr char esc[] =
  222. "uuuuuuuubtnufruuuuuuuuuuuuuuuuuu"
  223. "\0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
  224. "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0"
  225. "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
  226. "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
  227. "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
  228. "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
  229. "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
  230. // opening quote
  231. do_str1:
  232. if(BOOST_JSON_LIKELY(ss))
  233. ss.append('\x22'); // '"'
  234. else
  235. return suspend(state::str1);
  236. // fast loop,
  237. // copy unescaped
  238. do_str2:
  239. if(BOOST_JSON_LIKELY(ss))
  240. {
  241. std::size_t n = cs.remain();
  242. if(BOOST_JSON_LIKELY(n > 0))
  243. {
  244. if(ss.remain() > n)
  245. n = detail::count_unescaped(
  246. cs.data(), n);
  247. else
  248. n = detail::count_unescaped(
  249. cs.data(), ss.remain());
  250. if(n > 0)
  251. {
  252. ss.append(cs.data(), n);
  253. cs.skip(n);
  254. if(! ss)
  255. return suspend(state::str2);
  256. }
  257. }
  258. else
  259. {
  260. ss.append('\x22'); // '"'
  261. return true;
  262. }
  263. }
  264. else
  265. {
  266. return suspend(state::str2);
  267. }
  268. // slow loop,
  269. // handle escapes
  270. do_str3:
  271. while(BOOST_JSON_LIKELY(ss))
  272. {
  273. if(BOOST_JSON_LIKELY(cs))
  274. {
  275. auto const ch = *cs;
  276. auto const c = esc[static_cast<
  277. unsigned char>(ch)];
  278. ++cs;
  279. if(! c)
  280. {
  281. ss.append(ch);
  282. }
  283. else if(c != 'u')
  284. {
  285. ss.append('\\');
  286. if(BOOST_JSON_LIKELY(ss))
  287. {
  288. ss.append(c);
  289. }
  290. else
  291. {
  292. buf_[0] = c;
  293. return suspend(
  294. state::esc1);
  295. }
  296. }
  297. else
  298. {
  299. if(BOOST_JSON_LIKELY(
  300. ss.remain() >= 6))
  301. {
  302. ss.append("\\u00", 4);
  303. ss.append(hex[static_cast<
  304. unsigned char>(ch) >> 4]);
  305. ss.append(hex[static_cast<
  306. unsigned char>(ch) & 15]);
  307. }
  308. else
  309. {
  310. ss.append('\\');
  311. buf_[0] = hex[static_cast<
  312. unsigned char>(ch) >> 4];
  313. buf_[1] = hex[static_cast<
  314. unsigned char>(ch) & 15];
  315. goto do_utf1;
  316. }
  317. }
  318. }
  319. else
  320. {
  321. ss.append('\x22'); // '"'
  322. return true;
  323. }
  324. }
  325. return suspend(state::str3);
  326. do_str4:
  327. if(BOOST_JSON_LIKELY(ss))
  328. ss.append('\x22'); // '"'
  329. else
  330. return suspend(state::str4);
  331. do_esc1:
  332. if(BOOST_JSON_LIKELY(ss))
  333. ss.append(buf_[0]);
  334. else
  335. return suspend(state::esc1);
  336. goto do_str3;
  337. do_utf1:
  338. if(BOOST_JSON_LIKELY(ss))
  339. ss.append('u');
  340. else
  341. return suspend(state::utf1);
  342. do_utf2:
  343. if(BOOST_JSON_LIKELY(ss))
  344. ss.append('0');
  345. else
  346. return suspend(state::utf2);
  347. do_utf3:
  348. if(BOOST_JSON_LIKELY(ss))
  349. ss.append('0');
  350. else
  351. return suspend(state::utf3);
  352. do_utf4:
  353. if(BOOST_JSON_LIKELY(ss))
  354. ss.append(buf_[0]);
  355. else
  356. return suspend(state::utf4);
  357. do_utf5:
  358. if(BOOST_JSON_LIKELY(ss))
  359. ss.append(buf_[1]);
  360. else
  361. return suspend(state::utf5);
  362. goto do_str3;
  363. }
  364. template<bool StackEmpty>
  365. bool
  366. serializer::
  367. write_number(stream& ss0)
  368. {
  369. local_stream ss(ss0);
  370. if(StackEmpty || st_.empty())
  371. {
  372. switch(jv_->kind())
  373. {
  374. default:
  375. case kind::int64:
  376. if(BOOST_JSON_LIKELY(
  377. ss.remain() >=
  378. detail::max_number_chars))
  379. {
  380. ss.advance(detail::format_int64(
  381. ss.data(), jv_->get_int64()));
  382. return true;
  383. }
  384. cs0_ = { buf_, detail::format_int64(
  385. buf_, jv_->get_int64()) };
  386. break;
  387. case kind::uint64:
  388. if(BOOST_JSON_LIKELY(
  389. ss.remain() >=
  390. detail::max_number_chars))
  391. {
  392. ss.advance(detail::format_uint64(
  393. ss.data(), jv_->get_uint64()));
  394. return true;
  395. }
  396. cs0_ = { buf_, detail::format_uint64(
  397. buf_, jv_->get_uint64()) };
  398. break;
  399. case kind::double_:
  400. if(BOOST_JSON_LIKELY(
  401. ss.remain() >=
  402. detail::max_number_chars))
  403. {
  404. ss.advance(detail::format_double(
  405. ss.data(), jv_->get_double()));
  406. return true;
  407. }
  408. cs0_ = { buf_, detail::format_double(
  409. buf_, jv_->get_double()) };
  410. break;
  411. }
  412. }
  413. else
  414. {
  415. state st;
  416. st_.pop(st);
  417. BOOST_ASSERT(
  418. st == state::num);
  419. }
  420. auto const n = ss.remain();
  421. if(n < cs0_.remain())
  422. {
  423. ss.append(cs0_.data(), n);
  424. cs0_.skip(n);
  425. return suspend(state::num);
  426. }
  427. ss.append(
  428. cs0_.data(), cs0_.remain());
  429. return true;
  430. }
  431. template<bool StackEmpty>
  432. bool
  433. serializer::
  434. write_array(stream& ss0)
  435. {
  436. array const* pa;
  437. local_stream ss(ss0);
  438. array::const_iterator it;
  439. array::const_iterator end;
  440. if(StackEmpty || st_.empty())
  441. {
  442. pa = pa_;
  443. it = pa->begin();
  444. end = pa->end();
  445. }
  446. else
  447. {
  448. state st;
  449. st_.pop(st);
  450. st_.pop(it);
  451. st_.pop(pa);
  452. end = pa->end();
  453. switch(st)
  454. {
  455. default:
  456. case state::arr1: goto do_arr1;
  457. case state::arr2: goto do_arr2;
  458. case state::arr3: goto do_arr3;
  459. case state::arr4: goto do_arr4;
  460. break;
  461. }
  462. }
  463. do_arr1:
  464. if(BOOST_JSON_LIKELY(ss))
  465. ss.append('[');
  466. else
  467. return suspend(
  468. state::arr1, it, pa);
  469. if(it == end)
  470. goto do_arr4;
  471. for(;;)
  472. {
  473. do_arr2:
  474. jv_ = &*it;
  475. if(! write_value<StackEmpty>(ss))
  476. return suspend(
  477. state::arr2, it, pa);
  478. if(BOOST_JSON_UNLIKELY(
  479. ++it == end))
  480. break;
  481. do_arr3:
  482. if(BOOST_JSON_LIKELY(ss))
  483. ss.append(',');
  484. else
  485. return suspend(
  486. state::arr3, it, pa);
  487. }
  488. do_arr4:
  489. if(BOOST_JSON_LIKELY(ss))
  490. ss.append(']');
  491. else
  492. return suspend(
  493. state::arr4, it, pa);
  494. return true;
  495. }
  496. template<bool StackEmpty>
  497. bool
  498. serializer::
  499. write_object(stream& ss0)
  500. {
  501. object const* po;
  502. local_stream ss(ss0);
  503. object::const_iterator it;
  504. object::const_iterator end;
  505. if(StackEmpty || st_.empty())
  506. {
  507. po = po_;
  508. it = po->begin();
  509. end = po->end();
  510. }
  511. else
  512. {
  513. state st;
  514. st_.pop(st);
  515. st_.pop(it);
  516. st_.pop(po);
  517. end = po->end();
  518. switch(st)
  519. {
  520. default:
  521. case state::obj1: goto do_obj1;
  522. case state::obj2: goto do_obj2;
  523. case state::obj3: goto do_obj3;
  524. case state::obj4: goto do_obj4;
  525. case state::obj5: goto do_obj5;
  526. case state::obj6: goto do_obj6;
  527. break;
  528. }
  529. }
  530. do_obj1:
  531. if(BOOST_JSON_LIKELY(ss))
  532. ss.append('{');
  533. else
  534. return suspend(
  535. state::obj1, it, po);
  536. if(BOOST_JSON_UNLIKELY(
  537. it == end))
  538. goto do_obj6;
  539. for(;;)
  540. {
  541. cs0_ = {
  542. it->key().data(),
  543. it->key().size() };
  544. do_obj2:
  545. if(BOOST_JSON_UNLIKELY(
  546. ! write_string<StackEmpty>(ss)))
  547. return suspend(
  548. state::obj2, it, po);
  549. do_obj3:
  550. if(BOOST_JSON_LIKELY(ss))
  551. ss.append(':');
  552. else
  553. return suspend(
  554. state::obj3, it, po);
  555. do_obj4:
  556. jv_ = &it->value();
  557. if(BOOST_JSON_UNLIKELY(
  558. ! write_value<StackEmpty>(ss)))
  559. return suspend(
  560. state::obj4, it, po);
  561. ++it;
  562. if(BOOST_JSON_UNLIKELY(it == end))
  563. break;
  564. do_obj5:
  565. if(BOOST_JSON_LIKELY(ss))
  566. ss.append(',');
  567. else
  568. return suspend(
  569. state::obj5, it, po);
  570. }
  571. do_obj6:
  572. if(BOOST_JSON_LIKELY(ss))
  573. {
  574. ss.append('}');
  575. return true;
  576. }
  577. return suspend(
  578. state::obj6, it, po);
  579. }
  580. template<bool StackEmpty>
  581. bool
  582. serializer::
  583. write_value(stream& ss)
  584. {
  585. if(StackEmpty || st_.empty())
  586. {
  587. auto const& jv(*jv_);
  588. switch(jv.kind())
  589. {
  590. default:
  591. case kind::object:
  592. po_ = &jv.get_object();
  593. return write_object<true>(ss);
  594. case kind::array:
  595. pa_ = &jv.get_array();
  596. return write_array<true>(ss);
  597. case kind::string:
  598. {
  599. auto const& js = jv.get_string();
  600. cs0_ = { js.data(), js.size() };
  601. return write_string<true>(ss);
  602. }
  603. case kind::int64:
  604. case kind::uint64:
  605. case kind::double_:
  606. return write_number<true>(ss);
  607. case kind::bool_:
  608. if(jv.get_bool())
  609. {
  610. if(BOOST_JSON_LIKELY(
  611. ss.remain() >= 4))
  612. {
  613. ss.append("true", 4);
  614. return true;
  615. }
  616. return write_true<true>(ss);
  617. }
  618. else
  619. {
  620. if(BOOST_JSON_LIKELY(
  621. ss.remain() >= 5))
  622. {
  623. ss.append("false", 5);
  624. return true;
  625. }
  626. return write_false<true>(ss);
  627. }
  628. case kind::null:
  629. if(BOOST_JSON_LIKELY(
  630. ss.remain() >= 4))
  631. {
  632. ss.append("null", 4);
  633. return true;
  634. }
  635. return write_null<true>(ss);
  636. }
  637. }
  638. else
  639. {
  640. state st;
  641. st_.peek(st);
  642. switch(st)
  643. {
  644. default:
  645. case state::nul1: case state::nul2:
  646. case state::nul3: case state::nul4:
  647. return write_null<StackEmpty>(ss);
  648. case state::tru1: case state::tru2:
  649. case state::tru3: case state::tru4:
  650. return write_true<StackEmpty>(ss);
  651. case state::fal1: case state::fal2:
  652. case state::fal3: case state::fal4:
  653. case state::fal5:
  654. return write_false<StackEmpty>(ss);
  655. case state::str1: case state::str2:
  656. case state::str3: case state::str4:
  657. case state::esc1:
  658. case state::utf1: case state::utf2:
  659. case state::utf3: case state::utf4:
  660. case state::utf5:
  661. return write_string<StackEmpty>(ss);
  662. case state::num:
  663. return write_number<StackEmpty>(ss);
  664. case state::arr1: case state::arr2:
  665. case state::arr3: case state::arr4:
  666. return write_array<StackEmpty>(ss);
  667. case state::obj1: case state::obj2:
  668. case state::obj3: case state::obj4:
  669. case state::obj5: case state::obj6:
  670. return write_object<StackEmpty>(ss);
  671. }
  672. }
  673. }
  674. string_view
  675. serializer::
  676. read_some(
  677. char* dest, std::size_t size)
  678. {
  679. // If this goes off it means you forgot
  680. // to call reset() before seriailzing a
  681. // new value, or you never checked done()
  682. // to see if you should stop.
  683. BOOST_ASSERT(! done_);
  684. stream ss(dest, size);
  685. if(st_.empty())
  686. (this->*fn0_)(ss);
  687. else
  688. (this->*fn1_)(ss);
  689. if(st_.empty())
  690. {
  691. done_ = true;
  692. jv_ = nullptr;
  693. }
  694. return string_view(
  695. dest, ss.used(dest));
  696. }
  697. //----------------------------------------------------------
  698. serializer::
  699. serializer() noexcept
  700. {
  701. // ensure room for \uXXXX escape plus one
  702. BOOST_STATIC_ASSERT(
  703. sizeof(serializer::buf_) >= 7);
  704. }
  705. void
  706. serializer::
  707. reset(value const* p) noexcept
  708. {
  709. pv_ = p;
  710. fn0_ = &serializer::write_value<true>;
  711. fn1_ = &serializer::write_value<false>;
  712. jv_ = p;
  713. st_.clear();
  714. done_ = false;
  715. }
  716. void
  717. serializer::
  718. reset(array const* p) noexcept
  719. {
  720. pa_ = p;
  721. fn0_ = &serializer::write_array<true>;
  722. fn1_ = &serializer::write_array<false>;
  723. st_.clear();
  724. done_ = false;
  725. }
  726. void
  727. serializer::
  728. reset(object const* p) noexcept
  729. {
  730. po_ = p;
  731. fn0_ = &serializer::write_object<true>;
  732. fn1_ = &serializer::write_object<false>;
  733. st_.clear();
  734. done_ = false;
  735. }
  736. void
  737. serializer::
  738. reset(string const* p) noexcept
  739. {
  740. cs0_ = { p->data(), p->size() };
  741. fn0_ = &serializer::write_string<true>;
  742. fn1_ = &serializer::write_string<false>;
  743. st_.clear();
  744. done_ = false;
  745. }
  746. void
  747. serializer::
  748. reset(string_view sv) noexcept
  749. {
  750. cs0_ = { sv.data(), sv.size() };
  751. fn0_ = &serializer::write_string<true>;
  752. fn1_ = &serializer::write_string<false>;
  753. st_.clear();
  754. done_ = false;
  755. }
  756. string_view
  757. serializer::
  758. read(char* dest, std::size_t size)
  759. {
  760. if(! jv_)
  761. {
  762. static value const null;
  763. jv_ = &null;
  764. }
  765. return read_some(dest, size);
  766. }
  767. BOOST_JSON_NS_END
  768. #ifdef _MSC_VER
  769. #pragma warning(pop)
  770. #endif
  771. #endif