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.47 by root, Sun Jul 1 14:08:03 2007 UTC vs.
Revision 1.48 by root, Sun Jul 1 22:20:00 2007 UTC

59#define expect_true(expr) expect ((expr) != 0, 1) 59#define expect_true(expr) expect ((expr) != 0, 1)
60 60
61static HV *json_stash, *json_boolean_stash; // JSON::XS:: 61static HV *json_stash, *json_boolean_stash; // JSON::XS::
62static SV *json_true, *json_false; 62static SV *json_true, *json_false;
63 63
64typedef struct json { 64typedef struct {
65 U32 flags; 65 U32 flags;
66} JSON__XS; 66} JSON;
67 67
68///////////////////////////////////////////////////////////////////////////// 68/////////////////////////////////////////////////////////////////////////////
69// utility functions 69// utility functions
70 70
71static UV * 71inline void
72SvJSON (SV *sv)
73{
74 if (!(SvROK (sv) && SvOBJECT (SvRV (sv)) && SvSTASH (SvRV (sv)) == json_stash))
75 croak ("object is not of type JSON::XS");
76
77 return &SvUVX (SvRV (sv));
78}
79
80static void
81shrink (SV *sv) 72shrink (SV *sv)
82{ 73{
83 sv_utf8_downgrade (sv, 1); 74 sv_utf8_downgrade (sv, 1);
84 if (SvLEN (sv) > SvCUR (sv) + 1) 75 if (SvLEN (sv) > SvCUR (sv) + 1)
85 { 76 {
120typedef struct 111typedef struct
121{ 112{
122 char *cur; // SvPVX (sv) + current output position 113 char *cur; // SvPVX (sv) + current output position
123 char *end; // SvEND (sv) 114 char *end; // SvEND (sv)
124 SV *sv; // result scalar 115 SV *sv; // result scalar
125 struct json json; 116 JSON json;
126 U32 indent; // indentation level 117 U32 indent; // indentation level
127 U32 maxdepth; // max. indentation/recursion level 118 U32 maxdepth; // max. indentation/recursion level
128} enc_t; 119} enc_t;
129 120
130inline void 121inline void
618 croak ("encountered perl type (%s,0x%x) that JSON cannot handle, you might want to report this", 609 croak ("encountered perl type (%s,0x%x) that JSON cannot handle, you might want to report this",
619 SvPV_nolen (sv), SvFLAGS (sv)); 610 SvPV_nolen (sv), SvFLAGS (sv));
620} 611}
621 612
622static SV * 613static SV *
623encode_json (SV *scalar, struct json *json) 614encode_json (SV *scalar, JSON *json)
624{ 615{
625 enc_t enc; 616 enc_t enc;
626 617
627 if (!(json->flags & F_ALLOW_NONREF) && !SvROK (scalar)) 618 if (!(json->flags & F_ALLOW_NONREF) && !SvROK (scalar))
628 croak ("hash- or arrayref expected (not a simple scalar, use allow_nonref to allow this)"); 619 croak ("hash- or arrayref expected (not a simple scalar, use allow_nonref to allow this)");
656typedef struct 647typedef struct
657{ 648{
658 char *cur; // current parser pointer 649 char *cur; // current parser pointer
659 char *end; // end of input string 650 char *end; // end of input string
660 const char *err; // parse error, if != 0 651 const char *err; // parse error, if != 0
661 struct json json; 652 JSON json;
662 U32 depth; // recursion depth 653 U32 depth; // recursion depth
663 U32 maxdepth; // recursion depth limit 654 U32 maxdepth; // recursion depth limit
664} dec_t; 655} dec_t;
665 656
666inline void 657inline void
1169fail: 1160fail:
1170 return 0; 1161 return 0;
1171} 1162}
1172 1163
1173static SV * 1164static SV *
1174decode_json (SV *string, struct json *json, UV *offset_return) 1165decode_json (SV *string, JSON *json, UV *offset_return)
1175{ 1166{
1176 dec_t dec; 1167 dec_t dec;
1177 UV offset; 1168 UV offset;
1178 SV *sv; 1169 SV *sv;
1179 1170
1274 json_false = get_sv ("JSON::XS::false", 1); SvREADONLY_on (json_false); 1265 json_false = get_sv ("JSON::XS::false", 1); SvREADONLY_on (json_false);
1275} 1266}
1276 1267
1277PROTOTYPES: DISABLE 1268PROTOTYPES: DISABLE
1278 1269
1279SV *new (char *dummy) 1270void new (char *klass)
1280 CODE: 1271 PPCODE:
1281 RETVAL = sv_bless (newRV_noinc (newSVuv (F_DEFAULT)), json_stash); 1272{
1282 OUTPUT: 1273 SV *pv = NEWSV (0, sizeof (JSON));
1283 RETVAL 1274 SvPOK_only (pv);
1275 Zero (SvPVX (pv), 1, sizeof (JSON));
1276 ((JSON *)SvPVX (pv))->flags = F_DEFAULT;
1277 XPUSHs (sv_2mortal (sv_bless (newRV_noinc (pv), json_stash)));
1278}
1284 1279
1285SV *ascii (SV *self, int enable = 1) 1280void ascii (JSON *self, int enable = 1)
1286 ALIAS: 1281 ALIAS:
1287 ascii = F_ASCII 1282 ascii = F_ASCII
1288 latin1 = F_LATIN1 1283 latin1 = F_LATIN1
1289 utf8 = F_UTF8 1284 utf8 = F_UTF8
1290 indent = F_INDENT 1285 indent = F_INDENT
1294 pretty = F_PRETTY 1289 pretty = F_PRETTY
1295 allow_nonref = F_ALLOW_NONREF 1290 allow_nonref = F_ALLOW_NONREF
1296 shrink = F_SHRINK 1291 shrink = F_SHRINK
1297 allow_blessed = F_ALLOW_BLESSED 1292 allow_blessed = F_ALLOW_BLESSED
1298 convert_blessed = F_CONV_BLESSED 1293 convert_blessed = F_CONV_BLESSED
1299 CODE: 1294 PPCODE:
1300{ 1295{
1301 UV *uv = SvJSON (self);
1302 if (enable) 1296 if (enable)
1303 *uv |= ix; 1297 self->flags |= ix;
1304 else 1298 else
1305 *uv &= ~ix; 1299 self->flags &= ~ix;
1306 1300
1307 RETVAL = newSVsv (self); 1301 XPUSHs (ST (0));
1308} 1302}
1309 OUTPUT:
1310 RETVAL
1311 1303
1312SV *max_depth (SV *self, UV max_depth = 0x80000000UL) 1304void max_depth (JSON *self, UV max_depth = 0x80000000UL)
1313 CODE: 1305 PPCODE:
1314{ 1306{
1315 UV *uv = SvJSON (self);
1316 UV log2 = 0; 1307 UV log2 = 0;
1317 1308
1318 if (max_depth > 0x80000000UL) max_depth = 0x80000000UL; 1309 if (max_depth > 0x80000000UL) max_depth = 0x80000000UL;
1319 1310
1320 while ((1UL << log2) < max_depth) 1311 while ((1UL << log2) < max_depth)
1321 ++log2; 1312 ++log2;
1322 1313
1323 *uv = *uv & ~F_MAXDEPTH | (log2 << S_MAXDEPTH); 1314 self->flags = self->flags & ~F_MAXDEPTH | (log2 << S_MAXDEPTH);
1324 1315
1325 RETVAL = newSVsv (self); 1316 XPUSHs (ST (0));
1326} 1317}
1327 OUTPUT:
1328 RETVAL
1329 1318
1330SV *max_size (SV *self, UV max_size = 0) 1319void max_size (JSON *self, UV max_size = 0)
1331 CODE: 1320 PPCODE:
1332{ 1321{
1333 UV *uv = SvJSON (self);
1334 UV log2 = 0; 1322 UV log2 = 0;
1335 1323
1336 if (max_size > 0x80000000UL) max_size = 0x80000000UL; 1324 if (max_size > 0x80000000UL) max_size = 0x80000000UL;
1337 if (max_size == 1) max_size = 2; 1325 if (max_size == 1) max_size = 2;
1338 1326
1339 while ((1UL << log2) < max_size) 1327 while ((1UL << log2) < max_size)
1340 ++log2; 1328 ++log2;
1341 1329
1342 *uv = *uv & ~F_MAXSIZE | (log2 << S_MAXSIZE); 1330 self->flags = self->flags & ~F_MAXSIZE | (log2 << S_MAXSIZE);
1343 1331
1344 RETVAL = newSVsv (self); 1332 XPUSHs (ST (0));
1345} 1333}
1346 OUTPUT:
1347 RETVAL
1348 1334
1349void encode (SV *self, SV *scalar) 1335void encode (JSON *self, SV *scalar)
1350 PPCODE: 1336 PPCODE:
1351{
1352 struct json json = { *SvJSON (self) };
1353 XPUSHs (encode_json (scalar, &json)); 1337 XPUSHs (encode_json (scalar, self));
1354}
1355 1338
1356void decode (SV *self, SV *jsonstr) 1339void decode (JSON *self, SV *jsonstr)
1357 PPCODE: 1340 PPCODE:
1358{
1359 struct json json = { *SvJSON (self) };
1360 XPUSHs (decode_json (jsonstr, &json, 0)); 1341 XPUSHs (decode_json (jsonstr, self, 0));
1361}
1362 1342
1363void decode_prefix (SV *self, SV *jsonstr) 1343void decode_prefix (JSON *self, SV *jsonstr)
1364 PPCODE: 1344 PPCODE:
1365{ 1345{
1366 UV offset; 1346 UV offset;
1367 struct json json = { *SvJSON (self) };
1368 EXTEND (SP, 2); 1347 EXTEND (SP, 2);
1369 PUSHs (decode_json (jsonstr, &json, &offset)); 1348 PUSHs (decode_json (jsonstr, self, &offset));
1370 PUSHs (sv_2mortal (newSVuv (offset))); 1349 PUSHs (sv_2mortal (newSVuv (offset)));
1371} 1350}
1372 1351
1373PROTOTYPES: ENABLE 1352PROTOTYPES: ENABLE
1374 1353
1375void to_json (SV *scalar) 1354void to_json (SV *scalar)
1376 PPCODE: 1355 PPCODE:
1377{ 1356{
1378 struct json json = { F_DEFAULT | F_UTF8 }; 1357 JSON json = { F_DEFAULT | F_UTF8 };
1379 XPUSHs (encode_json (scalar, &json)); 1358 XPUSHs (encode_json (scalar, &json));
1380} 1359}
1381 1360
1382void from_json (SV *jsonstr) 1361void from_json (SV *jsonstr)
1383 PPCODE: 1362 PPCODE:
1384{ 1363{
1385 struct json json = { F_DEFAULT | F_UTF8 }; 1364 JSON json = { F_DEFAULT | F_UTF8 };
1386 XPUSHs (decode_json (jsonstr, &json, 0)); 1365 XPUSHs (decode_json (jsonstr, &json, 0));
1387} 1366}
1388 1367

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines