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