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(to_u32string(fld
)); }
192 pointer
& field_inplace(const std::string
& fld
) throw(std::bad_alloc
)
194 return field_inplace(to_u32string(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 to_u8string(_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
;
219 * Construct null object.
223 * Construct object of specified type.
225 node(null_tag
) throw();
226 node(boolean_tag
, bool b
) throw();
227 node(string_tag
, const std::u32string
& str
) throw(std::bad_alloc
);
228 node(string_tag
, const std::string
& str
) throw(std::bad_alloc
);
229 node(number_tag
, double n
) throw();
230 node(number_tag
, int64_t n
) throw();
231 node(number_tag
, uint64_t n
) throw();
232 node(array_tag
) throw();
233 node(object_tag
) throw();
237 bool operator==(const node
& n
) const;
238 bool operator!=(const node
& n
) const { return !(*this == n
); }
242 node(const node
& _node
) throw(std::bad_alloc
);
244 * Construct object from description.
246 node(const std::string
& doc
) throw(std::bad_alloc
, error
);
248 * Serialize document.
250 std::string
serialize() const throw(std::bad_alloc
, error
);
254 int type() const throw();
256 * Get type of node by pointer.
258 int type_of(const std::u32string
& pointer
) const throw(std::bad_alloc
);
259 int type_of(const std::string
& pointer
) const throw(std::bad_alloc
)
261 return type_of(to_u32string(pointer
));
263 int type_of(const pointer
& ptr
) const throw(std::bad_alloc
)
265 return type_of(ptr
._pointer
);
268 * Get type of node by pointer (indirect).
270 int type_of_indirect(const std::u32string
& pointer
) const throw(std::bad_alloc
);
271 int type_of_indirect(const std::string
& pointer
) const throw(std::bad_alloc
)
273 return type_of_indirect(to_u32string(pointer
));
275 int type_of_indirect(const pointer
& ptr
) const throw(std::bad_alloc
)
277 return type_of_indirect(ptr
._pointer
);
280 * Resolve an indirect pointer
282 std::u32string
resolve_indirect(const std::u32string
& pointer
) const throw(std::bad_alloc
);
283 std::string
resolve_indirect(const std::string
& pointer
) const throw(std::bad_alloc
)
285 return to_u8string(resolve_indirect(to_u32string(pointer
)));
287 pointer
resolve_indirect(const pointer
& ptr
) const throw(std::bad_alloc
)
289 return pointer(resolve_indirect(ptr
._pointer
));
292 * Get double numeric value (NT_NUMBER).
294 double as_double() const throw(error
);
296 * Get int64_t value (NT_NUMBER).
298 int64_t as_int() const throw(error
);
300 * Get uint64_t value (NT_NUMBER).
302 uint64_t as_uint() const throw(error
);
304 * Read the string as UTF-8 (NT_STRING).
306 const std::u32string
& as_string() const throw(std::bad_alloc
, error
);
307 std::string
as_string8() const throw(std::bad_alloc
, error
) { return to_u8string(as_string()); }
309 * Get boolean value (NT_BOOLEAN).
311 bool as_bool() const throw(error
);
313 * Read number of indices in array (NT_ARRAY).
315 size_t index_count() const throw(error
);
317 * Read specified index from array (NT_ARRAY).
319 const node
& index(size_t idx
) const throw(error
)
322 auto e
= index_soft(idx
, n
);
323 if(e
!= ERR_OK
) throw error(e
);
327 * Read number of indices in object key (NT_OBJECT).
329 size_t field_count(const std::u32string
& key
) const throw(error
);
330 size_t field_count(const std::string
& key
) const throw(std::bad_alloc
, error
)
332 return field_count(to_u32string(key
));
335 * Specified field exists (NT_OBJECT)
337 bool field_exists(const std::u32string
& key
) const throw(error
);
338 bool field_exists(const std::string
& key
) const throw(std::bad_alloc
, error
)
340 return field_exists(to_u32string(key
));
343 * Read specified key from object (NT_OBJECT).
345 const node
& field(const std::u32string
& key
, size_t subindex
= 0) const throw(error
)
348 auto e
= field_soft(key
, subindex
, n
);
349 if(e
!= ERR_OK
) throw error(e
);
352 const node
& field(const std::string
& key
, size_t subindex
= 0) const throw(std::bad_alloc
, error
)
354 return field(to_u32string(key
), subindex
);
358 * Apply JSON pointer (RFC 6901).
360 const node
& follow(const std::u32string
& pointer
) const throw(std::bad_alloc
, error
)
363 auto e
= follow_soft(pointer
, n
);
364 if(e
!= ERR_OK
) throw error(e
);
367 const node
& follow(const std::string
& pointer
) const throw(std::bad_alloc
, error
)
369 return follow(to_u32string(pointer
));
371 const node
& follow(const pointer
& ptr
) const throw(std::bad_alloc
, error
)
373 return follow(ptr
._pointer
);
376 * Apply JSON pointer (RFC 6901) following strings as indirect references.
378 const node
& follow_indirect(const std::u32string
& pointer
) const throw(std::bad_alloc
, error
)
380 return follow(resolve_indirect(pointer
));
382 const node
& follow_indirect(const std::string
& pointer
) const throw(std::bad_alloc
, error
)
384 return follow_indirect(to_u32string(pointer
));
386 const node
& follow_indirect(const pointer
& ptr
) const throw(std::bad_alloc
, error
)
388 return follow_indirect(ptr
._pointer
);
391 * Set value of node (any).
393 node
& operator=(const node
& node
) throw(std::bad_alloc
);
397 node
& set(null_tag
) throw();
398 node
& set(boolean_tag
, bool number
) throw();
399 node
& set(number_tag
, double number
) throw();
400 node
& set(number_tag
, int64_t number
) throw();
401 node
& set(number_tag
, uint64_t number
) throw();
402 node
& set(string_tag
, const std::u32string
& key
) throw(std::bad_alloc
);
403 node
& set(string_tag tag
, const std::string
& key
) throw(std::bad_alloc
)
405 return set(tag
, to_u32string(key
));
408 * Read/Write specified index from array (NT_ARRAY).
410 node
& index(size_t idx
) throw(error
)
413 auto e
= index_soft(idx
, n
);
414 if(e
!= ERR_OK
) throw error(e
);
418 * Append new element to array (NT_ARRAY).
420 node
& append(const node
& node
) throw(std::bad_alloc
, error
);
422 * Read/Write specified key from object (NT_OBJECT).
424 node
& field(const std::u32string
& key
, size_t subindex
= 0) throw(error
)
427 auto e
= field_soft(key
, subindex
, n
);
428 if(e
!= ERR_OK
) throw error(e
);
431 node
& field(const std::string
& key
, size_t subindex
= 0) throw(std::bad_alloc
, error
)
433 return field(to_u32string(key
), subindex
);
436 * Insert new element to object (NT_OBJECT).
438 node
& insert(const std::u32string
& key
, const node
& node
) throw(std::bad_alloc
, error
);
439 node
& insert(const std::string
& key
, const node
& node
) throw(std::bad_alloc
, error
)
441 return insert(to_u32string(key
), node
);
444 * Apply JSON pointer (RFC 6901).
446 node
& follow(const std::u32string
& pointer
) throw(std::bad_alloc
, error
)
449 auto e
= follow_soft(pointer
, n
);
450 if(e
!= ERR_OK
) throw error(e
);
453 node
& follow(const std::string
& pointer
) throw(std::bad_alloc
, error
)
455 return follow(to_u32string(pointer
));
457 node
& follow(const pointer
& ptr
) throw(std::bad_alloc
, error
)
459 return follow(ptr
._pointer
);
462 * Apply JSON pointer (RFC 6901) following strings as indirect references.
464 node
& follow_indirect(const std::u32string
& pointer
) throw(std::bad_alloc
, error
)
466 return follow(resolve_indirect(pointer
));
468 node
& follow_indirect(const std::string
& pointer
) throw(std::bad_alloc
, error
)
470 return follow_indirect(to_u32string(pointer
));
472 node
& follow_indirect(const pointer
& ptr
) throw(std::bad_alloc
, error
)
474 return follow_indirect(ptr
._pointer
);
477 * Return node specified by JSON pointer (RFC 6901). If the last component doesn't exist, it is created as NULL.
479 node
& operator[](const std::u32string
& pointer
) throw(std::bad_alloc
, error
);
480 node
& operator[](const std::string
& pointer
) throw(std::bad_alloc
, error
)
482 return (*this)[to_u32string(pointer
)];
484 node
& operator[](const pointer
& ptr
) throw(std::bad_alloc
, error
)
486 return (*this)[ptr
._pointer
];
489 * Create node at specified pointer and return it.
491 node
& insert_node(const std::u32string
& pointer
, const node
& nwn
) throw(std::bad_alloc
, error
);
492 node
& insert_node(const std::string
& pointer
, const node
& nwn
) throw(std::bad_alloc
, error
)
494 return insert_node(to_u32string(pointer
), nwn
);
496 node
& insert_node(const pointer
& ptr
, const node
& nwn
) throw(std::bad_alloc
, error
)
498 return insert_node(ptr
._pointer
, nwn
);
501 * Delete a node by pointer and return what was deleted.
503 node
delete_node(const std::u32string
& pointer
) throw(std::bad_alloc
, error
);
504 node
delete_node(const std::string
& pointer
) throw(std::bad_alloc
, error
)
506 return delete_node(to_u32string(pointer
));
508 node
delete_node(const pointer
& ptr
) throw(std::bad_alloc
, error
)
510 return delete_node(ptr
._pointer
);
513 * Synonym for follow().
515 const node
& operator[](const std::u32string
& pointer
) const throw(std::bad_alloc
, error
)
517 return follow(pointer
);
519 const node
& operator[](const std::string
& pointer
) const throw(std::bad_alloc
, error
)
521 return follow(pointer
);
523 const node
& operator[](const pointer
& ptr
) const throw(std::bad_alloc
, error
)
525 return follow(ptr
._pointer
);
528 * Delete an array index. The rest are shifted.
530 void erase_index(size_t idx
) throw(error
);
532 * Delete an array field. The rest are shifted.
534 void erase_field(const std::u32string
& fld
, size_t idx
= 0) throw(error
);
535 void erase_field(const std::string
& fld
, size_t idx
= 0) throw(std::bad_alloc
, error
)
537 erase_field(to_u32string(fld
), idx
);
540 * Delete an entiere array field.
542 void erase_field_all(const std::u32string
& fld
) throw(error
);
543 void erase_field_all(const std::string
& fld
) throw(std::bad_alloc
, error
)
545 erase_field_all(to_u32string(fld
));
548 * Apply a JSON patch.
550 node
patch(const node
& patch
) const throw(std::bad_alloc
, error
);
552 * Clear entiere array or object.
554 void clear() throw(error
);
561 typedef std::forward_iterator_tag iterator_category
;
562 typedef node value_type
;
563 typedef int difference_type
;
564 typedef node
& reference
;
565 typedef node
* pointer
;
567 iterator(node
& n
) throw(error
);
568 std::u32string
key() throw(std::bad_alloc
, error
);
569 std::string
key8() throw(std::bad_alloc
, error
) { return to_u8string(key()); }
570 size_t index() throw(error
);
571 node
& operator*() throw(error
);
572 node
* operator->() throw(error
);
573 iterator
operator++(int) throw(error
);
574 iterator
& operator++() throw(error
);
575 bool operator==(const iterator
& i
) throw();
576 bool operator!=(const iterator
& i
) throw();
589 typedef std::forward_iterator_tag iterator_category
;
590 typedef node value_type
;
591 typedef int difference_type
;
592 typedef const node
& reference
;
593 typedef const node
* pointer
;
594 const_iterator() throw();
595 const_iterator(const node
& n
) throw(error
);
596 std::u32string
key() throw(std::bad_alloc
, error
);
597 std::string
key8() throw(std::bad_alloc
, error
) { return to_u8string(key()); }
598 size_t index() throw(error
);
599 const node
& operator*() throw(error
);
600 const node
* operator->() throw(error
);
601 const_iterator
operator++(int) throw(error
);
602 const_iterator
& operator++() throw(error
);
603 bool operator==(const const_iterator
& i
) throw();
604 bool operator!=(const const_iterator
& i
) throw();
613 const_iterator
begin() const throw(error
) { return const_iterator(*this); }
614 const_iterator
end() const throw() { return const_iterator(); }
615 iterator
begin() throw(error
) { return iterator(*this); }
616 iterator
end() throw() { return iterator(); }
618 * Delete item pointed by iterator. The rest are shifted and new iterator is returned.
620 iterator
erase(iterator itr
) throw(error
);
625 number_holder() { sub
= 0; n
.n0
= 0; }
626 number_holder(const std::string
& expr
, size_t& ptr
, size_t len
);
627 template<typename T
> T
to() const
636 template<typename T
> void from(T val
);
637 void write(std::ostream
& s
) const;
638 bool operator==(const number_holder
& h
) const;
640 template<typename T
> bool cmp(const T
& num
) const;
648 friend class iterator
;
649 friend class const_iterator
;
650 void fixup_nodes(const node
& _node
);
651 void ctor(const std::string
& doc
, size_t& ptr
, size_t len
) throw(std::bad_alloc
, error
);
652 node(const std::string
& doc
, size_t& ptr
, size_t len
) throw(std::bad_alloc
, error
);
653 template<typename T
> void set_helper(T v
)
658 std::swap(_string
, tmp
);
662 template<typename T
> T
get_number_helper() const
665 throw error(ERR_NOT_A_NUMBER
);
666 return _number
.to
<T
>();
670 number_holder _number
;
672 std::u32string _string
;
673 std::list
<node
> xarray
;
674 std::vector
<node
*> xarray_index
;
675 std::map
<std::u32string
, std::list
<node
>> xobject
;
676 errorcode
follow_soft(const std::u32string
& pointer
, const node
*& out
) const throw(std::bad_alloc
);
677 errorcode
follow_soft(const std::u32string
& pointer
, node
*& out
) throw(std::bad_alloc
);
678 errorcode
field_soft(const std::u32string
& key
, size_t subindex
, node
*& out
) throw();
679 errorcode
field_soft(const std::u32string
& key
, size_t subindex
, const node
*& out
) const throw();
680 errorcode
index_soft(size_t index
, node
*& out
) throw();
681 errorcode
index_soft(size_t index
, const node
*& out
) const throw();
685 bool operator==(const int& n
, const JSON::number_tag
& v
);
686 bool operator==(const int& n
, const JSON::string_tag
& v
);
687 bool operator==(const int& n
, const JSON::boolean_tag
& v
);
688 bool operator==(const int& n
, const JSON::array_tag
& v
);
689 bool operator==(const int& n
, const JSON::object_tag
& v
);
690 bool operator==(const int& n
, const JSON::null_tag
& v
);
691 bool operator!=(const int& n
, const JSON::number_tag
& v
);
692 bool operator!=(const int& n
, const JSON::string_tag
& v
);
693 bool operator!=(const int& n
, const JSON::boolean_tag
& v
);
694 bool operator!=(const int& n
, const JSON::array_tag
& v
);
695 bool operator!=(const int& n
, const JSON::object_tag
& v
);
696 bool operator!=(const int& n
, const JSON::null_tag
& v
);