Upload UI
[lsnes.git] / src / library / json.cpp
blob63fb896f37d2fc50bf18a92bb8b4357ab2e78aa1
1 #include "json.hpp"
2 #include "string.hpp"
3 #include <limits>
4 #include <climits>
5 #include <sstream>
7 namespace JSON
9 const char* error_desc[] = {
10 "Success",
11 "Not a number",
12 "Not a string",
13 "Not a boolean",
14 "Not an array",
15 "Not an object",
16 "Not array nor object",
17 "Invalid index",
18 "Invalid key",
19 "Invalid instance",
20 "Trailing pointer escape character",
21 "Invalid pointer escape",
22 "Bad hexadecimal character",
23 "Invalid surrogate escape",
24 "Invalid escape sequence",
25 "Truncated string",
26 "Unknown value type",
27 "Garbage after end of JSON",
28 "Truncated JSON",
29 "Unexpected comma",
30 "Unexpected colon",
31 "Unexpected right brace",
32 "Unexpected right braket",
33 "Invalid number syntax",
34 "Expected string as object key",
35 "Expected colon",
36 "Expected comma",
37 "Unknown token type",
38 "Bad pointer append",
39 "Bad pointer index",
40 "Iterator past the end",
41 "Iterator points to deleted object",
42 "Iterator points to wrong object",
43 "Illegal character escaped",
44 "Control character in string",
45 "Invalid value subtype",
46 "Bad JSON patch",
47 "JSON patch test failed",
48 "JSON patch illegal move",
51 const char* state_desc[] = {
52 "",
53 "array next",
54 "end of document",
55 "object next",
56 "object colon",
57 "object name",
58 "string body",
59 "string escape",
60 "value start",
61 "number"
64 const char* asciinames[] = {
65 "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
66 "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US"
69 bool parse_size_t(const std::u32string& s, size_t& x)
71 x = 0;
72 for(size_t i = 0; i < s.length(); i++) {
73 if(s[i] < 48 || s[i] > 57)
74 return false;
75 if((std::numeric_limits<size_t>::max() - (size_t)(s[i] - 48)) / 10 < x)
76 return false;
77 x = 10 * x + (s[i] - 48);
79 return true;
82 std::pair<size_t, size_t> error::get_position_lc(const std::string& doc, size_t pos)
84 size_t r = 1, c = 1;
85 bool last_cr = false;
86 for(size_t i = 0; i < pos; i++) {
87 if(doc[i] == 13 || (doc[i] == 10 && !last_cr)) {
88 c = 1;
89 r++;
90 last_cr = (doc[i] == 13);
91 continue;
93 if(last_cr && doc[i] == 10) {
94 last_cr = false;
95 continue;
97 c++;
99 return std::make_pair(r, c);
102 const char* error::what() const throw()
104 if(state == PARSE_NOT_PARSING)
105 return error_desc[code];
106 else {
107 sprintf(buffer, "%s (while expecting %s) at byte %llu", error_desc[code], state_desc[state],
108 (unsigned long long)position);
109 return buffer;
113 std::string error::extended_error(const std::string& doc)
115 if(state == PARSE_NOT_PARSING)
116 return error_desc[code];
117 std::ostringstream s;
118 size_t pos = position;
119 while(pos < doc.length() && (doc[pos] == '\t' || doc[pos] == '\v' || doc[pos] == '\r' || doc[pos] == '\n' ||
120 doc[pos] == ' '))
121 pos++;
122 auto p2 = get_position_lc(doc, pos);
123 s << error_desc[code] << " (while expecting " << state_desc[state] << ") at ";
124 if(position == doc.length())
125 s << "end of input";
126 else {
127 std::ostringstream sample;
128 size_t p = pos;
129 for(size_t i = 0; i < 32; i++) {
130 if(p >= doc.length())
131 break;
132 if(doc[p] < 32) {
133 sample << "<" << asciinames[doc[p++]] << ">";
134 } else if(doc[p] < 127)
135 sample << doc[p++];
136 else if(doc[p] < 128)
137 sample << "<DEL>";
138 else if(doc[p] < 192)
139 sample << "<" << (int)doc[p++] << ">";
140 else if(doc[p] < 224) {
141 sample << doc[p++];
142 sample << doc[p++];
143 } else if(doc[p] < 240) {
144 sample << doc[p++];
145 sample << doc[p++];
146 sample << doc[p++];
147 } else if(doc[p] < 248) {
148 sample << doc[p++];
149 sample << doc[p++];
150 sample << doc[p++];
151 sample << doc[p++];
152 } else
153 sample << "<" << (int)doc[p++] << ">";
155 s << "line " << p2.first << " byte " << p2.second << " [near: '" << sample.str() << "']";
157 return s.str();
160 node number_tag::operator()(double v) const { return node(*this, v); }
161 node number_tag::operator()(uint64_t v) const { return node(*this, v); }
162 node number_tag::operator()(int64_t v) const { return node(*this, v); }
163 node string_tag::operator()(const std::string& s) const { return node(*this, s); }
164 node string_tag::operator()(const std::u32string& s) const { return node(*this, s); }
165 node boolean_tag::operator()(bool v) { return node(*this, v); }
166 node array_tag::operator()() const { return node(*this); }
167 node object_tag::operator()() const { return node(*this); }
168 node null_tag::operator()() const { return node(*this); }
170 node i(int64_t n) { return number(n); }
171 node u(uint64_t n) { return number(n); }
172 node f(double n) { return number(n); }
173 node b(bool bl) { return boolean(bl); }
174 node s(const std::string& st) { return string(st); }
175 node s(const std::u32string& st) { return string(st); }
176 node n() { return null(); }
178 number_tag number;
179 string_tag string;
180 boolean_tag boolean;
181 array_tag array;
182 object_tag object;
183 null_tag null;
184 none_tag none;
186 template<> void node::number_holder::from(double val) { sub = 0; n.n0 = val; }
187 template<> void node::number_holder::from(uint64_t val) { sub = 1; n.n1 = val; }
188 template<> void node::number_holder::from(int64_t val) { sub = 2; n.n2 = val; }
190 namespace
192 unsigned numchar(char c)
194 switch(c) {
195 case '0': return 0;
196 case '1': case '2': case '3': case '4': case '5':
197 case '6': case '7': case '8': case '9': return 1;
198 case '.': return 2;
199 case 'e': return 3;
200 case '+': return 4;
201 case '-': return 5;
202 default: return 6;
206 uint32_t numdfa[] = {
207 0x0F1FFF32, //0: STATE_INITIAL
208 0x0FFFFF32, //1: STATE_AFTER_MINUS
209 0x1FFF64FF, //2: STATE_INT_Z
210 0x1FFF6433, //3: STATE_INT_NZ
211 0x0FFFFF55, //4: STATE_DECIMAL
212 0x1FFF6F55, //5: STATE_DECIMAL_N
213 0x0F77FF88, //6: STATE_EXP
214 0x0FFFFF88, //7: STATE_EXP_SIGN
215 0x1FFFFF88, //8: STATE_EXP_N
219 node::number_holder::number_holder(const std::string& expr, size_t& ptr, size_t len)
221 //-?(0|1-9[0-9]+)(.[0-9]+)?([eE][+-]?[0-9]+)?
222 int state = 0;
223 size_t tmp = ptr;
224 size_t tmp2 = ptr;
225 std::string x;
226 while(tmp < len) {
227 unsigned c = numchar(expr[tmp]);
228 unsigned ns = (numdfa[state] >> (4 * c)) & 0xF;
229 if(ns == 0xF)
230 break;
231 else
232 state = ns;
233 tmp++;
235 if(!(numdfa[state] >> 28))
236 goto bad;
237 x = expr.substr(ptr, tmp - ptr);
238 ptr = tmp;
239 try {
240 if(regex_match("[0-9]+", x)) {
241 n.n1 = parse_value<uint64_t>(x);
242 sub = 1;
243 return;
245 } catch(...) {}
246 try {
247 if(regex_match("[+-]?[0-9]+", x)) {
248 n.n2 = parse_value<int64_t>(x);
249 sub = 2;
250 return;
252 } catch(...) {}
253 try {
254 n.n0 = parse_value<double>(x);
255 sub = 0;
256 return;
257 } catch(...) {}
258 bad:
259 throw error(ERR_INVALID_NUMBER, PARSE_NUMBER, tmp2);
263 void node::number_holder::write(std::ostream& s) const
265 switch(sub) {
266 case 0: s << n.n0; break;
267 case 1: s << n.n1; break;
268 case 2: s << n.n2; break;
272 template<typename T> bool node::number_holder::cmp(const T& num) const
274 switch(sub) {
275 case 0: return n.n0 == num;
276 case 1: return n.n1 == num;
277 case 2: return n.n2 == num;
279 throw error(ERR_UNKNOWN_SUBTYPE);
282 template<> bool node::number_holder::cmp(const int64_t& num) const
284 switch(sub) {
285 case 0: return n.n0 == num;
286 case 1: return num >= 0 && n.n1 == static_cast<uint64_t>(num);
287 case 2: return n.n2 == num;
289 throw error(ERR_UNKNOWN_SUBTYPE);
292 template<> bool node::number_holder::cmp(const uint64_t& num) const
294 switch(sub) {
295 case 0: return n.n0 == num;
296 case 1: return n.n1 == num;
297 case 2: return n.n2 >= 0 && static_cast<uint64_t>(n.n2) == num;
299 throw error(ERR_UNKNOWN_SUBTYPE);
303 bool node::number_holder::operator==(const number_holder& h) const
305 switch(sub) {
306 case 0: return h.cmp(n.n0);
307 case 1: return h.cmp(n.n1);
308 case 2: return h.cmp(n.n2);
310 throw error(ERR_UNKNOWN_SUBTYPE);
313 node::node() throw() : node(null) {}
314 node::node(null_tag) throw() { vtype = null; }
315 node::node(boolean_tag, bool b) throw() { vtype = boolean; _boolean = b; }
316 node::node(string_tag, const std::u32string& str) throw(std::bad_alloc) { vtype = string; _string = str; }
317 node::node(string_tag, const std::string& str) throw(std::bad_alloc) { vtype = string; _string = to_u32string(str); }
318 node::node(number_tag, double n) throw() { vtype = number; _number.from<double>(n); }
319 node::node(number_tag, int64_t n) throw() { vtype = number; _number.from<int64_t>(n); }
320 node::node(number_tag, uint64_t n) throw() { vtype = number; _number.from<uint64_t>(n); }
321 node::node(array_tag) throw() { vtype = array; }
322 node::node(object_tag) throw() { vtype = object; }
323 int node::type() const throw() { return vtype; }
325 node& node::set(null_tag) throw() { set_helper<uint64_t>(0); vtype = null; return *this; }
326 node& node::set(boolean_tag, bool n) throw() { set_helper<uint64_t>(0); vtype = boolean; _boolean = n; return *this; }
327 node& node::set(number_tag, double n) throw() { set_helper<double>(n); return *this; }
328 node& node::set(number_tag, int64_t n) throw() { set_helper<int64_t>(n); return *this; }
329 node& node::set(number_tag, uint64_t n) throw() { set_helper<int64_t>(n); return *this; }
331 node& node::set(string_tag, const std::u32string& key) throw(std::bad_alloc)
333 std::u32string tmp = key;
334 std::swap(_string, tmp);
335 vtype = string;
336 xarray.clear();
337 xobject.clear();
338 return *this;
341 double node::as_double() const throw(error)
343 return get_number_helper<double>();
346 int64_t node::as_int() const throw(error)
348 return get_number_helper<int64_t>();
351 uint64_t node::as_uint() const throw(error)
353 return get_number_helper<uint64_t>();
356 const std::u32string& node::as_string() const throw(std::bad_alloc, error)
358 if(vtype != string)
359 throw error(ERR_NOT_A_STRING);
360 return _string;
363 bool node::as_bool() const throw(error)
365 if(vtype != boolean)
366 throw error(ERR_NOT_A_BOOLEAN);
367 return _boolean;
370 size_t node::index_count() const throw(error)
372 if(vtype != array)
373 throw error(ERR_NOT_AN_ARRAY);
374 return xarray.size();
377 errorcode node::index_soft(size_t index, const node*& out) const throw()
379 if(vtype != array)
380 return ERR_NOT_AN_ARRAY;
381 if(index >= xarray_index.size())
382 return ERR_INDEX_INVALID;
383 out = xarray_index[index];
384 return ERR_OK;
387 errorcode node::index_soft(size_t index, node*& out) throw()
389 if(vtype != array)
390 return ERR_NOT_AN_ARRAY;
391 if(index >= xarray_index.size())
392 return ERR_INDEX_INVALID;
393 out = xarray_index[index];
394 return ERR_OK;
397 size_t node::field_count(const std::u32string& key) const throw(error)
399 if(vtype != object)
400 throw error(ERR_NOT_AN_OBJECT);
401 if(!xobject.count(key))
402 return 0;
403 return xobject.find(key)->second.size();
406 bool node::field_exists(const std::u32string& key) const throw(error)
408 return (field_count(key) > 0);
411 errorcode node::field_soft(const std::u32string& key, size_t subindex, const node*& out) const throw()
413 if(vtype != object)
414 return ERR_NOT_AN_OBJECT;
415 if(!xobject.count(key))
416 return ERR_KEY_INVALID;
417 const std::list<node>& l = xobject.find(key)->second;
418 size_t j = 0;
419 for(auto i = l.begin(); i != l.end(); i++, j++) {
420 if(j == subindex) {
421 out = &*i;
422 return ERR_OK;
425 return ERR_INSTANCE_INVALID;
428 errorcode node::field_soft(const std::u32string& key, size_t subindex, node*& out) throw()
430 if(vtype != object)
431 return ERR_NOT_AN_OBJECT;
432 if(!xobject.count(key))
433 return ERR_KEY_INVALID;
434 std::list<node>& l = xobject.find(key)->second;
435 size_t j = 0;
436 for(auto i = l.begin(); i != l.end(); i++, j++) {
437 if(j == subindex) {
438 out = &*i;
439 return ERR_OK;
442 return ERR_INSTANCE_INVALID;
445 node::node(const node& _node) throw(std::bad_alloc)
447 std::u32string tmp1 = _node._string;
448 std::list<node> tmp2 = _node.xarray;
449 std::map<std::u32string, std::list<node>> tmp3 = _node.xobject;
450 std::vector<node*> tmp4 = _node.xarray_index;
452 vtype = _node.vtype;
453 _number = _node._number;
454 _boolean = _node._boolean;
455 _string = _node._string;
456 xarray = _node.xarray;
457 xobject = _node.xobject;
458 xarray_index = _node.xarray_index;
459 fixup_nodes(_node);
462 node& node::operator=(const node& _node) throw(std::bad_alloc)
464 if(this == &_node)
465 return *this;
466 std::u32string tmp1 = _node._string;
467 std::list<node> tmp2 = _node.xarray;
468 std::map<std::u32string, std::list<node>> tmp3 = _node.xobject;
469 std::vector<node*> tmp4 = _node.xarray_index;
471 vtype = _node.vtype;
472 _number = _node._number;
473 _boolean = _node._boolean;
474 std::swap(_string, tmp1);
475 std::swap(xarray, tmp2);
476 std::swap(xobject, tmp3);
477 std::swap(xarray_index, tmp4);
478 fixup_nodes(_node);
479 return *this;
482 node& node::append(const node& _node) throw(std::bad_alloc, error)
484 if(vtype != array)
485 throw error(ERR_NOT_AN_ARRAY);
486 bool p = false;
487 try {
488 xarray.push_back(_node);
489 p = true;
490 node* ptr = &*xarray.rbegin();
491 xarray_index.push_back(ptr);
492 return *ptr;
493 } catch(std::bad_alloc& e) {
494 if(p)
495 xarray.pop_back();
496 throw;
500 node& node::insert(const std::u32string& key, const node& _node) throw(std::bad_alloc, error)
502 if(vtype != object)
503 throw error(ERR_NOT_AN_OBJECT);
504 try {
505 xobject[key].push_back(_node);
506 return *xobject[key].rbegin();
507 } catch(...) {
508 if(xobject.count(key) && xobject[key].empty())
509 xobject.erase(key);
510 throw;
514 namespace
516 errorcode jsonptr_unescape_soft(const std::u32string& c, size_t start, size_t end, std::u32string& _out)
518 std::basic_ostringstream<char32_t> out;
519 for(size_t ptr = start; ptr < end; ptr++) {
520 if(c[ptr] == '~') {
521 if(ptr == end - 1)
522 return ERR_POINTER_TRAILING_ESCAPE;
523 ptr++;
524 if(c[ptr] == '0')
525 out << U"~";
526 else if(c[ptr] == '1')
527 out << U"/";
528 else
529 return ERR_POINTER_INVALID_ESCAPE;
530 } else
531 out << c[ptr];
533 _out = out.str();
534 return ERR_OK;
537 std::u32string jsonptr_unescape(const std::u32string& c, size_t start, size_t end)
539 std::u32string o;
540 auto e = jsonptr_unescape_soft(c, start, end, o);
541 if(e != ERR_OK) throw error(e);
542 return o;
547 errorcode node::follow_soft(const std::u32string& pointer, const node*& current) const throw(std::bad_alloc)
549 errorcode e;
550 current = this;
551 size_t ptr = 0;
552 while(ptr < pointer.length()) {
553 size_t p = pointer.find_first_of(U"/", ptr);
554 if(p > pointer.length())
555 p = pointer.length();
556 std::u32string c;
557 auto e = jsonptr_unescape_soft(pointer, ptr, p, c);
558 if(e != ERR_OK) return e;
559 if(current->vtype == array) {
560 if(c == U"-")
561 return ERR_POINTER_BAD_APPEND;
562 size_t idx;
563 if(!parse_size_t(c, idx))
564 return ERR_POINTER_BAD_INDEX;
565 e = current->index_soft(idx, current);
566 if(e != ERR_OK) return e;
567 } else if(current->vtype == object) {
568 e = current->field_soft(c, 0, current);
569 if(e != ERR_OK) return e;
570 } else
571 return ERR_NOT_ARRAY_NOR_OBJECT;
572 ptr = p + 1;
574 return ERR_OK;
577 errorcode node::follow_soft(const std::u32string& pointer, node*& current) throw(std::bad_alloc)
579 current = this;
580 errorcode e;
581 size_t ptr = 0;
582 while(ptr < pointer.length()) {
583 size_t p = pointer.find_first_of(U"/", ptr);
584 if(p > pointer.length())
585 p = pointer.length();
586 std::u32string c;
587 auto e = jsonptr_unescape_soft(pointer, ptr, p, c);
588 if(e != ERR_OK) return e;
589 if(current->vtype == array) {
590 if(c == U"-")
591 return ERR_POINTER_BAD_APPEND;
592 size_t idx;
593 if(!parse_size_t(c, idx))
594 return ERR_POINTER_BAD_INDEX;
595 e = current->index_soft(idx, current);
596 if(e != ERR_OK) return e;
597 } else if(current->vtype == object) {
598 e = current->field_soft(c, 0, current);
599 if(e != ERR_OK) return e;
600 } else
601 return ERR_NOT_ARRAY_NOR_OBJECT;
602 ptr = p + 1;
604 return ERR_OK;
607 namespace
609 struct json_token
611 enum ttype { TSTRING, TNUMBER, TOBJECT, TARRAY, TINVALID, TCOMMA, TOBJECT_END, TARRAY_END, TCOLON,
612 TEOF, TTRUE, TFALSE, TNULL };
613 ttype type;
614 std::u32string value;
615 json_token(enum ttype t, const std::u32string& v) { type = t; value = v; }
616 json_token(enum ttype t) { type = t; }
619 uint32_t parse_hex(int32_t ch, parsestate state, size_t pos)
621 switch(ch) {
622 case '0': return 0;
623 case '1': return 1;
624 case '2': return 2;
625 case '3': return 3;
626 case '4': return 4;
627 case '5': return 5;
628 case '6': return 6;
629 case '7': return 7;
630 case '8': return 8;
631 case '9': return 9;
632 case 'A': case 'a': return 10;
633 case 'B': case 'b': return 11;
634 case 'C': case 'c': return 12;
635 case 'D': case 'd': return 13;
636 case 'E': case 'e': return 14;
637 case 'F': case 'f': return 15;
638 default: throw error(ERR_BAD_HEX, state, pos);
642 class iterator_counter
644 public:
645 iterator_counter(size_t& _count) : count(_count) { count = 0; }
646 char32_t& operator*() { count++; return x; }
647 iterator_counter& operator++() { return *this; }
648 size_t get_count() { return count; }
649 private:
650 char32_t x;
651 size_t& count;
654 //STATE_NORMAL 0
655 //STATE_ESCAPE 1
656 //STATE_ESCAPE_HEX0 2
657 //STATE_ESCAPE_HEX1 3
658 //STATE_ESCAPE_HEX2 4
659 //STATE_ESCAPE_HEX3 5
660 //STATE_ESCAPE_SURROGATE 6
661 //STATE_ESCAPE_SURROGATE2 7
662 //STATE_ESCAPE_SURROGATE_HEX0 8
663 //STATE_ESCAPE_SURROGATE_HEX1 9
664 //STATE_ESCAPE_SURROGATE_HEX2 10
665 //STATE_ESCAPE_SURROGATE_HEX3 11
667 template<typename T> size_t read_string_impl(T target, const std::string& doc, size_t ptr, size_t len)
669 uint16_t ustate = utf8_initial_state;
670 int estate = 0;
671 uint32_t extra = 0;
672 uint32_t tmp;
673 size_t i;
674 size_t lc = ptr;
675 for(i = ptr; i <= len; i++) {
676 int ch = -1;
677 if(i < len)
678 ch = (unsigned char)doc[i];
679 int32_t uch = utf8_parse_byte(ch, ustate);
680 if(uch < 0)
681 continue;
682 //Okay, have Unicode codepoint decoded.
683 switch(estate) {
684 case 0:
685 lc = i;
686 extra = 0;
687 if(uch < 32)
688 throw error(ERR_CONTROL_CHARACTER, PARSE_STRING_BODY, lc);
689 if(uch == '\"')
690 goto out;
691 if(uch == '\\')
692 estate = 1;
693 else {
694 *target = uch;
695 ++target;
697 break;
698 case 1:
699 switch(uch) {
700 case '\"': *target = U'\"'; ++target; estate = 0; break;
701 case '\\': *target = U'\\'; ++target; estate = 0; break;
702 case '/': *target = U'/'; ++target; estate = 0; break;
703 case 'b': *target = U'\b'; ++target; estate = 0; break;
704 case 'f': *target = U'\f'; ++target; estate = 0; break;
705 case 'n': *target = U'\n'; ++target; estate = 0; break;
706 case 'r': *target = U'\r'; ++target; estate = 0; break;
707 case 't': *target = U'\t'; ++target; estate = 0; break;
708 case 'u':
709 estate = 2;
710 break;
711 default:
712 throw error(ERR_INVALID_ESCAPE, PARSE_STRING_ESCAPE, lc);
714 break;
715 case 2: case 3: case 4: case 8: case 9: case 10:
716 extra = (extra << 4) | parse_hex(uch, PARSE_STRING_ESCAPE, lc);
717 estate++;
718 break;
719 case 5:
720 extra = (extra << 4) | parse_hex(uch, PARSE_STRING_ESCAPE, lc);
721 if((extra & 0xFC00) == 0xDC00)
722 throw error(ERR_INVALID_SURROGATE, PARSE_STRING_ESCAPE, lc);
723 else if((extra & 0xFC00) == 0xD800)
724 estate = 6;
725 else if((extra & 0xFFFE) == 0xFFFE)
726 throw error(ERR_ILLEGAL_CHARACTER, PARSE_STRING_ESCAPE, lc);
727 else {
728 estate = 0;
729 *target = extra;
730 ++target;
732 break;
733 case 6:
734 if(uch != '\\')
735 throw error(ERR_INVALID_SURROGATE, PARSE_STRING_ESCAPE, lc);
736 estate = 7;
737 break;
738 case 7:
739 if(uch != 'u')
740 throw error(ERR_INVALID_SURROGATE, PARSE_STRING_ESCAPE, lc);
741 estate = 8;
742 break;
743 case 11:
744 extra = (extra << 4) | parse_hex(uch, PARSE_STRING_ESCAPE, lc);
745 if((extra & 0xFC00FC00UL) != 0xD800DC00)
746 throw error(ERR_INVALID_SURROGATE, PARSE_STRING_ESCAPE, lc);
747 tmp = ((extra & 0x3FF0000) >> 6) + (extra & 0x3FF) + 0x10000;
748 if((tmp & 0xFFFE) == 0xFFFE)
749 throw error(ERR_ILLEGAL_CHARACTER, PARSE_STRING_ESCAPE, lc);
750 *target = tmp;
751 ++target;
752 estate = 0;
753 break;
756 throw error(ERR_TRUNCATED_STRING, estate ? PARSE_STRING_ESCAPE : PARSE_STRING_BODY, len);
757 out:
758 return i;
761 void read_string(std::u32string& target, const std::string& doc, size_t& ptr, size_t len)
763 size_t cpcnt;
764 read_string_impl(iterator_counter(cpcnt), doc, ptr, len);
765 target.resize(cpcnt);
766 ptr = read_string_impl(target.begin(), doc, ptr, len) + 1;
769 json_token parse_token(const std::string& doc, size_t& ptr, size_t len)
771 while(ptr < len && (doc[ptr] == ' ' || doc[ptr] == '\t' || doc[ptr] == '\r' || doc[ptr] == '\n'))
772 ptr++;
773 if(ptr >= len)
774 return json_token(json_token::TEOF);
775 if(doc[ptr] == '{') {
776 ptr++;
777 return json_token(json_token::TOBJECT);
779 if(doc[ptr] == '}') {
780 ptr++;
781 return json_token(json_token::TOBJECT_END);
783 if(doc[ptr] == '[') {
784 ptr++;
785 return json_token(json_token::TARRAY);
787 if(doc[ptr] == ']') {
788 ptr++;
789 return json_token(json_token::TARRAY_END);
791 if(doc[ptr] == ',') {
792 ptr++;
793 return json_token(json_token::TCOMMA);
795 if(doc[ptr] == ':') {
796 ptr++;
797 return json_token(json_token::TCOLON);
799 if(doc[ptr] == '\"') {
800 //String.
801 ptr++;
802 return json_token(json_token::TSTRING);
804 if(doc[ptr] == '-' || (doc[ptr] >= '0' && doc[ptr] <= '9')) {
805 //Number.
806 return json_token(json_token::TNUMBER);
808 if(doc[ptr] == 'n') {
809 if(ptr >= len || doc[ptr++] != 'n') goto bad;
810 if(ptr >= len || doc[ptr++] != 'u') goto bad;
811 if(ptr >= len || doc[ptr++] != 'l') goto bad;
812 if(ptr >= len || doc[ptr++] != 'l') goto bad;
813 return json_token(json_token::TNULL);
815 if(doc[ptr] == 'f') {
816 if(ptr >= len || doc[ptr++] != 'f') goto bad;
817 if(ptr >= len || doc[ptr++] != 'a') goto bad;
818 if(ptr >= len || doc[ptr++] != 'l') goto bad;
819 if(ptr >= len || doc[ptr++] != 's') goto bad;
820 if(ptr >= len || doc[ptr++] != 'e') goto bad;
821 return json_token(json_token::TFALSE);
823 if(doc[ptr] == 't') {
824 if(ptr >= len || doc[ptr++] != 't') goto bad;
825 if(ptr >= len || doc[ptr++] != 'r') goto bad;
826 if(ptr >= len || doc[ptr++] != 'u') goto bad;
827 if(ptr >= len || doc[ptr++] != 'e') goto bad;
828 return json_token(json_token::TTRUE);
830 bad:
831 return json_token(json_token::TINVALID);
835 const char* hexes = "0123456789abcdef";
837 std::string json_string_escape(const std::u32string& c)
839 std::ostringstream out;
840 out << "\"";
841 size_t len = c.length();
842 for(size_t i = 0; i < len; i++) {
843 if(c[i] == '\b') out << "\\b";
844 else if(c[i] == '\n') out << "\\n";
845 else if(c[i] == '\r') out << "\\r";
846 else if(c[i] == '\t') out << "\\t";
847 else if(c[i] == '\f') out << "\\f";
848 else if((c[i] & 0xFFFFFFE0) == 0)
849 out << "\\u00" << hexes[c[i] >> 4] << hexes[c[i] % 16];
850 else if(c[i] == U'\\')
851 out << "\\\\";
852 else if(c[i] == U'\"')
853 out << "\\\"";
854 else if(c[i] < 0x80)
855 out << (unsigned char)c[i];
856 else if(c[i] < 0x800) {
857 out << (unsigned char)(0xC0 + (c[i] >> 6));
858 out << (unsigned char)(0x80 + (c[i] & 0x3F));
859 } else if(c[i] < 0x10000) {
860 out << (unsigned char)(0xE0 + (c[i] >> 12));
861 out << (unsigned char)(0x80 + ((c[i] >> 6) & 0x3F));
862 out << (unsigned char)(0x80 + (c[i] & 0x3F));
863 } else if(c[i] < 0x10FFFF) {
864 out << (unsigned char)(0xF0 + (c[i] >> 18));
865 out << (unsigned char)(0x80 + ((c[i] >> 12) & 0x3F));
866 out << (unsigned char)(0x80 + ((c[i] >> 6) & 0x3F));
867 out << (unsigned char)(0x80 + (c[i] & 0x3F));
870 out << "\"";
871 return out.str();
874 void skip_ws(const std::string& doc, size_t& ptr, size_t len) {
875 while(ptr < len && (doc[ptr] == ' ' || doc[ptr] == '\t' || doc[ptr] == '\v' || doc[ptr] == '\r' ||
876 doc[ptr] == '\n')) {
877 ptr++;
881 std::u32string pointer_escape_field(const std::u32string& orig) throw(std::bad_alloc)
883 std::basic_stringstream<char32_t> x;
884 for(auto i : orig) {
885 if(i == U'~')
886 x << U"~0";
887 else if(i == U'/')
888 x << U"~1";
889 else
890 x << i;
892 return x.str();
895 std::u32string pointer_escape_index(uint64_t idx) throw(std::bad_alloc)
897 std::string orig = (stringfmt() << idx).str();
898 std::basic_ostringstream<char32_t> x;
899 for(auto i : orig)
900 x << (char32_t)i;
901 return x.str();
905 std::string node::serialize() const throw(std::bad_alloc, error)
907 std::ostringstream out;
908 bool first = true;
909 switch(vtype) {
910 case null_tag::id: return "null";
911 case boolean_tag::id: return _boolean ? "true" : "false";
912 case number_tag::id:
913 _number.write(out);
914 return out.str();
915 case string_tag::id:
916 return json_string_escape(_string);
917 case array_tag::id:
918 out << "[";
919 for(auto& i : xarray_index) {
920 if(!first) out << ",";
921 out << i->serialize();
922 first = false;
924 out << "]";
925 return out.str();
926 case object_tag::id:
927 out << "{";
928 for(auto& i : xobject) {
929 for(auto& j : i.second) {
930 if(!first) out << ",";
931 out << json_string_escape(i.first) << ":" << j.serialize();
932 first = false;
935 out << "}";
936 return out.str();
938 throw error(ERR_UNKNOWN_TYPE);
941 node::node(const std::string& doc) throw(std::bad_alloc, error)
943 size_t tmp = 0;
944 ctor(doc, tmp, doc.length());
945 skip_ws(doc, tmp, doc.length());
946 if(tmp < doc.length())
947 throw error(ERR_GARBAGE_AFTER_END, PARSE_END_OF_DOCUMENT, tmp);
950 void node::ctor(const std::string& doc, size_t& ptr, size_t len) throw(std::bad_alloc, error)
952 size_t tmp3;
953 tmp3 = ptr;
954 json_token t = parse_token(doc, ptr, len);
955 size_t tmp = ptr;
956 std::string tmp2;
957 switch(t.type) {
958 case json_token::TTRUE:
959 set(boolean, true);
960 return;
961 case json_token::TFALSE:
962 set(boolean, false);
963 return;
964 case json_token::TNULL:
965 set(null);
966 return;
967 case json_token::TEOF:
968 throw error(ERR_TRUNCATED_JSON, PARSE_VALUE_START, ptr);
969 case json_token::TCOMMA:
970 throw error(ERR_UNEXPECTED_COMMA, PARSE_VALUE_START, tmp3);
971 case json_token::TCOLON:
972 throw error(ERR_UNEXPECTED_COLON, PARSE_VALUE_START, tmp3);
973 case json_token::TARRAY_END:
974 throw error(ERR_UNEXPECTED_RIGHT_BRACKET, PARSE_VALUE_START, tmp3);
975 case json_token::TOBJECT_END:
976 throw error(ERR_UNEXPECTED_RIGHT_BRACE, PARSE_VALUE_START, tmp3);
977 case json_token::TSTRING:
978 set(string, U"");
979 read_string(_string, doc, ptr, len);
980 break;
981 case json_token::TNUMBER:
982 set(number, 0.0);
983 _number = number_holder(doc, ptr, len);
984 break;
985 case json_token::TOBJECT:
986 *this = object();
987 if(parse_token(doc, tmp, len).type == json_token::TOBJECT_END) {
988 ptr = tmp;
989 break;
991 while(true) {
992 tmp3 = ptr;
993 json_token t2 = parse_token(doc, ptr, len);
994 if(t2.type == json_token::TEOF)
995 throw error(ERR_TRUNCATED_JSON, PARSE_OBJECT_NAME, ptr);
996 if(t2.type != json_token::TSTRING)
997 throw error(ERR_EXPECTED_STRING_KEY, PARSE_OBJECT_NAME, tmp3);
998 std::u32string key;
999 read_string(key, doc, ptr, len);
1000 tmp3 = ptr;
1001 t2 = parse_token(doc, ptr, len);
1002 if(t2.type == json_token::TEOF)
1003 throw error(ERR_TRUNCATED_JSON, PARSE_OBJECT_COLON, ptr);
1004 if(t2.type != json_token::TCOLON)
1005 throw error(ERR_EXPECTED_COLON, PARSE_OBJECT_COLON, tmp3);
1006 insert(key, node(doc, ptr, len));
1007 tmp3 = ptr;
1008 t2 = parse_token(doc, ptr, len);
1009 if(t2.type == json_token::TEOF)
1010 throw error(ERR_TRUNCATED_JSON, PARSE_OBJECT_AFTER_VALUE, ptr);
1011 if(t2.type == json_token::TOBJECT_END)
1012 break;
1013 if(t2.type != json_token::TCOMMA)
1014 throw error(ERR_EXPECTED_COMMA, PARSE_OBJECT_AFTER_VALUE, tmp3);
1016 break;
1017 case json_token::TARRAY:
1018 *this = array();
1019 if(parse_token(doc, tmp, len).type == json_token::TARRAY_END) {
1020 ptr = tmp;
1021 break;
1023 while(true) {
1024 append(node(doc, ptr, len));
1025 tmp3 = ptr;
1026 json_token t2 = parse_token(doc, ptr, len);
1027 if(t2.type == json_token::TEOF)
1028 throw error(ERR_TRUNCATED_JSON, PARSE_ARRAY_AFTER_VALUE, ptr);
1029 if(t2.type == json_token::TARRAY_END)
1030 break;
1031 if(t2.type != json_token::TCOMMA)
1032 throw error(ERR_EXPECTED_COMMA, PARSE_ARRAY_AFTER_VALUE, tmp3);
1034 break;
1035 case json_token::TINVALID:
1036 throw error(ERR_UNKNOWN_CHARACTER, PARSE_VALUE_START, tmp3);
1040 node::node(const std::string& doc, size_t& ptr, size_t len) throw(std::bad_alloc, error)
1042 ctor(doc, ptr, len);
1045 node& node::operator[](const std::u32string& pointer) throw(std::bad_alloc, error)
1047 node* current = this;
1048 size_t ptr = 0;
1049 while(ptr < pointer.length()) {
1050 size_t p = pointer.find_first_of(U"/", ptr);
1051 if(p > pointer.length())
1052 p = pointer.length();
1053 std::u32string c = jsonptr_unescape(pointer, ptr, p);
1054 if(current->vtype == array) {
1055 if(c == U"-") {
1056 //End-of-array.
1057 if(p < pointer.length())
1058 throw error(ERR_POINTER_BAD_APPEND);
1059 return current->append(n());
1061 size_t idx;
1062 if(!parse_size_t(c, idx))
1063 throw error(ERR_POINTER_BAD_INDEX);
1064 if(idx > current->xarray.size())
1065 throw error(ERR_POINTER_BAD_APPEND);
1066 else if(idx == current->xarray.size())
1067 return current->append(n());
1068 current = &current->index(idx);
1069 } else if(current->vtype == object) {
1070 if(!current->field_exists(c) && p == pointer.length())
1071 return current->insert(c, n());
1072 current = &current->field(c);
1073 } else
1074 throw error(ERR_NOT_ARRAY_NOR_OBJECT);
1075 ptr = p + 1;
1077 return *current;
1080 node& node::insert_node(const std::u32string& pointer, const node& nwn) throw(std::bad_alloc, error)
1082 size_t s = pointer.find_last_of(U"/");
1083 node* base;
1084 std::u32string rest;
1085 size_t ptrlen = pointer.length();
1086 if(s < ptrlen) {
1087 base = &follow(pointer.substr(0, s));
1088 rest = jsonptr_unescape(pointer, s + 1, ptrlen);
1089 } else {
1090 base = this;
1091 rest = jsonptr_unescape(pointer, 0, ptrlen);
1093 if(base->type() == array) {
1094 if(rest == U"-")
1095 return base->append(nwn);
1096 size_t idx;
1097 if(!parse_size_t(rest, idx))
1098 throw error(ERR_POINTER_BAD_INDEX);
1099 if(idx > base->xarray.size())
1100 throw error(ERR_POINTER_BAD_APPEND);
1101 else if(idx == base->xarray.size())
1102 return base->append(nwn);
1103 bool p = false;
1104 try {
1105 base->xarray.push_back(nwn);
1106 p = true;
1107 node* ptr = &*base->xarray.rbegin();
1108 base->xarray_index.insert(base->xarray_index.begin() + idx, ptr);
1109 return *ptr;
1110 } catch(std::bad_alloc& e) {
1111 if(p)
1112 base->xarray.pop_back();
1113 throw;
1115 } else if(base->type() == object) {
1116 if(xobject.count(rest))
1117 return *base->xobject[rest].begin() = nwn;
1118 else {
1119 try {
1120 base->xobject[rest].push_back(nwn);
1121 return *base->xobject[rest].begin();
1122 } catch(...) {
1123 base->xobject.erase(rest);
1124 throw;
1127 } else
1128 throw error(ERR_NOT_ARRAY_NOR_OBJECT);
1131 node node::delete_node(const std::u32string& pointer) throw(std::bad_alloc, error)
1133 size_t s = pointer.find_last_of(U"/");
1134 node* base;
1135 std::u32string rest;
1136 size_t ptrlen = pointer.length();
1137 if(s < ptrlen) {
1138 base = &follow(pointer.substr(0, s));
1139 rest = jsonptr_unescape(pointer, s + 1, ptrlen);
1140 } else {
1141 base = this;
1142 rest = jsonptr_unescape(pointer, 0, ptrlen);
1144 if(base->type() == array) {
1145 if(rest == U"-")
1146 throw error(ERR_POINTER_BAD_APPEND);
1147 size_t idx;
1148 if(!parse_size_t(rest, idx))
1149 throw error(ERR_POINTER_BAD_INDEX);
1150 if(idx >= base->xarray.size())
1151 throw error(ERR_INDEX_INVALID);
1152 node* dptr = base->xarray_index[idx];
1153 node tmp = *dptr;
1154 for(auto i = base->xarray.begin(); i != base->xarray.end(); ++i)
1155 if(&*i == dptr) {
1156 base->xarray.erase(i);
1157 break;
1159 base->xarray_index.erase(base->xarray_index.begin() + idx);
1160 return tmp;
1161 } else if(base->type() == object) {
1162 if(xobject.count(rest)) {
1163 node tmp = *base->xobject[rest].begin();
1164 base->xobject.erase(rest);
1165 return tmp;
1166 } else
1167 throw error(ERR_KEY_INVALID);
1168 } else
1169 throw error(ERR_NOT_ARRAY_NOR_OBJECT);
1172 node node::patch(const node& patch) const throw(std::bad_alloc, error)
1174 node obj(*this);
1175 if(patch.type() != array)
1176 throw error(ERR_PATCH_BAD);
1177 for(auto& i : patch) {
1178 if(i.type() != object || i.field_count(U"op") != 1 || i.field(U"op").type() != string)
1179 throw error(ERR_PATCH_BAD);
1180 std::u32string op = i.field(U"op").as_string();
1181 if(op == U"test") {
1182 if(i.field_count(U"path") != 1 || i.field(U"path").type() != string)
1183 throw error(ERR_PATCH_BAD);
1184 if(i.field_count(U"value") != 1)
1185 throw error(ERR_PATCH_BAD);
1186 if(obj.follow(i.field(U"path").as_string()) != i.field("value"))
1187 throw error(ERR_PATCH_TEST_FAILED);
1188 } else if(op == U"remove") {
1189 if(i.field_count(U"path") != 1 || i.field(U"path").type() != string)
1190 throw error(ERR_PATCH_BAD);
1191 obj.delete_node(i.field(U"path").as_string());
1192 } else if(op == U"add") {
1193 if(i.field_count(U"path") != 1 || i.field(U"path").type() != string)
1194 throw error(ERR_PATCH_BAD);
1195 if(i.field_count(U"value") != 1)
1196 throw error(ERR_PATCH_BAD);
1197 obj.insert_node(i.field(U"path").as_string(), i.field("value"));
1198 } else if(op == U"replace") {
1199 if(i.field_count(U"path") != 1 || i.field(U"path").type() != string)
1200 throw error(ERR_PATCH_BAD);
1201 if(i.field_count(U"value") != 1)
1202 throw error(ERR_PATCH_BAD);
1203 obj.delete_node(i.field(U"path").as_string());
1204 obj.insert_node(i.field(U"path").as_string(), i.field("value"));
1205 } else if(op == U"move") {
1206 if(i.field_count(U"from") != 1 || i.field(U"from").type() != string)
1207 throw error(ERR_PATCH_BAD);
1208 if(i.field_count(U"path") != 1 || i.field(U"path").type() != string)
1209 throw error(ERR_PATCH_BAD);
1210 std::u32string from = i.field(U"from").as_string();
1211 std::u32string to = i.field(U"path").as_string();
1212 if(to.substr(0, from.length()) == from) {
1213 if(to.length() == from.length())
1214 continue;
1215 if(to.length() > from.length() && to[from.length()] == U'/')
1216 throw error(ERR_PATCH_ILLEGAL_MOVE);
1218 node tmp = obj.delete_node(from);
1219 obj.insert_node(to, tmp);
1220 } else if(op == U"copy") {
1221 if(i.field_count(U"from") != 1 || i.field(U"from").type() != string)
1222 throw error(ERR_PATCH_BAD);
1223 if(i.field_count(U"path") != 1 || i.field(U"path").type() != string)
1224 throw error(ERR_PATCH_BAD);
1225 const node& tmp = obj.follow(i.field(U"from").as_string());
1226 obj.insert_node(i.field(U"path").as_string(), tmp);
1227 } else
1228 throw error(ERR_PATCH_BAD);
1230 return obj;
1234 node::iterator::iterator() throw() { n = NULL; }
1236 node::iterator::iterator(node& _n) throw(error)
1238 n = &_n;
1239 idx = 0;
1240 if(n->type() == object) {
1241 if(n->xobject.empty())
1242 n = NULL;
1243 else
1244 _key = n->xobject.begin()->first;
1245 } else if(n->type() == array) {
1246 if(n->xarray.empty())
1247 n = NULL;
1248 } else
1249 throw error(ERR_NOT_ARRAY_NOR_OBJECT);
1252 std::u32string node::iterator::key() throw(std::bad_alloc, error)
1254 if(!n)
1255 throw error(ERR_ITERATOR_END);
1256 return (n->type() == object) ? _key : U"";
1259 size_t node::iterator::index() throw(error)
1261 if(!n)
1262 throw error(ERR_ITERATOR_END);
1263 return idx;
1266 node& node::iterator::operator*() throw(error)
1268 if(!n)
1269 throw error(ERR_ITERATOR_END);
1270 if(n->type() == object) {
1271 if(!n->xobject.count(_key))
1272 throw error(ERR_ITERATOR_DELETED);
1273 auto& l = n->xobject.find(_key)->second;
1274 size_t j = 0;
1275 for(auto i = l.begin(); i != l.end(); i++, j++) {
1276 if(j == idx)
1277 return *i;
1279 throw error(ERR_ITERATOR_DELETED);
1280 } else {
1281 if(idx >= n->xarray.size())
1282 throw error(ERR_ITERATOR_DELETED);
1283 return *n->xarray_index[idx];
1287 node* node::iterator::operator->() throw(error)
1289 return &**this;
1292 node::iterator node::iterator::operator++(int) throw(error)
1294 iterator tmp = *this;
1295 ++*this;
1296 return tmp;
1299 node::iterator& node::iterator::operator++() throw(error)
1301 if(!n)
1302 throw error(ERR_ITERATOR_END);
1303 idx++;
1304 if(n->type() == object) {
1305 if(!n->xobject.count(_key) || n->xobject.find(_key)->second.size() <= idx) {
1306 auto i = n->xobject.upper_bound(_key);
1307 if(i == n->xobject.end())
1308 n = NULL;
1309 else
1310 _key = i->first;
1311 idx = 0;
1313 } else {
1314 if(idx >= n->xarray_index.size())
1315 n = NULL;
1317 return *this;
1320 bool node::iterator::operator==(const iterator& i) throw()
1322 if(n != i.n)
1323 return false;
1324 if(!n && !i.n)
1325 return true;
1326 return (n == i.n && _key == i._key && idx == i.idx);
1329 bool node::iterator::operator!=(const iterator& i) throw() { return !(*this == i); }
1331 node::const_iterator::const_iterator() throw() { n = NULL; }
1333 node::const_iterator::const_iterator(const node& _n) throw(error)
1335 n = &_n;
1336 idx = 0;
1337 if(n->type() == object) {
1338 if(n->xobject.empty())
1339 n = NULL;
1340 else
1341 _key = n->xobject.begin()->first;
1342 } else if(n->type() == array) {
1343 if(n->xarray.empty())
1344 n = NULL;
1345 } else
1346 throw error(ERR_NOT_ARRAY_NOR_OBJECT);
1349 std::u32string node::const_iterator::key() throw(std::bad_alloc, error)
1351 if(!n)
1352 throw error(ERR_ITERATOR_END);
1353 return (n->type() == object) ? _key : U"";
1356 size_t node::const_iterator::index() throw(error)
1358 if(!n)
1359 throw error(ERR_ITERATOR_END);
1360 return idx;
1363 const node& node::const_iterator::operator*() throw(error)
1365 if(!n)
1366 throw error(ERR_ITERATOR_END);
1367 if(n->type() == object) {
1368 if(!n->xobject.count(_key))
1369 throw error(ERR_ITERATOR_DELETED);
1370 auto& l = n->xobject.find(_key)->second;
1371 size_t j = 0;
1372 for(auto i = l.begin(); i != l.end(); i++, j++) {
1373 if(j == idx)
1374 return *i;
1376 throw error(ERR_ITERATOR_DELETED);
1377 } else {
1378 if(idx >= n->xarray.size())
1379 throw error(ERR_ITERATOR_DELETED);
1380 return *n->xarray_index[idx];
1384 const node* node::const_iterator::operator->() throw(error)
1386 return &**this;
1389 node::const_iterator node::const_iterator::operator++(int) throw(error)
1391 const_iterator tmp = *this;
1392 ++*this;
1393 return tmp;
1396 node::const_iterator& node::const_iterator::operator++() throw(error)
1398 if(!n)
1399 throw error(ERR_ITERATOR_END);
1400 idx++;
1401 if(n->type() == object) {
1402 if(!n->xobject.count(_key) || n->xobject.find(_key)->second.size() <= idx) {
1403 auto i = n->xobject.upper_bound(_key);
1404 if(i == n->xobject.end())
1405 n = NULL;
1406 else
1407 _key = i->first;
1408 idx = 0;
1410 } else {
1411 if(idx >= n->xarray_index.size())
1412 n = NULL;
1414 return *this;
1417 bool node::const_iterator::operator==(const const_iterator& i) throw()
1419 if(n != i.n)
1420 return false;
1421 if(!n && !i.n)
1422 return true;
1423 return (n == i.n && _key == i._key && idx == i.idx);
1426 bool node::const_iterator::operator!=(const const_iterator& i) throw() { return !(*this == i); }
1428 void node::erase_index(size_t idx) throw(error)
1430 if(type() == array) {
1431 if(idx >= xarray_index.size())
1432 return;
1433 node* n = xarray_index[idx];
1434 xarray_index.erase(xarray_index.begin() + idx);
1435 for(auto i = xarray.begin(); i != xarray.end(); i++)
1436 if(&*i == n) {
1437 xarray.erase(i);
1438 return;
1440 } else
1441 throw error(ERR_NOT_AN_ARRAY);
1444 void node::erase_field(const std::u32string& fld, size_t idx) throw(error)
1446 if(type() == object) {
1447 if(xobject.count(fld)) {
1448 auto& l = xobject[fld];
1449 size_t j = 0;
1450 for(auto i = l.begin(); i != l.end(); i++, j++)
1451 if(j == idx) {
1452 l.erase(i);
1453 break;
1455 if(l.empty())
1456 xobject.erase(fld);
1458 } else
1459 throw error(ERR_NOT_AN_OBJECT);
1462 void node::erase_field_all(const std::u32string& fld) throw(error)
1464 if(type() == object) {
1465 if(xobject.count(fld))
1466 xobject.erase(fld);
1467 } else
1468 throw error(ERR_NOT_AN_OBJECT);
1471 void node::clear() throw(error)
1473 if(type() == object)
1474 xobject.clear();
1475 else if(type() == array) {
1476 xarray_index.clear();
1477 xobject.clear();
1478 } else
1479 throw error(ERR_NOT_ARRAY_NOR_OBJECT);
1482 node::iterator node::erase(node::iterator itr) throw(error)
1484 if(itr.n != this)
1485 throw error(ERR_WRONG_OBJECT);
1486 if(type() == object) {
1487 erase_field(itr._key, itr.idx);
1488 if(!xobject.count(itr._key) || itr.idx >= xobject[itr._key].size())
1489 itr++;
1490 return itr;
1491 } else if(type() == array) {
1492 erase_index(itr.idx);
1493 if(itr.idx >= xarray_index.size())
1494 itr.n = NULL;
1495 return itr;
1496 } else
1497 throw error(ERR_NOT_ARRAY_NOR_OBJECT);
1500 void node::fixup_nodes(const node& _node)
1502 auto i = xarray.begin();
1503 auto j = _node.xarray.begin();
1504 for(; i != xarray.end(); i++, j++) {
1505 for(size_t k = 0; k < _node.xarray_index.size(); k++)
1506 if(_node.xarray_index[k] == &*j)
1507 xarray_index[k] = &*i;
1511 bool node::operator==(const node& n) const
1513 if(this == &n)
1514 return true;
1515 if(vtype != n.vtype)
1516 return false;
1517 switch(vtype) {
1518 case null_tag::id:
1519 return true;
1520 case boolean_tag::id:
1521 return (_boolean == n._boolean);
1522 case number_tag::id:
1523 return (_number == n._number);
1524 case string_tag::id:
1525 return (_string == n._string);
1526 case array_tag::id:
1527 if(xarray_index.size() != n.xarray_index.size())
1528 return false;
1529 for(size_t i = 0; i < xarray_index.size(); i++)
1530 if(*xarray_index[i] != *n.xarray_index[i])
1531 return false;
1532 return true;
1533 case object_tag::id:
1534 for(auto& i : xobject)
1535 if(!n.xobject.count(i.first))
1536 return false;
1537 for(auto& i : n.xobject)
1538 if(!xobject.count(i.first))
1539 return false;
1540 for(auto& i : xobject) {
1541 auto& j = *xobject.find(i.first);
1542 auto& k = *n.xobject.find(i.first);
1543 if(j.second.size() != k.second.size())
1544 return false;
1545 auto j2 = j.second.begin();
1546 auto k2 = k.second.begin();
1547 for(; j2 != j.second.end(); j2++, k2++)
1548 if(*j2 != *k2)
1549 return false;
1551 return true;
1552 default:
1553 throw error(ERR_UNKNOWN_TYPE);
1557 int node::type_of(const std::u32string& pointer) const throw(std::bad_alloc)
1559 try {
1560 const node* n;
1561 if(follow_soft(pointer, n) != ERR_OK)
1562 return none.id;
1563 return n->type();
1564 } catch(std::bad_alloc& e) {
1565 throw;
1566 } catch(std::exception& e) {
1567 //Shouldn't happen.
1568 return none.id;
1572 int node::type_of_indirect(const std::u32string& pointer) const throw(std::bad_alloc)
1574 try {
1575 const node* n;
1576 if(follow_soft(pointer, n) != ERR_OK)
1577 return none.id;
1578 if(n->type() == string)
1579 return type_of(n->as_string());
1580 else
1581 return n->type();
1582 } catch(std::bad_alloc& e) {
1583 throw;
1584 } catch(std::exception& e) {
1585 //Shouldn't happen.
1586 return none.id;
1590 std::u32string node::resolve_indirect(const std::u32string& pointer) const throw(std::bad_alloc)
1592 try {
1593 const node& n = follow(pointer);
1594 if(n.type() == string)
1595 return n.as_string();
1596 else
1597 return pointer;
1598 } catch(std::bad_alloc& e) {
1599 throw;
1600 } catch(std::exception& e) {
1601 return pointer;
1605 pointer::pointer()
1609 pointer::pointer(const std::string& ptr) throw(std::bad_alloc)
1611 _pointer = to_u32string(ptr);
1614 pointer::pointer(const std::u32string& ptr) throw(std::bad_alloc)
1616 _pointer = ptr;
1619 pointer pointer::index(uint64_t idx) const throw(std::bad_alloc)
1621 if(_pointer.length())
1622 return pointer(_pointer + U"/" + pointer_escape_index(idx));
1623 else
1624 return pointer(pointer_escape_index(idx));
1627 pointer& pointer::index_inplace(uint64_t idx) throw(std::bad_alloc)
1629 if(_pointer.length())
1630 _pointer = _pointer + U"/" + pointer_escape_index(idx);
1631 else
1632 _pointer = pointer_escape_index(idx);
1633 return *this;
1636 pointer pointer::field(const std::u32string& fld) const throw(std::bad_alloc)
1638 if(_pointer.length())
1639 return pointer(_pointer + U"/" + pointer_escape_field(fld));
1640 else
1641 return pointer(pointer_escape_field(fld));
1645 pointer& pointer::field_inplace(const std::u32string& fld) throw(std::bad_alloc)
1647 if(_pointer.length())
1648 _pointer = _pointer + U"/" + pointer_escape_field(fld);
1649 else
1650 _pointer = pointer_escape_field(fld);
1651 return *this;
1654 pointer pointer::remove() const throw(std::bad_alloc)
1656 size_t p = _pointer.find_last_of(U"/");
1657 if(p >= _pointer.length())
1658 return pointer();
1659 else
1660 return pointer(_pointer.substr(0, p));
1663 pointer& pointer::remove_inplace() throw(std::bad_alloc)
1665 size_t p = _pointer.find_last_of(U"/");
1666 if(p >= _pointer.length())
1667 _pointer = U"";
1668 else
1669 _pointer = _pointer.substr(0, p);
1670 return *this;
1673 std::ostream& operator<<(std::ostream& s, const pointer& p)
1675 return s << to_u8string(p._pointer);
1678 std::basic_ostream<char32_t>& operator<<(std::basic_ostream<char32_t>& s, const pointer& p)
1680 return s << p._pointer;
1685 bool operator==(const int& n, const JSON::number_tag& v) { return v == n; }
1686 bool operator==(const int& n, const JSON::string_tag& v) { return v == n; }
1687 bool operator==(const int& n, const JSON::boolean_tag& v) { return v == n; }
1688 bool operator==(const int& n, const JSON::array_tag& v) { return v == n; }
1689 bool operator==(const int& n, const JSON::object_tag& v) { return v == n; }
1690 bool operator==(const int& n, const JSON::null_tag& v) { return v == n; }
1691 bool operator!=(const int& n, const JSON::number_tag& v) { return v != n; }
1692 bool operator!=(const int& n, const JSON::string_tag& v) { return v != n; }
1693 bool operator!=(const int& n, const JSON::boolean_tag& v) { return v != n; }
1694 bool operator!=(const int& n, const JSON::array_tag& v) { return v != n; }
1695 bool operator!=(const int& n, const JSON::object_tag& v) { return v != n; }
1696 bool operator!=(const int& n, const JSON::null_tag& v) { return v != n; }