serializer.ipp 19 KB

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