Coverage Report

Created: 2026-02-07 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boost/boost/json/detail/stream.hpp
Line
Count
Source
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_DETAIL_STREAM_HPP
11
#define BOOST_JSON_DETAIL_STREAM_HPP
12
13
namespace boost {
14
namespace json {
15
namespace detail {
16
17
class const_stream
18
{
19
    friend class local_const_stream;
20
21
    char const* p_;
22
    char const* end_;
23
24
public:
25
    const_stream() = default;
26
27
    const_stream(
28
        char const* data,
29
        std::size_t size) noexcept
30
27.2k
        : p_(data)
31
27.2k
        , end_(data + size)
32
27.2k
    {
33
27.2k
    }
34
35
    size_t
36
    used(char const* begin) const noexcept
37
0
    {
38
0
        return static_cast<
39
0
            size_t>(p_ - begin);
40
0
    }
41
42
    size_t
43
    remain() const noexcept
44
32.9k
    {
45
32.9k
        return end_ - p_;
46
32.9k
    }
47
48
    char const*
49
    data() const noexcept
50
28.4k
    {
51
28.4k
        return p_;
52
28.4k
    }
53
54
    operator bool() const noexcept
55
30.8M
    {
56
30.8M
        return p_ < end_;
57
30.8M
    }
58
59
    // unchecked
60
    char
61
    operator*() const noexcept
62
30.8M
    {
63
30.8M
        BOOST_ASSERT(p_ < end_);
64
30.8M
        return *p_;
65
30.8M
    }
66
67
    // unchecked
68
    const_stream&
69
    operator++() noexcept
70
30.8M
    {
71
30.8M
        BOOST_ASSERT(p_ < end_);
72
30.8M
        ++p_;
73
30.8M
        return *this;
74
30.8M
    }
75
76
    void
77
    skip(std::size_t n) noexcept
78
8.00k
    {
79
8.00k
        BOOST_ASSERT(n <= remain());
80
8.00k
        p_ += n;
81
8.00k
    }
82
83
    void
84
    skip_to(const char* p) noexcept
85
0
    {
86
0
        BOOST_ASSERT(p <= end_ && p >= p_);
87
0
        p_ = p;
88
0
    }
89
};
90
91
class local_const_stream
92
    : public const_stream
93
{
94
    const_stream& src_;
95
96
public:
97
    explicit
98
    local_const_stream(
99
        const_stream& src) noexcept
100
24.0k
        : const_stream(src)
101
24.0k
        , src_(src)
102
24.0k
    {
103
24.0k
    }
104
105
    ~local_const_stream()
106
24.0k
    {
107
24.0k
        src_.p_ = p_;
108
24.0k
    }
109
110
    void
111
    clip(std::size_t n) noexcept
112
0
    {
113
0
        if(static_cast<std::size_t>(
114
0
            src_.end_ - p_) > n)
115
0
            end_ = p_ + n;
116
0
        else
117
0
            end_ = src_.end_;
118
0
    }
119
};
120
121
class const_stream_wrapper
122
{
123
    const char*& p_;
124
    const char* const end_;
125
126
    friend class clipped_const_stream;
127
public:
128
    const_stream_wrapper(
129
        const char*& p,
130
        const char* end)
131
18.1M
        : p_(p)
132
18.1M
        , end_(end)
133
18.1M
    {
134
18.1M
    }
135
136
    void operator++() noexcept
137
186M
    {
138
186M
        ++p_;
139
186M
    }
140
141
    void operator+=(std::size_t n) noexcept
142
15.8M
    {
143
15.8M
        p_ += n;
144
15.8M
    }
145
146
    void operator=(const char* p) noexcept
147
56.2M
    {
148
56.2M
        p_ = p;
149
56.2M
    }
150
151
    char operator*() const noexcept
152
240M
    {
153
240M
        return *p_;
154
240M
    }
155
156
    operator bool() const noexcept
157
173M
    {
158
173M
        return p_ < end_;
159
173M
    }
160
161
    const char* begin() const noexcept
162
140M
    {
163
140M
        return p_;
164
140M
    }
165
166
    const char* end() const noexcept
167
38.1M
    {
168
38.1M
        return end_;
169
38.1M
    }
170
171
    std::size_t remain() const noexcept
172
15.7M
    {
173
15.7M
        return end_ - p_;
174
15.7M
    }
175
176
    std::size_t remain(const char* p) const noexcept
177
56
    {
178
56
        return end_ - p;
179
56
    }
180
181
    std::size_t used(const char* p) const noexcept
182
17.6M
    {
183
17.6M
        return p_ - p;
184
17.6M
    }
185
};
186
187
class clipped_const_stream
188
    : public const_stream_wrapper
189
{
190
    const char* clip_;
191
192
public:
193
    clipped_const_stream(
194
        const char*& p,
195
        const char* end)
196
107k
        : const_stream_wrapper(p, end)
197
107k
        , clip_(end)
198
107k
    {
199
107k
    }
200
201
    void operator=(const char* p)
202
0
    {
203
0
        p_ = p;
204
0
    }
205
206
    const char* end() const noexcept
207
0
    {
208
0
        return clip_;
209
0
    }
210
211
    operator bool() const noexcept
212
36.6M
    {
213
36.6M
        return p_ < clip_;
214
36.6M
    }
215
216
    std::size_t remain() const noexcept
217
554k
    {
218
554k
        return clip_ - p_;
219
554k
    }
220
221
    std::size_t remain(const char* p) const noexcept
222
0
    {
223
0
        return clip_ - p;
224
0
    }
225
226
    void
227
    clip(std::size_t n) noexcept
228
115k
    {
229
115k
        if(static_cast<std::size_t>(
230
115k
            end_ - p_) > n)
231
91.7k
            clip_ = p_ + n;
232
23.9k
        else
233
23.9k
            clip_ = end_;
234
115k
    }
235
};
236
237
//--------------------------------------
238
239
class stream
240
{
241
    friend class local_stream;
242
243
    char* p_;
244
    char* end_;
245
246
public:
247
    stream(
248
        char* data,
249
        std::size_t size) noexcept
250
9.60k
        : p_(data)
251
9.60k
        , end_(data + size)
252
9.60k
    {
253
9.60k
    }
254
255
    size_t
256
    used(char* begin) const noexcept
257
9.60k
    {
258
9.60k
        return static_cast<
259
9.60k
            size_t>(p_ - begin);
260
9.60k
    }
261
262
    size_t
263
    remain() const noexcept
264
10.0M
    {
265
10.0M
        return end_ - p_;
266
10.0M
    }
267
268
    char*
269
    data() noexcept
270
9.85M
    {
271
9.85M
        return p_;
272
9.85M
    }
273
274
    operator bool() const noexcept
275
41.7M
    {
276
41.7M
        return p_ < end_;
277
41.7M
    }
278
279
    // unchecked
280
    char&
281
    operator*() noexcept
282
0
    {
283
0
        BOOST_ASSERT(p_ < end_);
284
0
        return *p_;
285
0
    }
286
287
    // unchecked
288
    stream&
289
    operator++() noexcept
290
0
    {
291
0
        BOOST_ASSERT(p_ < end_);
292
0
        ++p_;
293
0
        return *this;
294
0
    }
295
296
    // unchecked
297
    void
298
    append(
299
        char const* src,
300
        std::size_t n) noexcept
301
216k
    {
302
216k
        BOOST_ASSERT(remain() >= n);
303
216k
        std::memcpy(p_, src, n);
304
216k
        p_ += n;
305
216k
    }
306
307
    // unchecked
308
    void
309
    append(char c) noexcept
310
41.9M
    {
311
41.9M
        BOOST_ASSERT(p_ < end_);
312
41.9M
        *p_++ = c;
313
41.9M
    }
314
315
    void
316
    advance(std::size_t n) noexcept
317
9.85M
    {
318
9.85M
        BOOST_ASSERT(remain() >= n);
319
9.85M
        p_ += n;
320
9.85M
    }
321
};
322
323
class local_stream
324
    : public stream
325
{
326
    stream& src_;
327
328
public:
329
    explicit
330
    local_stream(
331
        stream& src)
332
9.91M
        : stream(src)
333
9.91M
        , src_(src)
334
9.91M
    {
335
9.91M
    }
336
337
    ~local_stream()
338
9.91M
    {
339
9.91M
        src_.p_ = p_;
340
9.91M
    }
341
};
342
343
} // detail
344
} // namespace json
345
} // namespace boost
346
347
#endif