21457c7f4acda66aec1ce2b5fff31639696a322e
[packages/precise/mcollective.git] / lib / mcollective / vendor / json / ext / json / ext / parser / parser.c
1
2 #line 1 "parser.rl"
3 #include "parser.h"
4
5 /* unicode */
6
7 static const char digit_values[256] = {
8     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
9     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
10     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
11     -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1,
12     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
13     10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
14     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
15     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
16     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
17     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
18     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
19     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
20     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
21     -1, -1, -1, -1, -1, -1, -1
22 };
23
24 static UTF32 unescape_unicode(const unsigned char *p)
25 {
26     char b;
27     UTF32 result = 0;
28     b = digit_values[p[0]];
29     if (b < 0) return UNI_REPLACEMENT_CHAR;
30     result = (result << 4) | b;
31     b = digit_values[p[1]];
32     result = (result << 4) | b;
33     if (b < 0) return UNI_REPLACEMENT_CHAR;
34     b = digit_values[p[2]];
35     result = (result << 4) | b;
36     if (b < 0) return UNI_REPLACEMENT_CHAR;
37     b = digit_values[p[3]];
38     result = (result << 4) | b;
39     if (b < 0) return UNI_REPLACEMENT_CHAR;
40     return result;
41 }
42
43 static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
44 {
45     int len = 1;
46     if (ch <= 0x7F) {
47         buf[0] = (char) ch;
48     } else if (ch <= 0x07FF) {
49         buf[0] = (char) ((ch >> 6) | 0xC0);
50         buf[1] = (char) ((ch & 0x3F) | 0x80);
51         len++;
52     } else if (ch <= 0xFFFF) {
53         buf[0] = (char) ((ch >> 12) | 0xE0);
54         buf[1] = (char) (((ch >> 6) & 0x3F) | 0x80);
55         buf[2] = (char) ((ch & 0x3F) | 0x80);
56         len += 2;
57     } else if (ch <= 0x1fffff) {
58         buf[0] =(char) ((ch >> 18) | 0xF0);
59         buf[1] =(char) (((ch >> 12) & 0x3F) | 0x80);
60         buf[2] =(char) (((ch >> 6) & 0x3F) | 0x80);
61         buf[3] =(char) ((ch & 0x3F) | 0x80);
62         len += 3;
63     } else {
64         buf[0] = '?';
65     }
66     return len;
67 }
68
69 #ifdef HAVE_RUBY_ENCODING_H
70 static VALUE CEncoding_ASCII_8BIT, CEncoding_UTF_8, CEncoding_UTF_16BE,
71     CEncoding_UTF_16LE, CEncoding_UTF_32BE, CEncoding_UTF_32LE;
72 static ID i_encoding, i_encode;
73 #else
74 static ID i_iconv;
75 #endif
76
77 static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
78 static VALUE CNaN, CInfinity, CMinusInfinity;
79
80 static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
81           i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_quirks_mode,
82           i_object_class, i_array_class, i_key_p, i_deep_const_get, i_match,
83           i_match_string, i_aset, i_leftshift;
84
85
86 #line 109 "parser.rl"
87
88
89
90 #line 91 "parser.c"
91 static const int JSON_object_start = 1;
92 static const int JSON_object_first_final = 27;
93 static const int JSON_object_error = 0;
94
95 static const int JSON_object_en_main = 1;
96
97
98 #line 150 "parser.rl"
99
100
101 static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
102 {
103     int cs = EVIL;
104     VALUE last_name = Qnil;
105     VALUE object_class = json->object_class;
106
107     if (json->max_nesting && json->current_nesting > json->max_nesting) {
108         rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
109     }
110
111     *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
112
113
114 #line 115 "parser.c"
115         {
116         cs = JSON_object_start;
117         }
118
119 #line 165 "parser.rl"
120
121 #line 122 "parser.c"
122         {
123         if ( p == pe )
124                 goto _test_eof;
125         switch ( cs )
126         {
127 case 1:
128         if ( (*p) == 123 )
129                 goto st2;
130         goto st0;
131 st0:
132 cs = 0;
133         goto _out;
134 st2:
135         if ( ++p == pe )
136                 goto _test_eof2;
137 case 2:
138         switch( (*p) ) {
139                 case 13: goto st2;
140                 case 32: goto st2;
141                 case 34: goto tr2;
142                 case 47: goto st23;
143                 case 125: goto tr4;
144         }
145         if ( 9 <= (*p) && (*p) <= 10 )
146                 goto st2;
147         goto st0;
148 tr2:
149 #line 132 "parser.rl"
150         {
151         char *np;
152         json->parsing_name = 1;
153         np = JSON_parse_string(json, p, pe, &last_name);
154         json->parsing_name = 0;
155         if (np == NULL) { p--; {p++; cs = 3; goto _out;} } else {p = (( np))-1;}
156     }
157         goto st3;
158 st3:
159         if ( ++p == pe )
160                 goto _test_eof3;
161 case 3:
162 #line 163 "parser.c"
163         switch( (*p) ) {
164                 case 13: goto st3;
165                 case 32: goto st3;
166                 case 47: goto st4;
167                 case 58: goto st8;
168         }
169         if ( 9 <= (*p) && (*p) <= 10 )
170                 goto st3;
171         goto st0;
172 st4:
173         if ( ++p == pe )
174                 goto _test_eof4;
175 case 4:
176         switch( (*p) ) {
177                 case 42: goto st5;
178                 case 47: goto st7;
179         }
180         goto st0;
181 st5:
182         if ( ++p == pe )
183                 goto _test_eof5;
184 case 5:
185         if ( (*p) == 42 )
186                 goto st6;
187         goto st5;
188 st6:
189         if ( ++p == pe )
190                 goto _test_eof6;
191 case 6:
192         switch( (*p) ) {
193                 case 42: goto st6;
194                 case 47: goto st3;
195         }
196         goto st5;
197 st7:
198         if ( ++p == pe )
199                 goto _test_eof7;
200 case 7:
201         if ( (*p) == 10 )
202                 goto st3;
203         goto st7;
204 st8:
205         if ( ++p == pe )
206                 goto _test_eof8;
207 case 8:
208         switch( (*p) ) {
209                 case 13: goto st8;
210                 case 32: goto st8;
211                 case 34: goto tr11;
212                 case 45: goto tr11;
213                 case 47: goto st19;
214                 case 73: goto tr11;
215                 case 78: goto tr11;
216                 case 91: goto tr11;
217                 case 102: goto tr11;
218                 case 110: goto tr11;
219                 case 116: goto tr11;
220                 case 123: goto tr11;
221         }
222         if ( (*p) > 10 ) {
223                 if ( 48 <= (*p) && (*p) <= 57 )
224                         goto tr11;
225         } else if ( (*p) >= 9 )
226                 goto st8;
227         goto st0;
228 tr11:
229 #line 117 "parser.rl"
230         {
231         VALUE v = Qnil;
232         char *np = JSON_parse_value(json, p, pe, &v);
233         if (np == NULL) {
234             p--; {p++; cs = 9; goto _out;}
235         } else {
236             if (NIL_P(json->object_class)) {
237                 rb_hash_aset(*result, last_name, v);
238             } else {
239                 rb_funcall(*result, i_aset, 2, last_name, v);
240             }
241             {p = (( np))-1;}
242         }
243     }
244         goto st9;
245 st9:
246         if ( ++p == pe )
247                 goto _test_eof9;
248 case 9:
249 #line 250 "parser.c"
250         switch( (*p) ) {
251                 case 13: goto st9;
252                 case 32: goto st9;
253                 case 44: goto st10;
254                 case 47: goto st15;
255                 case 125: goto tr4;
256         }
257         if ( 9 <= (*p) && (*p) <= 10 )
258                 goto st9;
259         goto st0;
260 st10:
261         if ( ++p == pe )
262                 goto _test_eof10;
263 case 10:
264         switch( (*p) ) {
265                 case 13: goto st10;
266                 case 32: goto st10;
267                 case 34: goto tr2;
268                 case 47: goto st11;
269         }
270         if ( 9 <= (*p) && (*p) <= 10 )
271                 goto st10;
272         goto st0;
273 st11:
274         if ( ++p == pe )
275                 goto _test_eof11;
276 case 11:
277         switch( (*p) ) {
278                 case 42: goto st12;
279                 case 47: goto st14;
280         }
281         goto st0;
282 st12:
283         if ( ++p == pe )
284                 goto _test_eof12;
285 case 12:
286         if ( (*p) == 42 )
287                 goto st13;
288         goto st12;
289 st13:
290         if ( ++p == pe )
291                 goto _test_eof13;
292 case 13:
293         switch( (*p) ) {
294                 case 42: goto st13;
295                 case 47: goto st10;
296         }
297         goto st12;
298 st14:
299         if ( ++p == pe )
300                 goto _test_eof14;
301 case 14:
302         if ( (*p) == 10 )
303                 goto st10;
304         goto st14;
305 st15:
306         if ( ++p == pe )
307                 goto _test_eof15;
308 case 15:
309         switch( (*p) ) {
310                 case 42: goto st16;
311                 case 47: goto st18;
312         }
313         goto st0;
314 st16:
315         if ( ++p == pe )
316                 goto _test_eof16;
317 case 16:
318         if ( (*p) == 42 )
319                 goto st17;
320         goto st16;
321 st17:
322         if ( ++p == pe )
323                 goto _test_eof17;
324 case 17:
325         switch( (*p) ) {
326                 case 42: goto st17;
327                 case 47: goto st9;
328         }
329         goto st16;
330 st18:
331         if ( ++p == pe )
332                 goto _test_eof18;
333 case 18:
334         if ( (*p) == 10 )
335                 goto st9;
336         goto st18;
337 tr4:
338 #line 140 "parser.rl"
339         { p--; {p++; cs = 27; goto _out;} }
340         goto st27;
341 st27:
342         if ( ++p == pe )
343                 goto _test_eof27;
344 case 27:
345 #line 346 "parser.c"
346         goto st0;
347 st19:
348         if ( ++p == pe )
349                 goto _test_eof19;
350 case 19:
351         switch( (*p) ) {
352                 case 42: goto st20;
353                 case 47: goto st22;
354         }
355         goto st0;
356 st20:
357         if ( ++p == pe )
358                 goto _test_eof20;
359 case 20:
360         if ( (*p) == 42 )
361                 goto st21;
362         goto st20;
363 st21:
364         if ( ++p == pe )
365                 goto _test_eof21;
366 case 21:
367         switch( (*p) ) {
368                 case 42: goto st21;
369                 case 47: goto st8;
370         }
371         goto st20;
372 st22:
373         if ( ++p == pe )
374                 goto _test_eof22;
375 case 22:
376         if ( (*p) == 10 )
377                 goto st8;
378         goto st22;
379 st23:
380         if ( ++p == pe )
381                 goto _test_eof23;
382 case 23:
383         switch( (*p) ) {
384                 case 42: goto st24;
385                 case 47: goto st26;
386         }
387         goto st0;
388 st24:
389         if ( ++p == pe )
390                 goto _test_eof24;
391 case 24:
392         if ( (*p) == 42 )
393                 goto st25;
394         goto st24;
395 st25:
396         if ( ++p == pe )
397                 goto _test_eof25;
398 case 25:
399         switch( (*p) ) {
400                 case 42: goto st25;
401                 case 47: goto st2;
402         }
403         goto st24;
404 st26:
405         if ( ++p == pe )
406                 goto _test_eof26;
407 case 26:
408         if ( (*p) == 10 )
409                 goto st2;
410         goto st26;
411         }
412         _test_eof2: cs = 2; goto _test_eof;
413         _test_eof3: cs = 3; goto _test_eof;
414         _test_eof4: cs = 4; goto _test_eof;
415         _test_eof5: cs = 5; goto _test_eof;
416         _test_eof6: cs = 6; goto _test_eof;
417         _test_eof7: cs = 7; goto _test_eof;
418         _test_eof8: cs = 8; goto _test_eof;
419         _test_eof9: cs = 9; goto _test_eof;
420         _test_eof10: cs = 10; goto _test_eof;
421         _test_eof11: cs = 11; goto _test_eof;
422         _test_eof12: cs = 12; goto _test_eof;
423         _test_eof13: cs = 13; goto _test_eof;
424         _test_eof14: cs = 14; goto _test_eof;
425         _test_eof15: cs = 15; goto _test_eof;
426         _test_eof16: cs = 16; goto _test_eof;
427         _test_eof17: cs = 17; goto _test_eof;
428         _test_eof18: cs = 18; goto _test_eof;
429         _test_eof27: cs = 27; goto _test_eof;
430         _test_eof19: cs = 19; goto _test_eof;
431         _test_eof20: cs = 20; goto _test_eof;
432         _test_eof21: cs = 21; goto _test_eof;
433         _test_eof22: cs = 22; goto _test_eof;
434         _test_eof23: cs = 23; goto _test_eof;
435         _test_eof24: cs = 24; goto _test_eof;
436         _test_eof25: cs = 25; goto _test_eof;
437         _test_eof26: cs = 26; goto _test_eof;
438
439         _test_eof: {}
440         _out: {}
441         }
442
443 #line 166 "parser.rl"
444
445     if (cs >= JSON_object_first_final) {
446         if (json->create_additions) {
447             VALUE klassname = rb_hash_aref(*result, json->create_id);
448             if (!NIL_P(klassname)) {
449                 VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname);
450                 if (RTEST(rb_funcall(klass, i_json_creatable_p, 0))) {
451                     *result = rb_funcall(klass, i_json_create, 1, *result);
452                 }
453             }
454         }
455         return p + 1;
456     } else {
457         return NULL;
458     }
459 }
460
461
462
463 #line 464 "parser.c"
464 static const int JSON_value_start = 1;
465 static const int JSON_value_first_final = 21;
466 static const int JSON_value_error = 0;
467
468 static const int JSON_value_en_main = 1;
469
470
471 #line 265 "parser.rl"
472
473
474 static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
475 {
476     int cs = EVIL;
477
478
479 #line 480 "parser.c"
480         {
481         cs = JSON_value_start;
482         }
483
484 #line 272 "parser.rl"
485
486 #line 487 "parser.c"
487         {
488         if ( p == pe )
489                 goto _test_eof;
490         switch ( cs )
491         {
492 case 1:
493         switch( (*p) ) {
494                 case 34: goto tr0;
495                 case 45: goto tr2;
496                 case 73: goto st2;
497                 case 78: goto st9;
498                 case 91: goto tr5;
499                 case 102: goto st11;
500                 case 110: goto st15;
501                 case 116: goto st18;
502                 case 123: goto tr9;
503         }
504         if ( 48 <= (*p) && (*p) <= 57 )
505                 goto tr2;
506         goto st0;
507 st0:
508 cs = 0;
509         goto _out;
510 tr0:
511 #line 213 "parser.rl"
512         {
513         char *np = JSON_parse_string(json, p, pe, result);
514         if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
515     }
516         goto st21;
517 tr2:
518 #line 218 "parser.rl"
519         {
520         char *np;
521         if(pe > p + 9 - json->quirks_mode && !strncmp(MinusInfinity, p, 9)) {
522             if (json->allow_nan) {
523                 *result = CMinusInfinity;
524                 {p = (( p + 10))-1;}
525                 p--; {p++; cs = 21; goto _out;}
526             } else {
527                 rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
528             }
529         }
530         np = JSON_parse_float(json, p, pe, result);
531         if (np != NULL) {p = (( np))-1;}
532         np = JSON_parse_integer(json, p, pe, result);
533         if (np != NULL) {p = (( np))-1;}
534         p--; {p++; cs = 21; goto _out;}
535     }
536         goto st21;
537 tr5:
538 #line 236 "parser.rl"
539         {
540         char *np;
541         json->current_nesting++;
542         np = JSON_parse_array(json, p, pe, result);
543         json->current_nesting--;
544         if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
545     }
546         goto st21;
547 tr9:
548 #line 244 "parser.rl"
549         {
550         char *np;
551         json->current_nesting++;
552         np =  JSON_parse_object(json, p, pe, result);
553         json->current_nesting--;
554         if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
555     }
556         goto st21;
557 tr16:
558 #line 206 "parser.rl"
559         {
560         if (json->allow_nan) {
561             *result = CInfinity;
562         } else {
563             rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
564         }
565     }
566         goto st21;
567 tr18:
568 #line 199 "parser.rl"
569         {
570         if (json->allow_nan) {
571             *result = CNaN;
572         } else {
573             rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
574         }
575     }
576         goto st21;
577 tr22:
578 #line 193 "parser.rl"
579         {
580         *result = Qfalse;
581     }
582         goto st21;
583 tr25:
584 #line 190 "parser.rl"
585         {
586         *result = Qnil;
587     }
588         goto st21;
589 tr28:
590 #line 196 "parser.rl"
591         {
592         *result = Qtrue;
593     }
594         goto st21;
595 st21:
596         if ( ++p == pe )
597                 goto _test_eof21;
598 case 21:
599 #line 252 "parser.rl"
600         { p--; {p++; cs = 21; goto _out;} }
601 #line 602 "parser.c"
602         goto st0;
603 st2:
604         if ( ++p == pe )
605                 goto _test_eof2;
606 case 2:
607         if ( (*p) == 110 )
608                 goto st3;
609         goto st0;
610 st3:
611         if ( ++p == pe )
612                 goto _test_eof3;
613 case 3:
614         if ( (*p) == 102 )
615                 goto st4;
616         goto st0;
617 st4:
618         if ( ++p == pe )
619                 goto _test_eof4;
620 case 4:
621         if ( (*p) == 105 )
622                 goto st5;
623         goto st0;
624 st5:
625         if ( ++p == pe )
626                 goto _test_eof5;
627 case 5:
628         if ( (*p) == 110 )
629                 goto st6;
630         goto st0;
631 st6:
632         if ( ++p == pe )
633                 goto _test_eof6;
634 case 6:
635         if ( (*p) == 105 )
636                 goto st7;
637         goto st0;
638 st7:
639         if ( ++p == pe )
640                 goto _test_eof7;
641 case 7:
642         if ( (*p) == 116 )
643                 goto st8;
644         goto st0;
645 st8:
646         if ( ++p == pe )
647                 goto _test_eof8;
648 case 8:
649         if ( (*p) == 121 )
650                 goto tr16;
651         goto st0;
652 st9:
653         if ( ++p == pe )
654                 goto _test_eof9;
655 case 9:
656         if ( (*p) == 97 )
657                 goto st10;
658         goto st0;
659 st10:
660         if ( ++p == pe )
661                 goto _test_eof10;
662 case 10:
663         if ( (*p) == 78 )
664                 goto tr18;
665         goto st0;
666 st11:
667         if ( ++p == pe )
668                 goto _test_eof11;
669 case 11:
670         if ( (*p) == 97 )
671                 goto st12;
672         goto st0;
673 st12:
674         if ( ++p == pe )
675                 goto _test_eof12;
676 case 12:
677         if ( (*p) == 108 )
678                 goto st13;
679         goto st0;
680 st13:
681         if ( ++p == pe )
682                 goto _test_eof13;
683 case 13:
684         if ( (*p) == 115 )
685                 goto st14;
686         goto st0;
687 st14:
688         if ( ++p == pe )
689                 goto _test_eof14;
690 case 14:
691         if ( (*p) == 101 )
692                 goto tr22;
693         goto st0;
694 st15:
695         if ( ++p == pe )
696                 goto _test_eof15;
697 case 15:
698         if ( (*p) == 117 )
699                 goto st16;
700         goto st0;
701 st16:
702         if ( ++p == pe )
703                 goto _test_eof16;
704 case 16:
705         if ( (*p) == 108 )
706                 goto st17;
707         goto st0;
708 st17:
709         if ( ++p == pe )
710                 goto _test_eof17;
711 case 17:
712         if ( (*p) == 108 )
713                 goto tr25;
714         goto st0;
715 st18:
716         if ( ++p == pe )
717                 goto _test_eof18;
718 case 18:
719         if ( (*p) == 114 )
720                 goto st19;
721         goto st0;
722 st19:
723         if ( ++p == pe )
724                 goto _test_eof19;
725 case 19:
726         if ( (*p) == 117 )
727                 goto st20;
728         goto st0;
729 st20:
730         if ( ++p == pe )
731                 goto _test_eof20;
732 case 20:
733         if ( (*p) == 101 )
734                 goto tr28;
735         goto st0;
736         }
737         _test_eof21: cs = 21; goto _test_eof;
738         _test_eof2: cs = 2; goto _test_eof;
739         _test_eof3: cs = 3; goto _test_eof;
740         _test_eof4: cs = 4; goto _test_eof;
741         _test_eof5: cs = 5; goto _test_eof;
742         _test_eof6: cs = 6; goto _test_eof;
743         _test_eof7: cs = 7; goto _test_eof;
744         _test_eof8: cs = 8; goto _test_eof;
745         _test_eof9: cs = 9; goto _test_eof;
746         _test_eof10: cs = 10; goto _test_eof;
747         _test_eof11: cs = 11; goto _test_eof;
748         _test_eof12: cs = 12; goto _test_eof;
749         _test_eof13: cs = 13; goto _test_eof;
750         _test_eof14: cs = 14; goto _test_eof;
751         _test_eof15: cs = 15; goto _test_eof;
752         _test_eof16: cs = 16; goto _test_eof;
753         _test_eof17: cs = 17; goto _test_eof;
754         _test_eof18: cs = 18; goto _test_eof;
755         _test_eof19: cs = 19; goto _test_eof;
756         _test_eof20: cs = 20; goto _test_eof;
757
758         _test_eof: {}
759         _out: {}
760         }
761
762 #line 273 "parser.rl"
763
764     if (cs >= JSON_value_first_final) {
765         return p;
766     } else {
767         return NULL;
768     }
769 }
770
771
772 #line 773 "parser.c"
773 static const int JSON_integer_start = 1;
774 static const int JSON_integer_first_final = 3;
775 static const int JSON_integer_error = 0;
776
777 static const int JSON_integer_en_main = 1;
778
779
780 #line 289 "parser.rl"
781
782
783 static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
784 {
785     int cs = EVIL;
786
787
788 #line 789 "parser.c"
789         {
790         cs = JSON_integer_start;
791         }
792
793 #line 296 "parser.rl"
794     json->memo = p;
795
796 #line 797 "parser.c"
797         {
798         if ( p == pe )
799                 goto _test_eof;
800         switch ( cs )
801         {
802 case 1:
803         switch( (*p) ) {
804                 case 45: goto st2;
805                 case 48: goto st3;
806         }
807         if ( 49 <= (*p) && (*p) <= 57 )
808                 goto st5;
809         goto st0;
810 st0:
811 cs = 0;
812         goto _out;
813 st2:
814         if ( ++p == pe )
815                 goto _test_eof2;
816 case 2:
817         if ( (*p) == 48 )
818                 goto st3;
819         if ( 49 <= (*p) && (*p) <= 57 )
820                 goto st5;
821         goto st0;
822 st3:
823         if ( ++p == pe )
824                 goto _test_eof3;
825 case 3:
826         if ( 48 <= (*p) && (*p) <= 57 )
827                 goto st0;
828         goto tr4;
829 tr4:
830 #line 286 "parser.rl"
831         { p--; {p++; cs = 4; goto _out;} }
832         goto st4;
833 st4:
834         if ( ++p == pe )
835                 goto _test_eof4;
836 case 4:
837 #line 838 "parser.c"
838         goto st0;
839 st5:
840         if ( ++p == pe )
841                 goto _test_eof5;
842 case 5:
843         if ( 48 <= (*p) && (*p) <= 57 )
844                 goto st5;
845         goto tr4;
846         }
847         _test_eof2: cs = 2; goto _test_eof;
848         _test_eof3: cs = 3; goto _test_eof;
849         _test_eof4: cs = 4; goto _test_eof;
850         _test_eof5: cs = 5; goto _test_eof;
851
852         _test_eof: {}
853         _out: {}
854         }
855
856 #line 298 "parser.rl"
857
858     if (cs >= JSON_integer_first_final) {
859         long len = p - json->memo;
860         *result = rb_Integer(rb_str_new(json->memo, len));
861         return p + 1;
862     } else {
863         return NULL;
864     }
865 }
866
867
868 #line 869 "parser.c"
869 static const int JSON_float_start = 1;
870 static const int JSON_float_first_final = 8;
871 static const int JSON_float_error = 0;
872
873 static const int JSON_float_en_main = 1;
874
875
876 #line 320 "parser.rl"
877
878
879 static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
880 {
881     int cs = EVIL;
882
883
884 #line 885 "parser.c"
885         {
886         cs = JSON_float_start;
887         }
888
889 #line 327 "parser.rl"
890     json->memo = p;
891
892 #line 893 "parser.c"
893         {
894         if ( p == pe )
895                 goto _test_eof;
896         switch ( cs )
897         {
898 case 1:
899         switch( (*p) ) {
900                 case 45: goto st2;
901                 case 48: goto st3;
902         }
903         if ( 49 <= (*p) && (*p) <= 57 )
904                 goto st7;
905         goto st0;
906 st0:
907 cs = 0;
908         goto _out;
909 st2:
910         if ( ++p == pe )
911                 goto _test_eof2;
912 case 2:
913         if ( (*p) == 48 )
914                 goto st3;
915         if ( 49 <= (*p) && (*p) <= 57 )
916                 goto st7;
917         goto st0;
918 st3:
919         if ( ++p == pe )
920                 goto _test_eof3;
921 case 3:
922         switch( (*p) ) {
923                 case 46: goto st4;
924                 case 69: goto st5;
925                 case 101: goto st5;
926         }
927         goto st0;
928 st4:
929         if ( ++p == pe )
930                 goto _test_eof4;
931 case 4:
932         if ( 48 <= (*p) && (*p) <= 57 )
933                 goto st8;
934         goto st0;
935 st8:
936         if ( ++p == pe )
937                 goto _test_eof8;
938 case 8:
939         switch( (*p) ) {
940                 case 69: goto st5;
941                 case 101: goto st5;
942         }
943         if ( (*p) > 46 ) {
944                 if ( 48 <= (*p) && (*p) <= 57 )
945                         goto st8;
946         } else if ( (*p) >= 45 )
947                 goto st0;
948         goto tr9;
949 tr9:
950 #line 314 "parser.rl"
951         { p--; {p++; cs = 9; goto _out;} }
952         goto st9;
953 st9:
954         if ( ++p == pe )
955                 goto _test_eof9;
956 case 9:
957 #line 958 "parser.c"
958         goto st0;
959 st5:
960         if ( ++p == pe )
961                 goto _test_eof5;
962 case 5:
963         switch( (*p) ) {
964                 case 43: goto st6;
965                 case 45: goto st6;
966         }
967         if ( 48 <= (*p) && (*p) <= 57 )
968                 goto st10;
969         goto st0;
970 st6:
971         if ( ++p == pe )
972                 goto _test_eof6;
973 case 6:
974         if ( 48 <= (*p) && (*p) <= 57 )
975                 goto st10;
976         goto st0;
977 st10:
978         if ( ++p == pe )
979                 goto _test_eof10;
980 case 10:
981         switch( (*p) ) {
982                 case 69: goto st0;
983                 case 101: goto st0;
984         }
985         if ( (*p) > 46 ) {
986                 if ( 48 <= (*p) && (*p) <= 57 )
987                         goto st10;
988         } else if ( (*p) >= 45 )
989                 goto st0;
990         goto tr9;
991 st7:
992         if ( ++p == pe )
993                 goto _test_eof7;
994 case 7:
995         switch( (*p) ) {
996                 case 46: goto st4;
997                 case 69: goto st5;
998                 case 101: goto st5;
999         }
1000         if ( 48 <= (*p) && (*p) <= 57 )
1001                 goto st7;
1002         goto st0;
1003         }
1004         _test_eof2: cs = 2; goto _test_eof;
1005         _test_eof3: cs = 3; goto _test_eof;
1006         _test_eof4: cs = 4; goto _test_eof;
1007         _test_eof8: cs = 8; goto _test_eof;
1008         _test_eof9: cs = 9; goto _test_eof;
1009         _test_eof5: cs = 5; goto _test_eof;
1010         _test_eof6: cs = 6; goto _test_eof;
1011         _test_eof10: cs = 10; goto _test_eof;
1012         _test_eof7: cs = 7; goto _test_eof;
1013
1014         _test_eof: {}
1015         _out: {}
1016         }
1017
1018 #line 329 "parser.rl"
1019
1020     if (cs >= JSON_float_first_final) {
1021         long len = p - json->memo;
1022         *result = rb_Float(rb_str_new(json->memo, len));
1023         return p + 1;
1024     } else {
1025         return NULL;
1026     }
1027 }
1028
1029
1030
1031 #line 1032 "parser.c"
1032 static const int JSON_array_start = 1;
1033 static const int JSON_array_first_final = 17;
1034 static const int JSON_array_error = 0;
1035
1036 static const int JSON_array_en_main = 1;
1037
1038
1039 #line 369 "parser.rl"
1040
1041
1042 static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
1043 {
1044     int cs = EVIL;
1045     VALUE array_class = json->array_class;
1046
1047     if (json->max_nesting && json->current_nesting > json->max_nesting) {
1048         rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
1049     }
1050     *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
1051
1052
1053 #line 1054 "parser.c"
1054         {
1055         cs = JSON_array_start;
1056         }
1057
1058 #line 382 "parser.rl"
1059
1060 #line 1061 "parser.c"
1061         {
1062         if ( p == pe )
1063                 goto _test_eof;
1064         switch ( cs )
1065         {
1066 case 1:
1067         if ( (*p) == 91 )
1068                 goto st2;
1069         goto st0;
1070 st0:
1071 cs = 0;
1072         goto _out;
1073 st2:
1074         if ( ++p == pe )
1075                 goto _test_eof2;
1076 case 2:
1077         switch( (*p) ) {
1078                 case 13: goto st2;
1079                 case 32: goto st2;
1080                 case 34: goto tr2;
1081                 case 45: goto tr2;
1082                 case 47: goto st13;
1083                 case 73: goto tr2;
1084                 case 78: goto tr2;
1085                 case 91: goto tr2;
1086                 case 93: goto tr4;
1087                 case 102: goto tr2;
1088                 case 110: goto tr2;
1089                 case 116: goto tr2;
1090                 case 123: goto tr2;
1091         }
1092         if ( (*p) > 10 ) {
1093                 if ( 48 <= (*p) && (*p) <= 57 )
1094                         goto tr2;
1095         } else if ( (*p) >= 9 )
1096                 goto st2;
1097         goto st0;
1098 tr2:
1099 #line 346 "parser.rl"
1100         {
1101         VALUE v = Qnil;
1102         char *np = JSON_parse_value(json, p, pe, &v);
1103         if (np == NULL) {
1104             p--; {p++; cs = 3; goto _out;}
1105         } else {
1106             if (NIL_P(json->array_class)) {
1107                 rb_ary_push(*result, v);
1108             } else {
1109                 rb_funcall(*result, i_leftshift, 1, v);
1110             }
1111             {p = (( np))-1;}
1112         }
1113     }
1114         goto st3;
1115 st3:
1116         if ( ++p == pe )
1117                 goto _test_eof3;
1118 case 3:
1119 #line 1120 "parser.c"
1120         switch( (*p) ) {
1121                 case 13: goto st3;
1122                 case 32: goto st3;
1123                 case 44: goto st4;
1124                 case 47: goto st9;
1125                 case 93: goto tr4;
1126         }
1127         if ( 9 <= (*p) && (*p) <= 10 )
1128                 goto st3;
1129         goto st0;
1130 st4:
1131         if ( ++p == pe )
1132                 goto _test_eof4;
1133 case 4:
1134         switch( (*p) ) {
1135                 case 13: goto st4;
1136                 case 32: goto st4;
1137                 case 34: goto tr2;
1138                 case 45: goto tr2;
1139                 case 47: goto st5;
1140                 case 73: goto tr2;
1141                 case 78: goto tr2;
1142                 case 91: goto tr2;
1143                 case 102: goto tr2;
1144                 case 110: goto tr2;
1145                 case 116: goto tr2;
1146                 case 123: goto tr2;
1147         }
1148         if ( (*p) > 10 ) {
1149                 if ( 48 <= (*p) && (*p) <= 57 )
1150                         goto tr2;
1151         } else if ( (*p) >= 9 )
1152                 goto st4;
1153         goto st0;
1154 st5:
1155         if ( ++p == pe )
1156                 goto _test_eof5;
1157 case 5:
1158         switch( (*p) ) {
1159                 case 42: goto st6;
1160                 case 47: goto st8;
1161         }
1162         goto st0;
1163 st6:
1164         if ( ++p == pe )
1165                 goto _test_eof6;
1166 case 6:
1167         if ( (*p) == 42 )
1168                 goto st7;
1169         goto st6;
1170 st7:
1171         if ( ++p == pe )
1172                 goto _test_eof7;
1173 case 7:
1174         switch( (*p) ) {
1175                 case 42: goto st7;
1176                 case 47: goto st4;
1177         }
1178         goto st6;
1179 st8:
1180         if ( ++p == pe )
1181                 goto _test_eof8;
1182 case 8:
1183         if ( (*p) == 10 )
1184                 goto st4;
1185         goto st8;
1186 st9:
1187         if ( ++p == pe )
1188                 goto _test_eof9;
1189 case 9:
1190         switch( (*p) ) {
1191                 case 42: goto st10;
1192                 case 47: goto st12;
1193         }
1194         goto st0;
1195 st10:
1196         if ( ++p == pe )
1197                 goto _test_eof10;
1198 case 10:
1199         if ( (*p) == 42 )
1200                 goto st11;
1201         goto st10;
1202 st11:
1203         if ( ++p == pe )
1204                 goto _test_eof11;
1205 case 11:
1206         switch( (*p) ) {
1207                 case 42: goto st11;
1208                 case 47: goto st3;
1209         }
1210         goto st10;
1211 st12:
1212         if ( ++p == pe )
1213                 goto _test_eof12;
1214 case 12:
1215         if ( (*p) == 10 )
1216                 goto st3;
1217         goto st12;
1218 tr4:
1219 #line 361 "parser.rl"
1220         { p--; {p++; cs = 17; goto _out;} }
1221         goto st17;
1222 st17:
1223         if ( ++p == pe )
1224                 goto _test_eof17;
1225 case 17:
1226 #line 1227 "parser.c"
1227         goto st0;
1228 st13:
1229         if ( ++p == pe )
1230                 goto _test_eof13;
1231 case 13:
1232         switch( (*p) ) {
1233                 case 42: goto st14;
1234                 case 47: goto st16;
1235         }
1236         goto st0;
1237 st14:
1238         if ( ++p == pe )
1239                 goto _test_eof14;
1240 case 14:
1241         if ( (*p) == 42 )
1242                 goto st15;
1243         goto st14;
1244 st15:
1245         if ( ++p == pe )
1246                 goto _test_eof15;
1247 case 15:
1248         switch( (*p) ) {
1249                 case 42: goto st15;
1250                 case 47: goto st2;
1251         }
1252         goto st14;
1253 st16:
1254         if ( ++p == pe )
1255                 goto _test_eof16;
1256 case 16:
1257         if ( (*p) == 10 )
1258                 goto st2;
1259         goto st16;
1260         }
1261         _test_eof2: cs = 2; goto _test_eof;
1262         _test_eof3: cs = 3; goto _test_eof;
1263         _test_eof4: cs = 4; goto _test_eof;
1264         _test_eof5: cs = 5; goto _test_eof;
1265         _test_eof6: cs = 6; goto _test_eof;
1266         _test_eof7: cs = 7; goto _test_eof;
1267         _test_eof8: cs = 8; goto _test_eof;
1268         _test_eof9: cs = 9; goto _test_eof;
1269         _test_eof10: cs = 10; goto _test_eof;
1270         _test_eof11: cs = 11; goto _test_eof;
1271         _test_eof12: cs = 12; goto _test_eof;
1272         _test_eof17: cs = 17; goto _test_eof;
1273         _test_eof13: cs = 13; goto _test_eof;
1274         _test_eof14: cs = 14; goto _test_eof;
1275         _test_eof15: cs = 15; goto _test_eof;
1276         _test_eof16: cs = 16; goto _test_eof;
1277
1278         _test_eof: {}
1279         _out: {}
1280         }
1281
1282 #line 383 "parser.rl"
1283
1284     if(cs >= JSON_array_first_final) {
1285         return p + 1;
1286     } else {
1287         rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
1288         return NULL;
1289     }
1290 }
1291
1292 static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
1293 {
1294     char *p = string, *pe = string, *unescape;
1295     int unescape_len;
1296
1297     while (pe < stringEnd) {
1298         if (*pe == '\\') {
1299             unescape = (char *) "?";
1300             unescape_len = 1;
1301             if (pe > p) rb_str_buf_cat(result, p, pe - p);
1302             switch (*++pe) {
1303                 case 'n':
1304                     unescape = (char *) "\n";
1305                     break;
1306                 case 'r':
1307                     unescape = (char *) "\r";
1308                     break;
1309                 case 't':
1310                     unescape = (char *) "\t";
1311                     break;
1312                 case '"':
1313                     unescape = (char *) "\"";
1314                     break;
1315                 case '\\':
1316                     unescape = (char *) "\\";
1317                     break;
1318                 case 'b':
1319                     unescape = (char *) "\b";
1320                     break;
1321                 case 'f':
1322                     unescape = (char *) "\f";
1323                     break;
1324                 case 'u':
1325                     if (pe > stringEnd - 4) {
1326                         return Qnil;
1327                     } else {
1328                         char buf[4];
1329                         UTF32 ch = unescape_unicode((unsigned char *) ++pe);
1330                         pe += 3;
1331                         if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
1332                             pe++;
1333                             if (pe > stringEnd - 6) return Qnil;
1334                             if (pe[0] == '\\' && pe[1] == 'u') {
1335                                 UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
1336                                 ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
1337                                         | (sur & 0x3FF));
1338                                 pe += 5;
1339                             } else {
1340                                 unescape = (char *) "?";
1341                                 break;
1342                             }
1343                         }
1344                         unescape_len = convert_UTF32_to_UTF8(buf, ch);
1345                         unescape = buf;
1346                     }
1347                     break;
1348                 default:
1349                     p = pe;
1350                     continue;
1351             }
1352             rb_str_buf_cat(result, unescape, unescape_len);
1353             p = ++pe;
1354         } else {
1355             pe++;
1356         }
1357     }
1358     rb_str_buf_cat(result, p, pe - p);
1359     return result;
1360 }
1361
1362
1363 #line 1364 "parser.c"
1364 static const int JSON_string_start = 1;
1365 static const int JSON_string_first_final = 8;
1366 static const int JSON_string_error = 0;
1367
1368 static const int JSON_string_en_main = 1;
1369
1370
1371 #line 482 "parser.rl"
1372
1373
1374 static int
1375 match_i(VALUE regexp, VALUE klass, VALUE memo)
1376 {
1377     if (regexp == Qundef) return ST_STOP;
1378     if (RTEST(rb_funcall(klass, i_json_creatable_p, 0)) &&
1379       RTEST(rb_funcall(regexp, i_match, 1, rb_ary_entry(memo, 0)))) {
1380         rb_ary_push(memo, klass);
1381         return ST_STOP;
1382     }
1383     return ST_CONTINUE;
1384 }
1385
1386 static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
1387 {
1388     int cs = EVIL;
1389     VALUE match_string;
1390
1391     *result = rb_str_buf_new(0);
1392
1393 #line 1394 "parser.c"
1394         {
1395         cs = JSON_string_start;
1396         }
1397
1398 #line 503 "parser.rl"
1399     json->memo = p;
1400
1401 #line 1402 "parser.c"
1402         {
1403         if ( p == pe )
1404                 goto _test_eof;
1405         switch ( cs )
1406         {
1407 case 1:
1408         if ( (*p) == 34 )
1409                 goto st2;
1410         goto st0;
1411 st0:
1412 cs = 0;
1413         goto _out;
1414 st2:
1415         if ( ++p == pe )
1416                 goto _test_eof2;
1417 case 2:
1418         switch( (*p) ) {
1419                 case 34: goto tr2;
1420                 case 92: goto st3;
1421         }
1422         if ( 0 <= (*p) && (*p) <= 31 )
1423                 goto st0;
1424         goto st2;
1425 tr2:
1426 #line 468 "parser.rl"
1427         {
1428         *result = json_string_unescape(*result, json->memo + 1, p);
1429         if (NIL_P(*result)) {
1430             p--;
1431             {p++; cs = 8; goto _out;}
1432         } else {
1433             FORCE_UTF8(*result);
1434             {p = (( p + 1))-1;}
1435         }
1436     }
1437 #line 479 "parser.rl"
1438         { p--; {p++; cs = 8; goto _out;} }
1439         goto st8;
1440 st8:
1441         if ( ++p == pe )
1442                 goto _test_eof8;
1443 case 8:
1444 #line 1445 "parser.c"
1445         goto st0;
1446 st3:
1447         if ( ++p == pe )
1448                 goto _test_eof3;
1449 case 3:
1450         if ( (*p) == 117 )
1451                 goto st4;
1452         if ( 0 <= (*p) && (*p) <= 31 )
1453                 goto st0;
1454         goto st2;
1455 st4:
1456         if ( ++p == pe )
1457                 goto _test_eof4;
1458 case 4:
1459         if ( (*p) < 65 ) {
1460                 if ( 48 <= (*p) && (*p) <= 57 )
1461                         goto st5;
1462         } else if ( (*p) > 70 ) {
1463                 if ( 97 <= (*p) && (*p) <= 102 )
1464                         goto st5;
1465         } else
1466                 goto st5;
1467         goto st0;
1468 st5:
1469         if ( ++p == pe )
1470                 goto _test_eof5;
1471 case 5:
1472         if ( (*p) < 65 ) {
1473                 if ( 48 <= (*p) && (*p) <= 57 )
1474                         goto st6;
1475         } else if ( (*p) > 70 ) {
1476                 if ( 97 <= (*p) && (*p) <= 102 )
1477                         goto st6;
1478         } else
1479                 goto st6;
1480         goto st0;
1481 st6:
1482         if ( ++p == pe )
1483                 goto _test_eof6;
1484 case 6:
1485         if ( (*p) < 65 ) {
1486                 if ( 48 <= (*p) && (*p) <= 57 )
1487                         goto st7;
1488         } else if ( (*p) > 70 ) {
1489                 if ( 97 <= (*p) && (*p) <= 102 )
1490                         goto st7;
1491         } else
1492                 goto st7;
1493         goto st0;
1494 st7:
1495         if ( ++p == pe )
1496                 goto _test_eof7;
1497 case 7:
1498         if ( (*p) < 65 ) {
1499                 if ( 48 <= (*p) && (*p) <= 57 )
1500                         goto st2;
1501         } else if ( (*p) > 70 ) {
1502                 if ( 97 <= (*p) && (*p) <= 102 )
1503                         goto st2;
1504         } else
1505                 goto st2;
1506         goto st0;
1507         }
1508         _test_eof2: cs = 2; goto _test_eof;
1509         _test_eof8: cs = 8; goto _test_eof;
1510         _test_eof3: cs = 3; goto _test_eof;
1511         _test_eof4: cs = 4; goto _test_eof;
1512         _test_eof5: cs = 5; goto _test_eof;
1513         _test_eof6: cs = 6; goto _test_eof;
1514         _test_eof7: cs = 7; goto _test_eof;
1515
1516         _test_eof: {}
1517         _out: {}
1518         }
1519
1520 #line 505 "parser.rl"
1521
1522     if (json->create_additions && RTEST(match_string = json->match_string)) {
1523           VALUE klass;
1524           VALUE memo = rb_ary_new2(2);
1525           rb_ary_push(memo, *result);
1526           rb_hash_foreach(match_string, match_i, memo);
1527           klass = rb_ary_entry(memo, 1);
1528           if (RTEST(klass)) {
1529               *result = rb_funcall(klass, i_json_create, 1, *result);
1530           }
1531     }
1532
1533     if (json->symbolize_names && json->parsing_name) {
1534       *result = rb_str_intern(*result);
1535     }
1536     if (cs >= JSON_string_first_final) {
1537         return p + 1;
1538     } else {
1539         return NULL;
1540     }
1541 }
1542
1543 /*
1544  * Document-class: JSON::Ext::Parser
1545  *
1546  * This is the JSON parser implemented as a C extension. It can be configured
1547  * to be used by setting
1548  *
1549  *  JSON.parser = JSON::Ext::Parser
1550  *
1551  * with the method parser= in JSON.
1552  *
1553  */
1554
1555 static VALUE convert_encoding(VALUE source)
1556 {
1557     char *ptr = RSTRING_PTR(source);
1558     long len = RSTRING_LEN(source);
1559     if (len < 2) {
1560         rb_raise(eParserError, "A JSON text must at least contain two octets!");
1561     }
1562 #ifdef HAVE_RUBY_ENCODING_H
1563     {
1564         VALUE encoding = rb_funcall(source, i_encoding, 0);
1565         if (encoding == CEncoding_ASCII_8BIT) {
1566             if (len >= 4 &&  ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
1567                 source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_32BE);
1568             } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
1569                 source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16BE);
1570             } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
1571                 source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_32LE);
1572             } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
1573                 source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16LE);
1574             } else {
1575                 source = rb_str_dup(source);
1576                 FORCE_UTF8(source);
1577             }
1578         } else {
1579             source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8);
1580         }
1581     }
1582 #else
1583     if (len >= 4 &&  ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
1584       source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32be"), source);
1585     } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
1586       source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16be"), source);
1587     } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
1588       source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32le"), source);
1589     } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
1590       source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16le"), source);
1591     }
1592 #endif
1593     return source;
1594 }
1595
1596 /*
1597  * call-seq: new(source, opts => {})
1598  *
1599  * Creates a new JSON::Ext::Parser instance for the string _source_.
1600  *
1601  * Creates a new JSON::Ext::Parser instance for the string _source_.
1602  *
1603  * It will be configured by the _opts_ hash. _opts_ can have the following
1604  * keys:
1605  *
1606  * _opts_ can have the following keys:
1607  * * *max_nesting*: The maximum depth of nesting allowed in the parsed data
1608  *   structures. Disable depth checking with :max_nesting => false|nil|0, it
1609  *   defaults to 19.
1610  * * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
1611  *   defiance of RFC 4627 to be parsed by the Parser. This option defaults to
1612  *   false.
1613  * * *symbolize_names*: If set to true, returns symbols for the names
1614  *   (keys) in a JSON object. Otherwise strings are returned, which is also
1615  *   the default.
1616  * * *create_additions*: If set to false, the Parser doesn't create
1617  *   additions even if a matchin class and create_id was found. This option
1618  *   defaults to true.
1619  * * *object_class*: Defaults to Hash
1620  * * *array_class*: Defaults to Array
1621  * * *quirks_mode*: Enables quirks_mode for parser, that is for example
1622  *   parsing single JSON values instead of documents is possible.
1623  *
1624  */
1625 static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1626 {
1627     VALUE source, opts;
1628     GET_PARSER_INIT;
1629
1630     if (json->Vsource) {
1631         rb_raise(rb_eTypeError, "already initialized instance");
1632     }
1633     rb_scan_args(argc, argv, "11", &source, &opts);
1634     if (!NIL_P(opts)) {
1635         opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
1636         if (NIL_P(opts)) {
1637             rb_raise(rb_eArgError, "opts needs to be like a hash");
1638         } else {
1639             VALUE tmp = ID2SYM(i_max_nesting);
1640             if (option_given_p(opts, tmp)) {
1641                 VALUE max_nesting = rb_hash_aref(opts, tmp);
1642                 if (RTEST(max_nesting)) {
1643                     Check_Type(max_nesting, T_FIXNUM);
1644                     json->max_nesting = FIX2INT(max_nesting);
1645                 } else {
1646                     json->max_nesting = 0;
1647                 }
1648             } else {
1649                 json->max_nesting = 19;
1650             }
1651             tmp = ID2SYM(i_allow_nan);
1652             if (option_given_p(opts, tmp)) {
1653                 json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
1654             } else {
1655                 json->allow_nan = 0;
1656             }
1657             tmp = ID2SYM(i_symbolize_names);
1658             if (option_given_p(opts, tmp)) {
1659                 json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
1660             } else {
1661                 json->symbolize_names = 0;
1662             }
1663             tmp = ID2SYM(i_quirks_mode);
1664             if (option_given_p(opts, tmp)) {
1665                 VALUE quirks_mode = rb_hash_aref(opts, tmp);
1666                 json->quirks_mode = RTEST(quirks_mode) ? 1 : 0;
1667             } else {
1668                 json->quirks_mode = 0;
1669             }
1670             tmp = ID2SYM(i_create_additions);
1671             if (option_given_p(opts, tmp)) {
1672                 json->create_additions = RTEST(rb_hash_aref(opts, tmp));
1673             } else {
1674                 json->create_additions = 0;
1675             }
1676             tmp = ID2SYM(i_create_id);
1677             if (option_given_p(opts, tmp)) {
1678                 json->create_id = rb_hash_aref(opts, tmp);
1679             } else {
1680                 json->create_id = rb_funcall(mJSON, i_create_id, 0);
1681             }
1682             tmp = ID2SYM(i_object_class);
1683             if (option_given_p(opts, tmp)) {
1684                 json->object_class = rb_hash_aref(opts, tmp);
1685             } else {
1686                 json->object_class = Qnil;
1687             }
1688             tmp = ID2SYM(i_array_class);
1689             if (option_given_p(opts, tmp)) {
1690                 json->array_class = rb_hash_aref(opts, tmp);
1691             } else {
1692                 json->array_class = Qnil;
1693             }
1694             tmp = ID2SYM(i_match_string);
1695             if (option_given_p(opts, tmp)) {
1696                 VALUE match_string = rb_hash_aref(opts, tmp);
1697                 json->match_string = RTEST(match_string) ? match_string : Qnil;
1698             } else {
1699                 json->match_string = Qnil;
1700             }
1701         }
1702     } else {
1703         json->max_nesting = 19;
1704         json->allow_nan = 0;
1705         json->create_additions = 1;
1706         json->create_id = rb_funcall(mJSON, i_create_id, 0);
1707         json->object_class = Qnil;
1708         json->array_class = Qnil;
1709     }
1710     if (!json->quirks_mode) {
1711       source = convert_encoding(StringValue(source));
1712     }
1713     json->current_nesting = 0;
1714     json->len = RSTRING_LEN(source);
1715     json->source = RSTRING_PTR(source);;
1716     json->Vsource = source;
1717     return self;
1718 }
1719
1720
1721 #line 1722 "parser.c"
1722 static const int JSON_start = 1;
1723 static const int JSON_first_final = 10;
1724 static const int JSON_error = 0;
1725
1726 static const int JSON_en_main = 1;
1727
1728
1729 #line 729 "parser.rl"
1730
1731
1732 static VALUE cParser_parse_strict(VALUE self)
1733 {
1734     char *p, *pe;
1735     int cs = EVIL;
1736     VALUE result = Qnil;
1737     GET_PARSER;
1738
1739
1740 #line 1741 "parser.c"
1741         {
1742         cs = JSON_start;
1743         }
1744
1745 #line 739 "parser.rl"
1746     p = json->source;
1747     pe = p + json->len;
1748
1749 #line 1750 "parser.c"
1750         {
1751         if ( p == pe )
1752                 goto _test_eof;
1753         switch ( cs )
1754         {
1755 st1:
1756         if ( ++p == pe )
1757                 goto _test_eof1;
1758 case 1:
1759         switch( (*p) ) {
1760                 case 13: goto st1;
1761                 case 32: goto st1;
1762                 case 47: goto st2;
1763                 case 91: goto tr3;
1764                 case 123: goto tr4;
1765         }
1766         if ( 9 <= (*p) && (*p) <= 10 )
1767                 goto st1;
1768         goto st0;
1769 st0:
1770 cs = 0;
1771         goto _out;
1772 st2:
1773         if ( ++p == pe )
1774                 goto _test_eof2;
1775 case 2:
1776         switch( (*p) ) {
1777                 case 42: goto st3;
1778                 case 47: goto st5;
1779         }
1780         goto st0;
1781 st3:
1782         if ( ++p == pe )
1783                 goto _test_eof3;
1784 case 3:
1785         if ( (*p) == 42 )
1786                 goto st4;
1787         goto st3;
1788 st4:
1789         if ( ++p == pe )
1790                 goto _test_eof4;
1791 case 4:
1792         switch( (*p) ) {
1793                 case 42: goto st4;
1794                 case 47: goto st1;
1795         }
1796         goto st3;
1797 st5:
1798         if ( ++p == pe )
1799                 goto _test_eof5;
1800 case 5:
1801         if ( (*p) == 10 )
1802                 goto st1;
1803         goto st5;
1804 tr3:
1805 #line 718 "parser.rl"
1806         {
1807         char *np;
1808         json->current_nesting = 1;
1809         np = JSON_parse_array(json, p, pe, &result);
1810         if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
1811     }
1812         goto st10;
1813 tr4:
1814 #line 711 "parser.rl"
1815         {
1816         char *np;
1817         json->current_nesting = 1;
1818         np = JSON_parse_object(json, p, pe, &result);
1819         if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
1820     }
1821         goto st10;
1822 st10:
1823         if ( ++p == pe )
1824                 goto _test_eof10;
1825 case 10:
1826 #line 1827 "parser.c"
1827         switch( (*p) ) {
1828                 case 13: goto st10;
1829                 case 32: goto st10;
1830                 case 47: goto st6;
1831         }
1832         if ( 9 <= (*p) && (*p) <= 10 )
1833                 goto st10;
1834         goto st0;
1835 st6:
1836         if ( ++p == pe )
1837                 goto _test_eof6;
1838 case 6:
1839         switch( (*p) ) {
1840                 case 42: goto st7;
1841                 case 47: goto st9;
1842         }
1843         goto st0;
1844 st7:
1845         if ( ++p == pe )
1846                 goto _test_eof7;
1847 case 7:
1848         if ( (*p) == 42 )
1849                 goto st8;
1850         goto st7;
1851 st8:
1852         if ( ++p == pe )
1853                 goto _test_eof8;
1854 case 8:
1855         switch( (*p) ) {
1856                 case 42: goto st8;
1857                 case 47: goto st10;
1858         }
1859         goto st7;
1860 st9:
1861         if ( ++p == pe )
1862                 goto _test_eof9;
1863 case 9:
1864         if ( (*p) == 10 )
1865                 goto st10;
1866         goto st9;
1867         }
1868         _test_eof1: cs = 1; goto _test_eof;
1869         _test_eof2: cs = 2; goto _test_eof;
1870         _test_eof3: cs = 3; goto _test_eof;
1871         _test_eof4: cs = 4; goto _test_eof;
1872         _test_eof5: cs = 5; goto _test_eof;
1873         _test_eof10: cs = 10; goto _test_eof;
1874         _test_eof6: cs = 6; goto _test_eof;
1875         _test_eof7: cs = 7; goto _test_eof;
1876         _test_eof8: cs = 8; goto _test_eof;
1877         _test_eof9: cs = 9; goto _test_eof;
1878
1879         _test_eof: {}
1880         _out: {}
1881         }
1882
1883 #line 742 "parser.rl"
1884
1885     if (cs >= JSON_first_final && p == pe) {
1886         return result;
1887     } else {
1888         rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
1889         return Qnil;
1890     }
1891 }
1892
1893
1894
1895 #line 1896 "parser.c"
1896 static const int JSON_quirks_mode_start = 1;
1897 static const int JSON_quirks_mode_first_final = 10;
1898 static const int JSON_quirks_mode_error = 0;
1899
1900 static const int JSON_quirks_mode_en_main = 1;
1901
1902
1903 #line 767 "parser.rl"
1904
1905
1906 static VALUE cParser_parse_quirks_mode(VALUE self)
1907 {
1908     char *p, *pe;
1909     int cs = EVIL;
1910     VALUE result = Qnil;
1911     GET_PARSER;
1912
1913
1914 #line 1915 "parser.c"
1915         {
1916         cs = JSON_quirks_mode_start;
1917         }
1918
1919 #line 777 "parser.rl"
1920     p = json->source;
1921     pe = p + json->len;
1922
1923 #line 1924 "parser.c"
1924         {
1925         if ( p == pe )
1926                 goto _test_eof;
1927         switch ( cs )
1928         {
1929 st1:
1930         if ( ++p == pe )
1931                 goto _test_eof1;
1932 case 1:
1933         switch( (*p) ) {
1934                 case 13: goto st1;
1935                 case 32: goto st1;
1936                 case 34: goto tr2;
1937                 case 45: goto tr2;
1938                 case 47: goto st6;
1939                 case 73: goto tr2;
1940                 case 78: goto tr2;
1941                 case 91: goto tr2;
1942                 case 102: goto tr2;
1943                 case 110: goto tr2;
1944                 case 116: goto tr2;
1945                 case 123: goto tr2;
1946         }
1947         if ( (*p) > 10 ) {
1948                 if ( 48 <= (*p) && (*p) <= 57 )
1949                         goto tr2;
1950         } else if ( (*p) >= 9 )
1951                 goto st1;
1952         goto st0;
1953 st0:
1954 cs = 0;
1955         goto _out;
1956 tr2:
1957 #line 759 "parser.rl"
1958         {
1959         char *np = JSON_parse_value(json, p, pe, &result);
1960         if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
1961     }
1962         goto st10;
1963 st10:
1964         if ( ++p == pe )
1965                 goto _test_eof10;
1966 case 10:
1967 #line 1968 "parser.c"
1968         switch( (*p) ) {
1969                 case 13: goto st10;
1970                 case 32: goto st10;
1971                 case 47: goto st2;
1972         }
1973         if ( 9 <= (*p) && (*p) <= 10 )
1974                 goto st10;
1975         goto st0;
1976 st2:
1977         if ( ++p == pe )
1978                 goto _test_eof2;
1979 case 2:
1980         switch( (*p) ) {
1981                 case 42: goto st3;
1982                 case 47: goto st5;
1983         }
1984         goto st0;
1985 st3:
1986         if ( ++p == pe )
1987                 goto _test_eof3;
1988 case 3:
1989         if ( (*p) == 42 )
1990                 goto st4;
1991         goto st3;
1992 st4:
1993         if ( ++p == pe )
1994                 goto _test_eof4;
1995 case 4:
1996         switch( (*p) ) {
1997                 case 42: goto st4;
1998                 case 47: goto st10;
1999         }
2000         goto st3;
2001 st5:
2002         if ( ++p == pe )
2003                 goto _test_eof5;
2004 case 5:
2005         if ( (*p) == 10 )
2006                 goto st10;
2007         goto st5;
2008 st6:
2009         if ( ++p == pe )
2010                 goto _test_eof6;
2011 case 6:
2012         switch( (*p) ) {
2013                 case 42: goto st7;
2014                 case 47: goto st9;
2015         }
2016         goto st0;
2017 st7:
2018         if ( ++p == pe )
2019                 goto _test_eof7;
2020 case 7:
2021         if ( (*p) == 42 )
2022                 goto st8;
2023         goto st7;
2024 st8:
2025         if ( ++p == pe )
2026                 goto _test_eof8;
2027 case 8:
2028         switch( (*p) ) {
2029                 case 42: goto st8;
2030                 case 47: goto st1;
2031         }
2032         goto st7;
2033 st9:
2034         if ( ++p == pe )
2035                 goto _test_eof9;
2036 case 9:
2037         if ( (*p) == 10 )
2038                 goto st1;
2039         goto st9;
2040         }
2041         _test_eof1: cs = 1; goto _test_eof;
2042         _test_eof10: cs = 10; goto _test_eof;
2043         _test_eof2: cs = 2; goto _test_eof;
2044         _test_eof3: cs = 3; goto _test_eof;
2045         _test_eof4: cs = 4; goto _test_eof;
2046         _test_eof5: cs = 5; goto _test_eof;
2047         _test_eof6: cs = 6; goto _test_eof;
2048         _test_eof7: cs = 7; goto _test_eof;
2049         _test_eof8: cs = 8; goto _test_eof;
2050         _test_eof9: cs = 9; goto _test_eof;
2051
2052         _test_eof: {}
2053         _out: {}
2054         }
2055
2056 #line 780 "parser.rl"
2057
2058     if (cs >= JSON_quirks_mode_first_final && p == pe) {
2059         return result;
2060     } else {
2061         rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
2062         return Qnil;
2063     }
2064 }
2065
2066 /*
2067  * call-seq: parse()
2068  *
2069  *  Parses the current JSON text _source_ and returns the complete data
2070  *  structure as a result.
2071  */
2072 static VALUE cParser_parse(VALUE self)
2073 {
2074   GET_PARSER;
2075
2076   if (json->quirks_mode) {
2077     return cParser_parse_quirks_mode(self);
2078   } else {
2079     return cParser_parse_strict(self);
2080   }
2081 }
2082
2083
2084 static JSON_Parser *JSON_allocate()
2085 {
2086     JSON_Parser *json = ALLOC(JSON_Parser);
2087     MEMZERO(json, JSON_Parser, 1);
2088     return json;
2089 }
2090
2091 static void JSON_mark(JSON_Parser *json)
2092 {
2093     rb_gc_mark_maybe(json->Vsource);
2094     rb_gc_mark_maybe(json->create_id);
2095     rb_gc_mark_maybe(json->object_class);
2096     rb_gc_mark_maybe(json->array_class);
2097     rb_gc_mark_maybe(json->match_string);
2098 }
2099
2100 static void JSON_free(JSON_Parser *json)
2101 {
2102     ruby_xfree(json);
2103 }
2104
2105 static VALUE cJSON_parser_s_allocate(VALUE klass)
2106 {
2107     JSON_Parser *json = JSON_allocate();
2108     return Data_Wrap_Struct(klass, JSON_mark, JSON_free, json);
2109 }
2110
2111 /*
2112  * call-seq: source()
2113  *
2114  * Returns a copy of the current _source_ string, that was used to construct
2115  * this Parser.
2116  */
2117 static VALUE cParser_source(VALUE self)
2118 {
2119     GET_PARSER;
2120     return rb_str_dup(json->Vsource);
2121 }
2122
2123 /*
2124  * call-seq: quirks_mode?()
2125  *
2126  * Returns a true, if this parser is in quirks_mode, false otherwise.
2127  */
2128 static VALUE cParser_quirks_mode_p(VALUE self)
2129 {
2130     GET_PARSER;
2131     return json->quirks_mode ? Qtrue : Qfalse;
2132 }
2133
2134
2135 void Init_parser()
2136 {
2137     rb_require("json/common");
2138     mJSON = rb_define_module("JSON");
2139     mExt = rb_define_module_under(mJSON, "Ext");
2140     cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
2141     eParserError = rb_path2class("JSON::ParserError");
2142     eNestingError = rb_path2class("JSON::NestingError");
2143     rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
2144     rb_define_method(cParser, "initialize", cParser_initialize, -1);
2145     rb_define_method(cParser, "parse", cParser_parse, 0);
2146     rb_define_method(cParser, "source", cParser_source, 0);
2147     rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0);
2148
2149     CNaN = rb_const_get(mJSON, rb_intern("NaN"));
2150     CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
2151     CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
2152
2153     i_json_creatable_p = rb_intern("json_creatable?");
2154     i_json_create = rb_intern("json_create");
2155     i_create_id = rb_intern("create_id");
2156     i_create_additions = rb_intern("create_additions");
2157     i_chr = rb_intern("chr");
2158     i_max_nesting = rb_intern("max_nesting");
2159     i_allow_nan = rb_intern("allow_nan");
2160     i_symbolize_names = rb_intern("symbolize_names");
2161     i_quirks_mode = rb_intern("quirks_mode");
2162     i_object_class = rb_intern("object_class");
2163     i_array_class = rb_intern("array_class");
2164     i_match = rb_intern("match");
2165     i_match_string = rb_intern("match_string");
2166     i_key_p = rb_intern("key?");
2167     i_deep_const_get = rb_intern("deep_const_get");
2168     i_aset = rb_intern("[]=");
2169     i_leftshift = rb_intern("<<");
2170 #ifdef HAVE_RUBY_ENCODING_H
2171     CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
2172     CEncoding_UTF_16BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16be"));
2173     CEncoding_UTF_16LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16le"));
2174     CEncoding_UTF_32BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32be"));
2175     CEncoding_UTF_32LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32le"));
2176     CEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit"));
2177     i_encoding = rb_intern("encoding");
2178     i_encode = rb_intern("encode");
2179 #else
2180     i_iconv = rb_intern("iconv");
2181 #endif
2182 }
2183
2184 /*
2185  * Local variables:
2186  * mode: c
2187  * c-file-style: ruby
2188  * indent-tabs-mode: nil
2189  * End:
2190  */