Coverage Report

Created: 2025-08-28 06:51

/src/boost/boost/json/impl/serialize.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_SERIALIZE_IPP
11
#define BOOST_JSON_IMPL_SERIALIZE_IPP
12
13
#include <boost/json/serialize.hpp>
14
#include <boost/json/serializer.hpp>
15
#include <ostream>
16
17
namespace boost {
18
namespace json {
19
20
namespace {
21
22
int serialize_xalloc = std::ios::xalloc();
23
24
enum class serialize_stream_flags : long
25
{
26
    allow_infinity_and_nan = 1,
27
};
28
29
std::underlying_type<serialize_stream_flags>::type
30
to_bitmask( serialize_options const& opts )
31
0
{
32
0
    using E = serialize_stream_flags;
33
0
    using I = std::underlying_type<E>::type;
34
0
    return (opts.allow_infinity_and_nan
35
0
        ? static_cast<I>(E::allow_infinity_and_nan) : 0);
36
0
}
37
38
serialize_options
39
get_stream_flags( std::ostream& os )
40
0
{
41
0
    auto const flags = os.iword(serialize_xalloc);
42
43
0
    serialize_options opts;
44
0
    using E = serialize_stream_flags;
45
0
    using I = std::underlying_type<E>::type;
46
0
    opts.allow_infinity_and_nan =
47
0
        flags & static_cast<I>(E::allow_infinity_and_nan);
48
0
    return opts;
49
0
}
50
51
} // namespace
52
53
namespace detail {
54
55
void
56
serialize_impl(
57
    std::string& s,
58
    serializer& sr)
59
7.46k
{
60
    // serialize to a small buffer to avoid
61
    // the first few allocations in std::string
62
7.46k
    char buf[BOOST_JSON_STACK_BUFFER_SIZE];
63
7.46k
    string_view sv;
64
7.46k
    sv = sr.read(buf);
65
7.46k
    if(sr.done())
66
6.72k
    {
67
        // fast path
68
6.72k
        s.append(
69
6.72k
            sv.data(), sv.size());
70
6.72k
        return;
71
6.72k
    }
72
747
    std::size_t len = sv.size();
73
747
    s.reserve(len * 2);
74
747
    s.resize(s.capacity());
75
747
    BOOST_ASSERT(
76
747
        s.size() >= len * 2);
77
747
    std::memcpy(&s[0],
78
747
        sv.data(), sv.size());
79
747
    auto const lim =
80
747
        s.max_size() / 2;
81
747
    for(;;)
82
2.49k
    {
83
2.49k
        sv = sr.read(
84
2.49k
            &s[0] + len,
85
2.49k
            s.size() - len);
86
2.49k
        len += sv.size();
87
2.49k
        if(sr.done())
88
747
            break;
89
        // growth factor 2x
90
1.75k
        if(s.size() < lim)
91
1.75k
            s.resize(s.size() * 2);
92
0
        else
93
0
            s.resize(2 * lim);
94
1.75k
    }
95
747
    s.resize(len);
96
747
}
97
98
} // namespace detail
99
100
std::string
101
serialize(
102
    value const& jv,
103
    serialize_options const& opts)
104
7.46k
{
105
7.46k
    unsigned char buf[256];
106
7.46k
    serializer sr(
107
7.46k
        storage_ptr(),
108
7.46k
        buf,
109
7.46k
        sizeof(buf),
110
7.46k
        opts);
111
7.46k
    sr.reset(&jv);
112
7.46k
    std::string s;
113
7.46k
    serialize_impl(s, sr);
114
7.46k
    return s;
115
7.46k
}
116
117
std::string
118
serialize(
119
    array const& arr,
120
    serialize_options const& opts)
121
0
{
122
0
    unsigned char buf[256];
123
0
    serializer sr(
124
0
        storage_ptr(),
125
0
        buf,
126
0
        sizeof(buf),
127
0
        opts);
128
0
    std::string s;
129
0
    sr.reset(&arr);
130
0
    serialize_impl(s, sr);
131
0
    return s;
132
0
}
133
134
std::string
135
serialize(
136
    object const& obj,
137
    serialize_options const& opts)
138
0
{
139
0
    unsigned char buf[256];
140
0
    serializer sr(
141
0
        storage_ptr(),
142
0
        buf,
143
0
        sizeof(buf),
144
0
        opts);
145
0
    std::string s;
146
0
    sr.reset(&obj);
147
0
    serialize_impl(s, sr);
148
0
    return s;
149
0
}
150
151
std::string
152
serialize(
153
    string const& str,
154
    serialize_options const& opts)
155
0
{
156
0
    return serialize( str.subview(), opts );
157
0
}
158
159
// this is here for key_value_pair::key()
160
std::string
161
serialize(
162
    string_view sv,
163
    serialize_options const& opts)
164
0
{
165
0
    unsigned char buf[256];
166
0
    serializer sr(
167
0
        storage_ptr(),
168
0
        buf,
169
0
        sizeof(buf),
170
0
        opts);
171
0
    std::string s;
172
0
    sr.reset(sv);
173
0
    serialize_impl(s, sr);
174
0
    return s;
175
0
}
176
177
//----------------------------------------------------------
178
179
// tag::example_operator_lt_lt[]
180
// Serialize a value into an output stream
181
182
std::ostream&
183
operator<<( std::ostream& os, value const& jv )
184
0
{
185
    // Create a serializer
186
0
    serializer sr( get_stream_flags(os) );
187
188
    // Set the serializer up for our value
189
0
    sr.reset( &jv );
190
191
    // Loop until all output is produced.
192
0
    while( ! sr.done() )
193
0
    {
194
        // Use a local buffer to avoid allocation.
195
0
        char buf[ BOOST_JSON_STACK_BUFFER_SIZE ];
196
197
        // Fill our buffer with serialized characters and write it to the output stream.
198
0
        os << sr.read( buf );
199
0
    }
200
201
0
    return os;
202
0
}
203
// end::example_operator_lt_lt[]
204
205
static
206
void
207
to_ostream(
208
    std::ostream& os,
209
    serializer& sr)
210
0
{
211
0
    while(! sr.done())
212
0
    {
213
0
        char buf[BOOST_JSON_STACK_BUFFER_SIZE];
214
0
        auto s = sr.read(buf);
215
0
        os.write(s.data(), s.size());
216
0
    }
217
0
}
218
219
std::ostream&
220
operator<<(
221
    std::ostream& os,
222
    array const& arr)
223
0
{
224
0
    serializer sr( get_stream_flags(os) );
225
0
    sr.reset(&arr);
226
0
    to_ostream(os, sr);
227
0
    return os;
228
0
}
229
230
std::ostream&
231
operator<<(
232
    std::ostream& os,
233
    object const& obj)
234
0
{
235
0
    serializer sr( get_stream_flags(os) );
236
0
    sr.reset(&obj);
237
0
    to_ostream(os, sr);
238
0
    return os;
239
0
}
240
241
std::ostream&
242
operator<<(
243
    std::ostream& os,
244
    string const& str)
245
0
{
246
0
    serializer sr( get_stream_flags(os) );
247
0
    sr.reset(&str);
248
0
    to_ostream(os, sr);
249
0
    return os;
250
0
}
251
252
std::ostream&
253
operator<<( std::ostream& os, serialize_options const& opts )
254
0
{
255
0
    os.iword(serialize_xalloc) = to_bitmask(opts);
256
0
    return os;
257
0
}
258
259
} // namespace json
260
} // namespace boost
261
262
#endif