Coverage Report

Created: 2026-03-09 06:23

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
26.2k
        : p_(data)
31
26.2k
        , end_(data + size)
32
26.2k
    {
33
26.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
31.6k
    {
45
31.6k
        return end_ - p_;
46
31.6k
    }
47
48
    char const*
49
    data() const noexcept
50
25.9k
    {
51
25.9k
        return p_;
52
25.9k
    }
53
54
    operator bool() const noexcept
55
28.7M
    {
56
28.7M
        return p_ < end_;
57
28.7M
    }
58
59
    // unchecked
60
    char
61
    operator*() const noexcept
62
28.7M
    {
63
28.7M
        BOOST_ASSERT(p_ < end_);
64
28.7M
        return *p_;
65
28.7M
    }
66
67
    // unchecked
68
    const_stream&
69
    operator++() noexcept
70
28.7M
    {
71
28.7M
        BOOST_ASSERT(p_ < end_);
72
28.7M
        ++p_;
73
28.7M
        return *this;
74
28.7M
    }
75
76
    void
77
    skip(std::size_t n) noexcept
78
6.64k
    {
79
6.64k
        BOOST_ASSERT(n <= remain());
80
6.64k
        p_ += n;
81
6.64k
    }
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
23.0k
        : const_stream(src)
101
23.0k
        , src_(src)
102
23.0k
    {
103
23.0k
    }
104
105
    ~local_const_stream()
106
23.0k
    {
107
23.0k
        src_.p_ = p_;
108
23.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
17.3M
        : p_(p)
132
17.3M
        , end_(end)
133
17.3M
    {
134
17.3M
    }
135
136
    void operator++() noexcept
137
178M
    {
138
178M
        ++p_;
139
178M
    }
140
141
    void operator+=(std::size_t n) noexcept
142
14.9M
    {
143
14.9M
        p_ += n;
144
14.9M
    }
145
146
    void operator=(const char* p) noexcept
147
54.0M
    {
148
54.0M
        p_ = p;
149
54.0M
    }
150
151
    char operator*() const noexcept
152
225M
    {
153
225M
        return *p_;
154
225M
    }
155
156
    operator bool() const noexcept
157
163M
    {
158
163M
        return p_ < end_;
159
163M
    }
160
161
    const char* begin() const noexcept
162
133M
    {
163
133M
        return p_;
164
133M
    }
165
166
    const char* end() const noexcept
167
36.7M
    {
168
36.7M
        return end_;
169
36.7M
    }
170
171
    std::size_t remain() const noexcept
172
14.7M
    {
173
14.7M
        return end_ - p_;
174
14.7M
    }
175
176
    std::size_t remain(const char* p) const noexcept
177
64
    {
178
64
        return end_ - p;
179
64
    }
180
181
    std::size_t used(const char* p) const noexcept
182
16.8M
    {
183
16.8M
        return p_ - p;
184
16.8M
    }
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
111k
        : const_stream_wrapper(p, end)
197
111k
        , clip_(end)
198
111k
    {
199
111k
    }
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.1M
    {
213
36.1M
        return p_ < clip_;
214
36.1M
    }
215
216
    std::size_t remain() const noexcept
217
591k
    {
218
591k
        return clip_ - p_;
219
591k
    }
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
120k
    {
229
120k
        if(static_cast<std::size_t>(
230
120k
            end_ - p_) > n)
231
95.8k
            clip_ = p_ + n;
232
24.7k
        else
233
24.7k
            clip_ = end_;
234
120k
    }
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.55k
        : p_(data)
251
9.55k
        , end_(data + size)
252
9.55k
    {
253
9.55k
    }
254
255
    size_t
256
    used(char* begin) const noexcept
257
9.55k
    {
258
9.55k
        return static_cast<
259
9.55k
            size_t>(p_ - begin);
260
9.55k
    }
261
262
    size_t
263
    remain() const noexcept
264
8.54M
    {
265
8.54M
        return end_ - p_;
266
8.54M
    }
267
268
    char*
269
    data() noexcept
270
8.32M
    {
271
8.32M
        return p_;
272
8.32M
    }
273
274
    operator bool() const noexcept
275
37.6M
    {
276
37.6M
        return p_ < end_;
277
37.6M
    }
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
200k
    {
302
200k
        BOOST_ASSERT(remain() >= n);
303
200k
        std::memcpy(p_, src, n);
304
200k
        p_ += n;
305
200k
    }
306
307
    // unchecked
308
    void
309
    append(char c) noexcept
310
37.7M
    {
311
37.7M
        BOOST_ASSERT(p_ < end_);
312
37.7M
        *p_++ = c;
313
37.7M
    }
314
315
    void
316
    advance(std::size_t n) noexcept
317
8.32M
    {
318
8.32M
        BOOST_ASSERT(remain() >= n);
319
8.32M
        p_ += n;
320
8.32M
    }
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
8.39M
        : stream(src)
333
8.39M
        , src_(src)
334
8.39M
    {
335
8.39M
    }
336
337
    ~local_stream()
338
8.39M
    {
339
8.39M
        src_.p_ = p_;
340
8.39M
    }
341
};
342
343
} // detail
344
} // namespace json
345
} // namespace boost
346
347
#endif