… | |
… | |
78 | <= (unsigned type)((unsigned type)(end) - (unsigned type)(beg))) |
78 | <= (unsigned type)((unsigned type)(end) - (unsigned type)(beg))) |
79 | |
79 | |
80 | #define ERR_NESTING_EXCEEDED "json text or perl structure exceeds maximum nesting level (max_depth set too low?)" |
80 | #define ERR_NESTING_EXCEEDED "json text or perl structure exceeds maximum nesting level (max_depth set too low?)" |
81 | |
81 | |
82 | #ifdef USE_ITHREADS |
82 | #ifdef USE_ITHREADS |
83 | # define JSON_SLOW 1 |
|
|
84 | # define JSON_STASH (json_stash ? json_stash : gv_stashpv ("JSON::XS", 1)) |
83 | # define JSON_STASH (expect_true (json_stash) ? json_stash : gv_stashpv ("JSON::XS", 1)) |
85 | # define BOOL_STASH (bool_stash ? bool_stash : gv_stashpv ("Types::Serialiser::Boolean", 1)) |
84 | # define BOOL_STASH (expect_true (bool_stash) ? bool_stash : gv_stashpv ("Types::Serialiser::Boolean", 1)) |
|
|
85 | # define GET_BOOL(value) (expect_true (bool_ ## value) ? bool_ ## value : get_bool ("Types::Serialiser::" # value)) |
86 | #else |
86 | #else |
87 | # define JSON_SLOW 0 |
|
|
88 | # define JSON_STASH json_stash |
87 | # define JSON_STASH json_stash |
89 | # define BOOL_STASH bool_stash |
88 | # define BOOL_STASH bool_stash |
|
|
89 | # define GET_BOOL(value) bool_ ## value |
90 | #endif |
90 | #endif |
91 | |
91 | |
92 | // the amount of HEs to allocate on the stack, when sorting keys |
92 | // the amount of HEs to allocate on the stack, when sorting keys |
93 | #define STACK_HES 64 |
93 | #define STACK_HES 64 |
94 | |
94 | |
95 | static HV *json_stash, *bool_stash; // JSON::XS::, Types::Serialiser::Boolean:: |
95 | static HV *json_stash, *bool_stash; // JSON::XS::, Types::Serialiser::Boolean:: |
96 | static SV *bool_true, *bool_false, *sv_json; |
96 | static SV *bool_false, *bool_true; |
|
|
97 | static SV *sv_json; |
97 | |
98 | |
98 | enum { |
99 | enum { |
99 | INCR_M_WS = 0, // initial whitespace skipping, must be 0 |
100 | INCR_M_WS = 0, // initial whitespace skipping, must be 0 |
100 | INCR_M_STR, // inside string |
101 | INCR_M_STR, // inside string |
101 | INCR_M_BS, // inside backslash |
102 | INCR_M_BS, // inside backslash |
… | |
… | |
117 | // for the incremental parser |
118 | // for the incremental parser |
118 | SV *incr_text; // the source text so far |
119 | SV *incr_text; // the source text so far |
119 | STRLEN incr_pos; // the current offset into the text |
120 | STRLEN incr_pos; // the current offset into the text |
120 | int incr_nest; // {[]}-nesting level |
121 | int incr_nest; // {[]}-nesting level |
121 | unsigned char incr_mode; |
122 | unsigned char incr_mode; |
|
|
123 | |
|
|
124 | SV *v_false, *v_true; |
122 | } JSON; |
125 | } JSON; |
123 | |
126 | |
124 | INLINE void |
127 | INLINE void |
125 | json_init (JSON *json) |
128 | json_init (JSON *json) |
126 | { |
129 | { |
… | |
… | |
776 | { |
779 | { |
777 | HV *stash = SvSTASH (sv); |
780 | HV *stash = SvSTASH (sv); |
778 | |
781 | |
779 | if (stash == bool_stash) |
782 | if (stash == bool_stash) |
780 | { |
783 | { |
781 | if (SvIV (sv)) |
|
|
782 | encode_str (enc, "true", 4, 0); |
784 | if (SvIV (sv)) encode_str (enc, "true" , 4, 0); |
783 | else |
|
|
784 | encode_str (enc, "false", 5, 0); |
785 | else encode_str (enc, "false", 5, 0); |
785 | } |
786 | } |
786 | else if ((enc->json.flags & F_ALLOW_TAGS) && (method = gv_fetchmethod_autoload (stash, "FREEZE", 0))) |
787 | else if ((enc->json.flags & F_ALLOW_TAGS) && (method = gv_fetchmethod_autoload (stash, "FREEZE", 0))) |
787 | { |
788 | { |
788 | int count; |
789 | int count; |
789 | dSP; |
790 | dSP; |
… | |
… | |
1666 | case '-': |
1667 | case '-': |
1667 | case '0': case '1': case '2': case '3': case '4': |
1668 | case '0': case '1': case '2': case '3': case '4': |
1668 | case '5': case '6': case '7': case '8': case '9': |
1669 | case '5': case '6': case '7': case '8': case '9': |
1669 | return decode_num (dec); |
1670 | return decode_num (dec); |
1670 | |
1671 | |
|
|
1672 | case 'f': |
|
|
1673 | if (dec->end - dec->cur >= 5 && !memcmp (dec->cur, "false", 5)) |
|
|
1674 | { |
|
|
1675 | dec->cur += 5; |
|
|
1676 | |
|
|
1677 | if (expect_false (!dec->json.v_false)) |
|
|
1678 | dec->json.v_false = GET_BOOL (false); |
|
|
1679 | |
|
|
1680 | return newSVsv (dec->json.v_false); |
|
|
1681 | } |
|
|
1682 | else |
|
|
1683 | ERR ("'false' expected"); |
|
|
1684 | |
|
|
1685 | break; |
|
|
1686 | |
1671 | case 't': |
1687 | case 't': |
1672 | if (dec->end - dec->cur >= 4 && !memcmp (dec->cur, "true", 4)) |
1688 | if (dec->end - dec->cur >= 4 && !memcmp (dec->cur, "true", 4)) |
1673 | { |
1689 | { |
1674 | dec->cur += 4; |
1690 | dec->cur += 4; |
1675 | #if JSON_SLOW |
1691 | |
1676 | bool_true = get_bool ("Types::Serialiser::true"); |
1692 | if (expect_false (!dec->json.v_true)) |
1677 | #endif |
1693 | dec->json.v_true = GET_BOOL (true); |
|
|
1694 | |
1678 | return newSVsv (bool_true); |
1695 | return newSVsv (dec->json.v_true); |
1679 | } |
1696 | } |
1680 | else |
1697 | else |
1681 | ERR ("'true' expected"); |
1698 | ERR ("'true' expected"); |
1682 | |
|
|
1683 | break; |
|
|
1684 | |
|
|
1685 | case 'f': |
|
|
1686 | if (dec->end - dec->cur >= 5 && !memcmp (dec->cur, "false", 5)) |
|
|
1687 | { |
|
|
1688 | dec->cur += 5; |
|
|
1689 | #if JSON_SLOW |
|
|
1690 | bool_false = get_bool ("Types::Serialiser::false"); |
|
|
1691 | #endif |
|
|
1692 | return newSVsv (bool_false); |
|
|
1693 | } |
|
|
1694 | else |
|
|
1695 | ERR ("'false' expected"); |
|
|
1696 | |
1699 | |
1697 | break; |
1700 | break; |
1698 | |
1701 | |
1699 | case 'n': |
1702 | case 'n': |
1700 | if (dec->end - dec->cur >= 4 && !memcmp (dec->cur, "null", 4)) |
1703 | if (dec->end - dec->cur >= 4 && !memcmp (dec->cur, "null", 4)) |
… | |
… | |
1995 | : i >= 'A' && i <= 'F' ? i - 'A' + 10 |
1998 | : i >= 'A' && i <= 'F' ? i - 'A' + 10 |
1996 | : -1; |
1999 | : -1; |
1997 | |
2000 | |
1998 | json_stash = gv_stashpv ("JSON::XS" , 1); |
2001 | json_stash = gv_stashpv ("JSON::XS" , 1); |
1999 | bool_stash = gv_stashpv ("Types::Serialiser::Boolean", 1); |
2002 | bool_stash = gv_stashpv ("Types::Serialiser::Boolean", 1); |
|
|
2003 | bool_false = get_bool ("Types::Serialiser::false"); |
2000 | bool_true = get_bool ("Types::Serialiser::true"); |
2004 | bool_true = get_bool ("Types::Serialiser::true"); |
2001 | bool_false = get_bool ("Types::Serialiser::false"); |
|
|
2002 | |
2005 | |
2003 | sv_json = newSVpv ("JSON", 0); |
2006 | sv_json = newSVpv ("JSON", 0); |
2004 | SvREADONLY_on (sv_json); |
2007 | SvREADONLY_on (sv_json); |
2005 | |
2008 | |
2006 | CvNODEBUG_on (get_cv ("JSON::XS::incr_text", 0)); /* the debugger completely breaks lvalue subs */ |
2009 | CvNODEBUG_on (get_cv ("JSON::XS::incr_text", 0)); /* the debugger completely breaks lvalue subs */ |
… | |
… | |
2008 | |
2011 | |
2009 | PROTOTYPES: DISABLE |
2012 | PROTOTYPES: DISABLE |
2010 | |
2013 | |
2011 | void CLONE (...) |
2014 | void CLONE (...) |
2012 | CODE: |
2015 | CODE: |
|
|
2016 | // as long as these writes are atomic, the race should not matter |
|
|
2017 | // as existing threads either already use 0, or use the old value, |
|
|
2018 | // which is sitll correct for the initial thread. |
2013 | json_stash = 0; |
2019 | json_stash = 0; |
2014 | bool_stash = 0; |
2020 | bool_stash = 0; |
|
|
2021 | bool_false = 0; |
|
|
2022 | bool_true = 0; |
2015 | |
2023 | |
2016 | void new (char *klass) |
2024 | void new (char *klass) |
2017 | PPCODE: |
2025 | PPCODE: |
2018 | { |
2026 | { |
2019 | SV *pv = NEWSV (0, sizeof (JSON)); |
2027 | SV *pv = NEWSV (0, sizeof (JSON)); |
… | |
… | |
2022 | XPUSHs (sv_2mortal (sv_bless ( |
2030 | XPUSHs (sv_2mortal (sv_bless ( |
2023 | newRV_noinc (pv), |
2031 | newRV_noinc (pv), |
2024 | strEQ (klass, "JSON::XS") ? JSON_STASH : gv_stashpv (klass, 1) |
2032 | strEQ (klass, "JSON::XS") ? JSON_STASH : gv_stashpv (klass, 1) |
2025 | ))); |
2033 | ))); |
2026 | } |
2034 | } |
|
|
2035 | |
|
|
2036 | void boolean_values (JSON *self, SV *v_false = 0, SV *v_true = 0) |
|
|
2037 | PPCODE: |
|
|
2038 | self->v_false = newSVsv (v_false); |
|
|
2039 | self->v_true = newSVsv (v_true); |
|
|
2040 | XPUSHs (ST (0)); |
|
|
2041 | |
|
|
2042 | void get_boolean_values (JSON *self) |
|
|
2043 | PPCODE: |
|
|
2044 | if (self->v_false && self->v_true) |
|
|
2045 | { |
|
|
2046 | EXTEND (SP, 2); |
|
|
2047 | PUSHs (self->v_false); |
|
|
2048 | PUSHs (self->v_true); |
|
|
2049 | } |
2027 | |
2050 | |
2028 | void ascii (JSON *self, int enable = 1) |
2051 | void ascii (JSON *self, int enable = 1) |
2029 | ALIAS: |
2052 | ALIAS: |
2030 | ascii = F_ASCII |
2053 | ascii = F_ASCII |
2031 | latin1 = F_LATIN1 |
2054 | latin1 = F_LATIN1 |
… | |
… | |
2268 | self->incr_mode = 0; |
2291 | self->incr_mode = 0; |
2269 | } |
2292 | } |
2270 | |
2293 | |
2271 | void DESTROY (JSON *self) |
2294 | void DESTROY (JSON *self) |
2272 | CODE: |
2295 | CODE: |
|
|
2296 | SvREFCNT_dec (self->v_false); |
|
|
2297 | SvREFCNT_dec (self->v_true); |
2273 | SvREFCNT_dec (self->cb_sk_object); |
2298 | SvREFCNT_dec (self->cb_sk_object); |
2274 | SvREFCNT_dec (self->cb_object); |
2299 | SvREFCNT_dec (self->cb_object); |
2275 | SvREFCNT_dec (self->incr_text); |
2300 | SvREFCNT_dec (self->incr_text); |
2276 | |
2301 | |
2277 | PROTOTYPES: ENABLE |
2302 | PROTOTYPES: ENABLE |