10 const char* error_desc
[] = {
17 "Not array nor object",
21 "Trailing pointer escape character",
22 "Invalid pointer escape",
23 "Bad hexadecimal character",
24 "Invalid surrogate escape",
25 "Invalid escape sequence",
28 "Garbage after end of JSON",
32 "Unexpected right brace",
33 "Unexpected right braket",
34 "Invalid number syntax",
35 "Expected string as object key",
41 "Iterator past the end",
42 "Iterator points to deleted object",
43 "Iterator points to wrong object",
44 "Illegal character escaped",
45 "Control character in string",
46 "Invalid value subtype",
48 "JSON patch test failed",
49 "JSON patch illegal move",
52 const char* state_desc
[] = {
65 const char* asciinames
[] = {
66 "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
67 "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US"
70 bool parse_size_t(const std::u32string
& s
, size_t& x
)
73 for(size_t i
= 0; i
< s
.length(); i
++) {
74 if(s
[i
] < 48 || s
[i
] > 57)
76 if((std::numeric_limits
<size_t>::max() - (size_t)(s
[i
] - 48)) / 10 < x
)
78 x
= 10 * x
+ (s
[i
] - 48);
83 std::pair
<size_t, size_t> error::get_position_lc(const std::string
& doc
, size_t pos
)
87 for(size_t i
= 0; i
< pos
; i
++) {
88 if(doc
[i
] == 13 || (doc
[i
] == 10 && !last_cr
)) {
91 last_cr
= (doc
[i
] == 13);
94 if(last_cr
&& doc
[i
] == 10) {
100 return std::make_pair(r
, c
);
103 const char* error::what() const throw()
105 if(state
== PARSE_NOT_PARSING
)
106 return error_desc
[code
];
108 sprintf(buffer
, "%s (while expecting %s) at byte %llu", error_desc
[code
], state_desc
[state
],
109 (unsigned long long)position
);
114 std::string
error::extended_error(const std::string
& doc
)
116 if(state
== PARSE_NOT_PARSING
)
117 return error_desc
[code
];
118 std::ostringstream s
;
119 size_t pos
= position
;
120 while(pos
< doc
.length() && (doc
[pos
] == '\t' || doc
[pos
] == '\v' || doc
[pos
] == '\r' || doc
[pos
] == '\n' ||
123 auto p2
= get_position_lc(doc
, pos
);
124 s
<< error_desc
[code
] << " (while expecting " << state_desc
[state
] << ") at ";
125 if(position
== doc
.length())
128 std::ostringstream sample
;
130 for(size_t i
= 0; i
< 32; i
++) {
131 if(p
>= doc
.length())
134 sample
<< "<" << asciinames
[doc
[p
++]] << ">";
135 } else if(doc
[p
] < 127)
137 else if(doc
[p
] < 128)
139 else if(doc
[p
] < 192)
140 sample
<< "<" << (int)doc
[p
++] << ">";
141 else if(doc
[p
] < 224) {
144 } else if(doc
[p
] < 240) {
148 } else if(doc
[p
] < 248) {
154 sample
<< "<" << (int)doc
[p
++] << ">";
156 s
<< "line " << p2
.first
<< " byte " << p2
.second
<< " [near: '" << sample
.str() << "']";
161 node
number_tag::operator()(double v
) const { return node(*this, v
); }
162 node
number_tag::operator()(uint64_t v
) const { return node(*this, v
); }
163 node
number_tag::operator()(int64_t v
) const { return node(*this, v
); }
164 node
string_tag::operator()(const std::string
& s
) const { return node(*this, s
); }
165 node
string_tag::operator()(const std::u32string
& s
) const { return node(*this, s
); }
166 node
boolean_tag::operator()(bool v
) { return node(*this, v
); }
167 node
array_tag::operator()() const { return node(*this); }
168 node
object_tag::operator()() const { return node(*this); }
169 node
null_tag::operator()() const { return node(*this); }
171 node
i(int64_t n
) { return number(n
); }
172 node
u(uint64_t n
) { return number(n
); }
173 node
f(double n
) { return number(n
); }
174 node
b(bool bl
) { return boolean(bl
); }
175 node
s(const std::string
& st
) { return string(st
); }
176 node
s(const std::u32string
& st
) { return string(st
); }
177 node
n() { return null(); }
187 template<> void node::number_holder::from(double val
) { sub
= 0; n
.n0
= val
; }
188 template<> void node::number_holder::from(uint64_t val
) { sub
= 1; n
.n1
= val
; }
189 template<> void node::number_holder::from(int64_t val
) { sub
= 2; n
.n2
= val
; }
193 unsigned numchar(char c
)
197 case '1': case '2': case '3': case '4': case '5':
198 case '6': case '7': case '8': case '9': return 1;
207 uint32_t numdfa
[] = {
208 0x0F1FFF32, //0: STATE_INITIAL
209 0x0FFFFF32, //1: STATE_AFTER_MINUS
210 0x1FFF64FF, //2: STATE_INT_Z
211 0x1FFF6433, //3: STATE_INT_NZ
212 0x0FFFFF55, //4: STATE_DECIMAL
213 0x1FFF6F55, //5: STATE_DECIMAL_N
214 0x0F77FF88, //6: STATE_EXP
215 0x0FFFFF88, //7: STATE_EXP_SIGN
216 0x1FFFFF88, //8: STATE_EXP_N
220 node::number_holder::number_holder(const std::string
& expr
, size_t& ptr
, size_t len
)
222 //-?(0|1-9[0-9]+)(.[0-9]+)?([eE][+-]?[0-9]+)?
228 unsigned c
= numchar(expr
[tmp
]);
229 unsigned ns
= (numdfa
[state
] >> (4 * c
)) & 0xF;
236 if(!(numdfa
[state
] >> 28))
238 x
= expr
.substr(ptr
, tmp
- ptr
);
241 if(regex_match("[0-9]+", x
)) {
242 n
.n1
= parse_value
<uint64_t>(x
);
248 if(regex_match("[+-]?[0-9]+", x
)) {
249 n
.n2
= parse_value
<int64_t>(x
);
255 n
.n0
= parse_value
<double>(x
);
260 throw error(ERR_INVALID_NUMBER
, PARSE_NUMBER
, tmp2
);
264 void node::number_holder::write(std::ostream
& s
) const
267 case 0: s
<< n
.n0
; break;
268 case 1: s
<< n
.n1
; break;
269 case 2: s
<< n
.n2
; break;
273 template<typename T
> bool node::number_holder::cmp(const T
& num
) const
276 case 0: return n
.n0
== num
;
277 case 1: return n
.n1
== num
;
278 case 2: return n
.n2
== num
;
280 throw error(ERR_UNKNOWN_SUBTYPE
);
283 template<> bool node::number_holder::cmp(const int64_t& num
) const
286 case 0: return n
.n0
== num
;
287 case 1: return num
>= 0 && n
.n1
== static_cast<uint64_t>(num
);
288 case 2: return n
.n2
== num
;
290 throw error(ERR_UNKNOWN_SUBTYPE
);
293 template<> bool node::number_holder::cmp(const uint64_t& num
) const
296 case 0: return n
.n0
== num
;
297 case 1: return n
.n1
== num
;
298 case 2: return n
.n2
>= 0 && static_cast<uint64_t>(n
.n2
) == num
;
300 throw error(ERR_UNKNOWN_SUBTYPE
);
304 bool node::number_holder::operator==(const number_holder
& h
) const
307 case 0: return h
.cmp(n
.n0
);
308 case 1: return h
.cmp(n
.n1
);
309 case 2: return h
.cmp(n
.n2
);
311 throw error(ERR_UNKNOWN_SUBTYPE
);
314 node::node() throw() : node(null
) {}
315 node::node(null_tag
) throw() { vtype
= null
; }
316 node::node(boolean_tag
, bool b
) throw() { vtype
= boolean
; _boolean
= b
; }
317 node::node(string_tag
, const std::u32string
& str
) throw(std::bad_alloc
) { vtype
= string
; _string
= str
; }
318 node::node(string_tag
, const std::string
& str
) throw(std::bad_alloc
) { vtype
= string
; _string
= utf8::to32(str
); }
319 node::node(number_tag
, double n
) throw() { vtype
= number
; _number
.from
<double>(n
); }
320 node::node(number_tag
, int64_t n
) throw() { vtype
= number
; _number
.from
<int64_t>(n
); }
321 node::node(number_tag
, uint64_t n
) throw() { vtype
= number
; _number
.from
<uint64_t>(n
); }
322 node::node(array_tag
) throw() { vtype
= array
; }
323 node::node(object_tag
) throw() { vtype
= object
; }
324 int node::type() const throw() { return vtype
; }
326 node
& node::set(null_tag
) throw() { set_helper
<uint64_t>(0); vtype
= null
; return *this; }
327 node
& node::set(boolean_tag
, bool n
) throw() { set_helper
<uint64_t>(0); vtype
= boolean
; _boolean
= n
; return *this; }
328 node
& node::set(number_tag
, double n
) throw() { set_helper
<double>(n
); return *this; }
329 node
& node::set(number_tag
, int64_t n
) throw() { set_helper
<int64_t>(n
); return *this; }
330 node
& node::set(number_tag
, uint64_t n
) throw() { set_helper
<int64_t>(n
); return *this; }
332 node
& node::set(string_tag
, const std::u32string
& key
) throw(std::bad_alloc
)
334 std::u32string tmp
= key
;
335 std::swap(_string
, tmp
);
342 double node::as_double() const throw(error
)
344 return get_number_helper
<double>();
347 int64_t node::as_int() const throw(error
)
349 return get_number_helper
<int64_t>();
352 uint64_t node::as_uint() const throw(error
)
354 return get_number_helper
<uint64_t>();
357 const std::u32string
& node::as_string() const throw(std::bad_alloc
, error
)
360 throw error(ERR_NOT_A_STRING
);
364 bool node::as_bool() const throw(error
)
367 throw error(ERR_NOT_A_BOOLEAN
);
371 size_t node::index_count() const throw(error
)
374 throw error(ERR_NOT_AN_ARRAY
);
375 return xarray
.size();
378 errorcode
node::index_soft(size_t index
, const node
*& out
) const throw()
381 return ERR_NOT_AN_ARRAY
;
382 if(index
>= xarray_index
.size())
383 return ERR_INDEX_INVALID
;
384 out
= xarray_index
[index
];
388 errorcode
node::index_soft(size_t index
, node
*& out
) throw()
391 return ERR_NOT_AN_ARRAY
;
392 if(index
>= xarray_index
.size())
393 return ERR_INDEX_INVALID
;
394 out
= xarray_index
[index
];
398 size_t node::field_count(const std::u32string
& key
) const throw(error
)
401 throw error(ERR_NOT_AN_OBJECT
);
402 if(!xobject
.count(key
))
404 return xobject
.find(key
)->second
.size();
407 bool node::field_exists(const std::u32string
& key
) const throw(error
)
409 return (field_count(key
) > 0);
412 errorcode
node::field_soft(const std::u32string
& key
, size_t subindex
, const node
*& out
) const throw()
415 return ERR_NOT_AN_OBJECT
;
416 if(!xobject
.count(key
))
417 return ERR_KEY_INVALID
;
418 const std::list
<node
>& l
= xobject
.find(key
)->second
;
420 for(auto i
= l
.begin(); i
!= l
.end(); i
++, j
++) {
426 return ERR_INSTANCE_INVALID
;
429 errorcode
node::field_soft(const std::u32string
& key
, size_t subindex
, node
*& out
) throw()
432 return ERR_NOT_AN_OBJECT
;
433 if(!xobject
.count(key
))
434 return ERR_KEY_INVALID
;
435 std::list
<node
>& l
= xobject
.find(key
)->second
;
437 for(auto i
= l
.begin(); i
!= l
.end(); i
++, j
++) {
443 return ERR_INSTANCE_INVALID
;
446 node::node(const node
& _node
) throw(std::bad_alloc
)
448 std::u32string tmp1
= _node
._string
;
449 std::list
<node
> tmp2
= _node
.xarray
;
450 std::map
<std::u32string
, std::list
<node
>> tmp3
= _node
.xobject
;
451 std::vector
<node
*> tmp4
= _node
.xarray_index
;
454 _number
= _node
._number
;
455 _boolean
= _node
._boolean
;
456 _string
= _node
._string
;
457 xarray
= _node
.xarray
;
458 xobject
= _node
.xobject
;
459 xarray_index
= _node
.xarray_index
;
463 node
& node::operator=(const node
& _node
) throw(std::bad_alloc
)
467 std::u32string tmp1
= _node
._string
;
468 std::list
<node
> tmp2
= _node
.xarray
;
469 std::map
<std::u32string
, std::list
<node
>> tmp3
= _node
.xobject
;
470 std::vector
<node
*> tmp4
= _node
.xarray_index
;
473 _number
= _node
._number
;
474 _boolean
= _node
._boolean
;
475 std::swap(_string
, tmp1
);
476 std::swap(xarray
, tmp2
);
477 std::swap(xobject
, tmp3
);
478 std::swap(xarray_index
, tmp4
);
483 node
& node::append(const node
& _node
) throw(std::bad_alloc
, error
)
486 throw error(ERR_NOT_AN_ARRAY
);
489 xarray
.push_back(_node
);
491 node
* ptr
= &*xarray
.rbegin();
492 xarray_index
.push_back(ptr
);
494 } catch(std::bad_alloc
& e
) {
501 node
& node::insert(const std::u32string
& key
, const node
& _node
) throw(std::bad_alloc
, error
)
504 throw error(ERR_NOT_AN_OBJECT
);
506 xobject
[key
].push_back(_node
);
507 return *xobject
[key
].rbegin();
509 if(xobject
.count(key
) && xobject
[key
].empty())
517 errorcode
jsonptr_unescape_soft(const std::u32string
& c
, size_t start
, size_t end
, std::u32string
& _out
)
519 std::basic_ostringstream
<char32_t
> out
;
520 for(size_t ptr
= start
; ptr
< end
; ptr
++) {
523 return ERR_POINTER_TRAILING_ESCAPE
;
527 else if(c
[ptr
] == '1')
530 return ERR_POINTER_INVALID_ESCAPE
;
538 std::u32string
jsonptr_unescape(const std::u32string
& c
, size_t start
, size_t end
)
541 auto e
= jsonptr_unescape_soft(c
, start
, end
, o
);
542 if(e
!= ERR_OK
) throw error(e
);
548 errorcode
node::follow_soft(const std::u32string
& pointer
, const node
*& current
) const throw(std::bad_alloc
)
553 while(ptr
< pointer
.length()) {
554 size_t p
= pointer
.find_first_of(U
"/", ptr
);
555 if(p
> pointer
.length())
556 p
= pointer
.length();
558 auto e
= jsonptr_unescape_soft(pointer
, ptr
, p
, c
);
559 if(e
!= ERR_OK
) return e
;
560 if(current
->vtype
== array
) {
562 return ERR_POINTER_BAD_APPEND
;
564 if(!parse_size_t(c
, idx
))
565 return ERR_POINTER_BAD_INDEX
;
566 e
= current
->index_soft(idx
, current
);
567 if(e
!= ERR_OK
) return e
;
568 } else if(current
->vtype
== object
) {
569 e
= current
->field_soft(c
, 0, current
);
570 if(e
!= ERR_OK
) return e
;
572 return ERR_NOT_ARRAY_NOR_OBJECT
;
578 errorcode
node::follow_soft(const std::u32string
& pointer
, node
*& current
) throw(std::bad_alloc
)
583 while(ptr
< pointer
.length()) {
584 size_t p
= pointer
.find_first_of(U
"/", ptr
);
585 if(p
> pointer
.length())
586 p
= pointer
.length();
588 auto e
= jsonptr_unescape_soft(pointer
, ptr
, p
, c
);
589 if(e
!= ERR_OK
) return e
;
590 if(current
->vtype
== array
) {
592 return ERR_POINTER_BAD_APPEND
;
594 if(!parse_size_t(c
, idx
))
595 return ERR_POINTER_BAD_INDEX
;
596 e
= current
->index_soft(idx
, current
);
597 if(e
!= ERR_OK
) return e
;
598 } else if(current
->vtype
== object
) {
599 e
= current
->field_soft(c
, 0, current
);
600 if(e
!= ERR_OK
) return e
;
602 return ERR_NOT_ARRAY_NOR_OBJECT
;
612 enum ttype
{ TSTRING
, TNUMBER
, TOBJECT
, TARRAY
, TINVALID
, TCOMMA
, TOBJECT_END
, TARRAY_END
, TCOLON
,
613 TEOF
, TTRUE
, TFALSE
, TNULL
};
615 std::u32string value
;
616 json_token(enum ttype t
, const std::u32string
& v
) { type
= t
; value
= v
; }
617 json_token(enum ttype t
) { type
= t
; }
620 uint32_t parse_hex(int32_t ch
, parsestate state
, size_t pos
)
633 case 'A': case 'a': return 10;
634 case 'B': case 'b': return 11;
635 case 'C': case 'c': return 12;
636 case 'D': case 'd': return 13;
637 case 'E': case 'e': return 14;
638 case 'F': case 'f': return 15;
639 default: throw error(ERR_BAD_HEX
, state
, pos
);
643 class iterator_counter
646 iterator_counter(size_t& _count
) : count(_count
) { count
= 0; }
647 char32_t
& operator*() { count
++; return x
; }
648 iterator_counter
& operator++() { return *this; }
649 size_t get_count() { return count
; }
657 //STATE_ESCAPE_HEX0 2
658 //STATE_ESCAPE_HEX1 3
659 //STATE_ESCAPE_HEX2 4
660 //STATE_ESCAPE_HEX3 5
661 //STATE_ESCAPE_SURROGATE 6
662 //STATE_ESCAPE_SURROGATE2 7
663 //STATE_ESCAPE_SURROGATE_HEX0 8
664 //STATE_ESCAPE_SURROGATE_HEX1 9
665 //STATE_ESCAPE_SURROGATE_HEX2 10
666 //STATE_ESCAPE_SURROGATE_HEX3 11
668 template<typename T
> size_t read_string_impl(T target
, const std::string
& doc
, size_t ptr
, size_t len
)
670 uint16_t ustate
= utf8::initial_state
;
676 for(i
= ptr
; i
<= len
; i
++) {
679 ch
= (unsigned char)doc
[i
];
680 int32_t uch
= utf8::parse_byte(ch
, ustate
);
683 //Okay, have Unicode codepoint decoded.
689 throw error(ERR_CONTROL_CHARACTER
, PARSE_STRING_BODY
, lc
);
701 case '\"': *target
= U
'\"'; ++target
; estate
= 0; break;
702 case '\\': *target
= U
'\\'; ++target
; estate
= 0; break;
703 case '/': *target
= U
'/'; ++target
; estate
= 0; break;
704 case 'b': *target
= U
'\b'; ++target
; estate
= 0; break;
705 case 'f': *target
= U
'\f'; ++target
; estate
= 0; break;
706 case 'n': *target
= U
'\n'; ++target
; estate
= 0; break;
707 case 'r': *target
= U
'\r'; ++target
; estate
= 0; break;
708 case 't': *target
= U
'\t'; ++target
; estate
= 0; break;
713 throw error(ERR_INVALID_ESCAPE
, PARSE_STRING_ESCAPE
, lc
);
716 case 2: case 3: case 4: case 8: case 9: case 10:
717 extra
= (extra
<< 4) | parse_hex(uch
, PARSE_STRING_ESCAPE
, lc
);
721 extra
= (extra
<< 4) | parse_hex(uch
, PARSE_STRING_ESCAPE
, lc
);
722 if((extra
& 0xFC00) == 0xDC00)
723 throw error(ERR_INVALID_SURROGATE
, PARSE_STRING_ESCAPE
, lc
);
724 else if((extra
& 0xFC00) == 0xD800)
726 else if((extra
& 0xFFFE) == 0xFFFE)
727 throw error(ERR_ILLEGAL_CHARACTER
, PARSE_STRING_ESCAPE
, lc
);
736 throw error(ERR_INVALID_SURROGATE
, PARSE_STRING_ESCAPE
, lc
);
741 throw error(ERR_INVALID_SURROGATE
, PARSE_STRING_ESCAPE
, lc
);
745 extra
= (extra
<< 4) | parse_hex(uch
, PARSE_STRING_ESCAPE
, lc
);
746 if((extra
& 0xFC00FC00UL
) != 0xD800DC00)
747 throw error(ERR_INVALID_SURROGATE
, PARSE_STRING_ESCAPE
, lc
);
748 tmp
= ((extra
& 0x3FF0000) >> 6) + (extra
& 0x3FF) + 0x10000;
749 if((tmp
& 0xFFFE) == 0xFFFE)
750 throw error(ERR_ILLEGAL_CHARACTER
, PARSE_STRING_ESCAPE
, lc
);
757 throw error(ERR_TRUNCATED_STRING
, estate
? PARSE_STRING_ESCAPE
: PARSE_STRING_BODY
, len
);
762 void read_string(std::u32string
& target
, const std::string
& doc
, size_t& ptr
, size_t len
)
765 read_string_impl(iterator_counter(cpcnt
), doc
, ptr
, len
);
766 target
.resize(cpcnt
);
767 ptr
= read_string_impl(target
.begin(), doc
, ptr
, len
) + 1;
770 json_token
parse_token(const std::string
& doc
, size_t& ptr
, size_t len
)
772 while(ptr
< len
&& (doc
[ptr
] == ' ' || doc
[ptr
] == '\t' || doc
[ptr
] == '\r' || doc
[ptr
] == '\n'))
775 return json_token(json_token::TEOF
);
776 if(doc
[ptr
] == '{') {
778 return json_token(json_token::TOBJECT
);
780 if(doc
[ptr
] == '}') {
782 return json_token(json_token::TOBJECT_END
);
784 if(doc
[ptr
] == '[') {
786 return json_token(json_token::TARRAY
);
788 if(doc
[ptr
] == ']') {
790 return json_token(json_token::TARRAY_END
);
792 if(doc
[ptr
] == ',') {
794 return json_token(json_token::TCOMMA
);
796 if(doc
[ptr
] == ':') {
798 return json_token(json_token::TCOLON
);
800 if(doc
[ptr
] == '\"') {
803 return json_token(json_token::TSTRING
);
805 if(doc
[ptr
] == '-' || (doc
[ptr
] >= '0' && doc
[ptr
] <= '9')) {
807 return json_token(json_token::TNUMBER
);
809 if(doc
[ptr
] == 'n') {
810 if(ptr
>= len
|| doc
[ptr
++] != 'n') goto bad
;
811 if(ptr
>= len
|| doc
[ptr
++] != 'u') goto bad
;
812 if(ptr
>= len
|| doc
[ptr
++] != 'l') goto bad
;
813 if(ptr
>= len
|| doc
[ptr
++] != 'l') goto bad
;
814 return json_token(json_token::TNULL
);
816 if(doc
[ptr
] == 'f') {
817 if(ptr
>= len
|| doc
[ptr
++] != 'f') goto bad
;
818 if(ptr
>= len
|| doc
[ptr
++] != 'a') goto bad
;
819 if(ptr
>= len
|| doc
[ptr
++] != 'l') goto bad
;
820 if(ptr
>= len
|| doc
[ptr
++] != 's') goto bad
;
821 if(ptr
>= len
|| doc
[ptr
++] != 'e') goto bad
;
822 return json_token(json_token::TFALSE
);
824 if(doc
[ptr
] == 't') {
825 if(ptr
>= len
|| doc
[ptr
++] != 't') goto bad
;
826 if(ptr
>= len
|| doc
[ptr
++] != 'r') goto bad
;
827 if(ptr
>= len
|| doc
[ptr
++] != 'u') goto bad
;
828 if(ptr
>= len
|| doc
[ptr
++] != 'e') goto bad
;
829 return json_token(json_token::TTRUE
);
832 return json_token(json_token::TINVALID
);
835 std::string
json_string_escape(const std::u32string
& c
)
837 std::ostringstream out
;
839 size_t len
= c
.length();
840 for(size_t i
= 0; i
< len
; i
++) {
841 if(c
[i
] == '\b') out
<< "\\b";
842 else if(c
[i
] == '\n') out
<< "\\n";
843 else if(c
[i
] == '\r') out
<< "\\r";
844 else if(c
[i
] == '\t') out
<< "\\t";
845 else if(c
[i
] == '\f') out
<< "\\f";
846 else if((c
[i
] & 0xFFFFFFE0) == 0)
847 out
<< "\\u" << hex::to16(c
[i
]);
848 else if(c
[i
] == U
'\\')
850 else if(c
[i
] == U
'\"')
853 out
<< (unsigned char)c
[i
];
854 else if(c
[i
] < 0x800) {
855 out
<< (unsigned char)(0xC0 + (c
[i
] >> 6));
856 out
<< (unsigned char)(0x80 + (c
[i
] & 0x3F));
857 } else if(c
[i
] < 0x10000) {
858 out
<< (unsigned char)(0xE0 + (c
[i
] >> 12));
859 out
<< (unsigned char)(0x80 + ((c
[i
] >> 6) & 0x3F));
860 out
<< (unsigned char)(0x80 + (c
[i
] & 0x3F));
861 } else if(c
[i
] < 0x10FFFF) {
862 out
<< (unsigned char)(0xF0 + (c
[i
] >> 18));
863 out
<< (unsigned char)(0x80 + ((c
[i
] >> 12) & 0x3F));
864 out
<< (unsigned char)(0x80 + ((c
[i
] >> 6) & 0x3F));
865 out
<< (unsigned char)(0x80 + (c
[i
] & 0x3F));
872 void skip_ws(const std::string
& doc
, size_t& ptr
, size_t len
) {
873 while(ptr
< len
&& (doc
[ptr
] == ' ' || doc
[ptr
] == '\t' || doc
[ptr
] == '\v' || doc
[ptr
] == '\r' ||
879 std::u32string
pointer_escape_field(const std::u32string
& orig
) throw(std::bad_alloc
)
881 std::basic_stringstream
<char32_t
> x
;
893 std::u32string
pointer_escape_index(uint64_t idx
) throw(std::bad_alloc
)
895 std::string orig
= (stringfmt() << idx
).str();
896 std::basic_ostringstream
<char32_t
> x
;
903 std::string
node::serialize(printer
* _printer
) const throw(std::bad_alloc
, error
)
906 _printer
= _printer
? _printer
: &xprinter
;
907 printer
& oprinter
= *_printer
;
908 std::ostringstream out
;
911 case null_tag::id
: return oprinter
.value_val("null");
912 case boolean_tag::id
: return oprinter
.value_val(_boolean
? "true" : "false");
915 return oprinter
.value_val(out
.str());
917 return oprinter
.value_string(_string
);
919 out
<< oprinter
.array_begin();
920 for(auto& i
: xarray_index
) {
921 if(!first
) out
<< oprinter
.array_separator();
922 out
<< i
->serialize(_printer
);
925 out
<< oprinter
.array_end();
928 out
<< oprinter
.object_begin();
929 for(auto& i
: xobject
) {
930 for(auto& j
: i
.second
) {
931 if(!first
) out
<< oprinter
.object_separator();
932 out
<< oprinter
.object_key(i
.first
);
933 out
<< j
.serialize(_printer
);
937 out
<< oprinter
.object_end();
940 throw error(ERR_UNKNOWN_TYPE
);
943 node::node(const std::string
& doc
) throw(std::bad_alloc
, error
)
946 ctor(doc
, tmp
, doc
.length());
947 skip_ws(doc
, tmp
, doc
.length());
948 if(tmp
< doc
.length())
949 throw error(ERR_GARBAGE_AFTER_END
, PARSE_END_OF_DOCUMENT
, tmp
);
952 void node::ctor(const std::string
& doc
, size_t& ptr
, size_t len
) throw(std::bad_alloc
, error
)
956 json_token t
= parse_token(doc
, ptr
, len
);
960 case json_token::TTRUE
:
963 case json_token::TFALSE
:
966 case json_token::TNULL
:
969 case json_token::TEOF
:
970 throw error(ERR_TRUNCATED_JSON
, PARSE_VALUE_START
, ptr
);
971 case json_token::TCOMMA
:
972 throw error(ERR_UNEXPECTED_COMMA
, PARSE_VALUE_START
, tmp3
);
973 case json_token::TCOLON
:
974 throw error(ERR_UNEXPECTED_COLON
, PARSE_VALUE_START
, tmp3
);
975 case json_token::TARRAY_END
:
976 throw error(ERR_UNEXPECTED_RIGHT_BRACKET
, PARSE_VALUE_START
, tmp3
);
977 case json_token::TOBJECT_END
:
978 throw error(ERR_UNEXPECTED_RIGHT_BRACE
, PARSE_VALUE_START
, tmp3
);
979 case json_token::TSTRING
:
981 read_string(_string
, doc
, ptr
, len
);
983 case json_token::TNUMBER
:
985 _number
= number_holder(doc
, ptr
, len
);
987 case json_token::TOBJECT
:
989 if(parse_token(doc
, tmp
, len
).type
== json_token::TOBJECT_END
) {
995 json_token t2
= parse_token(doc
, ptr
, len
);
996 if(t2
.type
== json_token::TEOF
)
997 throw error(ERR_TRUNCATED_JSON
, PARSE_OBJECT_NAME
, ptr
);
998 if(t2
.type
!= json_token::TSTRING
)
999 throw error(ERR_EXPECTED_STRING_KEY
, PARSE_OBJECT_NAME
, tmp3
);
1001 read_string(key
, doc
, ptr
, len
);
1003 t2
= parse_token(doc
, ptr
, len
);
1004 if(t2
.type
== json_token::TEOF
)
1005 throw error(ERR_TRUNCATED_JSON
, PARSE_OBJECT_COLON
, ptr
);
1006 if(t2
.type
!= json_token::TCOLON
)
1007 throw error(ERR_EXPECTED_COLON
, PARSE_OBJECT_COLON
, tmp3
);
1008 insert(key
, node(doc
, ptr
, len
));
1010 t2
= parse_token(doc
, ptr
, len
);
1011 if(t2
.type
== json_token::TEOF
)
1012 throw error(ERR_TRUNCATED_JSON
, PARSE_OBJECT_AFTER_VALUE
, ptr
);
1013 if(t2
.type
== json_token::TOBJECT_END
)
1015 if(t2
.type
!= json_token::TCOMMA
)
1016 throw error(ERR_EXPECTED_COMMA
, PARSE_OBJECT_AFTER_VALUE
, tmp3
);
1019 case json_token::TARRAY
:
1021 if(parse_token(doc
, tmp
, len
).type
== json_token::TARRAY_END
) {
1026 append(node(doc
, ptr
, len
));
1028 json_token t2
= parse_token(doc
, ptr
, len
);
1029 if(t2
.type
== json_token::TEOF
)
1030 throw error(ERR_TRUNCATED_JSON
, PARSE_ARRAY_AFTER_VALUE
, ptr
);
1031 if(t2
.type
== json_token::TARRAY_END
)
1033 if(t2
.type
!= json_token::TCOMMA
)
1034 throw error(ERR_EXPECTED_COMMA
, PARSE_ARRAY_AFTER_VALUE
, tmp3
);
1037 case json_token::TINVALID
:
1038 throw error(ERR_UNKNOWN_CHARACTER
, PARSE_VALUE_START
, tmp3
);
1042 node::node(const std::string
& doc
, size_t& ptr
, size_t len
) throw(std::bad_alloc
, error
)
1044 ctor(doc
, ptr
, len
);
1047 node
& node::operator[](const std::u32string
& pointer
) throw(std::bad_alloc
, error
)
1049 node
* current
= this;
1051 while(ptr
< pointer
.length()) {
1052 size_t p
= pointer
.find_first_of(U
"/", ptr
);
1053 if(p
> pointer
.length())
1054 p
= pointer
.length();
1055 std::u32string c
= jsonptr_unescape(pointer
, ptr
, p
);
1056 if(current
->vtype
== array
) {
1059 if(p
< pointer
.length())
1060 throw error(ERR_POINTER_BAD_APPEND
);
1061 return current
->append(n());
1064 if(!parse_size_t(c
, idx
))
1065 throw error(ERR_POINTER_BAD_INDEX
);
1066 if(idx
> current
->xarray
.size())
1067 throw error(ERR_POINTER_BAD_APPEND
);
1068 else if(idx
== current
->xarray
.size())
1069 return current
->append(n());
1070 current
= ¤t
->index(idx
);
1071 } else if(current
->vtype
== object
) {
1072 if(!current
->field_exists(c
) && p
== pointer
.length())
1073 return current
->insert(c
, n());
1074 current
= ¤t
->field(c
);
1076 throw error(ERR_NOT_ARRAY_NOR_OBJECT
);
1082 node
& node::insert_node(const std::u32string
& pointer
, const node
& nwn
) throw(std::bad_alloc
, error
)
1084 size_t s
= pointer
.find_last_of(U
"/");
1086 std::u32string rest
;
1087 size_t ptrlen
= pointer
.length();
1089 base
= &follow(pointer
.substr(0, s
));
1090 rest
= jsonptr_unescape(pointer
, s
+ 1, ptrlen
);
1093 rest
= jsonptr_unescape(pointer
, 0, ptrlen
);
1095 if(base
->type() == array
) {
1097 return base
->append(nwn
);
1099 if(!parse_size_t(rest
, idx
))
1100 throw error(ERR_POINTER_BAD_INDEX
);
1101 if(idx
> base
->xarray
.size())
1102 throw error(ERR_POINTER_BAD_APPEND
);
1103 else if(idx
== base
->xarray
.size())
1104 return base
->append(nwn
);
1107 base
->xarray
.push_back(nwn
);
1109 node
* ptr
= &*base
->xarray
.rbegin();
1110 base
->xarray_index
.insert(base
->xarray_index
.begin() + idx
, ptr
);
1112 } catch(std::bad_alloc
& e
) {
1114 base
->xarray
.pop_back();
1117 } else if(base
->type() == object
) {
1118 if(xobject
.count(rest
))
1119 return *base
->xobject
[rest
].begin() = nwn
;
1122 base
->xobject
[rest
].push_back(nwn
);
1123 return *base
->xobject
[rest
].begin();
1125 base
->xobject
.erase(rest
);
1130 throw error(ERR_NOT_ARRAY_NOR_OBJECT
);
1133 node
node::delete_node(const std::u32string
& pointer
) throw(std::bad_alloc
, error
)
1135 size_t s
= pointer
.find_last_of(U
"/");
1137 std::u32string rest
;
1138 size_t ptrlen
= pointer
.length();
1140 base
= &follow(pointer
.substr(0, s
));
1141 rest
= jsonptr_unescape(pointer
, s
+ 1, ptrlen
);
1144 rest
= jsonptr_unescape(pointer
, 0, ptrlen
);
1146 if(base
->type() == array
) {
1148 throw error(ERR_POINTER_BAD_APPEND
);
1150 if(!parse_size_t(rest
, idx
))
1151 throw error(ERR_POINTER_BAD_INDEX
);
1152 if(idx
>= base
->xarray
.size())
1153 throw error(ERR_INDEX_INVALID
);
1154 node
* dptr
= base
->xarray_index
[idx
];
1156 for(auto i
= base
->xarray
.begin(); i
!= base
->xarray
.end(); ++i
)
1158 base
->xarray
.erase(i
);
1161 base
->xarray_index
.erase(base
->xarray_index
.begin() + idx
);
1163 } else if(base
->type() == object
) {
1164 if(xobject
.count(rest
)) {
1165 node tmp
= *base
->xobject
[rest
].begin();
1166 base
->xobject
.erase(rest
);
1169 throw error(ERR_KEY_INVALID
);
1171 throw error(ERR_NOT_ARRAY_NOR_OBJECT
);
1174 node
node::patch(const node
& patch
) const throw(std::bad_alloc
, error
)
1177 if(patch
.type() != array
)
1178 throw error(ERR_PATCH_BAD
);
1179 for(auto& i
: patch
) {
1180 if(i
.type() != object
|| i
.field_count(U
"op") != 1 || i
.field(U
"op").type() != string
)
1181 throw error(ERR_PATCH_BAD
);
1182 std::u32string op
= i
.field(U
"op").as_string();
1184 if(i
.field_count(U
"path") != 1 || i
.field(U
"path").type() != string
)
1185 throw error(ERR_PATCH_BAD
);
1186 if(i
.field_count(U
"value") != 1)
1187 throw error(ERR_PATCH_BAD
);
1188 if(obj
.follow(i
.field(U
"path").as_string()) != i
.field("value"))
1189 throw error(ERR_PATCH_TEST_FAILED
);
1190 } else if(op
== U
"remove") {
1191 if(i
.field_count(U
"path") != 1 || i
.field(U
"path").type() != string
)
1192 throw error(ERR_PATCH_BAD
);
1193 obj
.delete_node(i
.field(U
"path").as_string());
1194 } else if(op
== U
"add") {
1195 if(i
.field_count(U
"path") != 1 || i
.field(U
"path").type() != string
)
1196 throw error(ERR_PATCH_BAD
);
1197 if(i
.field_count(U
"value") != 1)
1198 throw error(ERR_PATCH_BAD
);
1199 obj
.insert_node(i
.field(U
"path").as_string(), i
.field("value"));
1200 } else if(op
== U
"replace") {
1201 if(i
.field_count(U
"path") != 1 || i
.field(U
"path").type() != string
)
1202 throw error(ERR_PATCH_BAD
);
1203 if(i
.field_count(U
"value") != 1)
1204 throw error(ERR_PATCH_BAD
);
1205 obj
.delete_node(i
.field(U
"path").as_string());
1206 obj
.insert_node(i
.field(U
"path").as_string(), i
.field("value"));
1207 } else if(op
== U
"move") {
1208 if(i
.field_count(U
"from") != 1 || i
.field(U
"from").type() != string
)
1209 throw error(ERR_PATCH_BAD
);
1210 if(i
.field_count(U
"path") != 1 || i
.field(U
"path").type() != string
)
1211 throw error(ERR_PATCH_BAD
);
1212 std::u32string from
= i
.field(U
"from").as_string();
1213 std::u32string to
= i
.field(U
"path").as_string();
1214 if(to
.substr(0, from
.length()) == from
) {
1215 if(to
.length() == from
.length())
1217 if(to
.length() > from
.length() && to
[from
.length()] == U
'/')
1218 throw error(ERR_PATCH_ILLEGAL_MOVE
);
1220 node tmp
= obj
.delete_node(from
);
1221 obj
.insert_node(to
, tmp
);
1222 } else if(op
== U
"copy") {
1223 if(i
.field_count(U
"from") != 1 || i
.field(U
"from").type() != string
)
1224 throw error(ERR_PATCH_BAD
);
1225 if(i
.field_count(U
"path") != 1 || i
.field(U
"path").type() != string
)
1226 throw error(ERR_PATCH_BAD
);
1227 const node
& tmp
= obj
.follow(i
.field(U
"from").as_string());
1228 obj
.insert_node(i
.field(U
"path").as_string(), tmp
);
1230 throw error(ERR_PATCH_BAD
);
1236 node::iterator::iterator() throw() { n
= NULL
; }
1238 node::iterator::iterator(node
& _n
) throw(error
)
1242 if(n
->type() == object
) {
1243 if(n
->xobject
.empty())
1246 _key
= n
->xobject
.begin()->first
;
1247 } else if(n
->type() == array
) {
1248 if(n
->xarray
.empty())
1251 throw error(ERR_NOT_ARRAY_NOR_OBJECT
);
1254 std::u32string
node::iterator::key() throw(std::bad_alloc
, error
)
1257 throw error(ERR_ITERATOR_END
);
1258 return (n
->type() == object
) ? _key
: U
"";
1261 size_t node::iterator::index() throw(error
)
1264 throw error(ERR_ITERATOR_END
);
1268 node
& node::iterator::operator*() throw(error
)
1271 throw error(ERR_ITERATOR_END
);
1272 if(n
->type() == object
) {
1273 if(!n
->xobject
.count(_key
))
1274 throw error(ERR_ITERATOR_DELETED
);
1275 auto& l
= n
->xobject
.find(_key
)->second
;
1277 for(auto i
= l
.begin(); i
!= l
.end(); i
++, j
++) {
1281 throw error(ERR_ITERATOR_DELETED
);
1283 if(idx
>= n
->xarray
.size())
1284 throw error(ERR_ITERATOR_DELETED
);
1285 return *n
->xarray_index
[idx
];
1289 node
* node::iterator::operator->() throw(error
)
1294 node::iterator
node::iterator::operator++(int) throw(error
)
1296 iterator tmp
= *this;
1301 node::iterator
& node::iterator::operator++() throw(error
)
1304 throw error(ERR_ITERATOR_END
);
1306 if(n
->type() == object
) {
1307 if(!n
->xobject
.count(_key
) || n
->xobject
.find(_key
)->second
.size() <= idx
) {
1308 auto i
= n
->xobject
.upper_bound(_key
);
1309 if(i
== n
->xobject
.end())
1316 if(idx
>= n
->xarray_index
.size())
1322 bool node::iterator::operator==(const iterator
& i
) throw()
1328 return (n
== i
.n
&& _key
== i
._key
&& idx
== i
.idx
);
1331 bool node::iterator::operator!=(const iterator
& i
) throw() { return !(*this == i
); }
1333 node::const_iterator::const_iterator() throw() { n
= NULL
; }
1335 node::const_iterator::const_iterator(const node
& _n
) throw(error
)
1339 if(n
->type() == object
) {
1340 if(n
->xobject
.empty())
1343 _key
= n
->xobject
.begin()->first
;
1344 } else if(n
->type() == array
) {
1345 if(n
->xarray
.empty())
1348 throw error(ERR_NOT_ARRAY_NOR_OBJECT
);
1351 std::u32string
node::const_iterator::key() throw(std::bad_alloc
, error
)
1354 throw error(ERR_ITERATOR_END
);
1355 return (n
->type() == object
) ? _key
: U
"";
1358 size_t node::const_iterator::index() throw(error
)
1361 throw error(ERR_ITERATOR_END
);
1365 const node
& node::const_iterator::operator*() throw(error
)
1368 throw error(ERR_ITERATOR_END
);
1369 if(n
->type() == object
) {
1370 if(!n
->xobject
.count(_key
))
1371 throw error(ERR_ITERATOR_DELETED
);
1372 auto& l
= n
->xobject
.find(_key
)->second
;
1374 for(auto i
= l
.begin(); i
!= l
.end(); i
++, j
++) {
1378 throw error(ERR_ITERATOR_DELETED
);
1380 if(idx
>= n
->xarray
.size())
1381 throw error(ERR_ITERATOR_DELETED
);
1382 return *n
->xarray_index
[idx
];
1386 const node
* node::const_iterator::operator->() throw(error
)
1391 node::const_iterator
node::const_iterator::operator++(int) throw(error
)
1393 const_iterator tmp
= *this;
1398 node::const_iterator
& node::const_iterator::operator++() throw(error
)
1401 throw error(ERR_ITERATOR_END
);
1403 if(n
->type() == object
) {
1404 if(!n
->xobject
.count(_key
) || n
->xobject
.find(_key
)->second
.size() <= idx
) {
1405 auto i
= n
->xobject
.upper_bound(_key
);
1406 if(i
== n
->xobject
.end())
1413 if(idx
>= n
->xarray_index
.size())
1419 bool node::const_iterator::operator==(const const_iterator
& i
) throw()
1425 return (n
== i
.n
&& _key
== i
._key
&& idx
== i
.idx
);
1428 bool node::const_iterator::operator!=(const const_iterator
& i
) throw() { return !(*this == i
); }
1430 void node::erase_index(size_t idx
) throw(error
)
1432 if(type() == array
) {
1433 if(idx
>= xarray_index
.size())
1435 node
* n
= xarray_index
[idx
];
1436 xarray_index
.erase(xarray_index
.begin() + idx
);
1437 for(auto i
= xarray
.begin(); i
!= xarray
.end(); i
++)
1443 throw error(ERR_NOT_AN_ARRAY
);
1446 void node::erase_field(const std::u32string
& fld
, size_t idx
) throw(error
)
1448 if(type() == object
) {
1449 if(xobject
.count(fld
)) {
1450 auto& l
= xobject
[fld
];
1452 for(auto i
= l
.begin(); i
!= l
.end(); i
++, j
++)
1461 throw error(ERR_NOT_AN_OBJECT
);
1464 void node::erase_field_all(const std::u32string
& fld
) throw(error
)
1466 if(type() == object
) {
1467 if(xobject
.count(fld
))
1470 throw error(ERR_NOT_AN_OBJECT
);
1473 void node::clear() throw(error
)
1475 if(type() == object
)
1477 else if(type() == array
) {
1478 xarray_index
.clear();
1481 throw error(ERR_NOT_ARRAY_NOR_OBJECT
);
1484 node::iterator
node::erase(node::iterator itr
) throw(error
)
1487 throw error(ERR_WRONG_OBJECT
);
1488 if(type() == object
) {
1489 erase_field(itr
._key
, itr
.idx
);
1490 if(!xobject
.count(itr
._key
) || itr
.idx
>= xobject
[itr
._key
].size())
1493 } else if(type() == array
) {
1494 erase_index(itr
.idx
);
1495 if(itr
.idx
>= xarray_index
.size())
1499 throw error(ERR_NOT_ARRAY_NOR_OBJECT
);
1502 void node::fixup_nodes(const node
& _node
)
1504 auto i
= xarray
.begin();
1505 auto j
= _node
.xarray
.begin();
1506 for(; i
!= xarray
.end(); i
++, j
++) {
1507 for(size_t k
= 0; k
< _node
.xarray_index
.size(); k
++)
1508 if(_node
.xarray_index
[k
] == &*j
)
1509 xarray_index
[k
] = &*i
;
1513 bool node::operator==(const node
& n
) const
1517 if(vtype
!= n
.vtype
)
1522 case boolean_tag::id
:
1523 return (_boolean
== n
._boolean
);
1524 case number_tag::id
:
1525 return (_number
== n
._number
);
1526 case string_tag::id
:
1527 return (_string
== n
._string
);
1529 if(xarray_index
.size() != n
.xarray_index
.size())
1531 for(size_t i
= 0; i
< xarray_index
.size(); i
++)
1532 if(*xarray_index
[i
] != *n
.xarray_index
[i
])
1535 case object_tag::id
:
1536 for(auto& i
: xobject
)
1537 if(!n
.xobject
.count(i
.first
))
1539 for(auto& i
: n
.xobject
)
1540 if(!xobject
.count(i
.first
))
1542 for(auto& i
: xobject
) {
1543 auto& j
= *xobject
.find(i
.first
);
1544 auto& k
= *n
.xobject
.find(i
.first
);
1545 if(j
.second
.size() != k
.second
.size())
1547 auto j2
= j
.second
.begin();
1548 auto k2
= k
.second
.begin();
1549 for(; j2
!= j
.second
.end(); j2
++, k2
++)
1555 throw error(ERR_UNKNOWN_TYPE
);
1559 int node::type_of(const std::u32string
& pointer
) const throw(std::bad_alloc
)
1563 if(follow_soft(pointer
, n
) != ERR_OK
)
1566 } catch(std::bad_alloc
& e
) {
1568 } catch(std::exception
& e
) {
1574 int node::type_of_indirect(const std::u32string
& pointer
) const throw(std::bad_alloc
)
1578 if(follow_soft(pointer
, n
) != ERR_OK
)
1580 if(n
->type() == string
)
1581 return type_of(n
->as_string());
1584 } catch(std::bad_alloc
& e
) {
1586 } catch(std::exception
& e
) {
1592 std::u32string
node::resolve_indirect(const std::u32string
& pointer
) const throw(std::bad_alloc
)
1595 const node
& n
= follow(pointer
);
1596 if(n
.type() == string
)
1597 return n
.as_string();
1600 } catch(std::bad_alloc
& e
) {
1602 } catch(std::exception
& e
) {
1611 pointer::pointer(const std::string
& ptr
) throw(std::bad_alloc
)
1613 _pointer
= utf8::to32(ptr
);
1616 pointer::pointer(const std::u32string
& ptr
) throw(std::bad_alloc
)
1621 pointer
pointer::index(uint64_t idx
) const throw(std::bad_alloc
)
1623 if(_pointer
.length())
1624 return pointer(_pointer
+ U
"/" + pointer_escape_index(idx
));
1626 return pointer(pointer_escape_index(idx
));
1629 pointer
& pointer::index_inplace(uint64_t idx
) throw(std::bad_alloc
)
1631 if(_pointer
.length())
1632 _pointer
= _pointer
+ U
"/" + pointer_escape_index(idx
);
1634 _pointer
= pointer_escape_index(idx
);
1638 pointer
pointer::field(const std::u32string
& fld
) const throw(std::bad_alloc
)
1640 if(_pointer
.length())
1641 return pointer(_pointer
+ U
"/" + pointer_escape_field(fld
));
1643 return pointer(pointer_escape_field(fld
));
1646 pointer
& pointer::field_inplace(const std::u32string
& fld
) throw(std::bad_alloc
)
1648 if(_pointer
.length())
1649 _pointer
= _pointer
+ U
"/" + pointer_escape_field(fld
);
1651 _pointer
= pointer_escape_field(fld
);
1655 pointer
pointer::remove() const throw(std::bad_alloc
)
1657 size_t p
= _pointer
.find_last_of(U
"/");
1658 if(p
>= _pointer
.length())
1661 return pointer(_pointer
.substr(0, p
));
1664 pointer
& pointer::remove_inplace() throw(std::bad_alloc
)
1666 size_t p
= _pointer
.find_last_of(U
"/");
1667 if(p
>= _pointer
.length())
1670 _pointer
= _pointer
.substr(0, p
);
1674 std::ostream
& operator<<(std::ostream
& s
, const pointer
& p
)
1676 return s
<< utf8::to8(p
._pointer
);
1679 std::basic_ostream
<char32_t
>& operator<<(std::basic_ostream
<char32_t
>& s
, const pointer
& p
)
1681 return s
<< p
._pointer
;
1684 printer::~printer() throw()
1688 std::string
printer::value_val(const std::string
& val
)
1693 std::string
printer::value_string(const std::u32string
& s
)
1695 return json_string_escape(s
);
1698 std::string
printer::array_begin()
1703 std::string
printer::array_separator()
1708 std::string
printer::array_end()
1713 std::string
printer::object_begin()
1718 std::string
printer::object_key(const std::u32string
& s
)
1720 return json_string_escape(s
) + ":";
1723 std::string
printer::object_separator()
1728 std::string
printer::object_end()
1733 printer_indenting::printer_indenting()
1739 printer_indenting::~printer_indenting() throw()
1743 std::string
printer_indenting::linestart(size_t _depth
)
1745 std::ostringstream s
;
1747 for(size_t i
= 0; i
< _depth
; i
++)
1752 std::string
printer_indenting::value_val(const std::string
& val
)
1760 //According to JSON rules, value is not allowed immediately after end of array/object, so
1761 //states S_END and S_START_END really have comma right before.
1763 return linestart(depth
) + val
;
1767 std::string
printer_indenting::value_string(const std::u32string
& s
)
1770 return json_string_escape(s
) + "\n";
1773 return json_string_escape(s
);
1775 //According to JSON rules, value is not allowed immediately after end of array/object, so
1776 //states S_END and S_START_END really have comma right before.
1778 return linestart(depth
) + json_string_escape(s
);
1782 std::string
printer_indenting::array_begin()
1786 //This can only happen in beginning of expression or after key.
1791 //This is really after ], or },
1798 //S_START_END really has comma right before due to JSON rules.
1800 return linestart(depth
++) + "[";
1804 std::string
printer_indenting::array_separator()
1809 //These states don't transition to comma.
1817 std::string
printer_indenting::array_end()
1824 //S_END or S_START_END is after ']' or '}'.
1825 //S_COMMA can't actually happen per JSON rules.
1828 return linestart(depth
) + "]" + (depth
? "" : "\n");
1830 state
= S_START_END
;
1832 return std::string("]") + (depth
? "" : "\n");
1836 std::string
printer_indenting::object_begin()
1840 //This can only happen in beginning of expression or after key.
1845 //This is really ], or },
1852 //S_START_END really has comma right before due to JSON rules.
1854 return linestart(depth
++) + "{";
1858 std::string
printer_indenting::object_key(const std::u32string
& s
)
1866 return linestart(depth
) + json_string_escape(s
) + ":";
1868 //Can't actually happe
1870 return json_string_escape(s
) + ":";
1874 std::string
printer_indenting::object_separator()
1879 //These states don't transition to comma.
1887 std::string
printer_indenting::object_end()
1894 //S_END or S_START_END is after ']' or '}'.
1895 //S_COMMA can't actually happen per JSON rules.
1898 return linestart(depth
) + "}" + (depth
? "" : "\n");
1900 state
= S_START_END
;
1908 bool operator==(const int& n
, const JSON::number_tag
& v
) { return v
== n
; }
1909 bool operator==(const int& n
, const JSON::string_tag
& v
) { return v
== n
; }
1910 bool operator==(const int& n
, const JSON::boolean_tag
& v
) { return v
== n
; }
1911 bool operator==(const int& n
, const JSON::array_tag
& v
) { return v
== n
; }
1912 bool operator==(const int& n
, const JSON::object_tag
& v
) { return v
== n
; }
1913 bool operator==(const int& n
, const JSON::null_tag
& v
) { return v
== n
; }
1914 bool operator!=(const int& n
, const JSON::number_tag
& v
) { return v
!= n
; }
1915 bool operator!=(const int& n
, const JSON::string_tag
& v
) { return v
!= n
; }
1916 bool operator!=(const int& n
, const JSON::boolean_tag
& v
) { return v
!= n
; }
1917 bool operator!=(const int& n
, const JSON::array_tag
& v
) { return v
!= n
; }
1918 bool operator!=(const int& n
, const JSON::object_tag
& v
) { return v
!= n
; }
1919 bool operator!=(const int& n
, const JSON::null_tag
& v
) { return v
!= n
; }