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