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.62 by root, Sun Aug 26 22:27:32 2007 UTC vs.
Revision 1.64 by root, Mon Aug 27 02:03:23 2007 UTC

27#define F_SPACE_AFTER 0x00000040UL 27#define F_SPACE_AFTER 0x00000040UL
28#define F_ALLOW_NONREF 0x00000100UL 28#define F_ALLOW_NONREF 0x00000100UL
29#define F_SHRINK 0x00000200UL 29#define F_SHRINK 0x00000200UL
30#define F_ALLOW_BLESSED 0x00000400UL 30#define F_ALLOW_BLESSED 0x00000400UL
31#define F_CONV_BLESSED 0x00000800UL 31#define F_CONV_BLESSED 0x00000800UL
32#define F_RELAXED 0x00001000UL
33
32#define F_MAXDEPTH 0xf8000000UL 34#define F_MAXDEPTH 0xf8000000UL
33#define S_MAXDEPTH 27 35#define S_MAXDEPTH 27
34#define F_MAXSIZE 0x01f00000UL 36#define F_MAXSIZE 0x01f00000UL
35#define S_MAXSIZE 20 37#define S_MAXSIZE 20
36#define F_HOOK 0x00080000UL // some hooks exist, so slow-path processing 38#define F_HOOK 0x00080000UL // some hooks exist, so slow-path processing
698 U32 depth; // recursion depth 700 U32 depth; // recursion depth
699 U32 maxdepth; // recursion depth limit 701 U32 maxdepth; // recursion depth limit
700} dec_t; 702} dec_t;
701 703
702inline void 704inline void
705decode_comment (dec_t *dec)
706{
707 // only '#'-style comments allowed a.t.m.
708
709 while (*dec->cur && *dec->cur != 0x0a && *dec->cur != 0x0d)
710 ++dec->cur;
711}
712
713inline void
703decode_ws (dec_t *dec) 714decode_ws (dec_t *dec)
704{ 715{
705 for (;;) 716 for (;;)
706 { 717 {
707 char ch = *dec->cur; 718 char ch = *dec->cur;
708 719
709 if (ch > 0x20 720 if (ch > 0x20)
721 {
722 if (expect_false (ch == '#'))
723 {
724 if (dec->json.flags & F_RELAXED)
725 decode_comment (dec);
726 else
727 break;
728 }
729 else
730 break;
731 }
710 || (ch != 0x20 && ch != 0x0a && ch != 0x0d && ch != 0x09)) 732 else if (ch != 0x20 && ch != 0x0a && ch != 0x0d && ch != 0x09)
711 break; 733 break; // parse error, but let higher level handle it, gives better error messages
712 734
713 ++dec->cur; 735 ++dec->cur;
714 } 736 }
715} 737}
716 738
1053 1075
1054 if (*dec->cur != ',') 1076 if (*dec->cur != ',')
1055 ERR (", or ] expected while parsing array"); 1077 ERR (", or ] expected while parsing array");
1056 1078
1057 ++dec->cur; 1079 ++dec->cur;
1080
1081 decode_ws (dec);
1082
1083 if (*dec->cur == ']' && dec->json.flags & F_RELAXED)
1084 {
1085 ++dec->cur;
1086 break;
1087 }
1058 } 1088 }
1059 1089
1060 DEC_DEC_DEPTH; 1090 DEC_DEC_DEPTH;
1061 return newRV_noinc ((SV *)av); 1091 return newRV_noinc ((SV *)av);
1062 1092
1078 if (*dec->cur == '}') 1108 if (*dec->cur == '}')
1079 ++dec->cur; 1109 ++dec->cur;
1080 else 1110 else
1081 for (;;) 1111 for (;;)
1082 { 1112 {
1083 decode_ws (dec); EXPECT_CH ('"'); 1113 EXPECT_CH ('"');
1084 1114
1085 // heuristic: assume that 1115 // heuristic: assume that
1086 // a) decode_str + hv_store_ent are abysmally slow. 1116 // a) decode_str + hv_store_ent are abysmally slow.
1087 // b) most hash keys are short, simple ascii text. 1117 // b) most hash keys are short, simple ascii text.
1088 // => try to "fast-match" such strings to avoid 1118 // => try to "fast-match" such strings to avoid
1102 if (!key) 1132 if (!key)
1103 goto fail; 1133 goto fail;
1104 1134
1105 decode_ws (dec); EXPECT_CH (':'); 1135 decode_ws (dec); EXPECT_CH (':');
1106 1136
1137 decode_ws (dec);
1107 value = decode_sv (dec); 1138 value = decode_sv (dec);
1108 if (!value) 1139 if (!value)
1109 { 1140 {
1110 SvREFCNT_dec (key); 1141 SvREFCNT_dec (key);
1111 goto fail; 1142 goto fail;
1123 int len = p - key; 1154 int len = p - key;
1124 dec->cur = p + 1; 1155 dec->cur = p + 1;
1125 1156
1126 decode_ws (dec); EXPECT_CH (':'); 1157 decode_ws (dec); EXPECT_CH (':');
1127 1158
1159 decode_ws (dec);
1128 value = decode_sv (dec); 1160 value = decode_sv (dec);
1129 if (!value) 1161 if (!value)
1130 goto fail; 1162 goto fail;
1131 1163
1132 hv_store (hv, key, len, value, 0); 1164 hv_store (hv, key, len, value, 0);
1148 1180
1149 if (*dec->cur != ',') 1181 if (*dec->cur != ',')
1150 ERR (", or } expected while parsing object/hash"); 1182 ERR (", or } expected while parsing object/hash");
1151 1183
1152 ++dec->cur; 1184 ++dec->cur;
1185
1186 decode_ws (dec);
1187
1188 if (*dec->cur == '}' && dec->json.flags & F_RELAXED)
1189 {
1190 ++dec->cur;
1191 break;
1192 }
1153 } 1193 }
1154 1194
1155 DEC_DEC_DEPTH; 1195 DEC_DEC_DEPTH;
1156 sv = newRV_noinc ((SV *)hv); 1196 sv = newRV_noinc ((SV *)hv);
1157 1197
1222} 1262}
1223 1263
1224static SV * 1264static SV *
1225decode_sv (dec_t *dec) 1265decode_sv (dec_t *dec)
1226{ 1266{
1227 decode_ws (dec);
1228
1229 // the beauty of JSON: you need exactly one character lookahead 1267 // the beauty of JSON: you need exactly one character lookahead
1230 // to parse anything. 1268 // to parse anything.
1231 switch (*dec->cur) 1269 switch (*dec->cur)
1232 { 1270 {
1233 case '"': ++dec->cur; return decode_str (dec); 1271 case '"': ++dec->cur; return decode_str (dec);
1317 1355
1318 if (dec.json.cb_object || dec.json.cb_sk_object) 1356 if (dec.json.cb_object || dec.json.cb_sk_object)
1319 dec.json.flags |= F_HOOK; 1357 dec.json.flags |= F_HOOK;
1320 1358
1321 *dec.end = 0; // this should basically be a nop, too, but make sure it's there 1359 *dec.end = 0; // this should basically be a nop, too, but make sure it's there
1360
1361 decode_ws (&dec);
1322 sv = decode_sv (&dec); 1362 sv = decode_sv (&dec);
1323 1363
1324 if (!(offset_return || !sv)) 1364 if (!(offset_return || !sv))
1325 { 1365 {
1326 // check for trailing garbage 1366 // check for trailing garbage
1423 pretty = F_PRETTY 1463 pretty = F_PRETTY
1424 allow_nonref = F_ALLOW_NONREF 1464 allow_nonref = F_ALLOW_NONREF
1425 shrink = F_SHRINK 1465 shrink = F_SHRINK
1426 allow_blessed = F_ALLOW_BLESSED 1466 allow_blessed = F_ALLOW_BLESSED
1427 convert_blessed = F_CONV_BLESSED 1467 convert_blessed = F_CONV_BLESSED
1468 relaxed = F_RELAXED
1428 PPCODE: 1469 PPCODE:
1429{ 1470{
1430 if (enable) 1471 if (enable)
1431 self->flags |= ix; 1472 self->flags |= ix;
1432 else 1473 else

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines