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