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