join 1.0
lightweight network framework library
Loading...
Searching...
No Matches
sax.hpp
Go to the documentation of this file.
1
25#ifndef JOIN_DATA_SAX_HPP
26#define JOIN_DATA_SAX_HPP
27
28// libjoin.
29#include <join/error.hpp>
30#include <join/value.hpp>
31#include <join/utils.hpp>
32#include <join/view.hpp>
33
34// C++.
35#include <system_error>
36#include <iostream>
37#include <fstream>
38#include <sstream>
39#include <memory>
40#include <string>
41#include <stack>
42
43// C.
44#include <cstddef>
45
46namespace join
47{
49 class Value;
50
54 enum class SaxErrc
55 {
56 StackOverflow = 1,
61 };
62
66 class SaxCategory : public std::error_category
67 {
68 public:
73 virtual const char* name () const noexcept;
74
80 virtual std::string message (int code) const;
81 };
82
87 const std::error_category& saxCategory () noexcept;
88
94 std::error_code make_error_code (SaxErrc code) noexcept;
95
101 std::error_condition make_error_condition (SaxErrc code) noexcept;
102
107 {
108 public:
112 SaxHandler () = default;
113
118 SaxHandler (const SaxHandler& other) = default;
119
125 SaxHandler& operator= (const SaxHandler& other) = default;
126
131 SaxHandler (SaxHandler&& other) = default;
132
138 SaxHandler& operator= (SaxHandler&& other) = default;
139
143 virtual ~SaxHandler () = default;
144
149 virtual int setNull () = 0;
150
156 virtual int setBool (bool value) = 0;
157
163 virtual int setInt (int32_t value) = 0;
164
170 virtual int setUint (uint32_t value) = 0;
171
177 virtual int setInt64 (int64_t value) = 0;
178
184 virtual int setUint64 (uint64_t value) = 0;
185
191 virtual int setDouble (double value) = 0;
192
198 virtual int setString (const std::string& value) = 0;
199
205 virtual int startArray (uint32_t size = 0) = 0;
206
211 virtual int stopArray ()
212 {
213 return 0;
214 }
215
221 virtual int startObject (uint32_t size = 0) = 0;
222
228 virtual int setKey (const Value& key) = 0;
229
234 virtual int stopObject ()
235 {
236 return 0;
237 }
238 };
239
244 {
245 public:
250 StreamWriter (std::ostream& document)
251 : SaxHandler ()
252 , _out (document.rdbuf ())
253 {
254 }
255
260 StreamWriter (const StreamWriter& other) = delete;
261
266 StreamWriter& operator= (const StreamWriter& other) = delete;
267
272 StreamWriter (StreamWriter&& other) = delete;
273
279
283 virtual ~StreamWriter () = default;
284
290 virtual int serialize (const Value& value)
291 {
292 return setValue (value);
293 }
294
295 protected:
301 int setValue (const Value& value)
302 {
303 switch (value.index ())
304 {
305 case Value::Boolean:
306 return setBool (value.get<Value::Boolean> ());
307
308 case Value::Integer:
309 return setInt (value.get<Value::Integer> ());
310
311 case Value::Unsigned:
312 return setUint (value.get<Value::Unsigned> ());
313
314 case Value::Integer64:
315 return setInt64 (value.get<Value::Integer64> ());
316
318 return setUint64 (value.get<Value::Unsigned64> ());
319
320 case Value::Real:
321 return setDouble (value.get<Value::Real> ());
322
323 case Value::String:
324 return setString (value.get<Value::String> ());
325
327 return setArray (value.get<Value::ArrayValue> ());
328
330 return setObject (value.get<Value::ObjectValue> ());
331
332 default:
333 return setNull ();
334 }
335 }
336
342 virtual int setArray (const Array& array)
343 {
344 if (startArray (array.size ()) == -1)
345 {
346 return -1;
347 }
348
349 for (auto const& element : array)
350 {
351 if (setValue (element) == -1)
352 {
353 return -1;
354 }
355 }
356
357 return stopArray ();
358 }
359
365 virtual int setObject (const Object& object)
366 {
367 if (startObject (object.size ()) == -1)
368 {
369 return -1;
370 }
371
372 for (auto const& member : object)
373 {
374 if (setKey (member.first) == -1)
375 {
376 return -1;
377 }
378
379 if (setValue (member.second) == -1)
380 {
381 return -1;
382 }
383 }
384
385 return stopObject ();
386 }
387
392 inline void append (char data) noexcept
393 {
394 _out->sputc (data);
395 }
396
401 inline void append2 (const char* data) noexcept
402 {
403 _out->sputc (data[0]);
404 _out->sputc (data[1]);
405 }
406
411 inline void append3 (const char* data) noexcept
412 {
413 _out->sputc (data[0]);
414 _out->sputc (data[1]);
415 _out->sputc (data[2]);
416 }
417
422 inline void append4 (const char* data) noexcept
423 {
424 _out->sputc (data[0]);
425 _out->sputc (data[1]);
426 _out->sputc (data[2]);
427 _out->sputc (data[3]);
428 }
429
434 inline void append5 (const char* data) noexcept
435 {
436 _out->sputc (data[0]);
437 _out->sputc (data[1]);
438 _out->sputc (data[2]);
439 _out->sputc (data[3]);
440 _out->sputc (data[4]);
441 }
442
448 inline void append (const char* data, uint32_t size) noexcept
449 {
450 _out->sputn (data, size);
451 }
452
453 protected:
455 std::streambuf* _out;
456 };
457
461 class StreamReader : protected SaxHandler
462 {
463 public:
469 : SaxHandler ()
470 , _root (root)
471 {
472 }
473
478 StreamReader (const StreamReader& other) = delete;
479
485 StreamReader& operator= (const StreamReader& other) = delete;
486
491 StreamReader (StreamReader&& other) = delete;
492
499
503 virtual ~StreamReader () = default;
504
511 virtual int deserialize (const char* document, size_t length) = 0;
512
519 virtual int deserialize (const char* first, const char* last) = 0;
520
526 virtual int deserialize (const std::string& document) = 0;
527
533 virtual int deserialize (std::stringstream& document) = 0;
534
540 virtual int deserialize (std::istringstream& document) = 0;
541
547 virtual int deserialize (std::fstream& document) = 0;
548
554 virtual int deserialize (std::ifstream& document) = 0;
555
561 virtual int deserialize (std::iostream& document) = 0;
562
568 virtual int deserialize (std::istream& document) = 0;
569
570 protected:
575 virtual int setNull () override
576 {
577 return setValue (Value (in_place_index_t<Value::Null>{}, nullptr));
578 }
579
585 virtual int setBool (bool value) override
586 {
588 }
589
595 virtual int setInt (int32_t value) override
596 {
598 }
599
605 virtual int setUint (uint32_t value) override
606 {
608 }
609
615 virtual int setInt64 (int64_t value) override
616 {
618 }
619
625 virtual int setUint64 (uint64_t value) override
626 {
628 }
629
635 virtual int setDouble (double value) override
636 {
637 return setValue (Value (in_place_index_t<Value::Real>{}, value));
638 }
639
645 virtual int setString (const std::string& value) override
646 {
648 }
649
655 virtual int startArray (uint32_t size = 0) override
656 {
657 Array array;
658 array.reserve (size ? size : 8);
659
660 if (JOIN_UNLIKELY (_stack.empty ()))
661 {
662 _root = std::move (array);
663 _stack.push (&_root);
664 return 0;
665 }
666
667 if (JOIN_UNLIKELY (_stack.size () >= _maxdepth))
668 {
670 return -1;
671 }
672
673 Value::Ptr parent = _stack.top ();
674
675 if (parent->index () == Value::ObjectValue)
676 {
677 _stack.push (&parent->insert ({std::move (_curkey), std::move (array)}));
678 }
679 else
680 {
681 _stack.push (&parent->pushBack (std::move (array)));
682 }
683
684 return 0;
685 }
686
691 virtual int stopArray () override
692 {
693 if (JOIN_LIKELY (_stack.size ()))
694 {
695 _stack.pop ();
696 }
697
698 return 0;
699 }
700
706 virtual int startObject (uint32_t size = 0) override
707 {
708 Object object;
709 object.reserve (size ? size : 8);
710
711 if (JOIN_UNLIKELY (_stack.empty ()))
712 {
713 _root = std::move (object);
714 _stack.push (&_root);
715 return 0;
716 }
717
718 if (JOIN_UNLIKELY (_stack.size () >= _maxdepth))
719 {
721 return -1;
722 }
723
724 Value::Ptr parent = _stack.top ();
725
726 if (parent->index () == Value::ObjectValue)
727 {
728 _stack.push (&parent->insert ({std::move (_curkey), std::move (object)}));
729 }
730 else
731 {
732 _stack.push (&parent->pushBack (std::move (object)));
733 }
734
735 return 0;
736 }
737
743 virtual int setKey (const Value& key) override
744 {
745 _curkey = key;
746 return 0;
747 }
748
753 virtual int stopObject () override
754 {
755 if (JOIN_LIKELY (_stack.size ()))
756 {
757 _stack.pop ();
758 }
759
760 return 0;
761 }
762
768 virtual int setValue (Value&& value)
769 {
770 if (JOIN_UNLIKELY (_stack.empty ()))
771 {
773 return -1;
774 }
775
776 Value::Ptr parent = _stack.top ();
777
778 if (parent->index () == Value::ObjectValue)
779 {
780 parent->insert ({std::move (_curkey), std::move (value)});
781 }
782 else
783 {
784 parent->pushBack (std::move (value));
785 }
786
787 return 0;
788 }
789
791 static constexpr size_t _maxdepth = 19;
792
794 std::stack<Value*> _stack;
795
798
801 };
802}
803
804namespace std
805{
807 template <>
808 struct is_error_condition_enum<join::SaxErrc> : public true_type
809 {
810 };
811}
812
813#endif
SAX API generic error category.
Definition sax.hpp:67
virtual std::string message(int code) const
translate SAX API generic error code to human readable error string.
Definition sax.cpp:44
virtual const char * name() const noexcept
get SAX API generic error category name.
Definition sax.cpp:35
SAX API interface class.
Definition sax.hpp:107
virtual int setInt(int32_t value)=0
set integer value.
virtual int setInt64(int64_t value)=0
set 64 bits integer value.
virtual int setString(const std::string &value)=0
set string value.
SaxHandler(SaxHandler &&other)=default
move constructor.
virtual int startArray(uint32_t size=0)=0
start array.
SaxHandler()=default
default constructor.
virtual int setNull()=0
set null value.
virtual int stopArray()
stop array.
Definition sax.hpp:211
SaxHandler(const SaxHandler &other)=default
copy constructor.
virtual int setBool(bool value)=0
set boolean value.
virtual int setDouble(double value)=0
set real value.
virtual int setKey(const Value &key)=0
set key.
virtual int startObject(uint32_t size=0)=0
start object.
virtual int setUint64(uint64_t value)=0
set unsigned 64 bits integer value.
virtual ~SaxHandler()=default
destroy instance.
virtual int setUint(uint32_t value)=0
set unsigned integer value.
virtual int stopObject()
stop object.
Definition sax.hpp:234
stream deserializer abstract class.
Definition sax.hpp:462
virtual int stopObject() override
stop object.
Definition sax.hpp:753
virtual int startArray(uint32_t size=0) override
start array.
Definition sax.hpp:655
virtual int deserialize(std::ifstream &document)=0
deserialize a document.
StreamReader(Value &root)
default constructor.
Definition sax.hpp:468
virtual int setInt64(int64_t value) override
set 64 bits integer value.
Definition sax.hpp:615
virtual int setUint(uint32_t value) override
set unsigned integer value.
Definition sax.hpp:605
virtual int deserialize(std::istringstream &document)=0
deserialize a document.
StreamReader(StreamReader &&other)=delete
move constructor.
std::stack< Value * > _stack
stack.
Definition sax.hpp:794
Value _curkey
current key.
Definition sax.hpp:797
virtual int setNull() override
set null value.
Definition sax.hpp:575
virtual int deserialize(std::istream &document)=0
deserialize a document.
virtual int deserialize(std::iostream &document)=0
deserialize a document.
virtual int setValue(Value &&value)
set value.
Definition sax.hpp:768
virtual int deserialize(const char *document, size_t length)=0
deserialize a document.
static constexpr size_t _maxdepth
max stack depth.
Definition sax.hpp:791
virtual int setUint64(uint64_t value) override
set unsigned 64 bits integer value.
Definition sax.hpp:625
virtual int deserialize(const char *first, const char *last)=0
deserialize a document.
virtual int deserialize(std::stringstream &document)=0
deserialize a document.
virtual int setKey(const Value &key) override
set key.
Definition sax.hpp:743
StreamReader(const StreamReader &other)=delete
copy constructor.
virtual int deserialize(std::fstream &document)=0
deserialize a document.
virtual int deserialize(const std::string &document)=0
deserialize a document.
StreamReader & operator=(const StreamReader &other)=delete
copy assignment.
virtual int setInt(int32_t value) override
set integer value.
Definition sax.hpp:595
virtual int startObject(uint32_t size=0) override
start object.
Definition sax.hpp:706
virtual int setBool(bool value) override
set boolean value.
Definition sax.hpp:585
virtual int stopArray() override
stop array.
Definition sax.hpp:691
Value & _root
root.
Definition sax.hpp:800
virtual int setDouble(double value) override
set real value.
Definition sax.hpp:635
virtual int setString(const std::string &value) override
set string value.
Definition sax.hpp:645
virtual ~StreamReader()=default
destroy instance.
stream serializer abstract class.
Definition sax.hpp:244
void append(const char *data, uint32_t size) noexcept
append characters to output stream in batch.
Definition sax.hpp:448
virtual ~StreamWriter()=default
Destroy the Writer instance.
int setValue(const Value &value)
set value.
Definition sax.hpp:301
virtual int setArray(const Array &array)
set array value.
Definition sax.hpp:342
std::streambuf * _out
underlying output stream.
Definition sax.hpp:455
virtual int setObject(const Object &object)
set object value.
Definition sax.hpp:365
virtual int serialize(const Value &value)
Serialize data.
Definition sax.hpp:290
StreamWriter(StreamWriter &&other)=delete
Create the Writer instance by move.
void append3(const char *data) noexcept
append 3-character literal to output stream in batch.
Definition sax.hpp:411
StreamWriter(const StreamWriter &other)=delete
Create the Writer instance by copy.
void append(char data) noexcept
append character to output stream in batch.
Definition sax.hpp:392
StreamWriter & operator=(const StreamWriter &other)=delete
Assign the Writer instance by copy.
void append5(const char *data) noexcept
append 5-character literal to output stream in batch.
Definition sax.hpp:434
StreamWriter(std::ostream &document)
create instance.
Definition sax.hpp:250
void append4(const char *data) noexcept
append 4-character literal to output stream in batch.
Definition sax.hpp:422
void append2(const char *data) noexcept
append 2-character literal to output stream in batch.
Definition sax.hpp:401
value class.
Definition value.hpp:64
@ Integer64
Definition value.hpp:75
@ Unsigned64
Definition value.hpp:76
@ Real
Definition value.hpp:77
@ Boolean
Definition value.hpp:72
@ String
Definition value.hpp:78
@ ArrayValue
Definition value.hpp:79
@ Integer
Definition value.hpp:73
@ Unsigned
Definition value.hpp:74
@ ObjectValue
Definition value.hpp:80
Value & pushBack(const Value &value)
appends element at the end of the nested container.
Definition value.hpp:1279
Value & insert(const Member &member)
insert element in the nested container.
Definition value.hpp:1216
constexpr std::enable_if_t< is_unique< T, Ts... >::value, T & > get()
get the variable value of the object type identified by type.
Definition variant.hpp:548
constexpr std::size_t index() const noexcept
return the index of the alternative that is currently held by the variant.
Definition variant.hpp:659
const std::string key(65, 'a')
key.
Definition acceptor.hpp:32
const std::error_category & saxCategory() noexcept
get error category.
Definition sax.cpp:67
SaxErrc
SAX API generic error codes.
Definition sax.hpp:55
std::vector< Value > Array
array.
Definition value.hpp:51
std::error_code make_error_code(join::Errc code) noexcept
Create an std::error_code object.
Definition error.cpp:150
thread_local std::error_code lastError
last error.
Definition error.cpp:32
std::vector< Member > Object
object.
Definition value.hpp:57
std::error_condition make_error_condition(join::Errc code) noexcept
Create an std::error_condition object.
Definition error.cpp:159
Definition error.hpp:137
disambiguation tag to indicate that the contained object should be constructed in-place.
Definition traits.hpp:57
#define JOIN_LIKELY(x)
Definition utils.hpp:46
#define JOIN_UNLIKELY(x)
Definition utils.hpp:47