ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/JSON-XS/XS.xs
Revision: 1.6
Committed: Fri Mar 23 15:10:55 2007 UTC (17 years, 2 months ago) by root
Branch: MAIN
Changes since 1.5: +89 -79 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #include "EXTERN.h"
2     #include "perl.h"
3     #include "XSUB.h"
4    
5     #include "assert.h"
6     #include "string.h"
7     #include "stdlib.h"
8    
9     #define F_ASCII 0x00000001
10     #define F_UTF8 0x00000002
11     #define F_INDENT 0x00000004
12     #define F_CANONICAL 0x00000008
13     #define F_SPACE_BEFORE 0x00000010
14     #define F_SPACE_AFTER 0x00000020
15     #define F_JSON_RPC 0x00000040
16 root 1.3 #define F_ALLOW_NONREF 0x00000080
17 root 1.6 #define F_SHRINK 0x00000100
18 root 1.1
19 root 1.2 #define F_PRETTY F_INDENT | F_SPACE_BEFORE | F_SPACE_AFTER
20 root 1.1 #define F_DEFAULT 0
21    
22     #define INIT_SIZE 32 // initial scalar size to be allocated
23    
24     #define SB do {
25     #define SE } while (0)
26    
27     static HV *json_stash;
28    
29     // structure used for encoding JSON
30     typedef struct
31     {
32     char *cur;
33     STRLEN len; // SvLEN (sv)
34     char *end; // SvEND (sv)
35     SV *sv;
36     UV flags;
37     int max_recurse;
38     int indent;
39     } enc_t;
40    
41     // structure used for decoding JSON
42     typedef struct
43     {
44     char *cur;
45     char *end;
46 root 1.4 const char *err;
47 root 1.1 UV flags;
48     } dec_t;
49    
50     static UV *
51     SvJSON (SV *sv)
52     {
53     if (!(SvROK (sv) && SvOBJECT (SvRV (sv)) && SvSTASH (SvRV (sv)) == json_stash))
54     croak ("object is not of type JSON::XS");
55    
56     return &SvUVX (SvRV (sv));
57     }
58    
59     /////////////////////////////////////////////////////////////////////////////
60    
61     static void
62     need (enc_t *enc, STRLEN len)
63     {
64     if (enc->cur + len >= enc->end)
65     {
66     STRLEN cur = enc->cur - SvPVX (enc->sv);
67     SvGROW (enc->sv, cur + len + 1);
68     enc->cur = SvPVX (enc->sv) + cur;
69 root 1.4 enc->end = SvPVX (enc->sv) + SvLEN (enc->sv);
70 root 1.1 }
71     }
72    
73     static void
74     encode_ch (enc_t *enc, char ch)
75     {
76     need (enc, 1);
77     *enc->cur++ = ch;
78     }
79    
80     static void
81     encode_str (enc_t *enc, char *str, STRLEN len, int is_utf8)
82     {
83     char *end = str + len;
84    
85 root 1.4 need (enc, len);
86    
87 root 1.1 while (str < end)
88     {
89     unsigned char ch = *(unsigned char *)str;
90 root 1.4
91 root 1.6 if (ch >= 0x20 && ch < 0x80) // most common case
92 root 1.4 {
93 root 1.6 if (ch == '"') // but with slow exceptions
94     {
95     need (enc, len += 1);
96     *enc->cur++ = '\\';
97     *enc->cur++ = '"';
98     }
99     else if (ch == '\\')
100     {
101     need (enc, len += 1);
102     *enc->cur++ = '\\';
103     *enc->cur++ = '\\';
104     }
105     else
106     *enc->cur++ = ch;
107    
108 root 1.4 ++str;
109 root 1.1 }
110     else
111     {
112 root 1.6 switch (ch)
113 root 1.1 {
114 root 1.6 case '\010': need (enc, len += 1); *enc->cur++ = '\\'; *enc->cur++ = 'b'; ++str; break;
115     case '\011': need (enc, len += 1); *enc->cur++ = '\\'; *enc->cur++ = 't'; ++str; break;
116     case '\012': need (enc, len += 1); *enc->cur++ = '\\'; *enc->cur++ = 'n'; ++str; break;
117     case '\014': need (enc, len += 1); *enc->cur++ = '\\'; *enc->cur++ = 'f'; ++str; break;
118     case '\015': need (enc, len += 1); *enc->cur++ = '\\'; *enc->cur++ = 'r'; ++str; break;
119 root 1.1
120 root 1.6 default:
121 root 1.1 {
122 root 1.6 STRLEN clen;
123     UV uch;
124    
125     if (is_utf8)
126     {
127     uch = utf8n_to_uvuni (str, end - str, &clen, UTF8_CHECK_ONLY);
128     if (clen == (STRLEN)-1)
129     croak ("malformed UTF-8 character in string, cannot convert to JSON");
130     }
131     else
132     {
133     uch = ch;
134     clen = 1;
135     }
136    
137     if (uch < 0x80 || enc->flags & F_ASCII)
138     {
139     if (uch > 0xFFFFUL)
140     {
141     need (enc, len += 11);
142     sprintf (enc->cur, "\\u%04x\\u%04x",
143     (uch - 0x10000) / 0x400 + 0xD800,
144     (uch - 0x10000) % 0x400 + 0xDC00);
145     enc->cur += 12;
146     }
147     else
148     {
149     static char hexdigit [16] = "0123456789abcdef";
150     need (enc, len += 5);
151     *enc->cur++ = '\\';
152     *enc->cur++ = 'u';
153     *enc->cur++ = hexdigit [ uch >> 12 ];
154     *enc->cur++ = hexdigit [(uch >> 8) & 15];
155     *enc->cur++ = hexdigit [(uch >> 4) & 15];
156     *enc->cur++ = hexdigit [(uch >> 0) & 15];
157     }
158 root 1.4
159 root 1.6 str += clen;
160     }
161     else if (is_utf8)
162     {
163     need (enc, len += clen);
164     do
165     {
166     *enc->cur++ = *str++;
167     }
168     while (--clen);
169     }
170     else
171     {
172     need (enc, 10); // never more than 11 bytes needed
173     enc->cur = uvuni_to_utf8_flags (enc->cur, uch, 0);
174     ++str;
175     }
176 root 1.5 }
177 root 1.4 }
178 root 1.1 }
179    
180     --len;
181     }
182     }
183    
184     #define INDENT SB \
185     if (enc->flags & F_INDENT) \
186     { \
187     int i_; \
188     need (enc, enc->indent); \
189     for (i_ = enc->indent * 3; i_--; )\
190     encode_ch (enc, ' '); \
191     } \
192     SE
193    
194 root 1.2 #define SPACE SB need (enc, 1); encode_ch (enc, ' '); SE
195 root 1.1 #define NL SB if (enc->flags & F_INDENT) { need (enc, 1); encode_ch (enc, '\n'); } SE
196     #define COMMA SB \
197     encode_ch (enc, ','); \
198     if (enc->flags & F_INDENT) \
199     NL; \
200     else if (enc->flags & F_SPACE_AFTER) \
201     SPACE; \
202     SE
203    
204     static void encode_sv (enc_t *enc, SV *sv);
205    
206     static void
207     encode_av (enc_t *enc, AV *av)
208     {
209     int i, len = av_len (av);
210    
211     encode_ch (enc, '['); NL;
212     ++enc->indent;
213    
214     for (i = 0; i <= len; ++i)
215     {
216     INDENT;
217     encode_sv (enc, *av_fetch (av, i, 0));
218    
219     if (i < len)
220     COMMA;
221     }
222    
223     NL;
224    
225     --enc->indent;
226     INDENT; encode_ch (enc, ']');
227     }
228    
229     static void
230     encode_he (enc_t *enc, HE *he)
231     {
232     encode_ch (enc, '"');
233    
234     if (HeKLEN (he) == HEf_SVKEY)
235     {
236     SV *sv = HeSVKEY (he);
237     STRLEN len;
238 root 1.4 char *str;
239    
240     SvGETMAGIC (sv);
241     str = SvPV (sv, len);
242 root 1.1
243     encode_str (enc, str, len, SvUTF8 (sv));
244     }
245     else
246     encode_str (enc, HeKEY (he), HeKLEN (he), HeKUTF8 (he));
247    
248     encode_ch (enc, '"');
249    
250     if (enc->flags & F_SPACE_BEFORE) SPACE;
251     encode_ch (enc, ':');
252     if (enc->flags & F_SPACE_AFTER ) SPACE;
253     encode_sv (enc, HeVAL (he));
254     }
255    
256     // compare hash entries, used when all keys are bytestrings
257     static int
258     he_cmp_fast (const void *a_, const void *b_)
259     {
260     int cmp;
261    
262     HE *a = *(HE **)a_;
263     HE *b = *(HE **)b_;
264    
265     STRLEN la = HeKLEN (a);
266     STRLEN lb = HeKLEN (b);
267    
268     if (!(cmp == memcmp (HeKEY (a), HeKEY (b), la < lb ? la : lb)))
269     cmp = la < lb ? -1 : la == lb ? 0 : 1;
270    
271     return cmp;
272     }
273    
274     // compare hash entries, used when some keys are sv's or utf-x
275     static int
276     he_cmp_slow (const void *a, const void *b)
277     {
278     return sv_cmp (HeSVKEY_force (*(HE **)a), HeSVKEY_force (*(HE **)b));
279     }
280    
281     static void
282     encode_hv (enc_t *enc, HV *hv)
283     {
284     int count, i;
285    
286     encode_ch (enc, '{'); NL; ++enc->indent;
287    
288     if ((count = hv_iterinit (hv)))
289     {
290     // for canonical output we have to sort by keys first
291     // actually, this is mostly due to the stupid so-called
292     // security workaround added somewhere in 5.8.x.
293     // that randomises hash orderings
294     if (enc->flags & F_CANONICAL)
295     {
296     HE *he, *hes [count];
297     int fast = 1;
298    
299     i = 0;
300     while ((he = hv_iternext (hv)))
301     {
302     hes [i++] = he;
303     if (HeKLEN (he) < 0 || HeKUTF8 (he))
304     fast = 0;
305     }
306    
307     assert (i == count);
308    
309     if (fast)
310     qsort (hes, count, sizeof (HE *), he_cmp_fast);
311     else
312     {
313     // hack to disable "use bytes"
314     COP *oldcop = PL_curcop, cop;
315     cop.op_private = 0;
316     PL_curcop = &cop;
317    
318     SAVETMPS;
319     qsort (hes, count, sizeof (HE *), he_cmp_slow);
320     FREETMPS;
321    
322     PL_curcop = oldcop;
323     }
324    
325     for (i = 0; i < count; ++i)
326     {
327     INDENT;
328     encode_he (enc, hes [i]);
329    
330     if (i < count - 1)
331     COMMA;
332     }
333    
334     NL;
335     }
336     else
337     {
338     SV *sv;
339     HE *he = hv_iternext (hv);
340    
341     for (;;)
342     {
343     INDENT;
344     encode_he (enc, he);
345    
346     if (!(he = hv_iternext (hv)))
347     break;
348    
349     COMMA;
350     }
351    
352     NL;
353     }
354     }
355    
356     --enc->indent; INDENT; encode_ch (enc, '}');
357     }
358    
359     static void
360     encode_sv (enc_t *enc, SV *sv)
361     {
362 root 1.4 SvGETMAGIC (sv);
363    
364 root 1.1 if (SvPOKp (sv))
365     {
366     STRLEN len;
367     char *str = SvPV (sv, len);
368     encode_ch (enc, '"');
369     encode_str (enc, str, len, SvUTF8 (sv));
370     encode_ch (enc, '"');
371     }
372     else if (SvNOKp (sv))
373     {
374     need (enc, NV_DIG + 32);
375     Gconvert (SvNVX (sv), NV_DIG, 0, enc->cur);
376     enc->cur += strlen (enc->cur);
377     }
378     else if (SvIOKp (sv))
379     {
380     need (enc, 64);
381     enc->cur +=
382     SvIsUV(sv)
383     ? snprintf (enc->cur, 64, "%"UVuf, (UV)SvUVX (sv))
384     : snprintf (enc->cur, 64, "%"IVdf, (IV)SvIVX (sv));
385     }
386     else if (SvROK (sv))
387     {
388     if (!--enc->max_recurse)
389     croak ("data structure too deep (hit recursion limit)");
390    
391     sv = SvRV (sv);
392    
393     switch (SvTYPE (sv))
394     {
395     case SVt_PVAV: encode_av (enc, (AV *)sv); break;
396     case SVt_PVHV: encode_hv (enc, (HV *)sv); break;
397    
398     default:
399     croak ("JSON can only represent references to arrays or hashes");
400     }
401     }
402     else if (!SvOK (sv))
403     encode_str (enc, "null", 4, 0);
404     else
405     croak ("encountered perl type that JSON cannot handle");
406     }
407    
408     static SV *
409     encode_json (SV *scalar, UV flags)
410     {
411 root 1.3 if (!(flags & F_ALLOW_NONREF) && !SvROK (scalar))
412     croak ("hash- or arraref required (not a simple scalar, use allow_nonref to allow this)");
413    
414 root 1.1 enc_t enc;
415     enc.flags = flags;
416     enc.sv = sv_2mortal (NEWSV (0, INIT_SIZE));
417     enc.cur = SvPVX (enc.sv);
418     enc.end = SvEND (enc.sv);
419     enc.max_recurse = 0;
420     enc.indent = 0;
421    
422     SvPOK_only (enc.sv);
423     encode_sv (&enc, scalar);
424    
425     if (!(flags & (F_ASCII | F_UTF8)))
426     SvUTF8_on (enc.sv);
427    
428     SvCUR_set (enc.sv, enc.cur - SvPVX (enc.sv));
429 root 1.6
430     #ifdef SvPV_shrink_to_cur
431     if (enc.flags & F_SHRINK)
432     SvPV_shrink_to_cur (enc.sv);
433     #endif
434 root 1.1 return enc.sv;
435     }
436    
437     /////////////////////////////////////////////////////////////////////////////
438    
439     #define WS \
440     for (;;) \
441     { \
442     char ch = *dec->cur; \
443     if (ch > 0x20 \
444     || (ch != 0x20 && ch != 0x0a && ch != 0x0d && ch != 0x09)) \
445     break; \
446     ++dec->cur; \
447     }
448    
449     #define ERR(reason) SB dec->err = reason; goto fail; SE
450     #define EXPECT_CH(ch) SB \
451     if (*dec->cur != ch) \
452     ERR (# ch " expected"); \
453     ++dec->cur; \
454     SE
455    
456     static SV *decode_sv (dec_t *dec);
457    
458     static signed char decode_hexdigit[256];
459    
460     static UV
461     decode_4hex (dec_t *dec)
462     {
463     signed char d1, d2, d3, d4;
464    
465     d1 = decode_hexdigit [((unsigned char *)dec->cur) [0]];
466     if (d1 < 0) ERR ("four hexadecimal digits expected");
467     d2 = decode_hexdigit [((unsigned char *)dec->cur) [1]];
468     if (d2 < 0) ERR ("four hexadecimal digits expected");
469     d3 = decode_hexdigit [((unsigned char *)dec->cur) [2]];
470     if (d3 < 0) ERR ("four hexadecimal digits expected");
471     d4 = decode_hexdigit [((unsigned char *)dec->cur) [3]];
472     if (d4 < 0) ERR ("four hexadecimal digits expected");
473    
474     dec->cur += 4;
475    
476     return ((UV)d1) << 12
477     | ((UV)d2) << 8
478     | ((UV)d3) << 4
479     | ((UV)d4);
480    
481     fail:
482     return (UV)-1;
483     }
484    
485 root 1.4 #define APPEND_GROW(n) SB \
486     if (cur + (n) >= end) \
487     { \
488     STRLEN ofs = cur - SvPVX (sv); \
489     SvGROW (sv, ofs + (n) + 1); \
490     cur = SvPVX (sv) + ofs; \
491     end = SvEND (sv); \
492     } \
493     SE
494    
495     #define APPEND_CH(ch) SB \
496     APPEND_GROW (1); \
497     *cur++ = (ch); \
498     SE
499    
500 root 1.1 static SV *
501     decode_str (dec_t *dec)
502     {
503     SV *sv = NEWSV (0,2);
504     int utf8 = 0;
505 root 1.4 char *cur = SvPVX (sv);
506     char *end = SvEND (sv);
507 root 1.1
508     for (;;)
509     {
510     unsigned char ch = *(unsigned char *)dec->cur;
511    
512     if (ch == '"')
513     break;
514     else if (ch == '\\')
515     {
516     switch (*++dec->cur)
517     {
518     case '\\':
519     case '/':
520     case '"': APPEND_CH (*dec->cur++); break;
521    
522     case 'b': APPEND_CH ('\010'); ++dec->cur; break;
523     case 't': APPEND_CH ('\011'); ++dec->cur; break;
524     case 'n': APPEND_CH ('\012'); ++dec->cur; break;
525     case 'f': APPEND_CH ('\014'); ++dec->cur; break;
526     case 'r': APPEND_CH ('\015'); ++dec->cur; break;
527    
528     case 'u':
529     {
530     UV lo, hi;
531     ++dec->cur;
532    
533     hi = decode_4hex (dec);
534     if (hi == (UV)-1)
535     goto fail;
536    
537     // possibly a surrogate pair
538     if (hi >= 0xd800 && hi < 0xdc00)
539     {
540     if (dec->cur [0] != '\\' || dec->cur [1] != 'u')
541 root 1.5 ERR ("missing low surrogate character in surrogate pair");
542 root 1.1
543     dec->cur += 2;
544    
545     lo = decode_4hex (dec);
546     if (lo == (UV)-1)
547     goto fail;
548    
549     if (lo < 0xdc00 || lo >= 0xe000)
550     ERR ("surrogate pair expected");
551    
552     hi = (hi - 0xD800) * 0x400 + (lo - 0xDC00) + 0x10000;
553     }
554 root 1.5 else if (hi >= 0xdc00 && hi < 0xe000)
555     ERR ("missing high surrogate character in surrogate pair");
556 root 1.1
557     if (hi >= 0x80)
558     {
559     utf8 = 1;
560    
561 root 1.4 APPEND_GROW (4); // at most 4 bytes for 21 bits
562     cur = (char *)uvuni_to_utf8_flags (cur, hi, 0);
563 root 1.1 }
564     else
565     APPEND_CH (hi);
566     }
567     break;
568 root 1.5
569     default:
570     --dec->cur;
571     ERR ("illegal backslash escape sequence in string");
572 root 1.1 }
573     }
574     else if (ch >= 0x20 && ch <= 0x7f)
575     APPEND_CH (*dec->cur++);
576     else if (ch >= 0x80)
577     {
578     STRLEN clen;
579     UV uch = utf8n_to_uvuni (dec->cur, dec->end - dec->cur, &clen, UTF8_CHECK_ONLY);
580 root 1.5 if (clen == (STRLEN)-1)
581 root 1.1 ERR ("malformed UTF-8 character in string, cannot convert to JSON");
582    
583 root 1.4 APPEND_GROW (clen);
584 root 1.5 do
585     {
586     *cur++ = *dec->cur++;
587     }
588     while (--clen);
589    
590     utf8 = 1;
591 root 1.1 }
592 root 1.5 else if (dec->cur == dec->end)
593     ERR ("unexpected end of string while parsing json string");
594 root 1.1 else
595     ERR ("invalid character encountered");
596     }
597    
598     ++dec->cur;
599    
600 root 1.4 SvCUR_set (sv, cur - SvPVX (sv));
601    
602 root 1.1 SvPOK_only (sv);
603     *SvEND (sv) = 0;
604    
605     if (utf8)
606     SvUTF8_on (sv);
607    
608 root 1.6 #ifdef SvPV_shrink_to_cur
609     if (dec->flags & F_SHRINK)
610     SvPV_shrink_to_cur (sv);
611     #endif
612    
613 root 1.1 return sv;
614    
615     fail:
616     SvREFCNT_dec (sv);
617     return 0;
618     }
619    
620     static SV *
621     decode_num (dec_t *dec)
622     {
623     int is_nv = 0;
624     char *start = dec->cur;
625    
626     // [minus]
627     if (*dec->cur == '-')
628     ++dec->cur;
629    
630     if (*dec->cur == '0')
631     {
632     ++dec->cur;
633     if (*dec->cur >= '0' && *dec->cur <= '9')
634     ERR ("malformed number (leading zero must not be followed by another digit)");
635     }
636 root 1.5 else if (*dec->cur < '0' || *dec->cur > '9')
637     ERR ("malformed number (no digits after initial minus)");
638     else
639     do
640     {
641     ++dec->cur;
642     }
643     while (*dec->cur >= '0' && *dec->cur <= '9');
644 root 1.1
645     // [frac]
646     if (*dec->cur == '.')
647     {
648 root 1.5 ++dec->cur;
649    
650     if (*dec->cur < '0' || *dec->cur > '9')
651     ERR ("malformed number (no digits after decimal point)");
652 root 1.1
653     do
654     {
655     ++dec->cur;
656     }
657     while (*dec->cur >= '0' && *dec->cur <= '9');
658 root 1.5
659     is_nv = 1;
660 root 1.1 }
661    
662     // [exp]
663     if (*dec->cur == 'e' || *dec->cur == 'E')
664     {
665 root 1.5 ++dec->cur;
666 root 1.1
667     if (*dec->cur == '-' || *dec->cur == '+')
668     ++dec->cur;
669    
670 root 1.5 if (*dec->cur < '0' || *dec->cur > '9')
671     ERR ("malformed number (no digits after exp sign)");
672    
673     do
674     {
675     ++dec->cur;
676     }
677     while (*dec->cur >= '0' && *dec->cur <= '9');
678    
679     is_nv = 1;
680 root 1.1 }
681    
682     if (!is_nv)
683     {
684     UV uv;
685     int numtype = grok_number (start, dec->cur - start, &uv);
686     if (numtype & IS_NUMBER_IN_UV)
687     if (numtype & IS_NUMBER_NEG)
688     {
689     if (uv < (UV)IV_MIN)
690     return newSViv (-(IV)uv);
691     }
692     else
693     return newSVuv (uv);
694     }
695    
696     return newSVnv (Atof (start));
697    
698     fail:
699     return 0;
700     }
701    
702     static SV *
703     decode_av (dec_t *dec)
704     {
705     AV *av = newAV ();
706    
707 root 1.5 WS;
708     if (*dec->cur == ']')
709     ++dec->cur;
710     else
711     for (;;)
712     {
713     SV *value;
714 root 1.1
715 root 1.5 value = decode_sv (dec);
716     if (!value)
717     goto fail;
718 root 1.1
719 root 1.5 av_push (av, value);
720 root 1.1
721 root 1.5 WS;
722 root 1.1
723 root 1.5 if (*dec->cur == ']')
724     {
725     ++dec->cur;
726     break;
727     }
728    
729     if (*dec->cur != ',')
730     ERR (", or ] expected while parsing array");
731 root 1.1
732 root 1.5 ++dec->cur;
733     }
734 root 1.1
735     return newRV_noinc ((SV *)av);
736    
737     fail:
738     SvREFCNT_dec (av);
739     return 0;
740     }
741    
742     static SV *
743     decode_hv (dec_t *dec)
744     {
745     HV *hv = newHV ();
746    
747 root 1.5 WS;
748     if (*dec->cur == '}')
749     ++dec->cur;
750     else
751     for (;;)
752     {
753     SV *key, *value;
754 root 1.1
755 root 1.5 WS; EXPECT_CH ('"');
756 root 1.1
757 root 1.5 key = decode_str (dec);
758     if (!key)
759     goto fail;
760 root 1.1
761 root 1.5 WS; EXPECT_CH (':');
762 root 1.1
763 root 1.5 value = decode_sv (dec);
764     if (!value)
765     {
766     SvREFCNT_dec (key);
767     goto fail;
768     }
769 root 1.1
770 root 1.5 //TODO: optimise
771     hv_store_ent (hv, key, value, 0);
772 root 1.1
773 root 1.5 WS;
774 root 1.1
775 root 1.5 if (*dec->cur == '}')
776     {
777     ++dec->cur;
778     break;
779     }
780 root 1.1
781 root 1.5 if (*dec->cur != ',')
782     ERR (", or } expected while parsing object/hash");
783 root 1.1
784 root 1.5 ++dec->cur;
785     }
786 root 1.1
787     return newRV_noinc ((SV *)hv);
788    
789     fail:
790     SvREFCNT_dec (hv);
791     return 0;
792     }
793    
794     static SV *
795     decode_sv (dec_t *dec)
796     {
797     WS;
798     switch (*dec->cur)
799     {
800     case '"': ++dec->cur; return decode_str (dec);
801     case '[': ++dec->cur; return decode_av (dec);
802     case '{': ++dec->cur; return decode_hv (dec);
803    
804     case '-':
805     case '0': case '1': case '2': case '3': case '4':
806     case '5': case '6': case '7': case '8': case '9':
807     return decode_num (dec);
808    
809     case 't':
810     if (dec->end - dec->cur >= 4 && !memcmp (dec->cur, "true", 4))
811     {
812     dec->cur += 4;
813     return newSViv (1);
814     }
815     else
816     ERR ("'true' expected");
817    
818     break;
819    
820     case 'f':
821     if (dec->end - dec->cur >= 5 && !memcmp (dec->cur, "false", 5))
822     {
823     dec->cur += 5;
824     return newSViv (0);
825     }
826     else
827     ERR ("'false' expected");
828    
829     break;
830    
831     case 'n':
832     if (dec->end - dec->cur >= 4 && !memcmp (dec->cur, "null", 4))
833     {
834     dec->cur += 4;
835 root 1.5 return newSVsv (&PL_sv_undef);
836 root 1.1 }
837     else
838     ERR ("'null' expected");
839    
840     break;
841    
842     default:
843     ERR ("malformed json string");
844     break;
845     }
846    
847     fail:
848     return 0;
849     }
850    
851     static SV *
852     decode_json (SV *string, UV flags)
853     {
854     SV *sv;
855    
856 root 1.5 if (flags & F_UTF8)
857     sv_utf8_downgrade (string, 0);
858     else
859 root 1.1 sv_utf8_upgrade (string);
860    
861     SvGROW (string, SvCUR (string) + 1); // should basically be a NOP
862    
863     dec_t dec;
864     dec.flags = flags;
865     dec.cur = SvPVX (string);
866     dec.end = SvEND (string);
867     dec.err = 0;
868    
869     sv = decode_sv (&dec);
870    
871     if (!sv)
872     {
873     IV offset = utf8_distance (dec.cur, SvPVX (string));
874     SV *uni = sv_newmortal ();
875 root 1.5 // horrible hack to silence warning inside pv_uni_display
876     COP cop;
877     memset (&cop, 0, sizeof (cop));
878     cop.cop_warnings = pWARN_NONE;
879     SAVEVPTR (PL_curcop);
880     PL_curcop = &cop;
881 root 1.1
882     pv_uni_display (uni, dec.cur, dec.end - dec.cur, 20, UNI_DISPLAY_QQ);
883 root 1.5 croak ("%s, at character offset %d (%s)",
884 root 1.1 dec.err,
885     (int)offset,
886     dec.cur != dec.end ? SvPV_nolen (uni) : "(end of string)");
887     }
888    
889 root 1.3 sv = sv_2mortal (sv);
890    
891     if (!(dec.flags & F_ALLOW_NONREF) && !SvROK (sv))
892     croak ("JSON object or array expected (but number, string, true, false or null found, use allow_nonref to allow this)");
893    
894     return sv;
895 root 1.1 }
896    
897     MODULE = JSON::XS PACKAGE = JSON::XS
898    
899     BOOT:
900     {
901     int i;
902    
903     memset (decode_hexdigit, 0xff, 256);
904     for (i = 10; i--; )
905     decode_hexdigit ['0' + i] = i;
906    
907 root 1.4 for (i = 7; i--; )
908 root 1.1 {
909     decode_hexdigit ['a' + i] = 10 + i;
910     decode_hexdigit ['A' + i] = 10 + i;
911     }
912    
913     json_stash = gv_stashpv ("JSON::XS", 1);
914     }
915    
916 root 1.4 PROTOTYPES: DISABLE
917    
918 root 1.1 SV *new (char *dummy)
919     CODE:
920     RETVAL = sv_bless (newRV_noinc (newSVuv (F_DEFAULT)), json_stash);
921     OUTPUT:
922     RETVAL
923    
924 root 1.6 SV *ascii (SV *self, int enable = 1)
925 root 1.1 ALIAS:
926     ascii = F_ASCII
927     utf8 = F_UTF8
928     indent = F_INDENT
929     canonical = F_CANONICAL
930     space_before = F_SPACE_BEFORE
931     space_after = F_SPACE_AFTER
932     json_rpc = F_JSON_RPC
933 root 1.2 pretty = F_PRETTY
934 root 1.3 allow_nonref = F_ALLOW_NONREF
935 root 1.6 shrink = F_SHRINK
936 root 1.1 CODE:
937     {
938     UV *uv = SvJSON (self);
939     if (enable)
940     *uv |= ix;
941     else
942     *uv &= ~ix;
943    
944     RETVAL = newSVsv (self);
945     }
946     OUTPUT:
947     RETVAL
948    
949     void encode (SV *self, SV *scalar)
950     PPCODE:
951     XPUSHs (encode_json (scalar, *SvJSON (self)));
952    
953 root 1.2 void decode (SV *self, SV *jsonstr)
954 root 1.1 PPCODE:
955 root 1.2 XPUSHs (decode_json (jsonstr, *SvJSON (self)));
956    
957 root 1.4 PROTOTYPES: ENABLE
958    
959 root 1.2 void to_json (SV *scalar)
960     PPCODE:
961     XPUSHs (encode_json (scalar, F_UTF8));
962    
963     void from_json (SV *jsonstr)
964     PPCODE:
965     XPUSHs (decode_json (jsonstr, F_UTF8));
966 root 1.1