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
];
109 sprintf(buffer
, "%s (while expecting %s) at byte %u", error_desc
[code
], state_desc
[state
],
115 std::string
error::extended_error(const std::string
& doc
)
117 if(state
== PARSE_NOT_PARSING
)
118 return error_desc
[code
];
119 std::ostringstream s
;
120 size_t pos
= position
;
121 while(pos
< doc
.length() && (doc
[pos
] == '\t' || doc
[pos
] == '\v' || doc
[pos
] == '\r' || doc
[pos
] == '\n' ||
124 auto p2
= get_position_lc(doc
, pos
);
125 s
<< error_desc
[code
] << " (while expecting " << state_desc
[state
] << ") at ";
126 if(position
== doc
.length())
129 std::ostringstream sample
;
131 for(size_t i
= 0; i
< 32; i
++) {
132 if(p
>= doc
.length())
135 sample
<< "<" << asciinames
[(unsigned char)doc
[p
++]] << ">";
136 } else if(doc
[p
] < 127)
138 else if(doc
[p
] < 128)
140 else if(doc
[p
] < 192)
141 sample
<< "<" << (int)doc
[p
++] << ">";
142 else if(doc
[p
] < 224) {
145 } else if(doc
[p
] < 240) {
149 } else if(doc
[p
] < 248) {
155 sample
<< "<" << (int)doc
[p
++] << ">";
157 s
<< "line " << p2
.first
<< " byte " << p2
.second
<< " [near: '" << sample
.str() << "']";
162 node
number_tag::operator()(double v
) const { return node(*this, v
); }
163 node
number_tag::operator()(uint64_t v
) const { return node(*this, v
); }
164 node
number_tag::operator()(int64_t v
) const { return node(*this, v
); }
165 node
string_tag::operator()(const std::string
& s
) const { return node(*this, s
); }
166 node
string_tag::operator()(const std::u32string
& s
) const { return node(*this, s
); }
167 node
boolean_tag::operator()(bool v
) { return node(*this, v
); }
168 node
array_tag::operator()() const { return node(*this); }
169 node
object_tag::operator()() const { return node(*this); }
170 node
null_tag::operator()() const { return node(*this); }
172 node
i(int64_t n
) { return number(n
); }
173 node
u(uint64_t n
) { return number(n
); }
174 node
f(double n
) { return number(n
); }
175 node
b(bool bl
) { return boolean(bl
); }
176 node
s(const std::string
& st
) { return string(st
); }
177 node
s(const std::u32string
& st
) { return string(st
); }
178 node
n() { return null(); }
188 template<> void node::number_holder::from(double val
) { sub
= 0; n
.n0
= val
; }
189 template<> void node::number_holder::from(uint64_t val
) { sub
= 1; n
.n1
= val
; }
190 template<> void node::number_holder::from(int64_t val
) { sub
= 2; n
.n2
= val
; }
194 unsigned numchar(char c
)
198 case '1': case '2': case '3': case '4': case '5':
199 case '6': case '7': case '8': case '9': return 1;
208 uint32_t numdfa
[] = {
209 0x0F1FFF32, //0: STATE_INITIAL
210 0x0FFFFF32, //1: STATE_AFTER_MINUS
211 0x1FFF64FF, //2: STATE_INT_Z
212 0x1FFF6433, //3: STATE_INT_NZ
213 0x0FFFFF55, //4: STATE_DECIMAL
214 0x1FFF6F55, //5: STATE_DECIMAL_N
215 0x0F77FF88, //6: STATE_EXP
216 0x0FFFFF88, //7: STATE_EXP_SIGN
217 0x1FFFFF88, //8: STATE_EXP_N
221 node::number_holder::number_holder(const std::string
& expr
, size_t& ptr
, size_t len
)
223 //-?(0|1-9[0-9]+)(.[0-9]+)?([eE][+-]?[0-9]+)?
229 unsigned c
= numchar(expr
[tmp
]);
230 unsigned ns
= (numdfa
[state
] >> (4 * c
)) & 0xF;
237 if(!(numdfa
[state
] >> 28))
239 x
= expr
.substr(ptr
, tmp
- ptr
);
242 if(regex_match("[0-9]+", x
)) {
243 n
.n1
= parse_value
<uint64_t>(x
);
249 if(regex_match("[+-]?[0-9]+", x
)) {
250 n
.n2
= parse_value
<int64_t>(x
);
256 n
.n0
= parse_value
<double>(x
);
261 throw error(ERR_INVALID_NUMBER
, PARSE_NUMBER
, tmp2
);
265 void node::number_holder::write(std::ostream
& s
) const
268 case 0: s
<< n
.n0
; break;
269 case 1: s
<< n
.n1
; break;
270 case 2: s
<< n
.n2
; break;
274 template<typename T
> bool node::number_holder::cmp(const T
& num
) const
277 case 0: return n
.n0
== num
;
278 case 1: return n
.n1
== num
;
279 case 2: return n
.n2
== num
;
281 throw error(ERR_UNKNOWN_SUBTYPE
);
284 template<> bool node::number_holder::cmp(const int64_t& num
) const
287 case 0: return n
.n0
== num
;
288 case 1: return num
>= 0 && n
.n1
== static_cast<uint64_t>(num
);
289 case 2: return n
.n2
== num
;
291 throw error(ERR_UNKNOWN_SUBTYPE
);
294 template<> bool node::number_holder::cmp(const uint64_t& num
) const
297 case 0: return n
.n0
== num
;
298 case 1: return n
.n1
== num
;
299 case 2: return n
.n2
>= 0 && static_cast<uint64_t>(n
.n2
) == num
;
301 throw error(ERR_UNKNOWN_SUBTYPE
);
305 bool node::number_holder::operator==(const number_holder
& h
) const
308 case 0: return h
.cmp(n
.n0
);
309 case 1: return h
.cmp(n
.n1
);
310 case 2: return h
.cmp(n
.n2
);
312 throw error(ERR_UNKNOWN_SUBTYPE
);
315 node::node() throw() : node(null
) {}
316 node::node(null_tag
) throw() { vtype
= null
; }
317 node::node(boolean_tag
, bool b
) throw() { vtype
= boolean
; _boolean
= b
; }
318 node::node(string_tag
, const std::u32string
& str
) throw(std::bad_alloc
) { vtype
= string
; _string
= str
; }
319 node::node(string_tag
, const std::string
& str
) throw(std::bad_alloc
) { vtype
= string
; _string
= utf8::to32(str
); }
320 node::node(number_tag
, double n
) throw() { vtype
= number
; _number
.from
<double>(n
); }
321 node::node(number_tag
, int64_t n
) throw() { vtype
= number
; _number
.from
<int64_t>(n
); }
322 node::node(number_tag
, uint64_t n
) throw() { vtype
= number
; _number
.from
<uint64_t>(n
); }
323 node::node(array_tag
) throw() { vtype
= array
; }
324 node::node(object_tag
) throw() { vtype
= object
; }
325 int node::type() const throw() { return vtype
; }
327 node
& node::set(null_tag
) throw() { set_helper
<uint64_t>(0); vtype
= null
; return *this; }
328 node
& node::set(boolean_tag
, bool n
) throw() { set_helper
<uint64_t>(0); vtype
= boolean
; _boolean
= n
; return *this; }
329 node
& node::set(number_tag
, double n
) throw() { set_helper
<double>(n
); return *this; }
330 node
& node::set(number_tag
, int64_t n
) throw() { set_helper
<int64_t>(n
); return *this; }
331 node
& node::set(number_tag
, uint64_t n
) throw() { set_helper
<int64_t>(n
); return *this; }
333 node
& node::set(string_tag
, const std::u32string
& key
) throw(std::bad_alloc
)
335 std::u32string tmp
= key
;
336 std::swap(_string
, tmp
);
343 double node::as_double() const throw(error
)
345 return get_number_helper
<double>();
348 int64_t node::as_int() const throw(error
)
350 return get_number_helper
<int64_t>();
353 uint64_t node::as_uint() const throw(error
)
355 return get_number_helper
<uint64_t>();
358 const std::u32string
& node::as_string() const throw(std::bad_alloc
, error
)
361 throw error(ERR_NOT_A_STRING
);
365 bool node::as_bool() const throw(error
)
368 throw error(ERR_NOT_A_BOOLEAN
);
372 size_t node::index_count() const throw(error
)
375 throw error(ERR_NOT_AN_ARRAY
);
376 return xarray
.size();
379 errorcode
node::index_soft(size_t index
, const node
*& out
) const throw()
382 return ERR_NOT_AN_ARRAY
;
383 if(index
>= xarray_index
.size())
384 return ERR_INDEX_INVALID
;
385 out
= xarray_index
[index
];
389 errorcode
node::index_soft(size_t index
, node
*& out
) throw()
392 return ERR_NOT_AN_ARRAY
;
393 if(index
>= xarray_index
.size())
394 return ERR_INDEX_INVALID
;
395 out
= xarray_index
[index
];
399 size_t node::field_count(const std::u32string
& key
) const throw(error
)
402 throw error(ERR_NOT_AN_OBJECT
);
403 if(!xobject
.count(key
))
405 return xobject
.find(key
)->second
.size();
408 bool node::field_exists(const std::u32string
& key
) const throw(error
)
410 return (field_count(key
) > 0);
413 errorcode
node::field_soft(const std::u32string
& key
, size_t subindex
, const node
*& out
) const throw()
416 return ERR_NOT_AN_OBJECT
;
417 if(!xobject
.count(key
))
418 return ERR_KEY_INVALID
;
419 const std::list
<node
>& l
= xobject
.find(key
)->second
;
421 for(auto i
= l
.begin(); i
!= l
.end(); i
++, j
++) {
427 return ERR_INSTANCE_INVALID
;
430 errorcode
node::field_soft(const std::u32string
& key
, size_t subindex
, node
*& out
) throw()
433 return ERR_NOT_AN_OBJECT
;
434 if(!xobject
.count(key
))
435 return ERR_KEY_INVALID
;
436 std::list
<node
>& l
= xobject
.find(key
)->second
;
438 for(auto i
= l
.begin(); i
!= l
.end(); i
++, j
++) {
444 return ERR_INSTANCE_INVALID
;
447 node::node(const node
& _node
) throw(std::bad_alloc
)
449 std::u32string tmp1
= _node
._string
;
450 std::list
<node
> tmp2
= _node
.xarray
;
451 std::map
<std::u32string
, std::list
<node
>> tmp3
= _node
.xobject
;
452 std::vector
<node
*> tmp4
= _node
.xarray_index
;
455 _number
= _node
._number
;
456 _boolean
= _node
._boolean
;
457 _string
= _node
._string
;
458 xarray
= _node
.xarray
;
459 xobject
= _node
.xobject
;
460 xarray_index
= _node
.xarray_index
;
464 node
& node::operator=(const node
& _node
) throw(std::bad_alloc
)
468 std::u32string tmp1
= _node
._string
;
469 std::list
<node
> tmp2
= _node
.xarray
;
470 std::map
<std::u32string
, std::list
<node
>> tmp3
= _node
.xobject
;
471 std::vector
<node
*> tmp4
= _node
.xarray_index
;
474 _number
= _node
._number
;
475 _boolean
= _node
._boolean
;
476 std::swap(_string
, tmp1
);
477 std::swap(xarray
, tmp2
);
478 std::swap(xobject
, tmp3
);
479 std::swap(xarray_index
, tmp4
);
484 node
& node::append(const node
& _node
) throw(std::bad_alloc
, error
)
487 throw error(ERR_NOT_AN_ARRAY
);
490 xarray
.push_back(_node
);
492 node
* ptr
= &*xarray
.rbegin();
493 xarray_index
.push_back(ptr
);
495 } catch(std::bad_alloc
& e
) {
502 node
& node::insert(const std::u32string
& key
, const node
& _node
) throw(std::bad_alloc
, error
)
505 throw error(ERR_NOT_AN_OBJECT
);
507 xobject
[key
].push_back(_node
);
508 return *xobject
[key
].rbegin();
510 if(xobject
.count(key
) && xobject
[key
].empty())
518 errorcode
jsonptr_unescape_soft(const std::u32string
& c
, size_t start
, size_t end
, std::u32string
& _out
)
520 std::basic_ostringstream
<char32_t
> out
;
521 for(size_t ptr
= start
; ptr
< end
; ptr
++) {
524 return ERR_POINTER_TRAILING_ESCAPE
;
528 else if(c
[ptr
] == '1')
531 return ERR_POINTER_INVALID_ESCAPE
;
539 std::u32string
jsonptr_unescape(const std::u32string
& c
, size_t start
, size_t end
)
542 auto e
= jsonptr_unescape_soft(c
, start
, end
, o
);
543 if(e
!= ERR_OK
) throw error(e
);
549 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
)
582 while(ptr
< pointer
.length()) {
583 size_t p
= pointer
.find_first_of(U
"/", ptr
);
584 if(p
> pointer
.length())
585 p
= pointer
.length();
587 auto e
= jsonptr_unescape_soft(pointer
, ptr
, p
, c
);
588 if(e
!= ERR_OK
) return e
;
589 if(current
->vtype
== array
) {
591 return ERR_POINTER_BAD_APPEND
;
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
;
601 return ERR_NOT_ARRAY_NOR_OBJECT
;
611 enum ttype
{ TSTRING
, TNUMBER
, TOBJECT
, TARRAY
, TINVALID
, TCOMMA
, TOBJECT_END
, TARRAY_END
, TCOLON
,
612 TEOF
, TTRUE
, TFALSE
, TNULL
};
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
)
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
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
; }
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
;
675 for(i
= ptr
; i
<= len
; i
++) {
678 ch
= (unsigned char)doc
[i
];
679 int32_t uch
= utf8::parse_byte(ch
, ustate
);
682 //Okay, have Unicode codepoint decoded.
688 throw error(ERR_CONTROL_CHARACTER
, PARSE_STRING_BODY
, lc
);
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;
712 throw error(ERR_INVALID_ESCAPE
, PARSE_STRING_ESCAPE
, lc
);
715 case 2: case 3: case 4: case 8: case 9: case 10:
716 extra
= (extra
<< 4) | parse_hex(uch
, PARSE_STRING_ESCAPE
, lc
);
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)
725 else if((extra
& 0xFFFE) == 0xFFFE)
726 throw error(ERR_ILLEGAL_CHARACTER
, PARSE_STRING_ESCAPE
, lc
);
735 throw error(ERR_INVALID_SURROGATE
, PARSE_STRING_ESCAPE
, lc
);
740 throw error(ERR_INVALID_SURROGATE
, PARSE_STRING_ESCAPE
, lc
);
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
);
756 throw error(ERR_TRUNCATED_STRING
, estate
? PARSE_STRING_ESCAPE
: PARSE_STRING_BODY
, len
);
761 void read_string(std::u32string
& target
, const std::string
& doc
, size_t& ptr
, size_t len
)
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'))
774 return json_token(json_token::TEOF
);
775 if(doc
[ptr
] == '{') {
777 return json_token(json_token::TOBJECT
);
779 if(doc
[ptr
] == '}') {
781 return json_token(json_token::TOBJECT_END
);
783 if(doc
[ptr
] == '[') {
785 return json_token(json_token::TARRAY
);
787 if(doc
[ptr
] == ']') {
789 return json_token(json_token::TARRAY_END
);
791 if(doc
[ptr
] == ',') {
793 return json_token(json_token::TCOMMA
);
795 if(doc
[ptr
] == ':') {
797 return json_token(json_token::TCOLON
);
799 if(doc
[ptr
] == '\"') {
802 return json_token(json_token::TSTRING
);
804 if(doc
[ptr
] == '-' || (doc
[ptr
] >= '0' && doc
[ptr
] <= '9')) {
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
);
831 return json_token(json_token::TINVALID
);
834 std::string
json_string_escape(const std::u32string
& c
)
836 std::ostringstream out
;
838 size_t len
= c
.length();
839 for(size_t i
= 0; i
< len
; i
++) {
840 if(c
[i
] == '\b') out
<< "\\b";
841 else if(c
[i
] == '\n') out
<< "\\n";
842 else if(c
[i
] == '\r') out
<< "\\r";
843 else if(c
[i
] == '\t') out
<< "\\t";
844 else if(c
[i
] == '\f') out
<< "\\f";
845 else if((c
[i
] & 0xFFFFFFE0) == 0)
846 out
<< "\\u" << hex::to16(c
[i
]);
847 else if(c
[i
] == U
'\\')
849 else if(c
[i
] == U
'\"')
852 out
<< (unsigned char)c
[i
];
853 else if(c
[i
] < 0x800) {
854 out
<< (unsigned char)(0xC0 + (c
[i
] >> 6));
855 out
<< (unsigned char)(0x80 + (c
[i
] & 0x3F));
856 } else if(c
[i
] < 0x10000) {
857 out
<< (unsigned char)(0xE0 + (c
[i
] >> 12));
858 out
<< (unsigned char)(0x80 + ((c
[i
] >> 6) & 0x3F));
859 out
<< (unsigned char)(0x80 + (c
[i
] & 0x3F));
860 } else if(c
[i
] < 0x10FFFF) {
861 out
<< (unsigned char)(0xF0 + (c
[i
] >> 18));
862 out
<< (unsigned char)(0x80 + ((c
[i
] >> 12) & 0x3F));
863 out
<< (unsigned char)(0x80 + ((c
[i
] >> 6) & 0x3F));
864 out
<< (unsigned char)(0x80 + (c
[i
] & 0x3F));
871 void skip_ws(const std::string
& doc
, size_t& ptr
, size_t len
) {
872 while(ptr
< len
&& (doc
[ptr
] == ' ' || doc
[ptr
] == '\t' || doc
[ptr
] == '\v' || doc
[ptr
] == '\r' ||
878 std::u32string
pointer_escape_field(const std::u32string
& orig
) throw(std::bad_alloc
)
880 std::basic_stringstream
<char32_t
> x
;
892 std::u32string
pointer_escape_index(uint64_t idx
) throw(std::bad_alloc
)
894 std::string orig
= (stringfmt() << idx
).str();
895 std::basic_ostringstream
<char32_t
> x
;
902 std::string
node::serialize(printer
* _printer
) const throw(std::bad_alloc
, error
)
905 _printer
= _printer
? _printer
: &xprinter
;
906 printer
& oprinter
= *_printer
;
907 std::ostringstream out
;
910 case null_tag::id
: return oprinter
.value_val("null");
911 case boolean_tag::id
: return oprinter
.value_val(_boolean
? "true" : "false");
914 return oprinter
.value_val(out
.str());
916 return oprinter
.value_string(_string
);
918 out
<< oprinter
.array_begin();
919 for(auto& i
: xarray_index
) {
920 if(!first
) out
<< oprinter
.array_separator();
921 out
<< i
->serialize(_printer
);
924 out
<< oprinter
.array_end();
927 out
<< oprinter
.object_begin();
928 for(auto& i
: xobject
) {
929 for(auto& j
: i
.second
) {
930 if(!first
) out
<< oprinter
.object_separator();
931 out
<< oprinter
.object_key(i
.first
);
932 out
<< j
.serialize(_printer
);
936 out
<< oprinter
.object_end();
939 throw error(ERR_UNKNOWN_TYPE
);
942 node::node(const std::string
& doc
) throw(std::bad_alloc
, error
)
945 ctor(doc
, tmp
, doc
.length());
946 skip_ws(doc
, tmp
, doc
.length());
947 if(tmp
< doc
.length())
948 throw error(ERR_GARBAGE_AFTER_END
, PARSE_END_OF_DOCUMENT
, tmp
);
951 void node::ctor(const std::string
& doc
, size_t& ptr
, size_t len
) throw(std::bad_alloc
, error
)
955 json_token t
= parse_token(doc
, ptr
, len
);
959 case json_token::TTRUE
:
962 case json_token::TFALSE
:
965 case json_token::TNULL
:
968 case json_token::TEOF
:
969 throw error(ERR_TRUNCATED_JSON
, PARSE_VALUE_START
, ptr
);
970 case json_token::TCOMMA
:
971 throw error(ERR_UNEXPECTED_COMMA
, PARSE_VALUE_START
, tmp3
);
972 case json_token::TCOLON
:
973 throw error(ERR_UNEXPECTED_COLON
, PARSE_VALUE_START
, tmp3
);
974 case json_token::TARRAY_END
:
975 throw error(ERR_UNEXPECTED_RIGHT_BRACKET
, PARSE_VALUE_START
, tmp3
);
976 case json_token::TOBJECT_END
:
977 throw error(ERR_UNEXPECTED_RIGHT_BRACE
, PARSE_VALUE_START
, tmp3
);
978 case json_token::TSTRING
:
980 read_string(_string
, doc
, ptr
, len
);
982 case json_token::TNUMBER
:
984 _number
= number_holder(doc
, ptr
, len
);
986 case json_token::TOBJECT
:
988 if(parse_token(doc
, tmp
, len
).type
== json_token::TOBJECT_END
) {
994 json_token t2
= parse_token(doc
, ptr
, len
);
995 if(t2
.type
== json_token::TEOF
)
996 throw error(ERR_TRUNCATED_JSON
, PARSE_OBJECT_NAME
, ptr
);
997 if(t2
.type
!= json_token::TSTRING
)
998 throw error(ERR_EXPECTED_STRING_KEY
, PARSE_OBJECT_NAME
, tmp3
);
1000 read_string(key
, doc
, ptr
, len
);
1002 t2
= parse_token(doc
, ptr
, len
);
1003 if(t2
.type
== json_token::TEOF
)
1004 throw error(ERR_TRUNCATED_JSON
, PARSE_OBJECT_COLON
, ptr
);
1005 if(t2
.type
!= json_token::TCOLON
)
1006 throw error(ERR_EXPECTED_COLON
, PARSE_OBJECT_COLON
, tmp3
);
1007 insert(key
, node(doc
, ptr
, len
));
1009 t2
= parse_token(doc
, ptr
, len
);
1010 if(t2
.type
== json_token::TEOF
)
1011 throw error(ERR_TRUNCATED_JSON
, PARSE_OBJECT_AFTER_VALUE
, ptr
);
1012 if(t2
.type
== json_token::TOBJECT_END
)
1014 if(t2
.type
!= json_token::TCOMMA
)
1015 throw error(ERR_EXPECTED_COMMA
, PARSE_OBJECT_AFTER_VALUE
, tmp3
);
1018 case json_token::TARRAY
:
1020 if(parse_token(doc
, tmp
, len
).type
== json_token::TARRAY_END
) {
1025 append(node(doc
, ptr
, len
));
1027 json_token t2
= parse_token(doc
, ptr
, len
);
1028 if(t2
.type
== json_token::TEOF
)
1029 throw error(ERR_TRUNCATED_JSON
, PARSE_ARRAY_AFTER_VALUE
, ptr
);
1030 if(t2
.type
== json_token::TARRAY_END
)
1032 if(t2
.type
!= json_token::TCOMMA
)
1033 throw error(ERR_EXPECTED_COMMA
, PARSE_ARRAY_AFTER_VALUE
, tmp3
);
1036 case json_token::TINVALID
:
1037 throw error(ERR_UNKNOWN_CHARACTER
, PARSE_VALUE_START
, tmp3
);
1041 node::node(const std::string
& doc
, size_t& ptr
, size_t len
) throw(std::bad_alloc
, error
)
1043 ctor(doc
, ptr
, len
);
1046 node
& node::operator[](const std::u32string
& pointer
) throw(std::bad_alloc
, error
)
1048 node
* current
= this;
1050 while(ptr
< pointer
.length()) {
1051 size_t p
= pointer
.find_first_of(U
"/", ptr
);
1052 if(p
> pointer
.length())
1053 p
= pointer
.length();
1054 std::u32string c
= jsonptr_unescape(pointer
, ptr
, p
);
1055 if(current
->vtype
== array
) {
1058 if(p
< pointer
.length())
1059 throw error(ERR_POINTER_BAD_APPEND
);
1060 return current
->append(n());
1063 if(!parse_size_t(c
, idx
))
1064 throw error(ERR_POINTER_BAD_INDEX
);
1065 if(idx
> current
->xarray
.size())
1066 throw error(ERR_POINTER_BAD_APPEND
);
1067 else if(idx
== current
->xarray
.size())
1068 return current
->append(n());
1069 current
= ¤t
->index(idx
);
1070 } else if(current
->vtype
== object
) {
1071 if(!current
->field_exists(c
) && p
== pointer
.length())
1072 return current
->insert(c
, n());
1073 current
= ¤t
->field(c
);
1075 throw error(ERR_NOT_ARRAY_NOR_OBJECT
);
1081 node
& node::insert_node(const std::u32string
& pointer
, const node
& nwn
) throw(std::bad_alloc
, error
)
1083 size_t s
= pointer
.find_last_of(U
"/");
1085 std::u32string rest
;
1086 size_t ptrlen
= pointer
.length();
1088 base
= &follow(pointer
.substr(0, s
));
1089 rest
= jsonptr_unescape(pointer
, s
+ 1, ptrlen
);
1092 rest
= jsonptr_unescape(pointer
, 0, ptrlen
);
1094 if(base
->type() == array
) {
1096 return base
->append(nwn
);
1098 if(!parse_size_t(rest
, idx
))
1099 throw error(ERR_POINTER_BAD_INDEX
);
1100 if(idx
> base
->xarray
.size())
1101 throw error(ERR_POINTER_BAD_APPEND
);
1102 else if(idx
== base
->xarray
.size())
1103 return base
->append(nwn
);
1106 base
->xarray
.push_back(nwn
);
1108 node
* ptr
= &*base
->xarray
.rbegin();
1109 base
->xarray_index
.insert(base
->xarray_index
.begin() + idx
, ptr
);
1111 } catch(std::bad_alloc
& e
) {
1113 base
->xarray
.pop_back();
1116 } else if(base
->type() == object
) {
1117 if(xobject
.count(rest
))
1118 return *base
->xobject
[rest
].begin() = nwn
;
1121 base
->xobject
[rest
].push_back(nwn
);
1122 return *base
->xobject
[rest
].begin();
1124 base
->xobject
.erase(rest
);
1129 throw error(ERR_NOT_ARRAY_NOR_OBJECT
);
1132 node
node::delete_node(const std::u32string
& pointer
) throw(std::bad_alloc
, error
)
1134 size_t s
= pointer
.find_last_of(U
"/");
1136 std::u32string rest
;
1137 size_t ptrlen
= pointer
.length();
1139 base
= &follow(pointer
.substr(0, s
));
1140 rest
= jsonptr_unescape(pointer
, s
+ 1, ptrlen
);
1143 rest
= jsonptr_unescape(pointer
, 0, ptrlen
);
1145 if(base
->type() == array
) {
1147 throw error(ERR_POINTER_BAD_APPEND
);
1149 if(!parse_size_t(rest
, idx
))
1150 throw error(ERR_POINTER_BAD_INDEX
);
1151 if(idx
>= base
->xarray
.size())
1152 throw error(ERR_INDEX_INVALID
);
1153 node
* dptr
= base
->xarray_index
[idx
];
1155 for(auto i
= base
->xarray
.begin(); i
!= base
->xarray
.end(); ++i
)
1157 base
->xarray
.erase(i
);
1160 base
->xarray_index
.erase(base
->xarray_index
.begin() + idx
);
1162 } else if(base
->type() == object
) {
1163 if(xobject
.count(rest
)) {
1164 node tmp
= *base
->xobject
[rest
].begin();
1165 base
->xobject
.erase(rest
);
1168 throw error(ERR_KEY_INVALID
);
1170 throw error(ERR_NOT_ARRAY_NOR_OBJECT
);
1173 node
node::patch(const node
& patch
) const throw(std::bad_alloc
, error
)
1176 if(patch
.type() != array
)
1177 throw error(ERR_PATCH_BAD
);
1178 for(auto& i
: patch
) {
1179 if(i
.type() != object
|| i
.field_count(U
"op") != 1 || i
.field(U
"op").type() != string
)
1180 throw error(ERR_PATCH_BAD
);
1181 std::u32string op
= i
.field(U
"op").as_string();
1183 if(i
.field_count(U
"path") != 1 || i
.field(U
"path").type() != string
)
1184 throw error(ERR_PATCH_BAD
);
1185 if(i
.field_count(U
"value") != 1)
1186 throw error(ERR_PATCH_BAD
);
1187 if(obj
.follow(i
.field(U
"path").as_string()) != i
.field("value"))
1188 throw error(ERR_PATCH_TEST_FAILED
);
1189 } else if(op
== U
"remove") {
1190 if(i
.field_count(U
"path") != 1 || i
.field(U
"path").type() != string
)
1191 throw error(ERR_PATCH_BAD
);
1192 obj
.delete_node(i
.field(U
"path").as_string());
1193 } else if(op
== U
"add") {
1194 if(i
.field_count(U
"path") != 1 || i
.field(U
"path").type() != string
)
1195 throw error(ERR_PATCH_BAD
);
1196 if(i
.field_count(U
"value") != 1)
1197 throw error(ERR_PATCH_BAD
);
1198 obj
.insert_node(i
.field(U
"path").as_string(), i
.field("value"));
1199 } else if(op
== U
"replace") {
1200 if(i
.field_count(U
"path") != 1 || i
.field(U
"path").type() != string
)
1201 throw error(ERR_PATCH_BAD
);
1202 if(i
.field_count(U
"value") != 1)
1203 throw error(ERR_PATCH_BAD
);
1204 obj
.delete_node(i
.field(U
"path").as_string());
1205 obj
.insert_node(i
.field(U
"path").as_string(), i
.field("value"));
1206 } else if(op
== U
"move") {
1207 if(i
.field_count(U
"from") != 1 || i
.field(U
"from").type() != string
)
1208 throw error(ERR_PATCH_BAD
);
1209 if(i
.field_count(U
"path") != 1 || i
.field(U
"path").type() != string
)
1210 throw error(ERR_PATCH_BAD
);
1211 std::u32string from
= i
.field(U
"from").as_string();
1212 std::u32string to
= i
.field(U
"path").as_string();
1213 if(to
.substr(0, from
.length()) == from
) {
1214 if(to
.length() == from
.length())
1216 if(to
.length() > from
.length() && to
[from
.length()] == U
'/')
1217 throw error(ERR_PATCH_ILLEGAL_MOVE
);
1219 node tmp
= obj
.delete_node(from
);
1220 obj
.insert_node(to
, tmp
);
1221 } else if(op
== U
"copy") {
1222 if(i
.field_count(U
"from") != 1 || i
.field(U
"from").type() != string
)
1223 throw error(ERR_PATCH_BAD
);
1224 if(i
.field_count(U
"path") != 1 || i
.field(U
"path").type() != string
)
1225 throw error(ERR_PATCH_BAD
);
1226 const node
& tmp
= obj
.follow(i
.field(U
"from").as_string());
1227 obj
.insert_node(i
.field(U
"path").as_string(), tmp
);
1229 throw error(ERR_PATCH_BAD
);
1235 node::iterator::iterator() throw() { n
= NULL
; }
1237 node::iterator::iterator(node
& _n
) throw(error
)
1241 if(n
->type() == object
) {
1242 if(n
->xobject
.empty())
1245 _key
= n
->xobject
.begin()->first
;
1246 } else if(n
->type() == array
) {
1247 if(n
->xarray
.empty())
1250 throw error(ERR_NOT_ARRAY_NOR_OBJECT
);
1253 std::u32string
node::iterator::key() throw(std::bad_alloc
, error
)
1256 throw error(ERR_ITERATOR_END
);
1257 return (n
->type() == object
) ? _key
: U
"";
1260 size_t node::iterator::index() throw(error
)
1263 throw error(ERR_ITERATOR_END
);
1267 node
& node::iterator::operator*() throw(error
)
1270 throw error(ERR_ITERATOR_END
);
1271 if(n
->type() == object
) {
1272 if(!n
->xobject
.count(_key
))
1273 throw error(ERR_ITERATOR_DELETED
);
1274 auto& l
= n
->xobject
.find(_key
)->second
;
1276 for(auto i
= l
.begin(); i
!= l
.end(); i
++, j
++) {
1280 throw error(ERR_ITERATOR_DELETED
);
1282 if(idx
>= n
->xarray
.size())
1283 throw error(ERR_ITERATOR_DELETED
);
1284 return *n
->xarray_index
[idx
];
1288 node
* node::iterator::operator->() throw(error
)
1293 node::iterator
node::iterator::operator++(int) throw(error
)
1295 iterator tmp
= *this;
1300 node::iterator
& node::iterator::operator++() throw(error
)
1303 throw error(ERR_ITERATOR_END
);
1305 if(n
->type() == object
) {
1306 if(!n
->xobject
.count(_key
) || n
->xobject
.find(_key
)->second
.size() <= idx
) {
1307 auto i
= n
->xobject
.upper_bound(_key
);
1308 if(i
== n
->xobject
.end())
1315 if(idx
>= n
->xarray_index
.size())
1321 bool node::iterator::operator==(const iterator
& i
) throw()
1327 return (n
== i
.n
&& _key
== i
._key
&& idx
== i
.idx
);
1330 bool node::iterator::operator!=(const iterator
& i
) throw() { return !(*this == i
); }
1332 node::const_iterator::const_iterator() throw() { n
= NULL
; }
1334 node::const_iterator::const_iterator(const node
& _n
) throw(error
)
1338 if(n
->type() == object
) {
1339 if(n
->xobject
.empty())
1342 _key
= n
->xobject
.begin()->first
;
1343 } else if(n
->type() == array
) {
1344 if(n
->xarray
.empty())
1347 throw error(ERR_NOT_ARRAY_NOR_OBJECT
);
1350 std::u32string
node::const_iterator::key() throw(std::bad_alloc
, error
)
1353 throw error(ERR_ITERATOR_END
);
1354 return (n
->type() == object
) ? _key
: U
"";
1357 size_t node::const_iterator::index() throw(error
)
1360 throw error(ERR_ITERATOR_END
);
1364 const node
& node::const_iterator::operator*() throw(error
)
1367 throw error(ERR_ITERATOR_END
);
1368 if(n
->type() == object
) {
1369 if(!n
->xobject
.count(_key
))
1370 throw error(ERR_ITERATOR_DELETED
);
1371 auto& l
= n
->xobject
.find(_key
)->second
;
1373 for(auto i
= l
.begin(); i
!= l
.end(); i
++, j
++) {
1377 throw error(ERR_ITERATOR_DELETED
);
1379 if(idx
>= n
->xarray
.size())
1380 throw error(ERR_ITERATOR_DELETED
);
1381 return *n
->xarray_index
[idx
];
1385 const node
* node::const_iterator::operator->() throw(error
)
1390 node::const_iterator
node::const_iterator::operator++(int) throw(error
)
1392 const_iterator tmp
= *this;
1397 node::const_iterator
& node::const_iterator::operator++() throw(error
)
1400 throw error(ERR_ITERATOR_END
);
1402 if(n
->type() == object
) {
1403 if(!n
->xobject
.count(_key
) || n
->xobject
.find(_key
)->second
.size() <= idx
) {
1404 auto i
= n
->xobject
.upper_bound(_key
);
1405 if(i
== n
->xobject
.end())
1412 if(idx
>= n
->xarray_index
.size())
1418 bool node::const_iterator::operator==(const const_iterator
& i
) throw()
1424 return (n
== i
.n
&& _key
== i
._key
&& idx
== i
.idx
);
1427 bool node::const_iterator::operator!=(const const_iterator
& i
) throw() { return !(*this == i
); }
1429 void node::erase_index(size_t idx
) throw(error
)
1431 if(type() == array
) {
1432 if(idx
>= xarray_index
.size())
1434 node
* n
= xarray_index
[idx
];
1435 xarray_index
.erase(xarray_index
.begin() + idx
);
1436 for(auto i
= xarray
.begin(); i
!= xarray
.end(); i
++)
1442 throw error(ERR_NOT_AN_ARRAY
);
1445 void node::erase_field(const std::u32string
& fld
, size_t idx
) throw(error
)
1447 if(type() == object
) {
1448 if(xobject
.count(fld
)) {
1449 auto& l
= xobject
[fld
];
1451 for(auto i
= l
.begin(); i
!= l
.end(); i
++, j
++)
1460 throw error(ERR_NOT_AN_OBJECT
);
1463 void node::erase_field_all(const std::u32string
& fld
) throw(error
)
1465 if(type() == object
) {
1466 if(xobject
.count(fld
))
1469 throw error(ERR_NOT_AN_OBJECT
);
1472 void node::clear() throw(error
)
1474 if(type() == object
)
1476 else if(type() == array
) {
1477 xarray_index
.clear();
1480 throw error(ERR_NOT_ARRAY_NOR_OBJECT
);
1483 node::iterator
node::erase(node::iterator itr
) throw(error
)
1486 throw error(ERR_WRONG_OBJECT
);
1487 if(type() == object
) {
1488 erase_field(itr
._key
, itr
.idx
);
1489 if(!xobject
.count(itr
._key
) || itr
.idx
>= xobject
[itr
._key
].size())
1492 } else if(type() == array
) {
1493 erase_index(itr
.idx
);
1494 if(itr
.idx
>= xarray_index
.size())
1498 throw error(ERR_NOT_ARRAY_NOR_OBJECT
);
1501 void node::fixup_nodes(const node
& _node
)
1503 auto i
= xarray
.begin();
1504 auto j
= _node
.xarray
.begin();
1505 for(; i
!= xarray
.end(); i
++, j
++) {
1506 for(size_t k
= 0; k
< _node
.xarray_index
.size(); k
++)
1507 if(_node
.xarray_index
[k
] == &*j
)
1508 xarray_index
[k
] = &*i
;
1512 bool node::operator==(const node
& n
) const
1516 if(vtype
!= n
.vtype
)
1521 case boolean_tag::id
:
1522 return (_boolean
== n
._boolean
);
1523 case number_tag::id
:
1524 return (_number
== n
._number
);
1525 case string_tag::id
:
1526 return (_string
== n
._string
);
1528 if(xarray_index
.size() != n
.xarray_index
.size())
1530 for(size_t i
= 0; i
< xarray_index
.size(); i
++)
1531 if(*xarray_index
[i
] != *n
.xarray_index
[i
])
1534 case object_tag::id
:
1535 for(auto& i
: xobject
)
1536 if(!n
.xobject
.count(i
.first
))
1538 for(auto& i
: n
.xobject
)
1539 if(!xobject
.count(i
.first
))
1541 for(auto& i
: xobject
) {
1542 auto& j
= *xobject
.find(i
.first
);
1543 auto& k
= *n
.xobject
.find(i
.first
);
1544 if(j
.second
.size() != k
.second
.size())
1546 auto j2
= j
.second
.begin();
1547 auto k2
= k
.second
.begin();
1548 for(; j2
!= j
.second
.end(); j2
++, k2
++)
1554 throw error(ERR_UNKNOWN_TYPE
);
1558 int node::type_of(const std::u32string
& pointer
) const throw(std::bad_alloc
)
1562 if(follow_soft(pointer
, n
) != ERR_OK
)
1565 } catch(std::bad_alloc
& e
) {
1567 } catch(std::exception
& e
) {
1573 int node::type_of_indirect(const std::u32string
& pointer
) const throw(std::bad_alloc
)
1577 if(follow_soft(pointer
, n
) != ERR_OK
)
1579 if(n
->type() == string
)
1580 return type_of(n
->as_string());
1583 } catch(std::bad_alloc
& e
) {
1585 } catch(std::exception
& e
) {
1591 std::u32string
node::resolve_indirect(const std::u32string
& pointer
) const throw(std::bad_alloc
)
1594 const node
& n
= follow(pointer
);
1595 if(n
.type() == string
)
1596 return n
.as_string();
1599 } catch(std::bad_alloc
& e
) {
1601 } catch(std::exception
& e
) {
1610 pointer::pointer(const std::string
& ptr
) throw(std::bad_alloc
)
1612 _pointer
= utf8::to32(ptr
);
1615 pointer::pointer(const std::u32string
& ptr
) throw(std::bad_alloc
)
1620 pointer
pointer::index(uint64_t idx
) const throw(std::bad_alloc
)
1622 if(_pointer
.length())
1623 return pointer(_pointer
+ U
"/" + pointer_escape_index(idx
));
1625 return pointer(pointer_escape_index(idx
));
1628 pointer
& pointer::index_inplace(uint64_t idx
) throw(std::bad_alloc
)
1630 if(_pointer
.length())
1631 _pointer
= _pointer
+ U
"/" + pointer_escape_index(idx
);
1633 _pointer
= pointer_escape_index(idx
);
1637 pointer
pointer::field(const std::u32string
& fld
) const throw(std::bad_alloc
)
1639 if(_pointer
.length())
1640 return pointer(_pointer
+ U
"/" + pointer_escape_field(fld
));
1642 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
);
1650 _pointer
= pointer_escape_field(fld
);
1654 pointer
pointer::remove() const throw(std::bad_alloc
)
1656 size_t p
= _pointer
.find_last_of(U
"/");
1657 if(p
>= _pointer
.length())
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())
1669 _pointer
= _pointer
.substr(0, p
);
1673 std::ostream
& operator<<(std::ostream
& s
, const pointer
& p
)
1675 return s
<< utf8::to8(p
._pointer
);
1678 std::basic_ostream
<char32_t
>& operator<<(std::basic_ostream
<char32_t
>& s
, const pointer
& p
)
1680 return s
<< p
._pointer
;
1683 printer::~printer() throw()
1687 std::string
printer::value_val(const std::string
& val
)
1692 std::string
printer::value_string(const std::u32string
& s
)
1694 return json_string_escape(s
);
1697 std::string
printer::array_begin()
1702 std::string
printer::array_separator()
1707 std::string
printer::array_end()
1712 std::string
printer::object_begin()
1717 std::string
printer::object_key(const std::u32string
& s
)
1719 return json_string_escape(s
) + ":";
1722 std::string
printer::object_separator()
1727 std::string
printer::object_end()
1732 printer_indenting::printer_indenting()
1738 printer_indenting::~printer_indenting() throw()
1742 std::string
printer_indenting::linestart(size_t _depth
)
1744 std::ostringstream s
;
1746 for(size_t i
= 0; i
< _depth
; i
++)
1751 std::string
printer_indenting::value_val(const std::string
& val
)
1759 //According to JSON rules, value is not allowed immediately after end of array/object, so
1760 //states S_END and S_START_END really have comma right before.
1762 return linestart(depth
) + val
;
1766 std::string
printer_indenting::value_string(const std::u32string
& s
)
1769 return json_string_escape(s
) + "\n";
1772 return json_string_escape(s
);
1774 //According to JSON rules, value is not allowed immediately after end of array/object, so
1775 //states S_END and S_START_END really have comma right before.
1777 return linestart(depth
) + json_string_escape(s
);
1781 std::string
printer_indenting::array_begin()
1785 //This can only happen in beginning of expression or after key.
1790 //This is really after ], or },
1797 //S_START_END really has comma right before due to JSON rules.
1799 return linestart(depth
++) + "[";
1801 return "<WTF?>"; //NOTREACHED.
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");
1834 return "<WTF?>"; //NOTREACHED.
1837 std::string
printer_indenting::object_begin()
1841 //This can only happen in beginning of expression or after key.
1846 //This is really ], or },
1853 //S_START_END really has comma right before due to JSON rules.
1855 return linestart(depth
++) + "{";
1857 return "<WTF?>"; //NOTREACHED.
1860 std::string
printer_indenting::object_key(const std::u32string
& s
)
1868 return linestart(depth
) + json_string_escape(s
) + ":";
1870 //Can't actually happe
1872 return json_string_escape(s
) + ":";
1874 return "<WTF?>"; //NOTREACHED.
1877 std::string
printer_indenting::object_separator()
1882 //These states don't transition to comma.
1890 std::string
printer_indenting::object_end()
1897 //S_END or S_START_END is after ']' or '}'.
1898 //S_COMMA can't actually happen per JSON rules.
1901 return linestart(depth
) + "}" + (depth
? "" : "\n");
1903 state
= S_START_END
;
1907 return "<WTF?>"; //NOTREACHED.
1912 bool operator==(const int& n
, const JSON::number_tag
& v
) { return v
== n
; }
1913 bool operator==(const int& n
, const JSON::string_tag
& v
) { return v
== n
; }
1914 bool operator==(const int& n
, const JSON::boolean_tag
& v
) { return v
== n
; }
1915 bool operator==(const int& n
, const JSON::array_tag
& v
) { return v
== n
; }
1916 bool operator==(const int& n
, const JSON::object_tag
& v
) { return v
== n
; }
1917 bool operator==(const int& n
, const JSON::null_tag
& v
) { return v
== n
; }
1918 bool operator!=(const int& n
, const JSON::number_tag
& v
) { return v
!= n
; }
1919 bool operator!=(const int& n
, const JSON::string_tag
& v
) { return v
!= n
; }
1920 bool operator!=(const int& n
, const JSON::boolean_tag
& v
) { return v
!= n
; }
1921 bool operator!=(const int& n
, const JSON::array_tag
& v
) { return v
!= n
; }
1922 bool operator!=(const int& n
, const JSON::object_tag
& v
) { return v
!= n
; }
1923 bool operator!=(const int& n
, const JSON::null_tag
& v
) { return v
!= n
; }