… | |
… | |
28 | #define F_SHRINK 0x00000200UL |
28 | #define F_SHRINK 0x00000200UL |
29 | #define F_ALLOW_BLESSED 0x00000400UL |
29 | #define F_ALLOW_BLESSED 0x00000400UL |
30 | #define F_CONV_BLESSED 0x00000800UL // NYI |
30 | #define F_CONV_BLESSED 0x00000800UL // NYI |
31 | #define F_MAXDEPTH 0xf8000000UL |
31 | #define F_MAXDEPTH 0xf8000000UL |
32 | #define S_MAXDEPTH 27 |
32 | #define S_MAXDEPTH 27 |
|
|
33 | #define F_MAXSIZE 0x01f00000UL |
|
|
34 | #define S_MAXSIZE 20 |
33 | |
35 | |
34 | #define DEC_DEPTH(flags) (1UL << ((flags & F_MAXDEPTH) >> S_MAXDEPTH)) |
36 | #define DEC_DEPTH(flags) (1UL << ((flags & F_MAXDEPTH) >> S_MAXDEPTH)) |
|
|
37 | #define DEC_SIZE(flags) (1UL << ((flags & F_MAXSIZE ) >> S_MAXSIZE )) |
35 | |
38 | |
36 | #define F_PRETTY F_INDENT | F_SPACE_BEFORE | F_SPACE_AFTER |
39 | #define F_PRETTY F_INDENT | F_SPACE_BEFORE | F_SPACE_AFTER |
37 | #define F_DEFAULT (9UL << S_MAXDEPTH) |
40 | #define F_DEFAULT (9UL << S_MAXDEPTH) |
38 | |
41 | |
39 | #define INIT_SIZE 32 // initial scalar size to be allocated |
42 | #define INIT_SIZE 32 // initial scalar size to be allocated |
… | |
… | |
1020 | if (*dec->cur == '}') |
1023 | if (*dec->cur == '}') |
1021 | ++dec->cur; |
1024 | ++dec->cur; |
1022 | else |
1025 | else |
1023 | for (;;) |
1026 | for (;;) |
1024 | { |
1027 | { |
1025 | SV *key, *value; |
|
|
1026 | |
|
|
1027 | decode_ws (dec); EXPECT_CH ('"'); |
1028 | decode_ws (dec); EXPECT_CH ('"'); |
1028 | |
1029 | |
1029 | key = decode_str (dec); |
1030 | // heuristic: assume that |
1030 | if (!key) |
1031 | // a) decode_str + hv_store_ent are abysmally slow |
1031 | goto fail; |
1032 | // b) most hash keys are short, simple ascii text |
|
|
1033 | // so try to "fast-match" such strings to avoid |
|
|
1034 | // the overhead of hv_store_ent. |
|
|
1035 | { |
|
|
1036 | SV *value; |
|
|
1037 | char *p = dec->cur; |
|
|
1038 | char *e = p + 24; // only try up to 24 bytes |
1032 | |
1039 | |
1033 | decode_ws (dec); EXPECT_CH (':'); |
1040 | for (;;) |
1034 | |
|
|
1035 | value = decode_sv (dec); |
|
|
1036 | if (!value) |
|
|
1037 | { |
1041 | { |
|
|
1042 | if (p == e || *p < 0x20 || *p >= 0x80 || *p == '\\') |
|
|
1043 | { |
|
|
1044 | // slow path, back up and use decode_str |
|
|
1045 | SV *key = decode_str (dec); |
|
|
1046 | if (!key) |
|
|
1047 | goto fail; |
|
|
1048 | |
|
|
1049 | decode_ws (dec); EXPECT_CH (':'); |
|
|
1050 | |
|
|
1051 | value = decode_sv (dec); |
|
|
1052 | if (!value) |
|
|
1053 | { |
|
|
1054 | SvREFCNT_dec (key); |
|
|
1055 | goto fail; |
|
|
1056 | } |
|
|
1057 | |
|
|
1058 | hv_store_ent (hv, key, value, 0); |
1038 | SvREFCNT_dec (key); |
1059 | SvREFCNT_dec (key); |
|
|
1060 | |
|
|
1061 | break; |
|
|
1062 | } |
|
|
1063 | else if (*p == '"') |
|
|
1064 | { |
|
|
1065 | // fast path, got a simple key |
|
|
1066 | char *key = dec->cur; |
|
|
1067 | int len = p - key; |
|
|
1068 | dec->cur = p + 1; |
|
|
1069 | |
|
|
1070 | decode_ws (dec); EXPECT_CH (':'); |
|
|
1071 | |
|
|
1072 | value = decode_sv (dec); |
|
|
1073 | if (!value) |
1039 | goto fail; |
1074 | goto fail; |
|
|
1075 | |
|
|
1076 | hv_store (hv, key, len, value, 0); |
|
|
1077 | |
|
|
1078 | break; |
|
|
1079 | } |
|
|
1080 | |
|
|
1081 | ++p; |
1040 | } |
1082 | } |
1041 | |
1083 | } |
1042 | hv_store_ent (hv, key, value, 0); |
|
|
1043 | SvREFCNT_dec (key); |
|
|
1044 | |
1084 | |
1045 | decode_ws (dec); |
1085 | decode_ws (dec); |
1046 | |
1086 | |
1047 | if (*dec->cur == '}') |
1087 | if (*dec->cur == '}') |
1048 | { |
1088 | { |
… | |
… | |
1132 | UV offset; |
1172 | UV offset; |
1133 | SV *sv; |
1173 | SV *sv; |
1134 | |
1174 | |
1135 | SvGETMAGIC (string); |
1175 | SvGETMAGIC (string); |
1136 | SvUPGRADE (string, SVt_PV); |
1176 | SvUPGRADE (string, SVt_PV); |
|
|
1177 | |
|
|
1178 | if (flags & F_MAXSIZE && SvCUR (string) > DEC_SIZE (flags)) |
|
|
1179 | croak ("attempted decode of JSON text of %lu bytes size, but max_size is set to %lu", |
|
|
1180 | (unsigned long)SvCUR (string), (unsigned long)DEC_SIZE (flags)); |
1137 | |
1181 | |
1138 | if (flags & F_UTF8) |
1182 | if (flags & F_UTF8) |
1139 | sv_utf8_downgrade (string, 0); |
1183 | sv_utf8_downgrade (string, 0); |
1140 | else |
1184 | else |
1141 | sv_utf8_upgrade (string); |
1185 | sv_utf8_upgrade (string); |
… | |
… | |
1276 | RETVAL = newSVsv (self); |
1320 | RETVAL = newSVsv (self); |
1277 | } |
1321 | } |
1278 | OUTPUT: |
1322 | OUTPUT: |
1279 | RETVAL |
1323 | RETVAL |
1280 | |
1324 | |
|
|
1325 | SV *max_size (SV *self, UV max_size = 0) |
|
|
1326 | CODE: |
|
|
1327 | { |
|
|
1328 | UV *uv = SvJSON (self); |
|
|
1329 | UV log2 = 0; |
|
|
1330 | |
|
|
1331 | if (max_size > 0x80000000UL) max_size = 0x80000000UL; |
|
|
1332 | if (max_size == 1) max_size = 2; |
|
|
1333 | |
|
|
1334 | while ((1UL << log2) < max_size) |
|
|
1335 | ++log2; |
|
|
1336 | |
|
|
1337 | *uv = *uv & ~F_MAXSIZE | (log2 << S_MAXSIZE); |
|
|
1338 | |
|
|
1339 | RETVAL = newSVsv (self); |
|
|
1340 | } |
|
|
1341 | OUTPUT: |
|
|
1342 | RETVAL |
|
|
1343 | |
1281 | void encode (SV *self, SV *scalar) |
1344 | void encode (SV *self, SV *scalar) |
1282 | PPCODE: |
1345 | PPCODE: |
1283 | XPUSHs (encode_json (scalar, *SvJSON (self))); |
1346 | XPUSHs (encode_json (scalar, *SvJSON (self))); |
1284 | |
1347 | |
1285 | void decode (SV *self, SV *jsonstr) |
1348 | void decode (SV *self, SV *jsonstr) |