ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/JSON-XS/XS.xs
Revision: 1.8
Committed: Fri Mar 23 16:13:59 2007 UTC (17 years, 2 months ago) by root
Branch: MAIN
Changes since 1.7: +14 -8 lines
Log Message:
*** empty log message ***

File Contents

# Content
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 #define F_ALLOW_NONREF 0x00000080
17 #define F_SHRINK 0x00000100
18
19 #define F_PRETTY F_INDENT | F_SPACE_BEFORE | F_SPACE_AFTER
20 #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 const char *err;
47 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 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 /////////////////////////////////////////////////////////////////////////////
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 enc->end = SvPVX (enc->sv) + SvLEN (enc->sv);
79 }
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 need (enc, len);
95
96 while (str < end)
97 {
98 unsigned char ch = *(unsigned char *)str;
99
100 if (ch >= 0x20 && ch < 0x80) // most common case
101 {
102 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 ++str;
118 }
119 else
120 {
121 switch (ch)
122 {
123 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
129 default:
130 {
131 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
168 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 need (enc, len += 10); // never more than 11 bytes needed
182 enc->cur = uvuni_to_utf8_flags (enc->cur, uch, 0);
183 ++str;
184 }
185 }
186 }
187 }
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 #define SPACE SB need (enc, 1); encode_ch (enc, ' '); SE
204 #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 char *str;
248
249 SvGETMAGIC (sv);
250 str = SvPV (sv, len);
251
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 forcefully disable "use bytes"
323 COP cop = *PL_curcop;
324 cop.op_private = 0;
325
326 ENTER;
327 SAVETMPS;
328
329 SAVEVPTR (PL_curcop);
330 PL_curcop = &cop;
331
332 qsort (hes, count, sizeof (HE *), he_cmp_slow);
333
334 FREETMPS;
335 LEAVE;
336 }
337
338 for (i = 0; i < count; ++i)
339 {
340 INDENT;
341 encode_he (enc, hes [i]);
342
343 if (i < count - 1)
344 COMMA;
345 }
346
347 NL;
348 }
349 else
350 {
351 SV *sv;
352 HE *he = hv_iternext (hv);
353
354 for (;;)
355 {
356 INDENT;
357 encode_he (enc, he);
358
359 if (!(he = hv_iternext (hv)))
360 break;
361
362 COMMA;
363 }
364
365 NL;
366 }
367 }
368
369 --enc->indent; INDENT; encode_ch (enc, '}');
370 }
371
372 static void
373 encode_sv (enc_t *enc, SV *sv)
374 {
375 SvGETMAGIC (sv);
376
377 if (SvPOKp (sv))
378 {
379 STRLEN len;
380 char *str = SvPV (sv, len);
381 encode_ch (enc, '"');
382 encode_str (enc, str, len, SvUTF8 (sv));
383 encode_ch (enc, '"');
384 }
385 else if (SvNOKp (sv))
386 {
387 need (enc, NV_DIG + 32);
388 Gconvert (SvNVX (sv), NV_DIG, 0, enc->cur);
389 enc->cur += strlen (enc->cur);
390 }
391 else if (SvIOKp (sv))
392 {
393 need (enc, 64);
394 enc->cur +=
395 SvIsUV(sv)
396 ? snprintf (enc->cur, 64, "%"UVuf, (UV)SvUVX (sv))
397 : snprintf (enc->cur, 64, "%"IVdf, (IV)SvIVX (sv));
398 }
399 else if (SvROK (sv))
400 {
401 if (!--enc->max_recurse)
402 croak ("data structure too deep (hit recursion limit)");
403
404 sv = SvRV (sv);
405
406 switch (SvTYPE (sv))
407 {
408 case SVt_PVAV: encode_av (enc, (AV *)sv); break;
409 case SVt_PVHV: encode_hv (enc, (HV *)sv); break;
410
411 default:
412 croak ("JSON can only represent references to arrays or hashes");
413 }
414 }
415 else if (!SvOK (sv))
416 encode_str (enc, "null", 4, 0);
417 else
418 croak ("encountered perl type that JSON cannot handle");
419 }
420
421 static SV *
422 encode_json (SV *scalar, UV flags)
423 {
424 if (!(flags & F_ALLOW_NONREF) && !SvROK (scalar))
425 croak ("hash- or arraref required (not a simple scalar, use allow_nonref to allow this)");
426
427 enc_t enc;
428 enc.flags = flags;
429 enc.sv = sv_2mortal (NEWSV (0, INIT_SIZE));
430 enc.cur = SvPVX (enc.sv);
431 enc.end = SvEND (enc.sv);
432 enc.max_recurse = 0;
433 enc.indent = 0;
434
435 SvPOK_only (enc.sv);
436 encode_sv (&enc, scalar);
437
438 if (!(flags & (F_ASCII | F_UTF8)))
439 SvUTF8_on (enc.sv);
440
441 SvCUR_set (enc.sv, enc.cur - SvPVX (enc.sv));
442
443 if (enc.flags & F_SHRINK)
444 shrink (enc.sv);
445
446 return enc.sv;
447 }
448
449 /////////////////////////////////////////////////////////////////////////////
450
451 #define WS \
452 for (;;) \
453 { \
454 char ch = *dec->cur; \
455 if (ch > 0x20 \
456 || (ch != 0x20 && ch != 0x0a && ch != 0x0d && ch != 0x09)) \
457 break; \
458 ++dec->cur; \
459 }
460
461 #define ERR(reason) SB dec->err = reason; goto fail; SE
462 #define EXPECT_CH(ch) SB \
463 if (*dec->cur != ch) \
464 ERR (# ch " expected"); \
465 ++dec->cur; \
466 SE
467
468 static SV *decode_sv (dec_t *dec);
469
470 static signed char decode_hexdigit[256];
471
472 static UV
473 decode_4hex (dec_t *dec)
474 {
475 signed char d1, d2, d3, d4;
476
477 d1 = decode_hexdigit [((unsigned char *)dec->cur) [0]];
478 if (d1 < 0) ERR ("four hexadecimal digits expected");
479 d2 = decode_hexdigit [((unsigned char *)dec->cur) [1]];
480 if (d2 < 0) ERR ("four hexadecimal digits expected");
481 d3 = decode_hexdigit [((unsigned char *)dec->cur) [2]];
482 if (d3 < 0) ERR ("four hexadecimal digits expected");
483 d4 = decode_hexdigit [((unsigned char *)dec->cur) [3]];
484 if (d4 < 0) ERR ("four hexadecimal digits expected");
485
486 dec->cur += 4;
487
488 return ((UV)d1) << 12
489 | ((UV)d2) << 8
490 | ((UV)d3) << 4
491 | ((UV)d4);
492
493 fail:
494 return (UV)-1;
495 }
496
497 #define APPEND_GROW(n) SB \
498 if (cur + (n) >= end) \
499 { \
500 STRLEN ofs = cur - SvPVX (sv); \
501 SvGROW (sv, ofs + (n) + 1); \
502 cur = SvPVX (sv) + ofs; \
503 end = SvEND (sv); \
504 } \
505 SE
506
507 #define APPEND_CH(ch) SB \
508 APPEND_GROW (1); \
509 *cur++ = (ch); \
510 SE
511
512 static SV *
513 decode_str (dec_t *dec)
514 {
515 SV *sv = NEWSV (0,2);
516 int utf8 = 0;
517 char *cur = SvPVX (sv);
518 char *end = SvEND (sv);
519
520 for (;;)
521 {
522 unsigned char ch = *(unsigned char *)dec->cur;
523
524 if (ch == '"')
525 break;
526 else if (ch == '\\')
527 {
528 switch (*++dec->cur)
529 {
530 case '\\':
531 case '/':
532 case '"': APPEND_CH (*dec->cur++); break;
533
534 case 'b': APPEND_CH ('\010'); ++dec->cur; break;
535 case 't': APPEND_CH ('\011'); ++dec->cur; break;
536 case 'n': APPEND_CH ('\012'); ++dec->cur; break;
537 case 'f': APPEND_CH ('\014'); ++dec->cur; break;
538 case 'r': APPEND_CH ('\015'); ++dec->cur; break;
539
540 case 'u':
541 {
542 UV lo, hi;
543 ++dec->cur;
544
545 hi = decode_4hex (dec);
546 if (hi == (UV)-1)
547 goto fail;
548
549 // possibly a surrogate pair
550 if (hi >= 0xd800 && hi < 0xdc00)
551 {
552 if (dec->cur [0] != '\\' || dec->cur [1] != 'u')
553 ERR ("missing low surrogate character in surrogate pair");
554
555 dec->cur += 2;
556
557 lo = decode_4hex (dec);
558 if (lo == (UV)-1)
559 goto fail;
560
561 if (lo < 0xdc00 || lo >= 0xe000)
562 ERR ("surrogate pair expected");
563
564 hi = (hi - 0xD800) * 0x400 + (lo - 0xDC00) + 0x10000;
565 }
566 else if (hi >= 0xdc00 && hi < 0xe000)
567 ERR ("missing high surrogate character in surrogate pair");
568
569 if (hi >= 0x80)
570 {
571 utf8 = 1;
572
573 APPEND_GROW (4); // at most 4 bytes for 21 bits
574 cur = (char *)uvuni_to_utf8_flags (cur, hi, 0);
575 }
576 else
577 APPEND_CH (hi);
578 }
579 break;
580
581 default:
582 --dec->cur;
583 ERR ("illegal backslash escape sequence in string");
584 }
585 }
586 else if (ch >= 0x20 && ch <= 0x7f)
587 APPEND_CH (*dec->cur++);
588 else if (ch >= 0x80)
589 {
590 STRLEN clen;
591 UV uch = utf8n_to_uvuni (dec->cur, dec->end - dec->cur, &clen, UTF8_CHECK_ONLY);
592 if (clen == (STRLEN)-1)
593 ERR ("malformed UTF-8 character in JSON string");
594
595 APPEND_GROW (clen);
596 do
597 {
598 *cur++ = *dec->cur++;
599 }
600 while (--clen);
601
602 utf8 = 1;
603 }
604 else if (dec->cur == dec->end)
605 ERR ("unexpected end of string while parsing json string");
606 else
607 ERR ("invalid character encountered");
608 }
609
610 ++dec->cur;
611
612 SvCUR_set (sv, cur - SvPVX (sv));
613
614 SvPOK_only (sv);
615 *SvEND (sv) = 0;
616
617 if (utf8)
618 SvUTF8_on (sv);
619
620 if (dec->flags & F_SHRINK)
621 shrink (sv);
622
623 return sv;
624
625 fail:
626 SvREFCNT_dec (sv);
627 return 0;
628 }
629
630 static SV *
631 decode_num (dec_t *dec)
632 {
633 int is_nv = 0;
634 char *start = dec->cur;
635
636 // [minus]
637 if (*dec->cur == '-')
638 ++dec->cur;
639
640 if (*dec->cur == '0')
641 {
642 ++dec->cur;
643 if (*dec->cur >= '0' && *dec->cur <= '9')
644 ERR ("malformed number (leading zero must not be followed by another digit)");
645 }
646 else if (*dec->cur < '0' || *dec->cur > '9')
647 ERR ("malformed number (no digits after initial minus)");
648 else
649 do
650 {
651 ++dec->cur;
652 }
653 while (*dec->cur >= '0' && *dec->cur <= '9');
654
655 // [frac]
656 if (*dec->cur == '.')
657 {
658 ++dec->cur;
659
660 if (*dec->cur < '0' || *dec->cur > '9')
661 ERR ("malformed number (no digits after decimal point)");
662
663 do
664 {
665 ++dec->cur;
666 }
667 while (*dec->cur >= '0' && *dec->cur <= '9');
668
669 is_nv = 1;
670 }
671
672 // [exp]
673 if (*dec->cur == 'e' || *dec->cur == 'E')
674 {
675 ++dec->cur;
676
677 if (*dec->cur == '-' || *dec->cur == '+')
678 ++dec->cur;
679
680 if (*dec->cur < '0' || *dec->cur > '9')
681 ERR ("malformed number (no digits after exp sign)");
682
683 do
684 {
685 ++dec->cur;
686 }
687 while (*dec->cur >= '0' && *dec->cur <= '9');
688
689 is_nv = 1;
690 }
691
692 if (!is_nv)
693 {
694 UV uv;
695 int numtype = grok_number (start, dec->cur - start, &uv);
696 if (numtype & IS_NUMBER_IN_UV)
697 if (numtype & IS_NUMBER_NEG)
698 {
699 if (uv < (UV)IV_MIN)
700 return newSViv (-(IV)uv);
701 }
702 else
703 return newSVuv (uv);
704 }
705
706 return newSVnv (Atof (start));
707
708 fail:
709 return 0;
710 }
711
712 static SV *
713 decode_av (dec_t *dec)
714 {
715 AV *av = newAV ();
716
717 WS;
718 if (*dec->cur == ']')
719 ++dec->cur;
720 else
721 for (;;)
722 {
723 SV *value;
724
725 value = decode_sv (dec);
726 if (!value)
727 goto fail;
728
729 av_push (av, value);
730
731 WS;
732
733 if (*dec->cur == ']')
734 {
735 ++dec->cur;
736 break;
737 }
738
739 if (*dec->cur != ',')
740 ERR (", or ] expected while parsing array");
741
742 ++dec->cur;
743 }
744
745 return newRV_noinc ((SV *)av);
746
747 fail:
748 SvREFCNT_dec (av);
749 return 0;
750 }
751
752 static SV *
753 decode_hv (dec_t *dec)
754 {
755 HV *hv = newHV ();
756
757 WS;
758 if (*dec->cur == '}')
759 ++dec->cur;
760 else
761 for (;;)
762 {
763 SV *key, *value;
764
765 WS; EXPECT_CH ('"');
766
767 key = decode_str (dec);
768 if (!key)
769 goto fail;
770
771 WS; EXPECT_CH (':');
772
773 value = decode_sv (dec);
774 if (!value)
775 {
776 SvREFCNT_dec (key);
777 goto fail;
778 }
779
780 //TODO: optimise
781 hv_store_ent (hv, key, value, 0);
782
783 WS;
784
785 if (*dec->cur == '}')
786 {
787 ++dec->cur;
788 break;
789 }
790
791 if (*dec->cur != ',')
792 ERR (", or } expected while parsing object/hash");
793
794 ++dec->cur;
795 }
796
797 return newRV_noinc ((SV *)hv);
798
799 fail:
800 SvREFCNT_dec (hv);
801 return 0;
802 }
803
804 static SV *
805 decode_sv (dec_t *dec)
806 {
807 WS;
808 switch (*dec->cur)
809 {
810 case '"': ++dec->cur; return decode_str (dec);
811 case '[': ++dec->cur; return decode_av (dec);
812 case '{': ++dec->cur; return decode_hv (dec);
813
814 case '-':
815 case '0': case '1': case '2': case '3': case '4':
816 case '5': case '6': case '7': case '8': case '9':
817 return decode_num (dec);
818
819 case 't':
820 if (dec->end - dec->cur >= 4 && !memcmp (dec->cur, "true", 4))
821 {
822 dec->cur += 4;
823 return newSViv (1);
824 }
825 else
826 ERR ("'true' expected");
827
828 break;
829
830 case 'f':
831 if (dec->end - dec->cur >= 5 && !memcmp (dec->cur, "false", 5))
832 {
833 dec->cur += 5;
834 return newSViv (0);
835 }
836 else
837 ERR ("'false' expected");
838
839 break;
840
841 case 'n':
842 if (dec->end - dec->cur >= 4 && !memcmp (dec->cur, "null", 4))
843 {
844 dec->cur += 4;
845 return newSVsv (&PL_sv_undef);
846 }
847 else
848 ERR ("'null' expected");
849
850 break;
851
852 default:
853 ERR ("malformed json string, neither array, object, number, string or atom");
854 break;
855 }
856
857 fail:
858 return 0;
859 }
860
861 static SV *
862 decode_json (SV *string, UV flags)
863 {
864 SV *sv;
865
866 if (flags & F_UTF8)
867 sv_utf8_downgrade (string, 0);
868 else
869 sv_utf8_upgrade (string);
870
871 SvGROW (string, SvCUR (string) + 1); // should basically be a NOP
872
873 dec_t dec;
874 dec.flags = flags;
875 dec.cur = SvPVX (string);
876 dec.end = SvEND (string);
877 dec.err = 0;
878
879 sv = decode_sv (&dec);
880
881 if (!sv)
882 {
883 IV offset = dec.flags & F_UTF8
884 ? dec.cur - SvPVX (string)
885 : utf8_distance (dec.cur, SvPVX (string));
886 SV *uni = sv_newmortal ();
887
888 // horrible hack to silence warning inside pv_uni_display
889 COP cop = *PL_curcop;
890 cop.cop_warnings = pWARN_NONE;
891 ENTER;
892 SAVEVPTR (PL_curcop);
893 PL_curcop = &cop;
894 pv_uni_display (uni, dec.cur, dec.end - dec.cur, 20, UNI_DISPLAY_QQ);
895 LEAVE;
896
897 croak ("%s, at character offset %d (%s)",
898 dec.err,
899 (int)offset,
900 dec.cur != dec.end ? SvPV_nolen (uni) : "(end of string)");
901 }
902
903 sv = sv_2mortal (sv);
904
905 if (!(dec.flags & F_ALLOW_NONREF) && !SvROK (sv))
906 croak ("JSON object or array expected (but number, string, true, false or null found, use allow_nonref to allow this)");
907
908 return sv;
909 }
910
911 MODULE = JSON::XS PACKAGE = JSON::XS
912
913 BOOT:
914 {
915 int i;
916
917 memset (decode_hexdigit, 0xff, 256);
918 for (i = 10; i--; )
919 decode_hexdigit ['0' + i] = i;
920
921 for (i = 7; i--; )
922 {
923 decode_hexdigit ['a' + i] = 10 + i;
924 decode_hexdigit ['A' + i] = 10 + i;
925 }
926
927 json_stash = gv_stashpv ("JSON::XS", 1);
928 }
929
930 PROTOTYPES: DISABLE
931
932 SV *new (char *dummy)
933 CODE:
934 RETVAL = sv_bless (newRV_noinc (newSVuv (F_DEFAULT)), json_stash);
935 OUTPUT:
936 RETVAL
937
938 SV *ascii (SV *self, int enable = 1)
939 ALIAS:
940 ascii = F_ASCII
941 utf8 = F_UTF8
942 indent = F_INDENT
943 canonical = F_CANONICAL
944 space_before = F_SPACE_BEFORE
945 space_after = F_SPACE_AFTER
946 json_rpc = F_JSON_RPC
947 pretty = F_PRETTY
948 allow_nonref = F_ALLOW_NONREF
949 shrink = F_SHRINK
950 CODE:
951 {
952 UV *uv = SvJSON (self);
953 if (enable)
954 *uv |= ix;
955 else
956 *uv &= ~ix;
957
958 RETVAL = newSVsv (self);
959 }
960 OUTPUT:
961 RETVAL
962
963 void encode (SV *self, SV *scalar)
964 PPCODE:
965 XPUSHs (encode_json (scalar, *SvJSON (self)));
966
967 void decode (SV *self, SV *jsonstr)
968 PPCODE:
969 XPUSHs (decode_json (jsonstr, *SvJSON (self)));
970
971 PROTOTYPES: ENABLE
972
973 void to_json (SV *scalar)
974 PPCODE:
975 XPUSHs (encode_json (scalar, F_UTF8));
976
977 void from_json (SV *jsonstr)
978 PPCODE:
979 XPUSHs (decode_json (jsonstr, F_UTF8));
980