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