]>
Commit | Line | Data |
---|---|---|
20effc67 TL |
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 | ||
f51cf556 TL |
13 | namespace boost { |
14 | namespace json { | |
20effc67 TL |
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; | |
20effc67 TL |
26 | |
27 | const_stream( | |
28 | char const* data, | |
29 | std::size_t size) noexcept | |
30 | : p_(data) | |
31 | , end_(data + size) | |
32 | { | |
33 | } | |
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 | remain() const noexcept | |
44 | { | |
45 | return end_ - p_; | |
46 | } | |
47 | ||
48 | char const* | |
49 | data() const noexcept | |
50 | { | |
51 | return p_; | |
52 | } | |
53 | ||
54 | operator bool() const noexcept | |
55 | { | |
56 | return p_ < end_; | |
57 | } | |
58 | ||
59 | // unchecked | |
60 | char | |
61 | operator*() const noexcept | |
62 | { | |
63 | BOOST_ASSERT(p_ < end_); | |
64 | return *p_; | |
65 | } | |
66 | ||
67 | // unchecked | |
68 | const_stream& | |
69 | operator++() noexcept | |
70 | { | |
71 | BOOST_ASSERT(p_ < end_); | |
72 | ++p_; | |
73 | return *this; | |
74 | } | |
75 | ||
76 | void | |
77 | skip(std::size_t n) noexcept | |
78 | { | |
79 | BOOST_ASSERT(n <= remain()); | |
80 | p_ += n; | |
81 | } | |
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 | local_const_stream( | |
99 | const_stream& src) noexcept | |
100 | : const_stream(src) | |
101 | , src_(src) | |
102 | { | |
103 | } | |
104 | ||
105 | ~local_const_stream() | |
106 | { | |
107 | src_.p_ = p_; | |
108 | } | |
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 | const_stream_wrapper( | |
129 | const char*& p, | |
130 | const char* end) | |
131 | : p_(p) | |
132 | , end_(end) | |
133 | { | |
134 | } | |
135 | ||
136 | void operator++() noexcept | |
137 | { | |
138 | ++p_; | |
139 | } | |
140 | ||
141 | void operator+=(std::size_t n) noexcept | |
142 | { | |
143 | p_ += n; | |
144 | } | |
145 | ||
146 | void operator=(const char* p) noexcept | |
147 | { | |
148 | p_ = p; | |
149 | } | |
150 | ||
151 | char operator*() const noexcept | |
152 | { | |
153 | return *p_; | |
154 | } | |
155 | ||
156 | operator bool() const noexcept | |
157 | { | |
158 | return p_ < end_; | |
159 | } | |
1e59de90 | 160 | |
20effc67 TL |
161 | const char* begin() const noexcept |
162 | { | |
163 | return p_; | |
164 | } | |
165 | ||
166 | const char* end() const noexcept | |
167 | { | |
168 | return end_; | |
169 | } | |
170 | ||
171 | std::size_t remain() const noexcept | |
172 | { | |
173 | return end_ - p_; | |
174 | } | |
175 | ||
176 | std::size_t remain(const char* p) const noexcept | |
177 | { | |
178 | return end_ - p; | |
179 | } | |
180 | ||
181 | std::size_t used(const char* p) const noexcept | |
182 | { | |
183 | 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 | clipped_const_stream( | |
194 | const char*& p, | |
195 | const char* end) | |
196 | : const_stream_wrapper(p, end) | |
197 | , clip_(end) | |
198 | { | |
199 | } | |
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 | operator bool() const noexcept | |
212 | { | |
213 | return p_ < clip_; | |
214 | } | |
215 | ||
216 | std::size_t remain() const noexcept | |
217 | { | |
218 | 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 | clip(std::size_t n) noexcept | |
228 | { | |
229 | if(static_cast<std::size_t>( | |
230 | end_ - p_) > n) | |
231 | clip_ = p_ + n; | |
232 | else | |
233 | clip_ = end_; | |
234 | } | |
235 | }; | |
236 | ||
237 | //-------------------------------------- | |
238 | ||
239 | class stream | |
240 | { | |
241 | friend class local_stream; | |
242 | ||
243 | char* p_; | |
244 | char* end_; | |
245 | ||
246 | public: | |
20effc67 TL |
247 | stream( |
248 | char* data, | |
249 | std::size_t size) noexcept | |
250 | : p_(data) | |
251 | , end_(data + size) | |
252 | { | |
253 | } | |
254 | ||
255 | size_t | |
256 | used(char* begin) const noexcept | |
257 | { | |
258 | return static_cast< | |
259 | size_t>(p_ - begin); | |
260 | } | |
261 | ||
262 | size_t | |
263 | remain() const noexcept | |
264 | { | |
265 | return end_ - p_; | |
266 | } | |
267 | ||
268 | char* | |
269 | data() noexcept | |
270 | { | |
271 | return p_; | |
272 | } | |
273 | ||
274 | operator bool() const noexcept | |
275 | { | |
276 | 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 | append( | |
299 | char const* src, | |
300 | std::size_t n) noexcept | |
301 | { | |
302 | BOOST_ASSERT(remain() >= n); | |
303 | std::memcpy(p_, src, n); | |
304 | p_ += n; | |
305 | } | |
306 | ||
307 | // unchecked | |
308 | void | |
309 | append(char c) noexcept | |
310 | { | |
311 | BOOST_ASSERT(p_ < end_); | |
312 | *p_++ = c; | |
313 | } | |
314 | ||
315 | void | |
316 | advance(std::size_t n) noexcept | |
317 | { | |
318 | BOOST_ASSERT(remain() >= n); | |
319 | p_ += n; | |
320 | } | |
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 | : stream(src) | |
333 | , src_(src) | |
334 | { | |
335 | } | |
336 | ||
337 | ~local_stream() | |
338 | { | |
339 | src_.p_ = p_; | |
340 | } | |
341 | }; | |
342 | ||
343 | } // detail | |
f51cf556 TL |
344 | } // namespace json |
345 | } // namespace boost | |
20effc67 TL |
346 | |
347 | #endif |