ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/JSON-XS/XS.xs
(Generate patch)

Comparing JSON-XS/XS.xs (file contents):
Revision 1.3 by root, Thu Mar 22 18:10:29 2007 UTC vs.
Revision 1.4 by root, Thu Mar 22 21:13:58 2007 UTC

40// structure used for decoding JSON 40// structure used for decoding JSON
41typedef struct 41typedef struct
42{ 42{
43 char *cur; 43 char *cur;
44 char *end; 44 char *end;
45 char *err; 45 const char *err;
46 UV flags; 46 UV flags;
47} dec_t; 47} dec_t;
48 48
49static UV * 49static UV *
50SvJSON (SV *sv) 50SvJSON (SV *sv)
63 if (enc->cur + len >= enc->end) 63 if (enc->cur + len >= enc->end)
64 { 64 {
65 STRLEN cur = enc->cur - SvPVX (enc->sv); 65 STRLEN cur = enc->cur - SvPVX (enc->sv);
66 SvGROW (enc->sv, cur + len + 1); 66 SvGROW (enc->sv, cur + len + 1);
67 enc->cur = SvPVX (enc->sv) + cur; 67 enc->cur = SvPVX (enc->sv) + cur;
68 enc->end = SvEND (enc->sv); 68 enc->end = SvPVX (enc->sv) + SvLEN (enc->sv);
69 } 69 }
70} 70}
71 71
72static void 72static void
73encode_ch (enc_t *enc, char ch) 73encode_ch (enc_t *enc, char ch)
79static void 79static void
80encode_str (enc_t *enc, char *str, STRLEN len, int is_utf8) 80encode_str (enc_t *enc, char *str, STRLEN len, int is_utf8)
81{ 81{
82 char *end = str + len; 82 char *end = str + len;
83 83
84 need (enc, len);
85
84 while (str < end) 86 while (str < end)
85 { 87 {
86 unsigned char ch = *(unsigned char *)str; 88 unsigned char ch = *(unsigned char *)str;
89
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 }
87 if (ch >= 0x20 && ch < 0x80) // most common case 104 else if (ch >= 0x20 && ch < 0x80) // most common case
88 { 105 {
89 *enc->cur++ = ch; 106 *enc->cur++ = ch;
90 str++; 107 ++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;
91 } 122 }
92 else 123 else
93 { 124 {
94 STRLEN clen; 125 STRLEN clen;
95 UV uch; 126 UV uch;
104 { 135 {
105 uch = ch; 136 uch = ch;
106 clen = 1; 137 clen = 1;
107 } 138 }
108 139
109 need (enc, len += 6);
110
111 if (uch < 0xa0 || enc->flags & F_ASCII) 140 if (uch < 0x80 || enc->flags & F_ASCII)
112 { 141 {
113 if (uch > 0xFFFFUL) 142 if (uch > 0xFFFFUL)
114 { 143 {
115 len += 6;
116 need (enc, len += 6); 144 need (enc, len += 11);
117 sprintf (enc->cur, "\\u%04x\\u%04x", 145 sprintf (enc->cur, "\\u%04x\\u%04x",
118 (uch - 0x10000) / 0x400 + 0xD800, 146 (uch - 0x10000) / 0x400 + 0xD800,
119 (uch - 0x10000) % 0x400 + 0xDC00); 147 (uch - 0x10000) % 0x400 + 0xDC00);
120 enc->cur += 12; 148 enc->cur += 12;
121 } 149 }
122 else 150 else
123 { 151 {
124 sprintf (enc->cur, "\\u%04x", uch); 152 static char hexdigit [16] = "0123456789abcdef";
153 need (enc, len += 5);
154 *enc->cur++ = '\\';
125 enc->cur += 6; 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];
126 } 160 }
161
162 str += clen;
127 } 163 }
128 else if (is_utf8) 164 else if (is_utf8)
129 { 165 {
130 memcpy (enc->cur, str, clen); 166 need (enc, len += clen);
167 while (clen--)
131 enc->cur += clen; 168 *enc->cur++ = *str++;
132 } 169 }
133 else 170 else
171 {
172 need (enc, 10); // never more than 11 bytes needed
134 enc->cur = uvuni_to_utf8_flags (enc->cur, uch, 0); 173 enc->cur = uvuni_to_utf8_flags (enc->cur, uch, 0);
135 174 ++str;
136 str += clen; 175 }
137 } 176 }
138 177
139 --len; 178 --len;
140 } 179 }
141} 180}
192 231
193 if (HeKLEN (he) == HEf_SVKEY) 232 if (HeKLEN (he) == HEf_SVKEY)
194 { 233 {
195 SV *sv = HeSVKEY (he); 234 SV *sv = HeSVKEY (he);
196 STRLEN len; 235 STRLEN len;
236 char *str;
237
238 SvGETMAGIC (sv);
197 char *str = SvPV (sv, len); 239 str = SvPV (sv, len);
198 240
199 encode_str (enc, str, len, SvUTF8 (sv)); 241 encode_str (enc, str, len, SvUTF8 (sv));
200 } 242 }
201 else 243 else
202 encode_str (enc, HeKEY (he), HeKLEN (he), HeKUTF8 (he)); 244 encode_str (enc, HeKEY (he), HeKLEN (he), HeKUTF8 (he));
313} 355}
314 356
315static void 357static void
316encode_sv (enc_t *enc, SV *sv) 358encode_sv (enc_t *enc, SV *sv)
317{ 359{
360 SvGETMAGIC (sv);
361
318 if (SvPOKp (sv)) 362 if (SvPOKp (sv))
319 { 363 {
320 STRLEN len; 364 STRLEN len;
321 char *str = SvPV (sv, len); 365 char *str = SvPV (sv, len);
322 encode_ch (enc, '"'); 366 encode_ch (enc, '"');
402 ++dec->cur; \ 446 ++dec->cur; \
403 SE 447 SE
404 448
405static SV *decode_sv (dec_t *dec); 449static SV *decode_sv (dec_t *dec);
406 450
407#define APPEND_CH(ch) SB \
408 SvGROW (sv, cur + 1 + 1); \
409 SvPVX (sv)[cur++] = (ch); \
410 SE
411
412static signed char decode_hexdigit[256]; 451static signed char decode_hexdigit[256];
413 452
414static UV 453static UV
415decode_4hex (dec_t *dec) 454decode_4hex (dec_t *dec)
416{ 455{
434 473
435fail: 474fail:
436 return (UV)-1; 475 return (UV)-1;
437} 476}
438 477
478#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
439static SV * 493static SV *
440decode_str (dec_t *dec) 494decode_str (dec_t *dec)
441{ 495{
442 SV *sv = NEWSV (0,2); 496 SV *sv = NEWSV (0,2);
443 STRLEN cur = 0;
444 int utf8 = 0; 497 int utf8 = 0;
498 char *cur = SvPVX (sv);
499 char *end = SvEND (sv);
445 500
446 for (;;) 501 for (;;)
447 { 502 {
448 unsigned char ch = *(unsigned char *)dec->cur; 503 unsigned char ch = *(unsigned char *)dec->cur;
449 504
494 549
495 if (hi >= 0x80) 550 if (hi >= 0x80)
496 { 551 {
497 utf8 = 1; 552 utf8 = 1;
498 553
499 SvGROW (sv, cur + 4 + 1); // at most 4 bytes for 21 bits 554 APPEND_GROW (4); // at most 4 bytes for 21 bits
500 cur = (char *)uvuni_to_utf8_flags (SvPVX (sv) + cur, hi, 0) - SvPVX (sv); 555 cur = (char *)uvuni_to_utf8_flags (cur, hi, 0);
501 } 556 }
502 else 557 else
503 APPEND_CH (hi); 558 APPEND_CH (hi);
504 } 559 }
505 break; 560 break;
512 STRLEN clen; 567 STRLEN clen;
513 UV uch = utf8n_to_uvuni (dec->cur, dec->end - dec->cur, &clen, UTF8_CHECK_ONLY); 568 UV uch = utf8n_to_uvuni (dec->cur, dec->end - dec->cur, &clen, UTF8_CHECK_ONLY);
514 if (clen < 0) 569 if (clen < 0)
515 ERR ("malformed UTF-8 character in string, cannot convert to JSON"); 570 ERR ("malformed UTF-8 character in string, cannot convert to JSON");
516 571
517 SvGROW (sv, cur + clen + 1); // at most 4 bytes for 21 bits 572 APPEND_GROW (clen);
518 memcpy (SvPVX (sv) + cur, dec->cur, clen); 573 memcpy (cur, dec->cur, clen);
574 cur += clen;
519 dec->cur += clen; 575 dec->cur += clen;
520 } 576 }
521 else 577 else
522 ERR ("invalid character encountered"); 578 ERR ("invalid character encountered");
523 } 579 }
524 580
525 ++dec->cur; 581 ++dec->cur;
526 582
583 SvCUR_set (sv, cur - SvPVX (sv));
584
527 SvPOK_only (sv); 585 SvPOK_only (sv);
528
529 SvCUR_set (sv, cur);
530 *SvEND (sv) = 0; 586 *SvEND (sv) = 0;
531 587
532 if (utf8) 588 if (utf8)
533 SvUTF8_on (sv); 589 SvUTF8_on (sv);
534 590
794 850
795 memset (decode_hexdigit, 0xff, 256); 851 memset (decode_hexdigit, 0xff, 256);
796 for (i = 10; i--; ) 852 for (i = 10; i--; )
797 decode_hexdigit ['0' + i] = i; 853 decode_hexdigit ['0' + i] = i;
798 854
799 for (i = 6; --i; ) 855 for (i = 7; i--; )
800 { 856 {
801 decode_hexdigit ['a' + i] = 10 + i; 857 decode_hexdigit ['a' + i] = 10 + i;
802 decode_hexdigit ['A' + i] = 10 + i; 858 decode_hexdigit ['A' + i] = 10 + i;
803 } 859 }
804 860
805 json_stash = gv_stashpv ("JSON::XS", 1); 861 json_stash = gv_stashpv ("JSON::XS", 1);
806} 862}
863
864PROTOTYPES: DISABLE
807 865
808SV *new (char *dummy) 866SV *new (char *dummy)
809 CODE: 867 CODE:
810 RETVAL = sv_bless (newRV_noinc (newSVuv (F_DEFAULT)), json_stash); 868 RETVAL = sv_bless (newRV_noinc (newSVuv (F_DEFAULT)), json_stash);
811 OUTPUT: 869 OUTPUT:
841 899
842void decode (SV *self, SV *jsonstr) 900void decode (SV *self, SV *jsonstr)
843 PPCODE: 901 PPCODE:
844 XPUSHs (decode_json (jsonstr, *SvJSON (self))); 902 XPUSHs (decode_json (jsonstr, *SvJSON (self)));
845 903
904PROTOTYPES: ENABLE
905
846void to_json (SV *scalar) 906void to_json (SV *scalar)
847 PPCODE: 907 PPCODE:
848 XPUSHs (encode_json (scalar, F_UTF8)); 908 XPUSHs (encode_json (scalar, F_UTF8));
849 909
850void from_json (SV *jsonstr) 910void from_json (SV *jsonstr)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines