1 #ifndef _library__json__hpp__included__
2 #define _library__json__hpp__included__
18 const static int id
= 2;
19 node
operator()(double v
) const;
20 node
operator()(uint64_t v
) const;
21 node
operator()(int64_t v
) const;
22 bool operator==(const int& n
) const { return n
== id
; }
23 bool operator!=(const int& n
) const { return !(*this == n
); }
24 operator int() { return id
; }
29 const static int id
= 3;
30 node
operator()(const std::string
& s
) const;
31 node
operator()(const std::u32string
& s
) const;
32 bool operator==(const int& n
) const { return n
== id
; }
33 bool operator!=(const int& n
) const { return !(*this == n
); }
34 operator int() { return id
; }
39 const static int id
= 1;
40 node
operator()(bool v
);
41 bool operator==(const int& n
) const { return n
== id
; }
42 bool operator!=(const int& n
) const { return !(*this == n
); }
43 operator int() { return id
; }
48 const static int id
= 4;
49 node
operator()() const;
50 bool operator==(const int& n
) const { return n
== id
; }
51 bool operator!=(const int& n
) const { return !(*this == n
); }
52 operator int() { return id
; }
56 const static int id
= 5;
57 node
operator()() const;
58 bool operator==(const int& n
) const { return n
== id
; }
59 bool operator!=(const int& n
) const { return !(*this == n
); }
60 operator int() { return id
; }
65 const static int id
= 0;
66 node
operator()() const;
67 bool operator==(const int& n
) const { return n
== id
; }
68 bool operator!=(const int& n
) const { return !(*this == n
); }
69 operator int() { return id
; }
74 const static int id
= -1;
75 bool operator==(const int& n
) const { return n
== id
; }
76 bool operator!=(const int& n
) const { return !(*this == n
); }
77 operator int() { return id
; }
80 extern number_tag number
;
81 extern string_tag string
;
82 extern boolean_tag boolean
;
83 extern array_tag array
;
84 extern object_tag object
;
92 node
s(const std::string
& st
);
93 node
s(const std::u32string
& st
);
99 ERR_NOT_A_NUMBER
, //Not a number in operation expecting one.
100 ERR_NOT_A_STRING
, //Not a string in operation expecting one.
101 ERR_NOT_A_BOOLEAN
, //Not a boolean in operation expecting one.
102 ERR_NOT_AN_ARRAY
, //Not an array in operation expecting one.
103 ERR_NOT_AN_OBJECT
, //Not an object in operation expecting one.
104 ERR_NOT_ARRAY_NOR_OBJECT
, //Not array nor object in operation expecting either.
105 ERR_INDEX_INVALID
, //Non-existent index accessed.
106 ERR_KEY_INVALID
, //Non-existent key accessed.
107 ERR_INSTANCE_INVALID
, //Non-existent instance (of key) accessed.
108 ERR_POINTER_TRAILING_ESCAPE
, //JSON pointer has trailing escape.
109 ERR_POINTER_INVALID_ESCAPE
, //JSON pointer has invalid escape.
110 ERR_BAD_HEX
, //Bad hexadecimal character.
111 ERR_INVALID_SURROGATE
, //Invalid surrogate escape sequence.
112 ERR_INVALID_ESCAPE
, //Invalid escape sequence.
113 ERR_TRUNCATED_STRING
, //Truncated string.
114 ERR_UNKNOWN_TYPE
, //Unknown value type.
115 ERR_GARBAGE_AFTER_END
, //Garbage after end of JSON.
116 ERR_TRUNCATED_JSON
, //JSON truncated.
117 ERR_UNEXPECTED_COMMA
, //Unexpected ','.
118 ERR_UNEXPECTED_COLON
, //Unexpected ':'.
119 ERR_UNEXPECTED_RIGHT_BRACE
, //Unexpected '}'.
120 ERR_UNEXPECTED_RIGHT_BRACKET
, //Unexpected ']'.
121 ERR_INVALID_NUMBER
, //Bad number syntax.
122 ERR_EXPECTED_STRING_KEY
, //Object key is not a string.
123 ERR_EXPECTED_COLON
, //Expected ':' here.
124 ERR_EXPECTED_COMMA
, //Expected ',' here.
125 ERR_UNKNOWN_CHARACTER
, //Unknown token type.
126 ERR_POINTER_BAD_APPEND
, //Bad JSON pointer append.
127 ERR_POINTER_BAD_INDEX
, //Bad JSON pointer index.
128 ERR_ITERATOR_END
, //Iterator already at end.
129 ERR_ITERATOR_DELETED
, //Iterator points to deleted object.
130 ERR_WRONG_OBJECT
, //Iterator points to wrong object.
131 ERR_ILLEGAL_CHARACTER
, //Illegal character generated by escape.
132 ERR_CONTROL_CHARACTER
, //Control character in string.
133 ERR_UNKNOWN_SUBTYPE
, //Unknown value subtype.
134 ERR_PATCH_BAD
, //Bad JSON patch.
135 ERR_PATCH_TEST_FAILED
, //TEST operation in patch failed.
136 ERR_PATCH_ILLEGAL_MOVE
, //MOVE operation in patch illegal.
141 PARSE_NOT_PARSING
= 0, //Not parsing.
142 PARSE_ARRAY_AFTER_VALUE
, //After value in array
143 PARSE_END_OF_DOCUMENT
, //At end of document
144 PARSE_OBJECT_AFTER_VALUE
, //After value in object
145 PARSE_OBJECT_COLON
, //Expecting for colon in object
146 PARSE_OBJECT_NAME
, //Expecting name in object
147 PARSE_STRING_BODY
, //Parsing string body
148 PARSE_STRING_ESCAPE
, //Parsing escape in string body
149 PARSE_VALUE_START
, //Parsing start of value
150 PARSE_NUMBER
, //Parsing number.
153 extern const char* error_desc
[];
154 extern const char* state_desc
[];
156 struct error
: public std::runtime_error
158 error(errorcode _code
) : runtime_error(error_desc
[_code
]), code(_code
), state(PARSE_NOT_PARSING
),
159 position(std::string::npos
) {}
160 error(errorcode _code
, parsestate _state
, size_t pos
) : runtime_error(error_desc
[_code
]), code(_code
),
161 state(_state
), position(pos
) {}
162 errorcode
get_code() { return code
; }
163 parsestate
get_state() { return state
; }
164 size_t get_position() { return position
; }
165 std::pair
<size_t, size_t> get_position_lc(const std::string
& doc
) { return get_position_lc(doc
, position
); }
166 std::pair
<size_t, size_t> get_position_lc(const std::string
& doc
, size_t pos
);
167 const char* what() const throw();
168 std::string
extended_error(const std::string
& doc
);
173 mutable char buffer
[512];
185 pointer(const std::string
& ptr
) throw(std::bad_alloc
);
186 pointer(const std::u32string
& ptr
) throw(std::bad_alloc
);
187 pointer
pastend() const throw(std::bad_alloc
) { return field(U
"-"); }
188 pointer
& pastend_inplace() throw(std::bad_alloc
) { return field_inplace(U
"-"); }
189 pointer
index(uint64_t idx
) const throw(std::bad_alloc
);
190 pointer
& index_inplace(uint64_t idx
) throw(std::bad_alloc
);
191 pointer
field(const std::string
& fld
) const throw(std::bad_alloc
) { return field(utf8::to32(fld
)); }
192 pointer
& field_inplace(const std::string
& fld
) throw(std::bad_alloc
)
194 return field_inplace(utf8::to32(fld
));
196 pointer
field(const std::u32string
& fld
) const throw(std::bad_alloc
);
197 pointer
& field_inplace(const std::u32string
& fld
) throw(std::bad_alloc
);
198 pointer
remove() const throw(std::bad_alloc
);
199 pointer
& remove_inplace() throw(std::bad_alloc
);
200 std::string
as_string8() const { return utf8::to8(_pointer
); }
201 std::u32string
as_string() const { return _pointer
; }
202 friend std::ostream
& operator<<(std::ostream
& s
, const pointer
& p
);
203 friend std::basic_ostream
<char32_t
>& operator<<(std::basic_ostream
<char32_t
>& s
, const pointer
& p
);
206 std::u32string _pointer
;
210 * A JSON pretty-printer base.
215 virtual ~printer() throw();
217 * Print a value that is null, boolean or integer.
219 virtual std::string
value_val(const std::string
& val
);
221 * Print a string value.
223 virtual std::string
value_string(const std::u32string
& s
);
225 * Print beginning of array.
227 virtual std::string
array_begin();
229 * Print a separator in array.
231 virtual std::string
array_separator();
233 * Print end of array.
235 virtual std::string
array_end();
237 * Print beginning of object.
239 virtual std::string
object_begin();
241 * Print key in object.
243 virtual std::string
object_key(const std::u32string
& s
);
245 * Print field separator in object.
247 virtual std::string
object_separator();
249 * Print end of object.
251 virtual std::string
object_end();
255 * A JSON pretty-printer (indenting).
257 class printer_indenting
: public printer
261 ~printer_indenting() throw();
262 std::string
value_val(const std::string
& val
);
263 std::string
value_string(const std::u32string
& s
);
264 std::string
array_begin();
265 std::string
array_separator();
266 std::string
array_end();
267 std::string
object_begin();
268 std::string
object_key(const std::u32string
& s
);
269 std::string
object_separator();
270 std::string
object_end();
272 std::string
linestart(size_t _depth
);
294 * Construct null object.
298 * Construct object of specified type.
300 node(null_tag
) throw();
301 node(boolean_tag
, bool b
) throw();
302 node(string_tag
, const std::u32string
& str
) throw(std::bad_alloc
);
303 node(string_tag
, const std::string
& str
) throw(std::bad_alloc
);
304 node(number_tag
, double n
) throw();
305 node(number_tag
, int64_t n
) throw();
306 node(number_tag
, uint64_t n
) throw();
307 node(array_tag
) throw();
308 node(object_tag
) throw();
312 bool operator==(const node
& n
) const;
313 bool operator!=(const node
& n
) const { return !(*this == n
); }
317 node(const node
& _node
) throw(std::bad_alloc
);
319 * Construct object from description.
321 node(const std::string
& doc
) throw(std::bad_alloc
, error
);
323 * Serialize document.
325 std::string
serialize(printer
* printer
= NULL
) const throw(std::bad_alloc
, error
);
329 int type() const throw();
331 * Get type of node by pointer.
333 int type_of(const std::u32string
& pointer
) const throw(std::bad_alloc
);
334 int type_of(const std::string
& pointer
) const throw(std::bad_alloc
)
336 return type_of(utf8::to32(pointer
));
338 int type_of(const pointer
& ptr
) const throw(std::bad_alloc
)
340 return type_of(ptr
._pointer
);
343 * Get type of node by pointer (indirect).
345 int type_of_indirect(const std::u32string
& pointer
) const throw(std::bad_alloc
);
346 int type_of_indirect(const std::string
& pointer
) const throw(std::bad_alloc
)
348 return type_of_indirect(utf8::to32(pointer
));
350 int type_of_indirect(const pointer
& ptr
) const throw(std::bad_alloc
)
352 return type_of_indirect(ptr
._pointer
);
355 * Resolve an indirect pointer
357 std::u32string
resolve_indirect(const std::u32string
& pointer
) const throw(std::bad_alloc
);
358 std::string
resolve_indirect(const std::string
& pointer
) const throw(std::bad_alloc
)
360 return utf8::to8(resolve_indirect(utf8::to32(pointer
)));
362 pointer
resolve_indirect(const pointer
& ptr
) const throw(std::bad_alloc
)
364 return pointer(resolve_indirect(ptr
._pointer
));
367 * Get double numeric value (NT_NUMBER).
369 double as_double() const throw(error
);
371 * Get int64_t value (NT_NUMBER).
373 int64_t as_int() const throw(error
);
375 * Get uint64_t value (NT_NUMBER).
377 uint64_t as_uint() const throw(error
);
379 * Read the string as UTF-8 (NT_STRING).
381 const std::u32string
& as_string() const throw(std::bad_alloc
, error
);
382 std::string
as_string8() const throw(std::bad_alloc
, error
) { return utf8::to8(as_string()); }
384 * Get boolean value (NT_BOOLEAN).
386 bool as_bool() const throw(error
);
388 * Read number of indices in array (NT_ARRAY).
390 size_t index_count() const throw(error
);
392 * Read specified index from array (NT_ARRAY).
394 const node
& index(size_t idx
) const throw(error
)
397 auto e
= index_soft(idx
, n
);
398 if(e
!= ERR_OK
) throw error(e
);
402 * Read number of indices in object key (NT_OBJECT).
404 size_t field_count(const std::u32string
& key
) const throw(error
);
405 size_t field_count(const std::string
& key
) const throw(std::bad_alloc
, error
)
407 return field_count(utf8::to32(key
));
410 * Specified field exists (NT_OBJECT)
412 bool field_exists(const std::u32string
& key
) const throw(error
);
413 bool field_exists(const std::string
& key
) const throw(std::bad_alloc
, error
)
415 return field_exists(utf8::to32(key
));
418 * Read specified key from object (NT_OBJECT).
420 const node
& field(const std::u32string
& key
, size_t subindex
= 0) const throw(error
)
423 auto e
= field_soft(key
, subindex
, n
);
424 if(e
!= ERR_OK
) throw error(e
);
427 const node
& field(const std::string
& key
, size_t subindex
= 0) const throw(std::bad_alloc
, error
)
429 return field(utf8::to32(key
), subindex
);
433 * Apply JSON pointer (RFC 6901).
435 const node
& follow(const std::u32string
& pointer
) const throw(std::bad_alloc
, error
)
438 auto e
= follow_soft(pointer
, n
);
439 if(e
!= ERR_OK
) throw error(e
);
442 const node
& follow(const std::string
& pointer
) const throw(std::bad_alloc
, error
)
444 return follow(utf8::to32(pointer
));
446 const node
& follow(const pointer
& ptr
) const throw(std::bad_alloc
, error
)
448 return follow(ptr
._pointer
);
451 * Apply JSON pointer (RFC 6901) following strings as indirect references.
453 const node
& follow_indirect(const std::u32string
& pointer
) const throw(std::bad_alloc
, error
)
455 return follow(resolve_indirect(pointer
));
457 const node
& follow_indirect(const std::string
& pointer
) const throw(std::bad_alloc
, error
)
459 return follow_indirect(utf8::to32(pointer
));
461 const node
& follow_indirect(const pointer
& ptr
) const throw(std::bad_alloc
, error
)
463 return follow_indirect(ptr
._pointer
);
466 * Set value of node (any).
468 node
& operator=(const node
& node
) throw(std::bad_alloc
);
472 node
& set(null_tag
) throw();
473 node
& set(boolean_tag
, bool number
) throw();
474 node
& set(number_tag
, double number
) throw();
475 node
& set(number_tag
, int64_t number
) throw();
476 node
& set(number_tag
, uint64_t number
) throw();
477 node
& set(string_tag
, const std::u32string
& key
) throw(std::bad_alloc
);
478 node
& set(string_tag tag
, const std::string
& key
) throw(std::bad_alloc
)
480 return set(tag
, utf8::to32(key
));
483 * Read/Write specified index from array (NT_ARRAY).
485 node
& index(size_t idx
) throw(error
)
488 auto e
= index_soft(idx
, n
);
489 if(e
!= ERR_OK
) throw error(e
);
493 * Append new element to array (NT_ARRAY).
495 node
& append(const node
& node
) throw(std::bad_alloc
, error
);
497 * Read/Write specified key from object (NT_OBJECT).
499 node
& field(const std::u32string
& key
, size_t subindex
= 0) throw(error
)
502 auto e
= field_soft(key
, subindex
, n
);
503 if(e
!= ERR_OK
) throw error(e
);
506 node
& field(const std::string
& key
, size_t subindex
= 0) throw(std::bad_alloc
, error
)
508 return field(utf8::to32(key
), subindex
);
511 * Insert new element to object (NT_OBJECT).
513 node
& insert(const std::u32string
& key
, const node
& node
) throw(std::bad_alloc
, error
);
514 node
& insert(const std::string
& key
, const node
& node
) throw(std::bad_alloc
, error
)
516 return insert(utf8::to32(key
), node
);
519 * Apply JSON pointer (RFC 6901).
521 node
& follow(const std::u32string
& pointer
) throw(std::bad_alloc
, error
)
524 auto e
= follow_soft(pointer
, n
);
525 if(e
!= ERR_OK
) throw error(e
);
528 node
& follow(const std::string
& pointer
) throw(std::bad_alloc
, error
)
530 return follow(utf8::to32(pointer
));
532 node
& follow(const pointer
& ptr
) throw(std::bad_alloc
, error
)
534 return follow(ptr
._pointer
);
537 * Apply JSON pointer (RFC 6901) following strings as indirect references.
539 node
& follow_indirect(const std::u32string
& pointer
) throw(std::bad_alloc
, error
)
541 return follow(resolve_indirect(pointer
));
543 node
& follow_indirect(const std::string
& pointer
) throw(std::bad_alloc
, error
)
545 return follow_indirect(utf8::to32(pointer
));
547 node
& follow_indirect(const pointer
& ptr
) throw(std::bad_alloc
, error
)
549 return follow_indirect(ptr
._pointer
);
552 * Return node specified by JSON pointer (RFC 6901). If the last component doesn't exist, it is created as NULL.
554 node
& operator[](const std::u32string
& pointer
) throw(std::bad_alloc
, error
);
555 node
& operator[](const std::string
& pointer
) throw(std::bad_alloc
, error
)
557 return (*this)[utf8::to32(pointer
)];
559 node
& operator[](const pointer
& ptr
) throw(std::bad_alloc
, error
)
561 return (*this)[ptr
._pointer
];
564 * Create node at specified pointer and return it.
566 node
& insert_node(const std::u32string
& pointer
, const node
& nwn
) throw(std::bad_alloc
, error
);
567 node
& insert_node(const std::string
& pointer
, const node
& nwn
) throw(std::bad_alloc
, error
)
569 return insert_node(utf8::to32(pointer
), nwn
);
571 node
& insert_node(const pointer
& ptr
, const node
& nwn
) throw(std::bad_alloc
, error
)
573 return insert_node(ptr
._pointer
, nwn
);
576 * Delete a node by pointer and return what was deleted.
578 node
delete_node(const std::u32string
& pointer
) throw(std::bad_alloc
, error
);
579 node
delete_node(const std::string
& pointer
) throw(std::bad_alloc
, error
)
581 return delete_node(utf8::to32(pointer
));
583 node
delete_node(const pointer
& ptr
) throw(std::bad_alloc
, error
)
585 return delete_node(ptr
._pointer
);
588 * Synonym for follow().
590 const node
& operator[](const std::u32string
& pointer
) const throw(std::bad_alloc
, error
)
592 return follow(pointer
);
594 const node
& operator[](const std::string
& pointer
) const throw(std::bad_alloc
, error
)
596 return follow(pointer
);
598 const node
& operator[](const pointer
& ptr
) const throw(std::bad_alloc
, error
)
600 return follow(ptr
._pointer
);
603 * Delete an array index. The rest are shifted.
605 void erase_index(size_t idx
) throw(error
);
607 * Delete an array field. The rest are shifted.
609 void erase_field(const std::u32string
& fld
, size_t idx
= 0) throw(error
);
610 void erase_field(const std::string
& fld
, size_t idx
= 0) throw(std::bad_alloc
, error
)
612 erase_field(utf8::to32(fld
), idx
);
615 * Delete an entiere array field.
617 void erase_field_all(const std::u32string
& fld
) throw(error
);
618 void erase_field_all(const std::string
& fld
) throw(std::bad_alloc
, error
)
620 erase_field_all(utf8::to32(fld
));
623 * Apply a JSON patch.
625 node
patch(const node
& patch
) const throw(std::bad_alloc
, error
);
627 * Clear entiere array or object.
629 void clear() throw(error
);
636 typedef std::forward_iterator_tag iterator_category
;
637 typedef node value_type
;
638 typedef int difference_type
;
639 typedef node
& reference
;
640 typedef node
* pointer
;
642 iterator(node
& n
) throw(error
);
643 std::u32string
key() throw(std::bad_alloc
, error
);
644 std::string
key8() throw(std::bad_alloc
, error
) { return utf8::to8(key()); }
645 size_t index() throw(error
);
646 node
& operator*() throw(error
);
647 node
* operator->() throw(error
);
648 iterator
operator++(int) throw(error
);
649 iterator
& operator++() throw(error
);
650 bool operator==(const iterator
& i
) throw();
651 bool operator!=(const iterator
& i
) throw();
664 typedef std::forward_iterator_tag iterator_category
;
665 typedef node value_type
;
666 typedef int difference_type
;
667 typedef const node
& reference
;
668 typedef const node
* pointer
;
669 const_iterator() throw();
670 const_iterator(const node
& n
) throw(error
);
671 std::u32string
key() throw(std::bad_alloc
, error
);
672 std::string
key8() throw(std::bad_alloc
, error
) { return utf8::to8(key()); }
673 size_t index() throw(error
);
674 const node
& operator*() throw(error
);
675 const node
* operator->() throw(error
);
676 const_iterator
operator++(int) throw(error
);
677 const_iterator
& operator++() throw(error
);
678 bool operator==(const const_iterator
& i
) throw();
679 bool operator!=(const const_iterator
& i
) throw();
688 const_iterator
begin() const throw(error
) { return const_iterator(*this); }
689 const_iterator
end() const throw() { return const_iterator(); }
690 iterator
begin() throw(error
) { return iterator(*this); }
691 iterator
end() throw() { return iterator(); }
693 * Delete item pointed by iterator. The rest are shifted and new iterator is returned.
695 iterator
erase(iterator itr
) throw(error
);
700 number_holder() { sub
= 0; n
.n0
= 0; }
701 number_holder(const std::string
& expr
, size_t& ptr
, size_t len
);
702 template<typename T
> T
to() const
711 template<typename T
> void from(T val
);
712 void write(std::ostream
& s
) const;
713 bool operator==(const number_holder
& h
) const;
715 template<typename T
> bool cmp(const T
& num
) const;
723 friend class iterator
;
724 friend class const_iterator
;
725 void fixup_nodes(const node
& _node
);
726 void ctor(const std::string
& doc
, size_t& ptr
, size_t len
) throw(std::bad_alloc
, error
);
727 node(const std::string
& doc
, size_t& ptr
, size_t len
) throw(std::bad_alloc
, error
);
728 template<typename T
> void set_helper(T v
)
733 std::swap(_string
, tmp
);
737 template<typename T
> T
get_number_helper() const
740 throw error(ERR_NOT_A_NUMBER
);
741 return _number
.to
<T
>();
745 number_holder _number
;
747 std::u32string _string
;
748 std::list
<node
> xarray
;
749 std::vector
<node
*> xarray_index
;
750 std::map
<std::u32string
, std::list
<node
>> xobject
;
751 errorcode
follow_soft(const std::u32string
& pointer
, const node
*& out
) const throw(std::bad_alloc
);
752 errorcode
follow_soft(const std::u32string
& pointer
, node
*& out
) throw(std::bad_alloc
);
753 errorcode
field_soft(const std::u32string
& key
, size_t subindex
, node
*& out
) throw();
754 errorcode
field_soft(const std::u32string
& key
, size_t subindex
, const node
*& out
) const throw();
755 errorcode
index_soft(size_t index
, node
*& out
) throw();
756 errorcode
index_soft(size_t index
, const node
*& out
) const throw();
760 bool operator==(const int& n
, const JSON::number_tag
& v
);
761 bool operator==(const int& n
, const JSON::string_tag
& v
);
762 bool operator==(const int& n
, const JSON::boolean_tag
& v
);
763 bool operator==(const int& n
, const JSON::array_tag
& v
);
764 bool operator==(const int& n
, const JSON::object_tag
& v
);
765 bool operator==(const int& n
, const JSON::null_tag
& v
);
766 bool operator!=(const int& n
, const JSON::number_tag
& v
);
767 bool operator!=(const int& n
, const JSON::string_tag
& v
);
768 bool operator!=(const int& n
, const JSON::boolean_tag
& v
);
769 bool operator!=(const int& n
, const JSON::array_tag
& v
);
770 bool operator!=(const int& n
, const JSON::object_tag
& v
);
771 bool operator!=(const int& n
, const JSON::null_tag
& v
);