join 1.0
lightweight network framework library
Loading...
Searching...
No Matches
value_builder.hpp
Go to the documentation of this file.
1
25#ifndef JOIN_DATA_VALUE_BUILDER_HPP
26#define JOIN_DATA_VALUE_BUILDER_HPP
27
28// libjoin.
29#include <join/value.hpp>
30#include <join/utils.hpp>
31#include <join/sax.hpp>
32
33// C++.
34#include <string_view>
35#include <iterator>
36#include <utility>
37#include <string>
38#include <vector>
39
40// C.
41#include <cstddef>
42
43namespace join
44{
49 {
50 public:
55 explicit ValueBuilder (Value& root)
56 : _stack (std::move (cache ()))
57 , _root (root)
58 {
59 }
60
65 ValueBuilder (const ValueBuilder& other) = delete;
66
72 ValueBuilder& operator= (const ValueBuilder& other) = delete;
73
78 ValueBuilder (ValueBuilder&& other) = delete;
79
86
91 {
92 _stack.clear ();
93 cache () = std::move (_stack);
94 }
95
100 int setNull ()
101 {
102 return emplaceValue (nullptr);
103 }
104
110 int setBool (bool value)
111 {
112 return emplaceValue (value);
113 }
114
120 int setInt (int32_t value)
121 {
122 return emplaceValue (value);
123 }
124
130 int setUint (uint32_t value)
131 {
132 return emplaceValue (value);
133 }
134
140 int setInt64 (int64_t value)
141 {
142 return emplaceValue (value);
143 }
144
150 int setUint64 (uint64_t value)
151 {
152 return emplaceValue (value);
153 }
154
160 int setDouble (double value)
161 {
162 return emplaceValue (value);
163 }
164
170 int setString (std::string_view value)
171 {
172 return emplaceValue (std::string (value));
173 }
174
180 int startArray ([[maybe_unused]] uint32_t size = 0)
181 {
182 if (JOIN_UNLIKELY (_depth == 0))
183 {
184 _stack.clear ();
185 }
186 else if (JOIN_UNLIKELY (_depth >= saxMaxDepth))
187 {
189 return -1;
190 }
191
192 _starts[_depth++] = _stack.size ();
193
194 return 0;
195 }
196
202 {
203 if (JOIN_UNLIKELY (_depth == 0))
204 {
206 return -1;
207 }
208
209 auto first = _stack.begin () + _starts[--_depth];
210 Array array (std::make_move_iterator (first), std::make_move_iterator (_stack.end ()));
211 _stack.erase (first, _stack.end ());
212
213 if (_depth == 0)
214 {
215 _root = std::move (array);
216 return 0;
217 }
218
219 _stack.emplace_back (std::move (array));
220
221 return 0;
222 }
223
229 int startObject ([[maybe_unused]] uint32_t size = 0)
230 {
231 if (JOIN_UNLIKELY (_depth == 0))
232 {
233 _stack.clear ();
234 }
235 else if (JOIN_UNLIKELY (_depth >= saxMaxDepth))
236 {
238 return -1;
239 }
240
241 _starts[_depth++] = _stack.size ();
242
243 return 0;
244 }
245
251 const Object& members (const Object& object) const noexcept
252 {
253 return object;
254 }
255
261 int setKey (std::nullptr_t key)
262 {
263 if (JOIN_UNLIKELY (_depth == 0))
264 {
266 return -1;
267 }
268
269 _stack.emplace_back (key);
270
271 return 0;
272 }
273
279 int setKey (bool key)
280 {
281 if (JOIN_UNLIKELY (_depth == 0))
282 {
284 return -1;
285 }
286
287 _stack.emplace_back (key);
288
289 return 0;
290 }
291
297 int setKey (int32_t key)
298 {
299 if (JOIN_UNLIKELY (_depth == 0))
300 {
302 return -1;
303 }
304
305 _stack.emplace_back (key);
306
307 return 0;
308 }
309
315 int setKey (uint32_t key)
316 {
317 if (JOIN_UNLIKELY (_depth == 0))
318 {
320 return -1;
321 }
322
323 _stack.emplace_back (key);
324
325 return 0;
326 }
327
333 int setKey (int64_t key)
334 {
335 if (JOIN_UNLIKELY (_depth == 0))
336 {
338 return -1;
339 }
340
341 _stack.emplace_back (key);
342
343 return 0;
344 }
345
351 int setKey (uint64_t key)
352 {
353 if (JOIN_UNLIKELY (_depth == 0))
354 {
356 return -1;
357 }
358
359 _stack.emplace_back (key);
360
361 return 0;
362 }
363
369 int setKey (double key)
370 {
371 if (JOIN_UNLIKELY (_depth == 0))
372 {
374 return -1;
375 }
376
377 _stack.emplace_back (key);
378
379 return 0;
380 }
381
387 int setKey (std::string_view key)
388 {
389 if (JOIN_UNLIKELY (_depth == 0))
390 {
392 return -1;
393 }
394
395 _stack.emplace_back (key);
396
397 return 0;
398 }
399
405 int setKey (const char* key)
406 {
407 return setKey (std::string_view (key));
408 }
409
415 {
416 if (JOIN_UNLIKELY (_depth == 0))
417 {
419 return -1;
420 }
421
422 if (JOIN_UNLIKELY ((_stack.size () - _starts[_depth - 1]) & 1))
423 {
425 return -1;
426 }
427
428 auto first = _stack.begin () + _starts[--_depth];
429 Object object;
430 object.reserve ((_stack.end () - first) / 2);
431 for (auto it = first; it != _stack.end (); it += 2)
432 {
433 object.emplace_back (std::move (it[0]), std::move (it[1]));
434 }
435 _stack.erase (first, _stack.end ());
436
437 if (_depth == 0)
438 {
439 _root = std::move (object);
440 return 0;
441 }
442
443 _stack.emplace_back (std::move (object));
444
445 return 0;
446 }
447
451 void reset () noexcept
452 {
453 _depth = 0;
454 _stack.clear ();
455 }
456
457 private:
463 template <typename T>
464 int emplaceValue (T&& value)
465 {
466 if (JOIN_UNLIKELY (_depth == 0))
467 {
468 _root = Value (std::forward<T> (value));
469 return 0;
470 }
471
472 _stack.emplace_back (std::forward<T> (value));
473
474 return 0;
475 }
476
481 static std::vector<Value>& cache () noexcept
482 {
483 thread_local std::vector<Value> stack;
484 return stack;
485 }
486
488 size_t _starts[saxMaxDepth] = {};
489
491 size_t _depth = 0;
492
494 std::vector<Value> _stack;
495
497 Value& _root;
498 };
499}
500
501#endif
value builder class, filled by balanced SAX calls.
Definition value_builder.hpp:49
int setKey(std::string_view key)
set string key.
Definition value_builder.hpp:387
int startArray(uint32_t size=0)
start array.
Definition value_builder.hpp:180
int setDouble(double value)
set real value.
Definition value_builder.hpp:160
int stopArray()
stop array.
Definition value_builder.hpp:201
int setKey(double key)
set real key.
Definition value_builder.hpp:369
ValueBuilder & operator=(const ValueBuilder &other)=delete
copy assignment.
int setKey(uint32_t key)
set unsigned integer key.
Definition value_builder.hpp:315
int setBool(bool value)
set boolean value.
Definition value_builder.hpp:110
int setInt(int32_t value)
set integer value.
Definition value_builder.hpp:120
int setNull()
set null value.
Definition value_builder.hpp:100
int setUint(uint32_t value)
set unsigned integer value.
Definition value_builder.hpp:130
void reset() noexcept
reset the parsing state, leaving the root untouched.
Definition value_builder.hpp:451
ValueBuilder(Value &root)
create instance.
Definition value_builder.hpp:55
int setKey(int32_t key)
set integer key.
Definition value_builder.hpp:297
int setKey(uint64_t key)
set unsigned 64 bits integer key.
Definition value_builder.hpp:351
ValueBuilder(ValueBuilder &&other)=delete
move constructor.
int setKey(int64_t key)
set 64 bits integer key.
Definition value_builder.hpp:333
ValueBuilder(const ValueBuilder &other)=delete
copy constructor.
int setKey(bool key)
set boolean key.
Definition value_builder.hpp:279
int setInt64(int64_t value)
set 64 bits integer value.
Definition value_builder.hpp:140
int stopObject()
stop object.
Definition value_builder.hpp:414
const Object & members(const Object &object) const noexcept
get object members in writing order.
Definition value_builder.hpp:251
int setString(std::string_view value)
set string value.
Definition value_builder.hpp:170
~ValueBuilder()
destroy instance.
Definition value_builder.hpp:90
int startObject(uint32_t size=0)
start object.
Definition value_builder.hpp:229
int setUint64(uint64_t value)
set unsigned 64 bits integer value.
Definition value_builder.hpp:150
int setKey(std::nullptr_t key)
set null key.
Definition value_builder.hpp:261
int setKey(const char *key)
set string key.
Definition value_builder.hpp:405
value class.
Definition value.hpp:92
const std::string key(65, 'a')
key.
Definition acceptor.hpp:32
std::vector< Value > Array
array.
Definition value.hpp:53
std::error_code make_error_code(join::Errc code) noexcept
Create an std::error_code object.
Definition error.cpp:195
constexpr size_t saxMaxDepth
max number of nested containers.
Definition sax.hpp:42
thread_local std::error_code lastError
last error.
Definition error.cpp:32
std::vector< Member > Object
object.
Definition value.hpp:86
Definition error.hpp:144
#define JOIN_UNLIKELY(x)
Definition utils.hpp:51