… | |
… | |
6 | #include <string.h> |
6 | #include <string.h> |
7 | #include <stdlib.h> |
7 | #include <stdlib.h> |
8 | #include <stdio.h> |
8 | #include <stdio.h> |
9 | #include <limits.h> |
9 | #include <limits.h> |
10 | #include <float.h> |
10 | #include <float.h> |
|
|
11 | #include <inttypes.h> |
11 | |
12 | |
12 | #if defined(__BORLANDC__) || defined(_MSC_VER) |
13 | #if defined(__BORLANDC__) || defined(_MSC_VER) |
13 | # define snprintf _snprintf // C compilers have this in stdio.h |
14 | # define snprintf _snprintf // C compilers have this in stdio.h |
14 | #endif |
15 | #endif |
15 | |
16 | |
… | |
… | |
361 | } enc_t; |
362 | } enc_t; |
362 | |
363 | |
363 | INLINE void |
364 | INLINE void |
364 | need (enc_t *enc, STRLEN len) |
365 | need (enc_t *enc, STRLEN len) |
365 | { |
366 | { |
366 | if (expect_false (enc->cur + len >= enc->end)) |
367 | if (expect_false ((uintptr_t)(enc->end - enc->cur) < len)) |
367 | { |
368 | { |
368 | STRLEN cur = enc->cur - (char *)SvPVX (enc->sv); |
369 | STRLEN cur = enc->cur - (char *)SvPVX (enc->sv); |
369 | SvGROW (enc->sv, cur + (len < (cur >> 2) ? cur >> 2 : len) + 1); |
370 | SvGROW (enc->sv, cur + (len < (cur >> 2) ? cur >> 2 : len) + 1); |
370 | enc->cur = SvPVX (enc->sv) + cur; |
371 | enc->cur = SvPVX (enc->sv) + cur; |
371 | enc->end = SvPVX (enc->sv) + SvLEN (enc->sv) - 1; |
372 | enc->end = SvPVX (enc->sv) + SvLEN (enc->sv) - 1; |
… | |
… | |
1689 | fail: |
1690 | fail: |
1690 | return 0; |
1691 | return 0; |
1691 | } |
1692 | } |
1692 | |
1693 | |
1693 | static SV * |
1694 | static SV * |
1694 | decode_json (SV *string, JSON *json, char **offset_return) |
1695 | decode_json (SV *string, JSON *json, STRLEN *offset_return) |
1695 | { |
1696 | { |
1696 | dec_t dec; |
1697 | dec_t dec; |
1697 | SV *sv; |
1698 | SV *sv; |
1698 | |
1699 | |
1699 | /* work around bugs in 5.10 where manipulating magic values |
1700 | /* work around bugs in 5.10 where manipulating magic values |
… | |
… | |
1752 | |
1753 | |
1753 | decode_ws (&dec); |
1754 | decode_ws (&dec); |
1754 | sv = decode_sv (&dec); |
1755 | sv = decode_sv (&dec); |
1755 | |
1756 | |
1756 | if (offset_return) |
1757 | if (offset_return) |
1757 | *offset_return = dec.cur; |
1758 | *offset_return = dec.cur - SvPVX (string); |
1758 | |
1759 | else if (sv) |
1759 | if (!(offset_return || !sv)) |
|
|
1760 | { |
1760 | { |
1761 | // check for trailing garbage |
1761 | // check for trailing garbage |
1762 | decode_ws (&dec); |
1762 | decode_ws (&dec); |
1763 | |
1763 | |
1764 | if (*dec.cur) |
1764 | if (*dec.cur) |
… | |
… | |
2111 | |
2111 | |
2112 | void decode_prefix (JSON *self, SV *jsonstr) |
2112 | void decode_prefix (JSON *self, SV *jsonstr) |
2113 | PPCODE: |
2113 | PPCODE: |
2114 | { |
2114 | { |
2115 | SV *sv; |
2115 | SV *sv; |
2116 | char *offset; |
2116 | STRLEN offset; |
2117 | PUTBACK; sv = decode_json (jsonstr, self, &offset); SPAGAIN; |
2117 | PUTBACK; sv = decode_json (jsonstr, self, &offset); SPAGAIN; |
2118 | EXTEND (SP, 2); |
2118 | EXTEND (SP, 2); |
2119 | PUSHs (sv); |
2119 | PUSHs (sv); |
2120 | PUSHs (sv_2mortal (newSVuv (ptr_to_index (jsonstr, offset)))); |
2120 | PUSHs (sv_2mortal (newSVuv (ptr_to_index (jsonstr, SvPV_nolen (jsonstr) + offset)))); |
2121 | } |
2121 | } |
2122 | |
2122 | |
2123 | void incr_parse (JSON *self, SV *jsonstr = 0) |
2123 | void incr_parse (JSON *self, SV *jsonstr = 0) |
2124 | PPCODE: |
2124 | PPCODE: |
2125 | { |
2125 | { |
… | |
… | |
2172 | |
2172 | |
2173 | if (GIMME_V != G_VOID) |
2173 | if (GIMME_V != G_VOID) |
2174 | do |
2174 | do |
2175 | { |
2175 | { |
2176 | SV *sv; |
2176 | SV *sv; |
2177 | char *offset; |
2177 | STRLEN offset; |
2178 | |
2178 | |
2179 | if (!INCR_DONE (self)) |
2179 | if (!INCR_DONE (self)) |
2180 | { |
2180 | { |
2181 | incr_parse (self); |
2181 | incr_parse (self); |
2182 | |
2182 | |
… | |
… | |
2198 | } |
2198 | } |
2199 | |
2199 | |
2200 | PUTBACK; sv = decode_json (self->incr_text, self, &offset); SPAGAIN; |
2200 | PUTBACK; sv = decode_json (self->incr_text, self, &offset); SPAGAIN; |
2201 | XPUSHs (sv); |
2201 | XPUSHs (sv); |
2202 | |
2202 | |
2203 | self->incr_pos -= offset - SvPVX (self->incr_text); |
2203 | self->incr_pos -= offset; |
2204 | self->incr_nest = 0; |
2204 | self->incr_nest = 0; |
2205 | self->incr_mode = 0; |
2205 | self->incr_mode = 0; |
2206 | |
2206 | |
2207 | sv_chop (self->incr_text, offset); |
2207 | sv_chop (self->incr_text, SvPVX (self->incr_text) + offset); |
2208 | } |
2208 | } |
2209 | while (GIMME_V == G_ARRAY); |
2209 | while (GIMME_V == G_ARRAY); |
2210 | } |
2210 | } |
2211 | |
2211 | |
2212 | SV *incr_text (JSON *self) |
2212 | SV *incr_text (JSON *self) |