ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/JSON-XS/XS.xs
(Generate patch)

Comparing JSON-XS/XS.xs (file contents):
Revision 1.44 by root, Mon Jun 25 04:08:17 2007 UTC vs.
Revision 1.46 by root, Mon Jun 25 22:11:39 2007 UTC

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
1325SV *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
1281void encode (SV *self, SV *scalar) 1344void 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
1285void decode (SV *self, SV *jsonstr) 1348void decode (SV *self, SV *jsonstr)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines