--- JSON-XS/XS.xs 2008/03/19 00:44:54 1.70 +++ JSON-XS/XS.xs 2008/03/19 03:17:38 1.71 @@ -52,11 +52,11 @@ #define SE } while (0) #if __GNUC__ >= 3 -# define expect(expr,value) __builtin_expect ((expr),(value)) -# define inline inline +# define expect(expr,value) __builtin_expect ((expr), (value)) +# define INLINE static inline #else # define expect(expr,value) (expr) -# define inline static +# define INLINE static #endif #define expect_false(expr) expect ((expr) != 0, 0) @@ -82,7 +82,7 @@ ///////////////////////////////////////////////////////////////////////////// // utility functions -inline void +INLINE void shrink (SV *sv) { sv_utf8_downgrade (sv, 1); @@ -101,7 +101,7 @@ // we special-case "safe" characters from U+80 .. U+7FF, // but use the very good perl function to parse anything else. // note that we never call this function for a ascii codepoints -inline UV +INLINE UV decode_utf8 (unsigned char *s, STRLEN len, STRLEN *clen) { if (expect_false (s[0] > 0xdf || s[0] < 0xc2)) @@ -130,9 +130,10 @@ JSON json; U32 indent; // indentation level U32 maxdepth; // max. indentation/recursion level + UV limit; // escape character values >= this value when encoding } enc_t; -inline void +INLINE void need (enc_t *enc, STRLEN len) { if (expect_false (enc->cur + len >= enc->end)) @@ -144,7 +145,7 @@ } } -inline void +INLINE void encode_ch (enc_t *enc, char ch) { need (enc, 1); @@ -208,13 +209,13 @@ clen = 1; } - if (uch > 0x10FFFFUL) - croak ("out of range codepoint (0x%lx) encountered, unrepresentable in JSON", (unsigned long)uch); - - if (uch < 0x80 || enc->json.flags & F_ASCII || (enc->json.flags & F_LATIN1 && uch > 0xFF)) + if (uch < 0x20 || uch >= enc->limit) { if (uch > 0xFFFFUL) { + if (uch > 0x10FFFFUL) + croak ("out of range codepoint (0x%lx) encountered, unrepresentable in JSON", (unsigned long)uch); + need (enc, len += 11); sprintf (enc->cur, "\\u%04x\\u%04x", (int)((uch - 0x10000) / 0x400 + 0xD800), @@ -263,7 +264,7 @@ } } -inline void +INLINE void encode_indent (enc_t *enc) { if (enc->json.flags & F_INDENT) @@ -276,14 +277,14 @@ } } -inline void +INLINE void encode_space (enc_t *enc) { need (enc, 1); encode_ch (enc, ' '); } -inline void +INLINE void encode_nl (enc_t *enc) { if (enc->json.flags & F_INDENT) @@ -293,7 +294,7 @@ } } -inline void +INLINE void encode_comma (enc_t *enc) { encode_ch (enc, ','); @@ -682,6 +683,9 @@ enc.end = SvEND (enc.sv); enc.indent = 0; enc.maxdepth = DEC_DEPTH (enc.json.flags); + enc.limit = enc.json.flags & F_ASCII ? 0x000080UL + : enc.json.flags & F_LATIN1 ? 0x000100UL + : 0x10FFFFUL; SvPOK_only (enc.sv); encode_sv (&enc, scalar); @@ -712,7 +716,7 @@ U32 maxdepth; // recursion depth limit } dec_t; -inline void +INLINE void decode_comment (dec_t *dec) { // only '#'-style comments allowed a.t.m. @@ -721,7 +725,7 @@ ++dec->cur; } -inline void +INLINE void decode_ws (dec_t *dec) { for (;;)