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.7 by root, Fri Mar 23 15:57:18 2007 UTC vs.
Revision 1.11 by root, Sat Mar 24 19:42:14 2007 UTC

10#define F_UTF8 0x00000002 10#define F_UTF8 0x00000002
11#define F_INDENT 0x00000004 11#define F_INDENT 0x00000004
12#define F_CANONICAL 0x00000008 12#define F_CANONICAL 0x00000008
13#define F_SPACE_BEFORE 0x00000010 13#define F_SPACE_BEFORE 0x00000010
14#define F_SPACE_AFTER 0x00000020 14#define F_SPACE_AFTER 0x00000020
15#define F_JSON_RPC 0x00000040
16#define F_ALLOW_NONREF 0x00000080 15#define F_ALLOW_NONREF 0x00000080
17#define F_SHRINK 0x00000100 16#define F_SHRINK 0x00000100
18 17
19#define F_PRETTY F_INDENT | F_SPACE_BEFORE | F_SPACE_AFTER 18#define F_PRETTY F_INDENT | F_SPACE_BEFORE | F_SPACE_AFTER
20#define F_DEFAULT 0 19#define F_DEFAULT 0
133 132
134 if (is_utf8) 133 if (is_utf8)
135 { 134 {
136 uch = utf8n_to_uvuni (str, end - str, &clen, UTF8_CHECK_ONLY); 135 uch = utf8n_to_uvuni (str, end - str, &clen, UTF8_CHECK_ONLY);
137 if (clen == (STRLEN)-1) 136 if (clen == (STRLEN)-1)
138 croak ("malformed UTF-8 character in string, cannot convert to JSON"); 137 croak ("malformed or illegal unicode character in string [%.11s], cannot convert to JSON", str);
139 } 138 }
140 else 139 else
141 { 140 {
142 uch = ch; 141 uch = ch;
143 clen = 1; 142 clen = 1;
144 } 143 }
145 144
145 if (uch > 0x10FFFFUL)
146 croak ("out of range codepoint (0x%lx) encountered, unrepresentable in JSON", (unsigned long)uch);
147
146 if (uch < 0x80 || enc->flags & F_ASCII) 148 if (uch < 0x80 || enc->flags & F_ASCII)
147 { 149 {
148 if (uch > 0xFFFFUL) 150 if (uch > 0xFFFFUL)
149 { 151 {
150 need (enc, len += 11); 152 need (enc, len += 11);
151 sprintf (enc->cur, "\\u%04x\\u%04x", 153 sprintf (enc->cur, "\\u%04x\\u%04x",
152 (uch - 0x10000) / 0x400 + 0xD800, 154 (int)((uch - 0x10000) / 0x400 + 0xD800),
153 (uch - 0x10000) % 0x400 + 0xDC00); 155 (int)((uch - 0x10000) % 0x400 + 0xDC00));
154 enc->cur += 12; 156 enc->cur += 12;
155 } 157 }
156 else 158 else
157 { 159 {
158 static char hexdigit [16] = "0123456789abcdef"; 160 static char hexdigit [16] = "0123456789abcdef";
272 HE *b = *(HE **)b_; 274 HE *b = *(HE **)b_;
273 275
274 STRLEN la = HeKLEN (a); 276 STRLEN la = HeKLEN (a);
275 STRLEN lb = HeKLEN (b); 277 STRLEN lb = HeKLEN (b);
276 278
277 if (!(cmp == memcmp (HeKEY (a), HeKEY (b), la < lb ? la : lb))) 279 if (!(cmp = memcmp (HeKEY (a), HeKEY (b), la < lb ? la : lb)))
278 cmp = la < lb ? -1 : la == lb ? 0 : 1; 280 cmp = la - lb;
279 281
280 return cmp; 282 return cmp;
281} 283}
282 284
283// compare hash entries, used when some keys are sv's or utf-x 285// compare hash entries, used when some keys are sv's or utf-x
317 319
318 if (fast) 320 if (fast)
319 qsort (hes, count, sizeof (HE *), he_cmp_fast); 321 qsort (hes, count, sizeof (HE *), he_cmp_fast);
320 else 322 else
321 { 323 {
322 // hack to disable "use bytes" 324 // hack to forcefully disable "use bytes"
323 COP *oldcop = PL_curcop, cop; 325 COP cop = *PL_curcop;
324 cop.op_private = 0; 326 cop.op_private = 0;
327
328 ENTER;
329 SAVETMPS;
330
331 SAVEVPTR (PL_curcop);
325 PL_curcop = &cop; 332 PL_curcop = &cop;
326 333
327 SAVETMPS;
328 qsort (hes, count, sizeof (HE *), he_cmp_slow); 334 qsort (hes, count, sizeof (HE *), he_cmp_slow);
335
329 FREETMPS; 336 FREETMPS;
330 337 LEAVE;
331 PL_curcop = oldcop;
332 } 338 }
333 339
334 for (i = 0; i < count; ++i) 340 for (i = 0; i < count; ++i)
335 { 341 {
336 INDENT; 342 INDENT;
392 ? snprintf (enc->cur, 64, "%"UVuf, (UV)SvUVX (sv)) 398 ? snprintf (enc->cur, 64, "%"UVuf, (UV)SvUVX (sv))
393 : snprintf (enc->cur, 64, "%"IVdf, (IV)SvIVX (sv)); 399 : snprintf (enc->cur, 64, "%"IVdf, (IV)SvIVX (sv));
394 } 400 }
395 else if (SvROK (sv)) 401 else if (SvROK (sv))
396 { 402 {
403 SV *rv = SvRV (sv);
404
397 if (!--enc->max_recurse) 405 if (!--enc->max_recurse)
398 croak ("data structure too deep (hit recursion limit)"); 406 croak ("data structure too deep (hit recursion limit)");
399 407
400 sv = SvRV (sv);
401
402 switch (SvTYPE (sv)) 408 switch (SvTYPE (rv))
403 { 409 {
404 case SVt_PVAV: encode_av (enc, (AV *)sv); break; 410 case SVt_PVAV: encode_av (enc, (AV *)rv); break;
405 case SVt_PVHV: encode_hv (enc, (HV *)sv); break; 411 case SVt_PVHV: encode_hv (enc, (HV *)rv); break;
406 412
407 default: 413 default:
408 croak ("JSON can only represent references to arrays or hashes"); 414 croak ("encountered %s, but JSON can only represent references to arrays or hashes",
415 SvPV_nolen (sv));
409 } 416 }
410 } 417 }
411 else if (!SvOK (sv)) 418 else if (!SvOK (sv))
412 encode_str (enc, "null", 4, 0); 419 encode_str (enc, "null", 4, 0);
413 else 420 else
414 croak ("encountered perl type that JSON cannot handle"); 421 croak ("encountered perl type (%s,0x%x) that JSON cannot handle, you might want to report this",
422 SvPV_nolen (sv), SvFLAGS (sv));
415} 423}
416 424
417static SV * 425static SV *
418encode_json (SV *scalar, UV flags) 426encode_json (SV *scalar, UV flags)
419{ 427{
420 if (!(flags & F_ALLOW_NONREF) && !SvROK (scalar)) 428 if (!(flags & F_ALLOW_NONREF) && !SvROK (scalar))
421 croak ("hash- or arraref required (not a simple scalar, use allow_nonref to allow this)"); 429 croak ("hash- or arrayref expected (not a simple scalar, use allow_nonref to allow this)");
422 430
423 enc_t enc; 431 enc_t enc;
424 enc.flags = flags; 432 enc.flags = flags;
425 enc.sv = sv_2mortal (NEWSV (0, INIT_SIZE)); 433 enc.sv = sv_2mortal (NEWSV (0, INIT_SIZE));
426 enc.cur = SvPVX (enc.sv); 434 enc.cur = SvPVX (enc.sv);
878 { 886 {
879 IV offset = dec.flags & F_UTF8 887 IV offset = dec.flags & F_UTF8
880 ? dec.cur - SvPVX (string) 888 ? dec.cur - SvPVX (string)
881 : utf8_distance (dec.cur, SvPVX (string)); 889 : utf8_distance (dec.cur, SvPVX (string));
882 SV *uni = sv_newmortal (); 890 SV *uni = sv_newmortal ();
891
883 // horrible hack to silence warning inside pv_uni_display 892 // horrible hack to silence warning inside pv_uni_display
884 COP cop; 893 COP cop = *PL_curcop;
885 memset (&cop, 0, sizeof (cop));
886 cop.cop_warnings = pWARN_NONE; 894 cop.cop_warnings = pWARN_NONE;
895 ENTER;
887 SAVEVPTR (PL_curcop); 896 SAVEVPTR (PL_curcop);
888 PL_curcop = &cop; 897 PL_curcop = &cop;
889
890 pv_uni_display (uni, dec.cur, dec.end - dec.cur, 20, UNI_DISPLAY_QQ); 898 pv_uni_display (uni, dec.cur, dec.end - dec.cur, 20, UNI_DISPLAY_QQ);
899 LEAVE;
900
891 croak ("%s, at character offset %d (%s)", 901 croak ("%s, at character offset %d (%s)",
892 dec.err, 902 dec.err,
893 (int)offset, 903 (int)offset,
894 dec.cur != dec.end ? SvPV_nolen (uni) : "(end of string)"); 904 dec.cur != dec.end ? SvPV_nolen (uni) : "(end of string)");
895 } 905 }
896 906
897 sv = sv_2mortal (sv); 907 sv = sv_2mortal (sv);
898 908
899 if (!(dec.flags & F_ALLOW_NONREF) && !SvROK (sv)) 909 if (!(dec.flags & F_ALLOW_NONREF) && !SvROK (sv))
900 croak ("JSON object or array expected (but number, string, true, false or null found, use allow_nonref to allow this)"); 910 croak ("JSON text must be an object or array (but found number, string, true, false or null, use allow_nonref to allow this)");
901 911
902 return sv; 912 return sv;
903} 913}
904 914
905MODULE = JSON::XS PACKAGE = JSON::XS 915MODULE = JSON::XS PACKAGE = JSON::XS
935 utf8 = F_UTF8 945 utf8 = F_UTF8
936 indent = F_INDENT 946 indent = F_INDENT
937 canonical = F_CANONICAL 947 canonical = F_CANONICAL
938 space_before = F_SPACE_BEFORE 948 space_before = F_SPACE_BEFORE
939 space_after = F_SPACE_AFTER 949 space_after = F_SPACE_AFTER
940 json_rpc = F_JSON_RPC
941 pretty = F_PRETTY 950 pretty = F_PRETTY
942 allow_nonref = F_ALLOW_NONREF 951 allow_nonref = F_ALLOW_NONREF
943 shrink = F_SHRINK 952 shrink = F_SHRINK
944 CODE: 953 CODE:
945{ 954{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines