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