Fix Win32 build
[lsnes.git] / include / library / json.hpp
bloba4e76aa729788ac4f3766a42d10e94e7022acfa4
1 #ifndef _library__json__hpp__included__
2 #define _library__json__hpp__included__
4 #include <cstdint>
5 #include <string>
6 #include <list>
7 #include <vector>
8 #include <stdexcept>
9 #include <map>
10 #include "utf8.hpp"
12 namespace JSON
14 class node;
16 struct number_tag
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; }
27 struct string_tag
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; }
37 struct boolean_tag
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; }
46 struct array_tag
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; }
55 struct object_tag {
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; }
63 struct null_tag
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; }
72 struct none_tag
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;
85 extern null_tag null;
86 extern none_tag none;
88 node i(int64_t n);
89 node u(uint64_t n);
90 node f(double n);
91 node b(bool bl);
92 node s(const std::string& st);
93 node s(const std::u32string& st);
94 node n();
96 enum errorcode
98 ERR_OK = 0, //All OK.
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.
139 enum parsestate
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);
169 private:
170 errorcode code;
171 parsestate state;
172 size_t position;
173 mutable char buffer[512];
176 class node;
179 * A JSON pointer
181 class pointer
183 public:
184 pointer();
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);
204 private:
205 friend class node;
206 std::u32string _pointer;
210 * A JSON pretty-printer base.
212 class printer
214 public:
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
259 public:
260 printer_indenting();
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();
271 private:
272 std::string linestart(size_t _depth);
273 size_t depth;
274 enum _state
276 S_STANDARD,
277 S_END,
278 S_COMMA,
279 S_START,
280 S_START_END,
281 } state;
285 * A JSON node.
287 class node
289 public:
291 * Type of node.
294 * Construct null object.
296 node() throw();
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();
310 * Compare nodes.
312 bool operator==(const node& n) const;
313 bool operator!=(const node& n) const { return !(*this == n); }
315 * Copy Constructor.
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);
327 * Get type of node.
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)
396 const node* n;
397 auto e = index_soft(idx, n);
398 if(e != ERR_OK) throw error(e);
399 return *n;
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)
422 const node* n;
423 auto e = field_soft(key, subindex, n);
424 if(e != ERR_OK) throw error(e);
425 return *n;
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)
437 const node* n;
438 auto e = follow_soft(pointer, n);
439 if(e != ERR_OK) throw error(e);
440 return *n;
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);
470 * Set value of node.
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)
487 node* n;
488 auto e = index_soft(idx, n);
489 if(e != ERR_OK) throw error(e);
490 return *n;
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)
501 node* n;
502 auto e = field_soft(key, subindex, n);
503 if(e != ERR_OK) throw error(e);
504 return *n;
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)
523 node* n;
524 auto e = follow_soft(pointer, n);
525 if(e != ERR_OK) throw error(e);
526 return *n;
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);
631 * Iterator.
633 class iterator
635 public:
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;
641 iterator() throw();
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();
652 private:
653 friend class node;
654 node* n;
655 size_t idx;
656 std::u32string _key;
659 * Constant iterator.
661 class const_iterator
663 public:
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();
680 private:
681 const node* n;
682 size_t idx;
683 std::u32string _key;
686 * Iterators
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);
696 private:
697 class number_holder
699 public:
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
704 switch(sub) {
705 case 0: return n.n0;
706 case 1: return n.n1;
707 case 2: return n.n2;
709 return 0;
711 template<typename T> void from(T val);
712 void write(std::ostream& s) const;
713 bool operator==(const number_holder& h) const;
714 private:
715 template<typename T> bool cmp(const T& num) const;
716 unsigned sub;
717 union {
718 double n0;
719 uint64_t n1;
720 int64_t n2;
721 } n;
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)
730 std::u32string tmp;
731 vtype = number;
732 _number.from<T>(v);
733 std::swap(_string, tmp);
734 xarray.clear();
735 xobject.clear();
737 template<typename T> T get_number_helper() const
739 if(vtype != number)
740 throw error(ERR_NOT_A_NUMBER);
741 return _number.to<T>();
744 int vtype;
745 number_holder _number;
746 bool _boolean;
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);
774 #endif