Save bitmaps as PNG
[lsnes.git] / include / library / json.hpp
blob8ed23ffe4361d58a173e771bccb594b7ccd2c187
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(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);
204 private:
205 friend class node;
206 std::u32string _pointer;
210 * A JSON node.
212 class node
214 public:
216 * Type of node.
219 * Construct null object.
221 node() throw();
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();
235 * Compare nodes.
237 bool operator==(const node& n) const;
238 bool operator!=(const node& n) const { return !(*this == n); }
240 * Copy Constructor.
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);
252 * Get type of node.
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)
321 const node* n;
322 auto e = index_soft(idx, n);
323 if(e != ERR_OK) throw error(e);
324 return *n;
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)
347 const node* n;
348 auto e = field_soft(key, subindex, n);
349 if(e != ERR_OK) throw error(e);
350 return *n;
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)
362 const node* n;
363 auto e = follow_soft(pointer, n);
364 if(e != ERR_OK) throw error(e);
365 return *n;
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);
395 * Set value of node.
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)
412 node* n;
413 auto e = index_soft(idx, n);
414 if(e != ERR_OK) throw error(e);
415 return *n;
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)
426 node* n;
427 auto e = field_soft(key, subindex, n);
428 if(e != ERR_OK) throw error(e);
429 return *n;
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)
448 node* n;
449 auto e = follow_soft(pointer, n);
450 if(e != ERR_OK) throw error(e);
451 return *n;
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);
556 * Iterator.
558 class iterator
560 public:
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;
566 iterator() throw();
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();
577 private:
578 friend class node;
579 node* n;
580 size_t idx;
581 std::u32string _key;
584 * Constant iterator.
586 class const_iterator
588 public:
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();
605 private:
606 const node* n;
607 size_t idx;
608 std::u32string _key;
611 * Iterators
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);
621 private:
622 class number_holder
624 public:
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
629 switch(sub) {
630 case 0: return n.n0;
631 case 1: return n.n1;
632 case 2: return n.n2;
634 return 0;
636 template<typename T> void from(T val);
637 void write(std::ostream& s) const;
638 bool operator==(const number_holder& h) const;
639 private:
640 template<typename T> bool cmp(const T& num) const;
641 unsigned sub;
642 union {
643 double n0;
644 uint64_t n1;
645 int64_t n2;
646 } n;
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)
655 std::u32string tmp;
656 vtype = number;
657 _number.from<T>(v);
658 std::swap(_string, tmp);
659 xarray.clear();
660 xobject.clear();
662 template<typename T> T get_number_helper() const
664 if(vtype != number)
665 throw error(ERR_NOT_A_NUMBER);
666 return _number.to<T>();
669 int vtype;
670 number_holder _number;
671 bool _boolean;
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);
699 #endif