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_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 35737 : const_stream(
28 : char const* data,
29 : std::size_t size) noexcept
30 35737 : : p_(data)
31 35737 : , end_(data + size)
32 : {
33 35737 : }
34 :
35 : size_t
36 : used(char const* begin) const noexcept
37 : {
38 : return static_cast<
39 : size_t>(p_ - begin);
40 : }
41 :
42 : size_t
43 64884 : remain() const noexcept
44 : {
45 64884 : return end_ - p_;
46 : }
47 :
48 : char const*
49 62262 : data() const noexcept
50 : {
51 62262 : return p_;
52 : }
53 :
54 31452012 : operator bool() const noexcept
55 : {
56 31452012 : return p_ < end_;
57 : }
58 :
59 : // unchecked
60 : char
61 31417565 : operator*() const noexcept
62 : {
63 31417565 : BOOST_ASSERT(p_ < end_);
64 31417565 : return *p_;
65 : }
66 :
67 : // unchecked
68 : const_stream&
69 31417565 : operator++() noexcept
70 : {
71 31417565 : BOOST_ASSERT(p_ < end_);
72 31417565 : ++p_;
73 31417565 : return *this;
74 : }
75 :
76 : void
77 26559 : skip(std::size_t n) noexcept
78 : {
79 26559 : BOOST_ASSERT(n <= remain());
80 26559 : p_ += n;
81 26559 : }
82 :
83 : void
84 : skip_to(const char* p) noexcept
85 : {
86 : BOOST_ASSERT(p <= end_ && p >= p_);
87 : p_ = p;
88 : }
89 : };
90 :
91 : class local_const_stream
92 : : public const_stream
93 : {
94 : const_stream& src_;
95 :
96 : public:
97 : explicit
98 44303 : local_const_stream(
99 : const_stream& src) noexcept
100 44303 : : const_stream(src)
101 44303 : , src_(src)
102 : {
103 44303 : }
104 :
105 44303 : ~local_const_stream()
106 : {
107 44303 : src_.p_ = p_;
108 44303 : }
109 :
110 : void
111 : clip(std::size_t n) noexcept
112 : {
113 : if(static_cast<std::size_t>(
114 : src_.end_ - p_) > n)
115 : end_ = p_ + n;
116 : else
117 : end_ = src_.end_;
118 : }
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 4794793 : const_stream_wrapper(
129 : const char*& p,
130 : const char* end)
131 4794793 : : p_(p)
132 4794793 : , end_(end)
133 : {
134 4794793 : }
135 :
136 63385394 : void operator++() noexcept
137 : {
138 63385394 : ++p_;
139 63385394 : }
140 :
141 2046839 : void operator+=(std::size_t n) noexcept
142 : {
143 2046839 : p_ += n;
144 2046839 : }
145 :
146 7324085 : void operator=(const char* p) noexcept
147 : {
148 7324085 : p_ = p;
149 7324085 : }
150 :
151 70856715 : char operator*() const noexcept
152 : {
153 70856715 : return *p_;
154 : }
155 :
156 76832364 : operator bool() const noexcept
157 : {
158 76832364 : return p_ < end_;
159 : }
160 :
161 20800222 : const char* begin() const noexcept
162 : {
163 20800222 : return p_;
164 : }
165 :
166 4866133 : const char* end() const noexcept
167 : {
168 4866133 : return end_;
169 : }
170 :
171 2135989 : std::size_t remain() const noexcept
172 : {
173 2135989 : return end_ - p_;
174 : }
175 :
176 3166 : std::size_t remain(const char* p) const noexcept
177 : {
178 3166 : return end_ - p;
179 : }
180 :
181 2315035 : std::size_t used(const char* p) const noexcept
182 : {
183 2315035 : return p_ - p;
184 : }
185 : };
186 :
187 : class clipped_const_stream
188 : : public const_stream_wrapper
189 : {
190 : const char* clip_;
191 :
192 : public:
193 13678 : clipped_const_stream(
194 : const char*& p,
195 : const char* end)
196 13678 : : const_stream_wrapper(p, end)
197 13678 : , clip_(end)
198 : {
199 13678 : }
200 :
201 : void operator=(const char* p)
202 : {
203 : p_ = p;
204 : }
205 :
206 : const char* end() const noexcept
207 : {
208 : return clip_;
209 : }
210 :
211 68643 : operator bool() const noexcept
212 : {
213 68643 : return p_ < clip_;
214 : }
215 :
216 11688 : std::size_t remain() const noexcept
217 : {
218 11688 : return clip_ - p_;
219 : }
220 :
221 : std::size_t remain(const char* p) const noexcept
222 : {
223 : return clip_ - p;
224 : }
225 :
226 : void
227 15663 : clip(std::size_t n) noexcept
228 : {
229 15663 : if(static_cast<std::size_t>(
230 15663 : end_ - p_) > n)
231 37 : clip_ = p_ + n;
232 : else
233 15626 : clip_ = end_;
234 15663 : }
235 : };
236 :
237 : //--------------------------------------
238 :
239 : class stream
240 : {
241 : friend class local_stream;
242 :
243 : char* p_;
244 : char* end_;
245 :
246 : public:
247 32987 : stream(
248 : char* data,
249 : std::size_t size) noexcept
250 32987 : : p_(data)
251 32987 : , end_(data + size)
252 : {
253 32987 : }
254 :
255 : size_t
256 32985 : used(char* begin) const noexcept
257 : {
258 : return static_cast<
259 32985 : size_t>(p_ - begin);
260 : }
261 :
262 : size_t
263 90573 : remain() const noexcept
264 : {
265 90573 : return end_ - p_;
266 : }
267 :
268 : char*
269 2957 : data() noexcept
270 : {
271 2957 : return p_;
272 : }
273 :
274 31624080 : operator bool() const noexcept
275 : {
276 31624080 : return p_ < end_;
277 : }
278 :
279 : // unchecked
280 : char&
281 : operator*() noexcept
282 : {
283 : BOOST_ASSERT(p_ < end_);
284 : return *p_;
285 : }
286 :
287 : // unchecked
288 : stream&
289 : operator++() noexcept
290 : {
291 : BOOST_ASSERT(p_ < end_);
292 : ++p_;
293 : return *this;
294 : }
295 :
296 : // unchecked
297 : void
298 32736 : append(
299 : char const* src,
300 : std::size_t n) noexcept
301 : {
302 32736 : BOOST_ASSERT(remain() >= n);
303 32736 : std::memcpy(p_, src, n);
304 32736 : p_ += n;
305 32736 : }
306 :
307 : // unchecked
308 : void
309 31554322 : append(char c) noexcept
310 : {
311 31554322 : BOOST_ASSERT(p_ < end_);
312 31554322 : *p_++ = c;
313 31554322 : }
314 :
315 : void
316 2957 : advance(std::size_t n) noexcept
317 : {
318 2957 : BOOST_ASSERT(remain() >= n);
319 2957 : p_ += n;
320 2957 : }
321 : };
322 :
323 : class local_stream
324 : : public stream
325 : {
326 : stream& src_;
327 :
328 : public:
329 : explicit
330 84518 : local_stream(
331 : stream& src)
332 84518 : : stream(src)
333 84518 : , src_(src)
334 : {
335 84518 : }
336 :
337 84518 : ~local_stream()
338 : {
339 84518 : src_.p_ = p_;
340 84518 : }
341 : };
342 :
343 : } // detail
344 : } // namespace json
345 : } // namespace boost
346 :
347 : #endif
|