Coverage Report

Created: 2023-06-07 06:25

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