json 2.9.1 → 2.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES.md +12 -0
- data/LEGAL +0 -52
- data/README.md +75 -2
- data/ext/json/ext/fbuffer/fbuffer.h +1 -10
- data/ext/json/ext/generator/generator.c +394 -263
- data/ext/json/ext/parser/parser.c +762 -2522
- data/json.gemspec +3 -4
- data/lib/json/add/symbol.rb +7 -2
- data/lib/json/common.rb +107 -10
- data/lib/json/ext/generator/state.rb +1 -11
- data/lib/json/ext.rb +26 -4
- data/lib/json/truffle_ruby/generator.rb +111 -50
- data/lib/json/version.rb +1 -1
- metadata +6 -11
- data/ext/json/ext/parser/parser.rl +0 -1465
@@ -1,9 +1,34 @@
|
|
1
|
-
/* This file is automatically generated from parser.rl by using ragel */
|
2
|
-
#line 1 "parser.rl"
|
3
1
|
#include "ruby.h"
|
4
|
-
#include "
|
2
|
+
#include "ruby/encoding.h"
|
5
3
|
|
6
|
-
|
4
|
+
/* shims */
|
5
|
+
/* This is the fallback definition from Ruby 3.4 */
|
6
|
+
|
7
|
+
#ifndef RBIMPL_STDBOOL_H
|
8
|
+
#if defined(__cplusplus)
|
9
|
+
# if defined(HAVE_STDBOOL_H) && (__cplusplus >= 201103L)
|
10
|
+
# include <cstdbool>
|
11
|
+
# endif
|
12
|
+
#elif defined(HAVE_STDBOOL_H)
|
13
|
+
# include <stdbool.h>
|
14
|
+
#elif !defined(HAVE__BOOL)
|
15
|
+
typedef unsigned char _Bool;
|
16
|
+
# define bool _Bool
|
17
|
+
# define true ((_Bool)+1)
|
18
|
+
# define false ((_Bool)+0)
|
19
|
+
# define __bool_true_false_are_defined
|
20
|
+
#endif
|
21
|
+
#endif
|
22
|
+
|
23
|
+
#ifndef RB_UNLIKELY
|
24
|
+
#define RB_UNLIKELY(expr) expr
|
25
|
+
#endif
|
26
|
+
|
27
|
+
#ifndef RB_LIKELY
|
28
|
+
#define RB_LIKELY(expr) expr
|
29
|
+
#endif
|
30
|
+
|
31
|
+
static VALUE mJSON, eNestingError, Encoding_UTF_8;
|
7
32
|
static VALUE CNaN, CInfinity, CMinusInfinity;
|
8
33
|
|
9
34
|
static ID i_json_creatable_p, i_json_create, i_create_id,
|
@@ -30,7 +55,8 @@ static const char deprecated_create_additions_warning[] =
|
|
30
55
|
|
31
56
|
#ifndef HAVE_RB_HASH_BULK_INSERT
|
32
57
|
// For TruffleRuby
|
33
|
-
void
|
58
|
+
void
|
59
|
+
rb_hash_bulk_insert(long count, const VALUE *pairs, VALUE hash)
|
34
60
|
{
|
35
61
|
long index = 0;
|
36
62
|
while (index < count) {
|
@@ -42,6 +68,11 @@ void rb_hash_bulk_insert(long count, const VALUE *pairs, VALUE hash)
|
|
42
68
|
}
|
43
69
|
#endif
|
44
70
|
|
71
|
+
#ifndef HAVE_RB_HASH_NEW_CAPA
|
72
|
+
#define rb_hash_new_capa(n) rb_hash_new()
|
73
|
+
#endif
|
74
|
+
|
75
|
+
|
45
76
|
/* name cache */
|
46
77
|
|
47
78
|
#include <string.h>
|
@@ -104,7 +135,7 @@ static VALUE rstring_cache_fetch(rvalue_cache *cache, const char *str, const lon
|
|
104
135
|
return Qfalse;
|
105
136
|
}
|
106
137
|
|
107
|
-
if (RB_UNLIKELY(!isalpha(str[0]))) {
|
138
|
+
if (RB_UNLIKELY(!isalpha((unsigned char)str[0]))) {
|
108
139
|
// Simple heuristic, if the first character isn't a letter,
|
109
140
|
// we're much less likely to see this string again.
|
110
141
|
// We mostly want to cache strings that are likely to be repeated.
|
@@ -156,7 +187,7 @@ static VALUE rsymbol_cache_fetch(rvalue_cache *cache, const char *str, const lon
|
|
156
187
|
return Qfalse;
|
157
188
|
}
|
158
189
|
|
159
|
-
if (RB_UNLIKELY(!isalpha(str[0]))) {
|
190
|
+
if (RB_UNLIKELY(!isalpha((unsigned char)str[0]))) {
|
160
191
|
// Simple heuristic, if the first character isn't a letter,
|
161
192
|
// we're much less likely to see this string again.
|
162
193
|
// We mostly want to cache strings that are likely to be repeated.
|
@@ -231,13 +262,14 @@ static rvalue_stack *rvalue_stack_grow(rvalue_stack *stack, VALUE *handle, rvalu
|
|
231
262
|
return stack;
|
232
263
|
}
|
233
264
|
|
234
|
-
static
|
265
|
+
static VALUE rvalue_stack_push(rvalue_stack *stack, VALUE value, VALUE *handle, rvalue_stack **stack_ref)
|
235
266
|
{
|
236
267
|
if (RB_UNLIKELY(stack->head >= stack->capa)) {
|
237
268
|
stack = rvalue_stack_grow(stack, handle, stack_ref);
|
238
269
|
}
|
239
270
|
stack->ptr[stack->head] = value;
|
240
271
|
stack->head++;
|
272
|
+
return value;
|
241
273
|
}
|
242
274
|
|
243
275
|
static inline VALUE *rvalue_stack_peek(rvalue_stack *stack, long count)
|
@@ -301,10 +333,12 @@ static rvalue_stack *rvalue_stack_spill(rvalue_stack *old_stack, VALUE *handle,
|
|
301
333
|
|
302
334
|
static void rvalue_stack_eagerly_release(VALUE handle)
|
303
335
|
{
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
336
|
+
if (handle) {
|
337
|
+
rvalue_stack *stack;
|
338
|
+
TypedData_Get_Struct(handle, rvalue_stack, &JSON_Parser_rvalue_stack_type, stack);
|
339
|
+
RTYPEDDATA_DATA(handle) = NULL;
|
340
|
+
rvalue_stack_free(stack);
|
341
|
+
}
|
308
342
|
}
|
309
343
|
|
310
344
|
/* unicode */
|
@@ -374,17 +408,12 @@ static int convert_UTF32_to_UTF8(char *buf, uint32_t ch)
|
|
374
408
|
}
|
375
409
|
|
376
410
|
typedef struct JSON_ParserStruct {
|
377
|
-
VALUE Vsource;
|
378
|
-
char *source;
|
379
|
-
long len;
|
380
|
-
char *memo;
|
381
411
|
VALUE create_id;
|
382
412
|
VALUE object_class;
|
383
413
|
VALUE array_class;
|
384
414
|
VALUE decimal_class;
|
415
|
+
ID decimal_method_id;
|
385
416
|
VALUE match_string;
|
386
|
-
FBuffer fbuffer;
|
387
|
-
int in_array;
|
388
417
|
int max_nesting;
|
389
418
|
bool allow_nan;
|
390
419
|
bool allow_trailing_comma;
|
@@ -393,29 +422,23 @@ typedef struct JSON_ParserStruct {
|
|
393
422
|
bool freeze;
|
394
423
|
bool create_additions;
|
395
424
|
bool deprecated_create_additions;
|
396
|
-
|
397
|
-
rvalue_stack *stack;
|
398
|
-
VALUE stack_handle;
|
399
|
-
} JSON_Parser;
|
425
|
+
} JSON_ParserConfig;
|
400
426
|
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
#define EVIL 0x666
|
427
|
+
typedef struct JSON_ParserStateStruct {
|
428
|
+
VALUE stack_handle;
|
429
|
+
const char *cursor;
|
430
|
+
const char *end;
|
431
|
+
rvalue_stack *stack;
|
432
|
+
rvalue_cache name_cache;
|
433
|
+
int in_array;
|
434
|
+
int current_nesting;
|
435
|
+
} JSON_ParserState;
|
411
436
|
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
|
416
|
-
static char *JSON_parse_number(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
417
|
-
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
|
437
|
+
#define GET_PARSER_CONFIG \
|
438
|
+
JSON_ParserConfig *config; \
|
439
|
+
TypedData_Get_Struct(self, JSON_ParserConfig, &JSON_ParserConfig_type, config)
|
418
440
|
|
441
|
+
static const rb_data_type_t JSON_ParserConfig_type;
|
419
442
|
|
420
443
|
#ifndef HAVE_STRNLEN
|
421
444
|
static size_t strnlen(const char *s, size_t maxlen)
|
@@ -433,7 +456,7 @@ static void raise_parse_error(const char *format, const char *start)
|
|
433
456
|
{
|
434
457
|
char buffer[PARSE_ERROR_FRAGMENT_LEN + 1];
|
435
458
|
|
436
|
-
size_t len = strnlen(start, PARSE_ERROR_FRAGMENT_LEN);
|
459
|
+
size_t len = start ? strnlen(start, PARSE_ERROR_FRAGMENT_LEN) : 0;
|
437
460
|
const char *ptr = start;
|
438
461
|
|
439
462
|
if (len == PARSE_ERROR_FRAGMENT_LEN) {
|
@@ -445,1047 +468,228 @@ static void raise_parse_error(const char *format, const char *start)
|
|
445
468
|
rb_enc_raise(enc_utf8, rb_path2class("JSON::ParserError"), format, ptr);
|
446
469
|
}
|
447
470
|
|
471
|
+
static const bool whitespace[256] = {
|
472
|
+
[' '] = 1,
|
473
|
+
['\t'] = 1,
|
474
|
+
['\n'] = 1,
|
475
|
+
['\r'] = 1,
|
476
|
+
['/'] = 1,
|
477
|
+
};
|
448
478
|
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
#line 455 "parser.c"
|
455
|
-
enum {JSON_object_start = 1};
|
456
|
-
enum {JSON_object_first_final = 32};
|
457
|
-
enum {JSON_object_error = 0};
|
458
|
-
|
459
|
-
enum {JSON_object_en_main = 1};
|
460
|
-
|
461
|
-
|
462
|
-
#line 513 "parser.rl"
|
463
|
-
|
464
|
-
|
465
|
-
#define PUSH(result) rvalue_stack_push(json->stack, result, &json->stack_handle, &json->stack)
|
466
|
-
|
467
|
-
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
479
|
+
static void
|
480
|
+
json_eat_comments(JSON_ParserState *state)
|
468
481
|
{
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
{
|
480
|
-
cs = JSON_object_start;
|
481
|
-
}
|
482
|
-
|
483
|
-
#line 528 "parser.rl"
|
484
|
-
|
485
|
-
#line 486 "parser.c"
|
486
|
-
{
|
487
|
-
short _widec;
|
488
|
-
if ( p == pe )
|
489
|
-
goto _test_eof;
|
490
|
-
switch ( cs )
|
491
|
-
{
|
492
|
-
case 1:
|
493
|
-
if ( (*p) == 123 )
|
494
|
-
goto st2;
|
495
|
-
goto st0;
|
496
|
-
st0:
|
497
|
-
cs = 0;
|
498
|
-
goto _out;
|
499
|
-
st2:
|
500
|
-
if ( ++p == pe )
|
501
|
-
goto _test_eof2;
|
502
|
-
case 2:
|
503
|
-
switch( (*p) ) {
|
504
|
-
case 13: goto st2;
|
505
|
-
case 32: goto st2;
|
506
|
-
case 34: goto tr2;
|
507
|
-
case 47: goto st28;
|
508
|
-
case 125: goto tr4;
|
509
|
-
}
|
510
|
-
if ( 9 <= (*p) && (*p) <= 10 )
|
511
|
-
goto st2;
|
512
|
-
goto st0;
|
513
|
-
tr2:
|
514
|
-
#line 492 "parser.rl"
|
515
|
-
{
|
516
|
-
char *np;
|
517
|
-
json->parsing_name = true;
|
518
|
-
np = JSON_parse_string(json, p, pe, result);
|
519
|
-
json->parsing_name = false;
|
520
|
-
if (np == NULL) { p--; {p++; cs = 3; goto _out;} } else {
|
521
|
-
PUSH(*result);
|
522
|
-
{p = (( np))-1;}
|
523
|
-
}
|
524
|
-
}
|
525
|
-
goto st3;
|
526
|
-
st3:
|
527
|
-
if ( ++p == pe )
|
528
|
-
goto _test_eof3;
|
529
|
-
case 3:
|
530
|
-
#line 531 "parser.c"
|
531
|
-
switch( (*p) ) {
|
532
|
-
case 13: goto st3;
|
533
|
-
case 32: goto st3;
|
534
|
-
case 47: goto st4;
|
535
|
-
case 58: goto st8;
|
536
|
-
}
|
537
|
-
if ( 9 <= (*p) && (*p) <= 10 )
|
538
|
-
goto st3;
|
539
|
-
goto st0;
|
540
|
-
st4:
|
541
|
-
if ( ++p == pe )
|
542
|
-
goto _test_eof4;
|
543
|
-
case 4:
|
544
|
-
switch( (*p) ) {
|
545
|
-
case 42: goto st5;
|
546
|
-
case 47: goto st7;
|
547
|
-
}
|
548
|
-
goto st0;
|
549
|
-
st5:
|
550
|
-
if ( ++p == pe )
|
551
|
-
goto _test_eof5;
|
552
|
-
case 5:
|
553
|
-
if ( (*p) == 42 )
|
554
|
-
goto st6;
|
555
|
-
goto st5;
|
556
|
-
st6:
|
557
|
-
if ( ++p == pe )
|
558
|
-
goto _test_eof6;
|
559
|
-
case 6:
|
560
|
-
switch( (*p) ) {
|
561
|
-
case 42: goto st6;
|
562
|
-
case 47: goto st3;
|
563
|
-
}
|
564
|
-
goto st5;
|
565
|
-
st7:
|
566
|
-
if ( ++p == pe )
|
567
|
-
goto _test_eof7;
|
568
|
-
case 7:
|
569
|
-
if ( (*p) == 10 )
|
570
|
-
goto st3;
|
571
|
-
goto st7;
|
572
|
-
st8:
|
573
|
-
if ( ++p == pe )
|
574
|
-
goto _test_eof8;
|
575
|
-
case 8:
|
576
|
-
switch( (*p) ) {
|
577
|
-
case 13: goto st8;
|
578
|
-
case 32: goto st8;
|
579
|
-
case 34: goto tr11;
|
580
|
-
case 45: goto tr11;
|
581
|
-
case 47: goto st24;
|
582
|
-
case 73: goto tr11;
|
583
|
-
case 78: goto tr11;
|
584
|
-
case 91: goto tr11;
|
585
|
-
case 102: goto tr11;
|
586
|
-
case 110: goto tr11;
|
587
|
-
case 116: goto tr11;
|
588
|
-
case 123: goto tr11;
|
589
|
-
}
|
590
|
-
if ( (*p) > 10 ) {
|
591
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
592
|
-
goto tr11;
|
593
|
-
} else if ( (*p) >= 9 )
|
594
|
-
goto st8;
|
595
|
-
goto st0;
|
596
|
-
tr11:
|
597
|
-
#line 481 "parser.rl"
|
598
|
-
{
|
599
|
-
char *np = JSON_parse_value(json, p, pe, result, current_nesting);
|
600
|
-
if (np == NULL) {
|
601
|
-
p--; {p++; cs = 9; goto _out;}
|
602
|
-
} else {
|
603
|
-
{p = (( np))-1;}
|
604
|
-
}
|
605
|
-
}
|
606
|
-
goto st9;
|
607
|
-
st9:
|
608
|
-
if ( ++p == pe )
|
609
|
-
goto _test_eof9;
|
610
|
-
case 9:
|
611
|
-
#line 612 "parser.c"
|
612
|
-
_widec = (*p);
|
613
|
-
if ( (*p) < 13 ) {
|
614
|
-
if ( (*p) > 9 ) {
|
615
|
-
if ( 10 <= (*p) && (*p) <= 10 ) {
|
616
|
-
_widec = (short)(128 + ((*p) - -128));
|
617
|
-
if (
|
618
|
-
#line 490 "parser.rl"
|
619
|
-
json->allow_trailing_comma ) _widec += 256;
|
620
|
-
}
|
621
|
-
} else if ( (*p) >= 9 ) {
|
622
|
-
_widec = (short)(128 + ((*p) - -128));
|
623
|
-
if (
|
624
|
-
#line 490 "parser.rl"
|
625
|
-
json->allow_trailing_comma ) _widec += 256;
|
626
|
-
}
|
627
|
-
} else if ( (*p) > 13 ) {
|
628
|
-
if ( (*p) < 44 ) {
|
629
|
-
if ( 32 <= (*p) && (*p) <= 32 ) {
|
630
|
-
_widec = (short)(128 + ((*p) - -128));
|
631
|
-
if (
|
632
|
-
#line 490 "parser.rl"
|
633
|
-
json->allow_trailing_comma ) _widec += 256;
|
634
|
-
}
|
635
|
-
} else if ( (*p) > 44 ) {
|
636
|
-
if ( 47 <= (*p) && (*p) <= 47 ) {
|
637
|
-
_widec = (short)(128 + ((*p) - -128));
|
638
|
-
if (
|
639
|
-
#line 490 "parser.rl"
|
640
|
-
json->allow_trailing_comma ) _widec += 256;
|
641
|
-
}
|
642
|
-
} else {
|
643
|
-
_widec = (short)(128 + ((*p) - -128));
|
644
|
-
if (
|
645
|
-
#line 490 "parser.rl"
|
646
|
-
json->allow_trailing_comma ) _widec += 256;
|
647
|
-
}
|
648
|
-
} else {
|
649
|
-
_widec = (short)(128 + ((*p) - -128));
|
650
|
-
if (
|
651
|
-
#line 490 "parser.rl"
|
652
|
-
json->allow_trailing_comma ) _widec += 256;
|
653
|
-
}
|
654
|
-
switch( _widec ) {
|
655
|
-
case 125: goto tr4;
|
656
|
-
case 269: goto st10;
|
657
|
-
case 288: goto st10;
|
658
|
-
case 300: goto st11;
|
659
|
-
case 303: goto st16;
|
660
|
-
case 525: goto st9;
|
661
|
-
case 544: goto st9;
|
662
|
-
case 556: goto st2;
|
663
|
-
case 559: goto st20;
|
664
|
-
}
|
665
|
-
if ( _widec > 266 ) {
|
666
|
-
if ( 521 <= _widec && _widec <= 522 )
|
667
|
-
goto st9;
|
668
|
-
} else if ( _widec >= 265 )
|
669
|
-
goto st10;
|
670
|
-
goto st0;
|
671
|
-
tr4:
|
672
|
-
#line 503 "parser.rl"
|
673
|
-
{ p--; {p++; cs = 32; goto _out;} }
|
674
|
-
goto st32;
|
675
|
-
st32:
|
676
|
-
if ( ++p == pe )
|
677
|
-
goto _test_eof32;
|
678
|
-
case 32:
|
679
|
-
#line 680 "parser.c"
|
680
|
-
goto st0;
|
681
|
-
st10:
|
682
|
-
if ( ++p == pe )
|
683
|
-
goto _test_eof10;
|
684
|
-
case 10:
|
685
|
-
switch( (*p) ) {
|
686
|
-
case 13: goto st10;
|
687
|
-
case 32: goto st10;
|
688
|
-
case 44: goto st11;
|
689
|
-
case 47: goto st16;
|
690
|
-
case 125: goto tr4;
|
691
|
-
}
|
692
|
-
if ( 9 <= (*p) && (*p) <= 10 )
|
693
|
-
goto st10;
|
694
|
-
goto st0;
|
695
|
-
st11:
|
696
|
-
if ( ++p == pe )
|
697
|
-
goto _test_eof11;
|
698
|
-
case 11:
|
699
|
-
switch( (*p) ) {
|
700
|
-
case 13: goto st11;
|
701
|
-
case 32: goto st11;
|
702
|
-
case 34: goto tr2;
|
703
|
-
case 47: goto st12;
|
704
|
-
}
|
705
|
-
if ( 9 <= (*p) && (*p) <= 10 )
|
706
|
-
goto st11;
|
707
|
-
goto st0;
|
708
|
-
st12:
|
709
|
-
if ( ++p == pe )
|
710
|
-
goto _test_eof12;
|
711
|
-
case 12:
|
712
|
-
switch( (*p) ) {
|
713
|
-
case 42: goto st13;
|
714
|
-
case 47: goto st15;
|
715
|
-
}
|
716
|
-
goto st0;
|
717
|
-
st13:
|
718
|
-
if ( ++p == pe )
|
719
|
-
goto _test_eof13;
|
720
|
-
case 13:
|
721
|
-
if ( (*p) == 42 )
|
722
|
-
goto st14;
|
723
|
-
goto st13;
|
724
|
-
st14:
|
725
|
-
if ( ++p == pe )
|
726
|
-
goto _test_eof14;
|
727
|
-
case 14:
|
728
|
-
switch( (*p) ) {
|
729
|
-
case 42: goto st14;
|
730
|
-
case 47: goto st11;
|
731
|
-
}
|
732
|
-
goto st13;
|
733
|
-
st15:
|
734
|
-
if ( ++p == pe )
|
735
|
-
goto _test_eof15;
|
736
|
-
case 15:
|
737
|
-
if ( (*p) == 10 )
|
738
|
-
goto st11;
|
739
|
-
goto st15;
|
740
|
-
st16:
|
741
|
-
if ( ++p == pe )
|
742
|
-
goto _test_eof16;
|
743
|
-
case 16:
|
744
|
-
switch( (*p) ) {
|
745
|
-
case 42: goto st17;
|
746
|
-
case 47: goto st19;
|
747
|
-
}
|
748
|
-
goto st0;
|
749
|
-
st17:
|
750
|
-
if ( ++p == pe )
|
751
|
-
goto _test_eof17;
|
752
|
-
case 17:
|
753
|
-
if ( (*p) == 42 )
|
754
|
-
goto st18;
|
755
|
-
goto st17;
|
756
|
-
st18:
|
757
|
-
if ( ++p == pe )
|
758
|
-
goto _test_eof18;
|
759
|
-
case 18:
|
760
|
-
switch( (*p) ) {
|
761
|
-
case 42: goto st18;
|
762
|
-
case 47: goto st10;
|
763
|
-
}
|
764
|
-
goto st17;
|
765
|
-
st19:
|
766
|
-
if ( ++p == pe )
|
767
|
-
goto _test_eof19;
|
768
|
-
case 19:
|
769
|
-
if ( (*p) == 10 )
|
770
|
-
goto st10;
|
771
|
-
goto st19;
|
772
|
-
st20:
|
773
|
-
if ( ++p == pe )
|
774
|
-
goto _test_eof20;
|
775
|
-
case 20:
|
776
|
-
_widec = (*p);
|
777
|
-
if ( (*p) > 42 ) {
|
778
|
-
if ( 47 <= (*p) && (*p) <= 47 ) {
|
779
|
-
_widec = (short)(128 + ((*p) - -128));
|
780
|
-
if (
|
781
|
-
#line 490 "parser.rl"
|
782
|
-
json->allow_trailing_comma ) _widec += 256;
|
783
|
-
}
|
784
|
-
} else if ( (*p) >= 42 ) {
|
785
|
-
_widec = (short)(128 + ((*p) - -128));
|
786
|
-
if (
|
787
|
-
#line 490 "parser.rl"
|
788
|
-
json->allow_trailing_comma ) _widec += 256;
|
789
|
-
}
|
790
|
-
switch( _widec ) {
|
791
|
-
case 298: goto st17;
|
792
|
-
case 303: goto st19;
|
793
|
-
case 554: goto st21;
|
794
|
-
case 559: goto st23;
|
795
|
-
}
|
796
|
-
goto st0;
|
797
|
-
st21:
|
798
|
-
if ( ++p == pe )
|
799
|
-
goto _test_eof21;
|
800
|
-
case 21:
|
801
|
-
_widec = (*p);
|
802
|
-
if ( (*p) < 42 ) {
|
803
|
-
if ( (*p) <= 41 ) {
|
804
|
-
_widec = (short)(128 + ((*p) - -128));
|
805
|
-
if (
|
806
|
-
#line 490 "parser.rl"
|
807
|
-
json->allow_trailing_comma ) _widec += 256;
|
808
|
-
}
|
809
|
-
} else if ( (*p) > 42 ) {
|
810
|
-
if ( 43 <= (*p) )
|
811
|
-
{ _widec = (short)(128 + ((*p) - -128));
|
812
|
-
if (
|
813
|
-
#line 490 "parser.rl"
|
814
|
-
json->allow_trailing_comma ) _widec += 256;
|
815
|
-
}
|
816
|
-
} else {
|
817
|
-
_widec = (short)(128 + ((*p) - -128));
|
818
|
-
if (
|
819
|
-
#line 490 "parser.rl"
|
820
|
-
json->allow_trailing_comma ) _widec += 256;
|
821
|
-
}
|
822
|
-
switch( _widec ) {
|
823
|
-
case 298: goto st18;
|
824
|
-
case 554: goto st22;
|
825
|
-
}
|
826
|
-
if ( _widec > 383 ) {
|
827
|
-
if ( 384 <= _widec && _widec <= 639 )
|
828
|
-
goto st21;
|
829
|
-
} else if ( _widec >= 128 )
|
830
|
-
goto st17;
|
831
|
-
goto st0;
|
832
|
-
st22:
|
833
|
-
if ( ++p == pe )
|
834
|
-
goto _test_eof22;
|
835
|
-
case 22:
|
836
|
-
_widec = (*p);
|
837
|
-
if ( (*p) < 43 ) {
|
838
|
-
if ( (*p) > 41 ) {
|
839
|
-
if ( 42 <= (*p) && (*p) <= 42 ) {
|
840
|
-
_widec = (short)(128 + ((*p) - -128));
|
841
|
-
if (
|
842
|
-
#line 490 "parser.rl"
|
843
|
-
json->allow_trailing_comma ) _widec += 256;
|
844
|
-
}
|
845
|
-
} else {
|
846
|
-
_widec = (short)(128 + ((*p) - -128));
|
847
|
-
if (
|
848
|
-
#line 490 "parser.rl"
|
849
|
-
json->allow_trailing_comma ) _widec += 256;
|
850
|
-
}
|
851
|
-
} else if ( (*p) > 46 ) {
|
852
|
-
if ( (*p) > 47 ) {
|
853
|
-
if ( 48 <= (*p) )
|
854
|
-
{ _widec = (short)(128 + ((*p) - -128));
|
855
|
-
if (
|
856
|
-
#line 490 "parser.rl"
|
857
|
-
json->allow_trailing_comma ) _widec += 256;
|
858
|
-
}
|
859
|
-
} else if ( (*p) >= 47 ) {
|
860
|
-
_widec = (short)(128 + ((*p) - -128));
|
861
|
-
if (
|
862
|
-
#line 490 "parser.rl"
|
863
|
-
json->allow_trailing_comma ) _widec += 256;
|
864
|
-
}
|
865
|
-
} else {
|
866
|
-
_widec = (short)(128 + ((*p) - -128));
|
867
|
-
if (
|
868
|
-
#line 490 "parser.rl"
|
869
|
-
json->allow_trailing_comma ) _widec += 256;
|
870
|
-
}
|
871
|
-
switch( _widec ) {
|
872
|
-
case 298: goto st18;
|
873
|
-
case 303: goto st10;
|
874
|
-
case 554: goto st22;
|
875
|
-
case 559: goto st9;
|
876
|
-
}
|
877
|
-
if ( _widec > 383 ) {
|
878
|
-
if ( 384 <= _widec && _widec <= 639 )
|
879
|
-
goto st21;
|
880
|
-
} else if ( _widec >= 128 )
|
881
|
-
goto st17;
|
882
|
-
goto st0;
|
883
|
-
st23:
|
884
|
-
if ( ++p == pe )
|
885
|
-
goto _test_eof23;
|
886
|
-
case 23:
|
887
|
-
_widec = (*p);
|
888
|
-
if ( (*p) < 10 ) {
|
889
|
-
if ( (*p) <= 9 ) {
|
890
|
-
_widec = (short)(128 + ((*p) - -128));
|
891
|
-
if (
|
892
|
-
#line 490 "parser.rl"
|
893
|
-
json->allow_trailing_comma ) _widec += 256;
|
894
|
-
}
|
895
|
-
} else if ( (*p) > 10 ) {
|
896
|
-
if ( 11 <= (*p) )
|
897
|
-
{ _widec = (short)(128 + ((*p) - -128));
|
898
|
-
if (
|
899
|
-
#line 490 "parser.rl"
|
900
|
-
json->allow_trailing_comma ) _widec += 256;
|
901
|
-
}
|
902
|
-
} else {
|
903
|
-
_widec = (short)(128 + ((*p) - -128));
|
904
|
-
if (
|
905
|
-
#line 490 "parser.rl"
|
906
|
-
json->allow_trailing_comma ) _widec += 256;
|
907
|
-
}
|
908
|
-
switch( _widec ) {
|
909
|
-
case 266: goto st10;
|
910
|
-
case 522: goto st9;
|
911
|
-
}
|
912
|
-
if ( _widec > 383 ) {
|
913
|
-
if ( 384 <= _widec && _widec <= 639 )
|
914
|
-
goto st23;
|
915
|
-
} else if ( _widec >= 128 )
|
916
|
-
goto st19;
|
917
|
-
goto st0;
|
918
|
-
st24:
|
919
|
-
if ( ++p == pe )
|
920
|
-
goto _test_eof24;
|
921
|
-
case 24:
|
922
|
-
switch( (*p) ) {
|
923
|
-
case 42: goto st25;
|
924
|
-
case 47: goto st27;
|
925
|
-
}
|
926
|
-
goto st0;
|
927
|
-
st25:
|
928
|
-
if ( ++p == pe )
|
929
|
-
goto _test_eof25;
|
930
|
-
case 25:
|
931
|
-
if ( (*p) == 42 )
|
932
|
-
goto st26;
|
933
|
-
goto st25;
|
934
|
-
st26:
|
935
|
-
if ( ++p == pe )
|
936
|
-
goto _test_eof26;
|
937
|
-
case 26:
|
938
|
-
switch( (*p) ) {
|
939
|
-
case 42: goto st26;
|
940
|
-
case 47: goto st8;
|
941
|
-
}
|
942
|
-
goto st25;
|
943
|
-
st27:
|
944
|
-
if ( ++p == pe )
|
945
|
-
goto _test_eof27;
|
946
|
-
case 27:
|
947
|
-
if ( (*p) == 10 )
|
948
|
-
goto st8;
|
949
|
-
goto st27;
|
950
|
-
st28:
|
951
|
-
if ( ++p == pe )
|
952
|
-
goto _test_eof28;
|
953
|
-
case 28:
|
954
|
-
switch( (*p) ) {
|
955
|
-
case 42: goto st29;
|
956
|
-
case 47: goto st31;
|
957
|
-
}
|
958
|
-
goto st0;
|
959
|
-
st29:
|
960
|
-
if ( ++p == pe )
|
961
|
-
goto _test_eof29;
|
962
|
-
case 29:
|
963
|
-
if ( (*p) == 42 )
|
964
|
-
goto st30;
|
965
|
-
goto st29;
|
966
|
-
st30:
|
967
|
-
if ( ++p == pe )
|
968
|
-
goto _test_eof30;
|
969
|
-
case 30:
|
970
|
-
switch( (*p) ) {
|
971
|
-
case 42: goto st30;
|
972
|
-
case 47: goto st2;
|
973
|
-
}
|
974
|
-
goto st29;
|
975
|
-
st31:
|
976
|
-
if ( ++p == pe )
|
977
|
-
goto _test_eof31;
|
978
|
-
case 31:
|
979
|
-
if ( (*p) == 10 )
|
980
|
-
goto st2;
|
981
|
-
goto st31;
|
982
|
-
}
|
983
|
-
_test_eof2: cs = 2; goto _test_eof;
|
984
|
-
_test_eof3: cs = 3; goto _test_eof;
|
985
|
-
_test_eof4: cs = 4; goto _test_eof;
|
986
|
-
_test_eof5: cs = 5; goto _test_eof;
|
987
|
-
_test_eof6: cs = 6; goto _test_eof;
|
988
|
-
_test_eof7: cs = 7; goto _test_eof;
|
989
|
-
_test_eof8: cs = 8; goto _test_eof;
|
990
|
-
_test_eof9: cs = 9; goto _test_eof;
|
991
|
-
_test_eof32: cs = 32; goto _test_eof;
|
992
|
-
_test_eof10: cs = 10; goto _test_eof;
|
993
|
-
_test_eof11: cs = 11; goto _test_eof;
|
994
|
-
_test_eof12: cs = 12; goto _test_eof;
|
995
|
-
_test_eof13: cs = 13; goto _test_eof;
|
996
|
-
_test_eof14: cs = 14; goto _test_eof;
|
997
|
-
_test_eof15: cs = 15; goto _test_eof;
|
998
|
-
_test_eof16: cs = 16; goto _test_eof;
|
999
|
-
_test_eof17: cs = 17; goto _test_eof;
|
1000
|
-
_test_eof18: cs = 18; goto _test_eof;
|
1001
|
-
_test_eof19: cs = 19; goto _test_eof;
|
1002
|
-
_test_eof20: cs = 20; goto _test_eof;
|
1003
|
-
_test_eof21: cs = 21; goto _test_eof;
|
1004
|
-
_test_eof22: cs = 22; goto _test_eof;
|
1005
|
-
_test_eof23: cs = 23; goto _test_eof;
|
1006
|
-
_test_eof24: cs = 24; goto _test_eof;
|
1007
|
-
_test_eof25: cs = 25; goto _test_eof;
|
1008
|
-
_test_eof26: cs = 26; goto _test_eof;
|
1009
|
-
_test_eof27: cs = 27; goto _test_eof;
|
1010
|
-
_test_eof28: cs = 28; goto _test_eof;
|
1011
|
-
_test_eof29: cs = 29; goto _test_eof;
|
1012
|
-
_test_eof30: cs = 30; goto _test_eof;
|
1013
|
-
_test_eof31: cs = 31; goto _test_eof;
|
1014
|
-
|
1015
|
-
_test_eof: {}
|
1016
|
-
_out: {}
|
1017
|
-
}
|
1018
|
-
|
1019
|
-
#line 529 "parser.rl"
|
1020
|
-
|
1021
|
-
if (cs >= JSON_object_first_final) {
|
1022
|
-
long count = json->stack->head - stack_head;
|
1023
|
-
|
1024
|
-
if (RB_UNLIKELY(json->object_class)) {
|
1025
|
-
VALUE object = rb_class_new_instance(0, 0, json->object_class);
|
1026
|
-
long index = 0;
|
1027
|
-
VALUE *items = rvalue_stack_peek(json->stack, count);
|
1028
|
-
while (index < count) {
|
1029
|
-
VALUE name = items[index++];
|
1030
|
-
VALUE value = items[index++];
|
1031
|
-
rb_funcall(object, i_aset, 2, name, value);
|
1032
|
-
}
|
1033
|
-
*result = object;
|
1034
|
-
} else {
|
1035
|
-
VALUE hash;
|
1036
|
-
#ifdef HAVE_RB_HASH_NEW_CAPA
|
1037
|
-
hash = rb_hash_new_capa(count >> 1);
|
1038
|
-
#else
|
1039
|
-
hash = rb_hash_new();
|
1040
|
-
#endif
|
1041
|
-
rb_hash_bulk_insert(count, rvalue_stack_peek(json->stack, count), hash);
|
1042
|
-
*result = hash;
|
1043
|
-
}
|
1044
|
-
rvalue_stack_pop(json->stack, count);
|
1045
|
-
|
1046
|
-
if (RB_UNLIKELY(json->create_additions)) {
|
1047
|
-
VALUE klassname;
|
1048
|
-
if (json->object_class) {
|
1049
|
-
klassname = rb_funcall(*result, i_aref, 1, json->create_id);
|
1050
|
-
} else {
|
1051
|
-
klassname = rb_hash_aref(*result, json->create_id);
|
482
|
+
if (state->cursor + 1 < state->end) {
|
483
|
+
switch(state->cursor[1]) {
|
484
|
+
case '/': {
|
485
|
+
state->cursor = memchr(state->cursor, '\n', state->end - state->cursor);
|
486
|
+
if (!state->cursor) {
|
487
|
+
state->cursor = state->end;
|
488
|
+
} else {
|
489
|
+
state->cursor++;
|
490
|
+
}
|
491
|
+
break;
|
1052
492
|
}
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
493
|
+
case '*': {
|
494
|
+
state->cursor += 2;
|
495
|
+
while (true) {
|
496
|
+
state->cursor = memchr(state->cursor, '*', state->end - state->cursor);
|
497
|
+
if (!state->cursor) {
|
498
|
+
state->cursor = state->end;
|
499
|
+
raise_parse_error("unexpected end of input, expected closing '*/'", state->cursor);
|
500
|
+
} else {
|
501
|
+
state->cursor++;
|
502
|
+
if (state->cursor < state->end && *state->cursor == '/') {
|
503
|
+
state->cursor++;
|
504
|
+
break;
|
505
|
+
}
|
1058
506
|
}
|
1059
|
-
*result = rb_funcall(klass, i_json_create, 1, *result);
|
1060
507
|
}
|
508
|
+
break;
|
1061
509
|
}
|
510
|
+
default:
|
511
|
+
raise_parse_error("unexpected token at '%s'", state->cursor);
|
512
|
+
break;
|
1062
513
|
}
|
1063
|
-
return p + 1;
|
1064
514
|
} else {
|
1065
|
-
|
515
|
+
raise_parse_error("unexpected token at '%s'", state->cursor);
|
1066
516
|
}
|
1067
517
|
}
|
1068
518
|
|
1069
|
-
|
1070
|
-
|
1071
|
-
enum {JSON_value_start = 1};
|
1072
|
-
enum {JSON_value_first_final = 29};
|
1073
|
-
enum {JSON_value_error = 0};
|
1074
|
-
|
1075
|
-
enum {JSON_value_en_main = 1};
|
1076
|
-
|
1077
|
-
|
1078
|
-
#line 662 "parser.rl"
|
1079
|
-
|
1080
|
-
|
1081
|
-
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
519
|
+
static inline void
|
520
|
+
json_eat_whitespace(JSON_ParserState *state)
|
1082
521
|
{
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
1086
|
-
#line 1087 "parser.c"
|
1087
|
-
{
|
1088
|
-
cs = JSON_value_start;
|
1089
|
-
}
|
1090
|
-
|
1091
|
-
#line 669 "parser.rl"
|
1092
|
-
|
1093
|
-
#line 1094 "parser.c"
|
1094
|
-
{
|
1095
|
-
if ( p == pe )
|
1096
|
-
goto _test_eof;
|
1097
|
-
switch ( cs )
|
1098
|
-
{
|
1099
|
-
st1:
|
1100
|
-
if ( ++p == pe )
|
1101
|
-
goto _test_eof1;
|
1102
|
-
case 1:
|
1103
|
-
switch( (*p) ) {
|
1104
|
-
case 13: goto st1;
|
1105
|
-
case 32: goto st1;
|
1106
|
-
case 34: goto tr2;
|
1107
|
-
case 45: goto tr3;
|
1108
|
-
case 47: goto st6;
|
1109
|
-
case 73: goto st10;
|
1110
|
-
case 78: goto st17;
|
1111
|
-
case 91: goto tr7;
|
1112
|
-
case 102: goto st19;
|
1113
|
-
case 110: goto st23;
|
1114
|
-
case 116: goto st26;
|
1115
|
-
case 123: goto tr11;
|
1116
|
-
}
|
1117
|
-
if ( (*p) > 10 ) {
|
1118
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
1119
|
-
goto tr3;
|
1120
|
-
} else if ( (*p) >= 9 )
|
1121
|
-
goto st1;
|
1122
|
-
goto st0;
|
1123
|
-
st0:
|
1124
|
-
cs = 0;
|
1125
|
-
goto _out;
|
1126
|
-
tr2:
|
1127
|
-
#line 607 "parser.rl"
|
1128
|
-
{
|
1129
|
-
char *np = JSON_parse_string(json, p, pe, result);
|
1130
|
-
if (np == NULL) {
|
1131
|
-
p--;
|
1132
|
-
{p++; cs = 29; goto _out;}
|
522
|
+
while (state->cursor < state->end && RB_UNLIKELY(whitespace[(unsigned char)*state->cursor])) {
|
523
|
+
if (RB_LIKELY(*state->cursor != '/')) {
|
524
|
+
state->cursor++;
|
1133
525
|
} else {
|
1134
|
-
|
526
|
+
json_eat_comments(state);
|
1135
527
|
}
|
1136
528
|
}
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
if (json->allow_nan) {
|
1144
|
-
*result = CMinusInfinity;
|
1145
|
-
{p = (( p + 10))-1;}
|
1146
|
-
p--; {p++; cs = 29; goto _out;}
|
1147
|
-
} else {
|
1148
|
-
raise_parse_error("unexpected token at '%s'", p);
|
1149
|
-
}
|
1150
|
-
}
|
1151
|
-
np = JSON_parse_number(json, p, pe, result);
|
1152
|
-
if (np != NULL) {
|
1153
|
-
{p = (( np))-1;}
|
1154
|
-
}
|
1155
|
-
p--; {p++; cs = 29; goto _out;}
|
529
|
+
}
|
530
|
+
|
531
|
+
static inline VALUE build_string(const char *start, const char *end, bool intern, bool symbolize)
|
532
|
+
{
|
533
|
+
if (symbolize) {
|
534
|
+
intern = true;
|
1156
535
|
}
|
1157
|
-
|
1158
|
-
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
536
|
+
VALUE result;
|
537
|
+
# ifdef HAVE_RB_ENC_INTERNED_STR
|
538
|
+
if (intern) {
|
539
|
+
result = rb_enc_interned_str(start, (long)(end - start), enc_utf8);
|
540
|
+
} else {
|
541
|
+
result = rb_utf8_str_new(start, (long)(end - start));
|
542
|
+
}
|
543
|
+
# else
|
544
|
+
result = rb_utf8_str_new(start, (long)(end - start));
|
545
|
+
if (intern) {
|
546
|
+
result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
|
1166
547
|
}
|
1167
|
-
|
1168
|
-
|
1169
|
-
|
1170
|
-
|
1171
|
-
char *np;
|
1172
|
-
np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
|
1173
|
-
if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
|
548
|
+
# endif
|
549
|
+
|
550
|
+
if (symbolize) {
|
551
|
+
result = rb_str_intern(result);
|
1174
552
|
}
|
1175
|
-
|
1176
|
-
|
1177
|
-
|
1178
|
-
|
1179
|
-
|
1180
|
-
|
553
|
+
|
554
|
+
return result;
|
555
|
+
}
|
556
|
+
|
557
|
+
static inline VALUE json_string_fastpath(JSON_ParserState *state, const char *string, const char *stringEnd, bool is_name, bool intern, bool symbolize)
|
558
|
+
{
|
559
|
+
size_t bufferSize = stringEnd - string;
|
560
|
+
|
561
|
+
if (is_name && state->in_array) {
|
562
|
+
VALUE cached_key;
|
563
|
+
if (RB_UNLIKELY(symbolize)) {
|
564
|
+
cached_key = rsymbol_cache_fetch(&state->name_cache, string, bufferSize);
|
1181
565
|
} else {
|
1182
|
-
|
566
|
+
cached_key = rstring_cache_fetch(&state->name_cache, string, bufferSize);
|
1183
567
|
}
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
#line 593 "parser.rl"
|
1188
|
-
{
|
1189
|
-
if (json->allow_nan) {
|
1190
|
-
*result = CNaN;
|
1191
|
-
} else {
|
1192
|
-
raise_parse_error("unexpected token at '%s'", p - 2);
|
568
|
+
|
569
|
+
if (RB_LIKELY(cached_key)) {
|
570
|
+
return cached_key;
|
1193
571
|
}
|
1194
572
|
}
|
1195
|
-
goto st29;
|
1196
|
-
tr31:
|
1197
|
-
#line 587 "parser.rl"
|
1198
|
-
{
|
1199
|
-
*result = Qfalse;
|
1200
|
-
}
|
1201
|
-
goto st29;
|
1202
|
-
tr34:
|
1203
|
-
#line 584 "parser.rl"
|
1204
|
-
{
|
1205
|
-
*result = Qnil;
|
1206
|
-
}
|
1207
|
-
goto st29;
|
1208
|
-
tr37:
|
1209
|
-
#line 590 "parser.rl"
|
1210
|
-
{
|
1211
|
-
*result = Qtrue;
|
1212
|
-
}
|
1213
|
-
goto st29;
|
1214
|
-
st29:
|
1215
|
-
if ( ++p == pe )
|
1216
|
-
goto _test_eof29;
|
1217
|
-
case 29:
|
1218
|
-
#line 649 "parser.rl"
|
1219
|
-
{ p--; {p++; cs = 29; goto _out;} }
|
1220
|
-
#line 1221 "parser.c"
|
1221
|
-
switch( (*p) ) {
|
1222
|
-
case 13: goto st29;
|
1223
|
-
case 32: goto st29;
|
1224
|
-
case 47: goto st2;
|
1225
|
-
}
|
1226
|
-
if ( 9 <= (*p) && (*p) <= 10 )
|
1227
|
-
goto st29;
|
1228
|
-
goto st0;
|
1229
|
-
st2:
|
1230
|
-
if ( ++p == pe )
|
1231
|
-
goto _test_eof2;
|
1232
|
-
case 2:
|
1233
|
-
switch( (*p) ) {
|
1234
|
-
case 42: goto st3;
|
1235
|
-
case 47: goto st5;
|
1236
|
-
}
|
1237
|
-
goto st0;
|
1238
|
-
st3:
|
1239
|
-
if ( ++p == pe )
|
1240
|
-
goto _test_eof3;
|
1241
|
-
case 3:
|
1242
|
-
if ( (*p) == 42 )
|
1243
|
-
goto st4;
|
1244
|
-
goto st3;
|
1245
|
-
st4:
|
1246
|
-
if ( ++p == pe )
|
1247
|
-
goto _test_eof4;
|
1248
|
-
case 4:
|
1249
|
-
switch( (*p) ) {
|
1250
|
-
case 42: goto st4;
|
1251
|
-
case 47: goto st29;
|
1252
|
-
}
|
1253
|
-
goto st3;
|
1254
|
-
st5:
|
1255
|
-
if ( ++p == pe )
|
1256
|
-
goto _test_eof5;
|
1257
|
-
case 5:
|
1258
|
-
if ( (*p) == 10 )
|
1259
|
-
goto st29;
|
1260
|
-
goto st5;
|
1261
|
-
st6:
|
1262
|
-
if ( ++p == pe )
|
1263
|
-
goto _test_eof6;
|
1264
|
-
case 6:
|
1265
|
-
switch( (*p) ) {
|
1266
|
-
case 42: goto st7;
|
1267
|
-
case 47: goto st9;
|
1268
|
-
}
|
1269
|
-
goto st0;
|
1270
|
-
st7:
|
1271
|
-
if ( ++p == pe )
|
1272
|
-
goto _test_eof7;
|
1273
|
-
case 7:
|
1274
|
-
if ( (*p) == 42 )
|
1275
|
-
goto st8;
|
1276
|
-
goto st7;
|
1277
|
-
st8:
|
1278
|
-
if ( ++p == pe )
|
1279
|
-
goto _test_eof8;
|
1280
|
-
case 8:
|
1281
|
-
switch( (*p) ) {
|
1282
|
-
case 42: goto st8;
|
1283
|
-
case 47: goto st1;
|
1284
|
-
}
|
1285
|
-
goto st7;
|
1286
|
-
st9:
|
1287
|
-
if ( ++p == pe )
|
1288
|
-
goto _test_eof9;
|
1289
|
-
case 9:
|
1290
|
-
if ( (*p) == 10 )
|
1291
|
-
goto st1;
|
1292
|
-
goto st9;
|
1293
|
-
st10:
|
1294
|
-
if ( ++p == pe )
|
1295
|
-
goto _test_eof10;
|
1296
|
-
case 10:
|
1297
|
-
if ( (*p) == 110 )
|
1298
|
-
goto st11;
|
1299
|
-
goto st0;
|
1300
|
-
st11:
|
1301
|
-
if ( ++p == pe )
|
1302
|
-
goto _test_eof11;
|
1303
|
-
case 11:
|
1304
|
-
if ( (*p) == 102 )
|
1305
|
-
goto st12;
|
1306
|
-
goto st0;
|
1307
|
-
st12:
|
1308
|
-
if ( ++p == pe )
|
1309
|
-
goto _test_eof12;
|
1310
|
-
case 12:
|
1311
|
-
if ( (*p) == 105 )
|
1312
|
-
goto st13;
|
1313
|
-
goto st0;
|
1314
|
-
st13:
|
1315
|
-
if ( ++p == pe )
|
1316
|
-
goto _test_eof13;
|
1317
|
-
case 13:
|
1318
|
-
if ( (*p) == 110 )
|
1319
|
-
goto st14;
|
1320
|
-
goto st0;
|
1321
|
-
st14:
|
1322
|
-
if ( ++p == pe )
|
1323
|
-
goto _test_eof14;
|
1324
|
-
case 14:
|
1325
|
-
if ( (*p) == 105 )
|
1326
|
-
goto st15;
|
1327
|
-
goto st0;
|
1328
|
-
st15:
|
1329
|
-
if ( ++p == pe )
|
1330
|
-
goto _test_eof15;
|
1331
|
-
case 15:
|
1332
|
-
if ( (*p) == 116 )
|
1333
|
-
goto st16;
|
1334
|
-
goto st0;
|
1335
|
-
st16:
|
1336
|
-
if ( ++p == pe )
|
1337
|
-
goto _test_eof16;
|
1338
|
-
case 16:
|
1339
|
-
if ( (*p) == 121 )
|
1340
|
-
goto tr25;
|
1341
|
-
goto st0;
|
1342
|
-
st17:
|
1343
|
-
if ( ++p == pe )
|
1344
|
-
goto _test_eof17;
|
1345
|
-
case 17:
|
1346
|
-
if ( (*p) == 97 )
|
1347
|
-
goto st18;
|
1348
|
-
goto st0;
|
1349
|
-
st18:
|
1350
|
-
if ( ++p == pe )
|
1351
|
-
goto _test_eof18;
|
1352
|
-
case 18:
|
1353
|
-
if ( (*p) == 78 )
|
1354
|
-
goto tr27;
|
1355
|
-
goto st0;
|
1356
|
-
st19:
|
1357
|
-
if ( ++p == pe )
|
1358
|
-
goto _test_eof19;
|
1359
|
-
case 19:
|
1360
|
-
if ( (*p) == 97 )
|
1361
|
-
goto st20;
|
1362
|
-
goto st0;
|
1363
|
-
st20:
|
1364
|
-
if ( ++p == pe )
|
1365
|
-
goto _test_eof20;
|
1366
|
-
case 20:
|
1367
|
-
if ( (*p) == 108 )
|
1368
|
-
goto st21;
|
1369
|
-
goto st0;
|
1370
|
-
st21:
|
1371
|
-
if ( ++p == pe )
|
1372
|
-
goto _test_eof21;
|
1373
|
-
case 21:
|
1374
|
-
if ( (*p) == 115 )
|
1375
|
-
goto st22;
|
1376
|
-
goto st0;
|
1377
|
-
st22:
|
1378
|
-
if ( ++p == pe )
|
1379
|
-
goto _test_eof22;
|
1380
|
-
case 22:
|
1381
|
-
if ( (*p) == 101 )
|
1382
|
-
goto tr31;
|
1383
|
-
goto st0;
|
1384
|
-
st23:
|
1385
|
-
if ( ++p == pe )
|
1386
|
-
goto _test_eof23;
|
1387
|
-
case 23:
|
1388
|
-
if ( (*p) == 117 )
|
1389
|
-
goto st24;
|
1390
|
-
goto st0;
|
1391
|
-
st24:
|
1392
|
-
if ( ++p == pe )
|
1393
|
-
goto _test_eof24;
|
1394
|
-
case 24:
|
1395
|
-
if ( (*p) == 108 )
|
1396
|
-
goto st25;
|
1397
|
-
goto st0;
|
1398
|
-
st25:
|
1399
|
-
if ( ++p == pe )
|
1400
|
-
goto _test_eof25;
|
1401
|
-
case 25:
|
1402
|
-
if ( (*p) == 108 )
|
1403
|
-
goto tr34;
|
1404
|
-
goto st0;
|
1405
|
-
st26:
|
1406
|
-
if ( ++p == pe )
|
1407
|
-
goto _test_eof26;
|
1408
|
-
case 26:
|
1409
|
-
if ( (*p) == 114 )
|
1410
|
-
goto st27;
|
1411
|
-
goto st0;
|
1412
|
-
st27:
|
1413
|
-
if ( ++p == pe )
|
1414
|
-
goto _test_eof27;
|
1415
|
-
case 27:
|
1416
|
-
if ( (*p) == 117 )
|
1417
|
-
goto st28;
|
1418
|
-
goto st0;
|
1419
|
-
st28:
|
1420
|
-
if ( ++p == pe )
|
1421
|
-
goto _test_eof28;
|
1422
|
-
case 28:
|
1423
|
-
if ( (*p) == 101 )
|
1424
|
-
goto tr37;
|
1425
|
-
goto st0;
|
1426
|
-
}
|
1427
|
-
_test_eof1: cs = 1; goto _test_eof;
|
1428
|
-
_test_eof29: cs = 29; goto _test_eof;
|
1429
|
-
_test_eof2: cs = 2; goto _test_eof;
|
1430
|
-
_test_eof3: cs = 3; goto _test_eof;
|
1431
|
-
_test_eof4: cs = 4; goto _test_eof;
|
1432
|
-
_test_eof5: cs = 5; goto _test_eof;
|
1433
|
-
_test_eof6: cs = 6; goto _test_eof;
|
1434
|
-
_test_eof7: cs = 7; goto _test_eof;
|
1435
|
-
_test_eof8: cs = 8; goto _test_eof;
|
1436
|
-
_test_eof9: cs = 9; goto _test_eof;
|
1437
|
-
_test_eof10: cs = 10; goto _test_eof;
|
1438
|
-
_test_eof11: cs = 11; goto _test_eof;
|
1439
|
-
_test_eof12: cs = 12; goto _test_eof;
|
1440
|
-
_test_eof13: cs = 13; goto _test_eof;
|
1441
|
-
_test_eof14: cs = 14; goto _test_eof;
|
1442
|
-
_test_eof15: cs = 15; goto _test_eof;
|
1443
|
-
_test_eof16: cs = 16; goto _test_eof;
|
1444
|
-
_test_eof17: cs = 17; goto _test_eof;
|
1445
|
-
_test_eof18: cs = 18; goto _test_eof;
|
1446
|
-
_test_eof19: cs = 19; goto _test_eof;
|
1447
|
-
_test_eof20: cs = 20; goto _test_eof;
|
1448
|
-
_test_eof21: cs = 21; goto _test_eof;
|
1449
|
-
_test_eof22: cs = 22; goto _test_eof;
|
1450
|
-
_test_eof23: cs = 23; goto _test_eof;
|
1451
|
-
_test_eof24: cs = 24; goto _test_eof;
|
1452
|
-
_test_eof25: cs = 25; goto _test_eof;
|
1453
|
-
_test_eof26: cs = 26; goto _test_eof;
|
1454
|
-
_test_eof27: cs = 27; goto _test_eof;
|
1455
|
-
_test_eof28: cs = 28; goto _test_eof;
|
1456
|
-
|
1457
|
-
_test_eof: {}
|
1458
|
-
_out: {}
|
1459
|
-
}
|
1460
|
-
|
1461
|
-
#line 670 "parser.rl"
|
1462
|
-
|
1463
|
-
if (json->freeze) {
|
1464
|
-
OBJ_FREEZE(*result);
|
1465
|
-
}
|
1466
573
|
|
1467
|
-
|
1468
|
-
PUSH(*result);
|
1469
|
-
return p;
|
1470
|
-
} else {
|
1471
|
-
return NULL;
|
1472
|
-
}
|
574
|
+
return build_string(string, stringEnd, intern, symbolize);
|
1473
575
|
}
|
1474
576
|
|
577
|
+
static VALUE json_string_unescape(JSON_ParserState *state, const char *string, const char *stringEnd, bool is_name, bool intern, bool symbolize)
|
578
|
+
{
|
579
|
+
size_t bufferSize = stringEnd - string;
|
580
|
+
const char *p = string, *pe = string, *unescape, *bufferStart;
|
581
|
+
char *buffer;
|
582
|
+
int unescape_len;
|
583
|
+
char buf[4];
|
1475
584
|
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
585
|
+
if (is_name && state->in_array) {
|
586
|
+
VALUE cached_key;
|
587
|
+
if (RB_UNLIKELY(symbolize)) {
|
588
|
+
cached_key = rsymbol_cache_fetch(&state->name_cache, string, bufferSize);
|
589
|
+
} else {
|
590
|
+
cached_key = rstring_cache_fetch(&state->name_cache, string, bufferSize);
|
591
|
+
}
|
1480
592
|
|
1481
|
-
|
593
|
+
if (RB_LIKELY(cached_key)) {
|
594
|
+
return cached_key;
|
595
|
+
}
|
596
|
+
}
|
1482
597
|
|
598
|
+
VALUE result = rb_str_buf_new(bufferSize);
|
599
|
+
rb_enc_associate_index(result, utf8_encindex);
|
600
|
+
buffer = RSTRING_PTR(result);
|
601
|
+
bufferStart = buffer;
|
602
|
+
|
603
|
+
while ((pe = memchr(pe, '\\', stringEnd - pe))) {
|
604
|
+
unescape = (char *) "?";
|
605
|
+
unescape_len = 1;
|
606
|
+
if (pe > p) {
|
607
|
+
MEMCPY(buffer, p, char, pe - p);
|
608
|
+
buffer += pe - p;
|
609
|
+
}
|
610
|
+
switch (*++pe) {
|
611
|
+
case 'n':
|
612
|
+
unescape = (char *) "\n";
|
613
|
+
break;
|
614
|
+
case 'r':
|
615
|
+
unescape = (char *) "\r";
|
616
|
+
break;
|
617
|
+
case 't':
|
618
|
+
unescape = (char *) "\t";
|
619
|
+
break;
|
620
|
+
case '"':
|
621
|
+
unescape = (char *) "\"";
|
622
|
+
break;
|
623
|
+
case '\\':
|
624
|
+
unescape = (char *) "\\";
|
625
|
+
break;
|
626
|
+
case 'b':
|
627
|
+
unescape = (char *) "\b";
|
628
|
+
break;
|
629
|
+
case 'f':
|
630
|
+
unescape = (char *) "\f";
|
631
|
+
break;
|
632
|
+
case 'u':
|
633
|
+
if (pe > stringEnd - 5) {
|
634
|
+
raise_parse_error("incomplete unicode character escape sequence at '%s'", p);
|
635
|
+
} else {
|
636
|
+
uint32_t ch = unescape_unicode((unsigned char *) ++pe);
|
637
|
+
pe += 3;
|
638
|
+
/* To handle values above U+FFFF, we take a sequence of
|
639
|
+
* \uXXXX escapes in the U+D800..U+DBFF then
|
640
|
+
* U+DC00..U+DFFF ranges, take the low 10 bits from each
|
641
|
+
* to make a 20-bit number, then add 0x10000 to get the
|
642
|
+
* final codepoint.
|
643
|
+
*
|
644
|
+
* See Unicode 15: 3.8 "Surrogates", 5.3 "Handling
|
645
|
+
* Surrogate Pairs in UTF-16", and 23.6 "Surrogates
|
646
|
+
* Area".
|
647
|
+
*/
|
648
|
+
if ((ch & 0xFC00) == 0xD800) {
|
649
|
+
pe++;
|
650
|
+
if (pe > stringEnd - 6) {
|
651
|
+
raise_parse_error("incomplete surrogate pair at '%s'", p);
|
652
|
+
}
|
653
|
+
if (pe[0] == '\\' && pe[1] == 'u') {
|
654
|
+
uint32_t sur = unescape_unicode((unsigned char *) pe + 2);
|
655
|
+
ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
|
656
|
+
| (sur & 0x3FF));
|
657
|
+
pe += 5;
|
658
|
+
} else {
|
659
|
+
unescape = (char *) "?";
|
660
|
+
break;
|
661
|
+
}
|
662
|
+
}
|
663
|
+
unescape_len = convert_UTF32_to_UTF8(buf, ch);
|
664
|
+
unescape = buf;
|
665
|
+
}
|
666
|
+
break;
|
667
|
+
default:
|
668
|
+
p = pe;
|
669
|
+
continue;
|
670
|
+
}
|
671
|
+
MEMCPY(buffer, unescape, char, unescape_len);
|
672
|
+
buffer += unescape_len;
|
673
|
+
p = ++pe;
|
674
|
+
}
|
1483
675
|
|
1484
|
-
|
676
|
+
if (stringEnd > p) {
|
677
|
+
MEMCPY(buffer, p, char, stringEnd - p);
|
678
|
+
buffer += stringEnd - p;
|
679
|
+
}
|
680
|
+
rb_str_set_len(result, buffer - bufferStart);
|
1485
681
|
|
682
|
+
if (symbolize) {
|
683
|
+
result = rb_str_intern(result);
|
684
|
+
} else if (intern) {
|
685
|
+
result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
|
686
|
+
}
|
687
|
+
|
688
|
+
return result;
|
689
|
+
}
|
1486
690
|
|
1487
691
|
#define MAX_FAST_INTEGER_SIZE 18
|
1488
|
-
static inline VALUE
|
692
|
+
static inline VALUE fast_decode_integer(const char *p, const char *pe)
|
1489
693
|
{
|
1490
694
|
bool negative = false;
|
1491
695
|
if (*p == '-') {
|
@@ -1506,1102 +710,459 @@ static inline VALUE fast_parse_integer(char *p, char *pe)
|
|
1506
710
|
return LL2NUM(memo);
|
1507
711
|
}
|
1508
712
|
|
1509
|
-
static
|
713
|
+
static VALUE json_decode_large_integer(const char *start, long len)
|
1510
714
|
{
|
1511
|
-
|
715
|
+
VALUE buffer_v;
|
716
|
+
char *buffer = RB_ALLOCV_N(char, buffer_v, len + 1);
|
717
|
+
MEMCPY(buffer, start, char, len);
|
718
|
+
buffer[len] = '\0';
|
719
|
+
VALUE number = rb_cstr2inum(buffer, 10);
|
720
|
+
RB_ALLOCV_END(buffer_v);
|
721
|
+
return number;
|
722
|
+
}
|
723
|
+
|
724
|
+
static inline VALUE
|
725
|
+
json_decode_integer(const char *start, const char *end)
|
726
|
+
{
|
727
|
+
long len = end - start;
|
1512
728
|
if (RB_LIKELY(len < MAX_FAST_INTEGER_SIZE)) {
|
1513
|
-
|
1514
|
-
} else {
|
1515
|
-
fbuffer_clear(&json->fbuffer);
|
1516
|
-
fbuffer_append(&json->fbuffer, json->memo, len);
|
1517
|
-
fbuffer_append_char(&json->fbuffer, '\0');
|
1518
|
-
*result = rb_cstr2inum(FBUFFER_PTR(&json->fbuffer), 10);
|
729
|
+
return fast_decode_integer(start, end);
|
1519
730
|
}
|
1520
|
-
return
|
731
|
+
return json_decode_large_integer(start, len);
|
1521
732
|
}
|
1522
733
|
|
734
|
+
static VALUE json_decode_large_float(const char *start, long len)
|
735
|
+
{
|
736
|
+
VALUE buffer_v;
|
737
|
+
char *buffer = RB_ALLOCV_N(char, buffer_v, len + 1);
|
738
|
+
MEMCPY(buffer, start, char, len);
|
739
|
+
buffer[len] = '\0';
|
740
|
+
VALUE number = DBL2NUM(rb_cstr_to_dbl(buffer, 1));
|
741
|
+
RB_ALLOCV_END(buffer_v);
|
742
|
+
return number;
|
743
|
+
}
|
1523
744
|
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
745
|
+
static VALUE json_decode_float(JSON_ParserConfig *config, const char *start, const char *end)
|
746
|
+
{
|
747
|
+
long len = end - start;
|
748
|
+
|
749
|
+
if (RB_UNLIKELY(config->decimal_class)) {
|
750
|
+
VALUE text = rb_str_new(start, len);
|
751
|
+
return rb_funcallv(config->decimal_class, config->decimal_method_id, 1, &text);
|
752
|
+
} else if (RB_LIKELY(len < 64)) {
|
753
|
+
char buffer[64];
|
754
|
+
MEMCPY(buffer, start, char, len);
|
755
|
+
buffer[len] = '\0';
|
756
|
+
return DBL2NUM(rb_cstr_to_dbl(buffer, 1));
|
757
|
+
} else {
|
758
|
+
return json_decode_large_float(start, len);
|
759
|
+
}
|
760
|
+
}
|
1528
761
|
|
1529
|
-
|
762
|
+
static inline VALUE json_decode_array(JSON_ParserState *state, JSON_ParserConfig *config, long count)
|
763
|
+
{
|
764
|
+
VALUE array;
|
765
|
+
if (RB_UNLIKELY(config->array_class)) {
|
766
|
+
array = rb_class_new_instance(0, 0, config->array_class);
|
767
|
+
VALUE *items = rvalue_stack_peek(state->stack, count);
|
768
|
+
long index;
|
769
|
+
for (index = 0; index < count; index++) {
|
770
|
+
rb_funcall(array, i_leftshift, 1, items[index]);
|
771
|
+
}
|
772
|
+
} else {
|
773
|
+
array = rb_ary_new_from_values(count, rvalue_stack_peek(state->stack, count));
|
774
|
+
}
|
1530
775
|
|
776
|
+
rvalue_stack_pop(state->stack, count);
|
1531
777
|
|
1532
|
-
|
778
|
+
if (config->freeze) {
|
779
|
+
RB_OBJ_FREEZE(array);
|
780
|
+
}
|
1533
781
|
|
782
|
+
return array;
|
783
|
+
}
|
1534
784
|
|
1535
|
-
static
|
785
|
+
static inline VALUE json_decode_object(JSON_ParserState *state, JSON_ParserConfig *config, long count)
|
1536
786
|
{
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1543
|
-
|
1544
|
-
|
1545
|
-
|
1546
|
-
#line 751 "parser.rl"
|
1547
|
-
json->memo = p;
|
1548
|
-
|
1549
|
-
#line 1550 "parser.c"
|
1550
|
-
{
|
1551
|
-
if ( p == pe )
|
1552
|
-
goto _test_eof;
|
1553
|
-
switch ( cs )
|
1554
|
-
{
|
1555
|
-
case 1:
|
1556
|
-
switch( (*p) ) {
|
1557
|
-
case 45: goto st2;
|
1558
|
-
case 48: goto st6;
|
1559
|
-
}
|
1560
|
-
if ( 49 <= (*p) && (*p) <= 57 )
|
1561
|
-
goto st10;
|
1562
|
-
goto st0;
|
1563
|
-
st0:
|
1564
|
-
cs = 0;
|
1565
|
-
goto _out;
|
1566
|
-
st2:
|
1567
|
-
if ( ++p == pe )
|
1568
|
-
goto _test_eof2;
|
1569
|
-
case 2:
|
1570
|
-
if ( (*p) == 48 )
|
1571
|
-
goto st6;
|
1572
|
-
if ( 49 <= (*p) && (*p) <= 57 )
|
1573
|
-
goto st10;
|
1574
|
-
goto st0;
|
1575
|
-
st6:
|
1576
|
-
if ( ++p == pe )
|
1577
|
-
goto _test_eof6;
|
1578
|
-
case 6:
|
1579
|
-
switch( (*p) ) {
|
1580
|
-
case 45: goto st0;
|
1581
|
-
case 46: goto tr8;
|
1582
|
-
case 69: goto tr9;
|
1583
|
-
case 101: goto tr9;
|
1584
|
-
}
|
1585
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
1586
|
-
goto st0;
|
1587
|
-
goto tr7;
|
1588
|
-
tr7:
|
1589
|
-
#line 735 "parser.rl"
|
1590
|
-
{ p--; {p++; cs = 7; goto _out;} }
|
1591
|
-
goto st7;
|
1592
|
-
st7:
|
1593
|
-
if ( ++p == pe )
|
1594
|
-
goto _test_eof7;
|
1595
|
-
case 7:
|
1596
|
-
#line 1597 "parser.c"
|
1597
|
-
goto st0;
|
1598
|
-
tr8:
|
1599
|
-
#line 736 "parser.rl"
|
1600
|
-
{ is_float = true; }
|
1601
|
-
goto st3;
|
1602
|
-
st3:
|
1603
|
-
if ( ++p == pe )
|
1604
|
-
goto _test_eof3;
|
1605
|
-
case 3:
|
1606
|
-
#line 1607 "parser.c"
|
1607
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
1608
|
-
goto st8;
|
1609
|
-
goto st0;
|
1610
|
-
st8:
|
1611
|
-
if ( ++p == pe )
|
1612
|
-
goto _test_eof8;
|
1613
|
-
case 8:
|
1614
|
-
switch( (*p) ) {
|
1615
|
-
case 69: goto st4;
|
1616
|
-
case 101: goto st4;
|
1617
|
-
}
|
1618
|
-
if ( (*p) > 46 ) {
|
1619
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
1620
|
-
goto st8;
|
1621
|
-
} else if ( (*p) >= 45 )
|
1622
|
-
goto st0;
|
1623
|
-
goto tr7;
|
1624
|
-
tr9:
|
1625
|
-
#line 736 "parser.rl"
|
1626
|
-
{ is_float = true; }
|
1627
|
-
goto st4;
|
1628
|
-
st4:
|
1629
|
-
if ( ++p == pe )
|
1630
|
-
goto _test_eof4;
|
1631
|
-
case 4:
|
1632
|
-
#line 1633 "parser.c"
|
1633
|
-
switch( (*p) ) {
|
1634
|
-
case 43: goto st5;
|
1635
|
-
case 45: goto st5;
|
1636
|
-
}
|
1637
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
1638
|
-
goto st9;
|
1639
|
-
goto st0;
|
1640
|
-
st5:
|
1641
|
-
if ( ++p == pe )
|
1642
|
-
goto _test_eof5;
|
1643
|
-
case 5:
|
1644
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
1645
|
-
goto st9;
|
1646
|
-
goto st0;
|
1647
|
-
st9:
|
1648
|
-
if ( ++p == pe )
|
1649
|
-
goto _test_eof9;
|
1650
|
-
case 9:
|
1651
|
-
switch( (*p) ) {
|
1652
|
-
case 69: goto st0;
|
1653
|
-
case 101: goto st0;
|
1654
|
-
}
|
1655
|
-
if ( (*p) > 46 ) {
|
1656
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
1657
|
-
goto st9;
|
1658
|
-
} else if ( (*p) >= 45 )
|
1659
|
-
goto st0;
|
1660
|
-
goto tr7;
|
1661
|
-
st10:
|
1662
|
-
if ( ++p == pe )
|
1663
|
-
goto _test_eof10;
|
1664
|
-
case 10:
|
1665
|
-
switch( (*p) ) {
|
1666
|
-
case 45: goto st0;
|
1667
|
-
case 46: goto tr8;
|
1668
|
-
case 69: goto tr9;
|
1669
|
-
case 101: goto tr9;
|
1670
|
-
}
|
1671
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
1672
|
-
goto st10;
|
1673
|
-
goto tr7;
|
1674
|
-
}
|
1675
|
-
_test_eof2: cs = 2; goto _test_eof;
|
1676
|
-
_test_eof6: cs = 6; goto _test_eof;
|
1677
|
-
_test_eof7: cs = 7; goto _test_eof;
|
1678
|
-
_test_eof3: cs = 3; goto _test_eof;
|
1679
|
-
_test_eof8: cs = 8; goto _test_eof;
|
1680
|
-
_test_eof4: cs = 4; goto _test_eof;
|
1681
|
-
_test_eof5: cs = 5; goto _test_eof;
|
1682
|
-
_test_eof9: cs = 9; goto _test_eof;
|
1683
|
-
_test_eof10: cs = 10; goto _test_eof;
|
1684
|
-
|
1685
|
-
_test_eof: {}
|
1686
|
-
_out: {}
|
1687
|
-
}
|
1688
|
-
|
1689
|
-
#line 753 "parser.rl"
|
1690
|
-
|
1691
|
-
if (cs >= JSON_float_first_final) {
|
1692
|
-
if (!is_float) {
|
1693
|
-
return JSON_decode_integer(json, p, result);
|
787
|
+
VALUE object;
|
788
|
+
if (RB_UNLIKELY(config->object_class)) {
|
789
|
+
object = rb_class_new_instance(0, 0, config->object_class);
|
790
|
+
long index = 0;
|
791
|
+
VALUE *items = rvalue_stack_peek(state->stack, count);
|
792
|
+
while (index < count) {
|
793
|
+
VALUE name = items[index++];
|
794
|
+
VALUE value = items[index++];
|
795
|
+
rb_funcall(object, i_aset, 2, name, value);
|
1694
796
|
}
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
mod = json->decimal_class;
|
1700
|
-
method_id = i_try_convert;
|
1701
|
-
} else if (rb_respond_to(json->decimal_class, i_new)) {
|
1702
|
-
mod = json->decimal_class;
|
1703
|
-
method_id = i_new;
|
1704
|
-
} else if (RB_TYPE_P(json->decimal_class, T_CLASS)) {
|
1705
|
-
VALUE name = rb_class_name(json->decimal_class);
|
1706
|
-
const char *name_cstr = RSTRING_PTR(name);
|
1707
|
-
const char *last_colon = strrchr(name_cstr, ':');
|
1708
|
-
if (last_colon) {
|
1709
|
-
const char *mod_path_end = last_colon - 1;
|
1710
|
-
VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr);
|
1711
|
-
mod = rb_path_to_class(mod_path);
|
797
|
+
} else {
|
798
|
+
object = rb_hash_new_capa(count);
|
799
|
+
rb_hash_bulk_insert(count, rvalue_stack_peek(state->stack, count), object);
|
800
|
+
}
|
1712
801
|
|
1713
|
-
|
1714
|
-
|
1715
|
-
|
1716
|
-
|
1717
|
-
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
802
|
+
rvalue_stack_pop(state->stack, count);
|
803
|
+
|
804
|
+
if (RB_UNLIKELY(config->create_additions)) {
|
805
|
+
VALUE klassname;
|
806
|
+
if (config->object_class) {
|
807
|
+
klassname = rb_funcall(object, i_aref, 1, config->create_id);
|
808
|
+
} else {
|
809
|
+
klassname = rb_hash_aref(object, config->create_id);
|
810
|
+
}
|
811
|
+
if (!NIL_P(klassname)) {
|
812
|
+
VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname);
|
813
|
+
if (RTEST(rb_funcall(klass, i_json_creatable_p, 0))) {
|
814
|
+
if (config->deprecated_create_additions) {
|
815
|
+
json_deprecated(deprecated_create_additions_warning);
|
1721
816
|
}
|
817
|
+
object = rb_funcall(klass, i_json_create, 1, object);
|
1722
818
|
}
|
1723
819
|
}
|
820
|
+
}
|
1724
821
|
|
1725
|
-
|
1726
|
-
|
1727
|
-
|
1728
|
-
fbuffer_append_char(&json->fbuffer, '\0');
|
822
|
+
if (config->freeze) {
|
823
|
+
RB_OBJ_FREEZE(object);
|
824
|
+
}
|
1729
825
|
|
1730
|
-
|
1731
|
-
|
1732
|
-
*result = rb_funcallv(mod, method_id, 1, &text);
|
1733
|
-
} else {
|
1734
|
-
*result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(&json->fbuffer), 1));
|
1735
|
-
}
|
826
|
+
return object;
|
827
|
+
}
|
1736
828
|
|
1737
|
-
|
1738
|
-
|
1739
|
-
|
829
|
+
static int match_i(VALUE regexp, VALUE klass, VALUE memo)
|
830
|
+
{
|
831
|
+
if (regexp == Qundef) return ST_STOP;
|
832
|
+
if (RTEST(rb_funcall(klass, i_json_creatable_p, 0)) &&
|
833
|
+
RTEST(rb_funcall(regexp, i_match, 1, rb_ary_entry(memo, 0)))) {
|
834
|
+
rb_ary_push(memo, klass);
|
835
|
+
return ST_STOP;
|
1740
836
|
}
|
837
|
+
return ST_CONTINUE;
|
1741
838
|
}
|
1742
839
|
|
840
|
+
static inline VALUE json_decode_string(JSON_ParserState *state, JSON_ParserConfig *config, const char *start, const char *end, bool escaped, bool is_name)
|
841
|
+
{
|
842
|
+
VALUE string;
|
843
|
+
bool intern = is_name || config->freeze;
|
844
|
+
bool symbolize = is_name && config->symbolize_names;
|
845
|
+
if (escaped) {
|
846
|
+
string = json_string_unescape(state, start, end, is_name, intern, symbolize);
|
847
|
+
} else {
|
848
|
+
string = json_string_fastpath(state, start, end, is_name, intern, symbolize);
|
849
|
+
}
|
1743
850
|
|
851
|
+
if (RB_UNLIKELY(config->create_additions && RTEST(config->match_string))) {
|
852
|
+
VALUE klass;
|
853
|
+
VALUE memo = rb_ary_new2(2);
|
854
|
+
rb_ary_push(memo, string);
|
855
|
+
rb_hash_foreach(config->match_string, match_i, memo);
|
856
|
+
klass = rb_ary_entry(memo, 1);
|
857
|
+
if (RTEST(klass)) {
|
858
|
+
string = rb_funcall(klass, i_json_create, 1, string);
|
859
|
+
}
|
860
|
+
}
|
1744
861
|
|
1745
|
-
|
1746
|
-
|
1747
|
-
enum {JSON_array_first_final = 22};
|
1748
|
-
enum {JSON_array_error = 0};
|
1749
|
-
|
1750
|
-
enum {JSON_array_en_main = 1};
|
1751
|
-
|
1752
|
-
|
1753
|
-
#line 833 "parser.rl"
|
862
|
+
return string;
|
863
|
+
}
|
1754
864
|
|
865
|
+
#define PUSH(result) rvalue_stack_push(state->stack, result, &state->stack_handle, &state->stack)
|
866
|
+
|
867
|
+
static const bool string_scan[256] = {
|
868
|
+
// ASCII Control Characters
|
869
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
870
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
871
|
+
// ASCII Characters
|
872
|
+
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // '"'
|
873
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
874
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
875
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, // '\\'
|
876
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
877
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
878
|
+
};
|
1755
879
|
|
1756
|
-
static
|
880
|
+
static inline VALUE json_parse_string(JSON_ParserState *state, JSON_ParserConfig *config, bool is_name)
|
1757
881
|
{
|
1758
|
-
|
1759
|
-
|
1760
|
-
|
1761
|
-
|
1762
|
-
|
1763
|
-
|
1764
|
-
|
1765
|
-
|
1766
|
-
|
1767
|
-
|
1768
|
-
|
1769
|
-
|
1770
|
-
|
1771
|
-
|
1772
|
-
|
1773
|
-
|
1774
|
-
|
1775
|
-
|
1776
|
-
|
1777
|
-
|
1778
|
-
|
1779
|
-
|
1780
|
-
|
1781
|
-
if ( (*p) == 91 )
|
1782
|
-
goto st2;
|
1783
|
-
goto st0;
|
1784
|
-
st0:
|
1785
|
-
cs = 0;
|
1786
|
-
goto _out;
|
1787
|
-
st2:
|
1788
|
-
if ( ++p == pe )
|
1789
|
-
goto _test_eof2;
|
1790
|
-
case 2:
|
1791
|
-
switch( (*p) ) {
|
1792
|
-
case 13: goto st2;
|
1793
|
-
case 32: goto st2;
|
1794
|
-
case 34: goto tr2;
|
1795
|
-
case 45: goto tr2;
|
1796
|
-
case 47: goto st18;
|
1797
|
-
case 73: goto tr2;
|
1798
|
-
case 78: goto tr2;
|
1799
|
-
case 91: goto tr2;
|
1800
|
-
case 93: goto tr4;
|
1801
|
-
case 102: goto tr2;
|
1802
|
-
case 110: goto tr2;
|
1803
|
-
case 116: goto tr2;
|
1804
|
-
case 123: goto tr2;
|
1805
|
-
}
|
1806
|
-
if ( (*p) > 10 ) {
|
1807
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
1808
|
-
goto tr2;
|
1809
|
-
} else if ( (*p) >= 9 )
|
1810
|
-
goto st2;
|
1811
|
-
goto st0;
|
1812
|
-
tr2:
|
1813
|
-
#line 813 "parser.rl"
|
1814
|
-
{
|
1815
|
-
VALUE v = Qnil;
|
1816
|
-
char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
|
1817
|
-
if (np == NULL) {
|
1818
|
-
p--; {p++; cs = 3; goto _out;}
|
1819
|
-
} else {
|
1820
|
-
{p = (( np))-1;}
|
1821
|
-
}
|
1822
|
-
}
|
1823
|
-
goto st3;
|
1824
|
-
st3:
|
1825
|
-
if ( ++p == pe )
|
1826
|
-
goto _test_eof3;
|
1827
|
-
case 3:
|
1828
|
-
#line 1829 "parser.c"
|
1829
|
-
_widec = (*p);
|
1830
|
-
if ( 44 <= (*p) && (*p) <= 44 ) {
|
1831
|
-
_widec = (short)(128 + ((*p) - -128));
|
1832
|
-
if (
|
1833
|
-
#line 823 "parser.rl"
|
1834
|
-
json->allow_trailing_comma ) _widec += 256;
|
1835
|
-
}
|
1836
|
-
switch( _widec ) {
|
1837
|
-
case 13: goto st3;
|
1838
|
-
case 32: goto st3;
|
1839
|
-
case 47: goto st4;
|
1840
|
-
case 93: goto tr4;
|
1841
|
-
case 300: goto st8;
|
1842
|
-
case 556: goto st13;
|
1843
|
-
}
|
1844
|
-
if ( 9 <= _widec && _widec <= 10 )
|
1845
|
-
goto st3;
|
1846
|
-
goto st0;
|
1847
|
-
st4:
|
1848
|
-
if ( ++p == pe )
|
1849
|
-
goto _test_eof4;
|
1850
|
-
case 4:
|
1851
|
-
switch( (*p) ) {
|
1852
|
-
case 42: goto st5;
|
1853
|
-
case 47: goto st7;
|
1854
|
-
}
|
1855
|
-
goto st0;
|
1856
|
-
st5:
|
1857
|
-
if ( ++p == pe )
|
1858
|
-
goto _test_eof5;
|
1859
|
-
case 5:
|
1860
|
-
if ( (*p) == 42 )
|
1861
|
-
goto st6;
|
1862
|
-
goto st5;
|
1863
|
-
st6:
|
1864
|
-
if ( ++p == pe )
|
1865
|
-
goto _test_eof6;
|
1866
|
-
case 6:
|
1867
|
-
switch( (*p) ) {
|
1868
|
-
case 42: goto st6;
|
1869
|
-
case 47: goto st3;
|
1870
|
-
}
|
1871
|
-
goto st5;
|
1872
|
-
st7:
|
1873
|
-
if ( ++p == pe )
|
1874
|
-
goto _test_eof7;
|
1875
|
-
case 7:
|
1876
|
-
if ( (*p) == 10 )
|
1877
|
-
goto st3;
|
1878
|
-
goto st7;
|
1879
|
-
tr4:
|
1880
|
-
#line 825 "parser.rl"
|
1881
|
-
{ p--; {p++; cs = 22; goto _out;} }
|
1882
|
-
goto st22;
|
1883
|
-
st22:
|
1884
|
-
if ( ++p == pe )
|
1885
|
-
goto _test_eof22;
|
1886
|
-
case 22:
|
1887
|
-
#line 1888 "parser.c"
|
1888
|
-
goto st0;
|
1889
|
-
st8:
|
1890
|
-
if ( ++p == pe )
|
1891
|
-
goto _test_eof8;
|
1892
|
-
case 8:
|
1893
|
-
switch( (*p) ) {
|
1894
|
-
case 13: goto st8;
|
1895
|
-
case 32: goto st8;
|
1896
|
-
case 34: goto tr2;
|
1897
|
-
case 45: goto tr2;
|
1898
|
-
case 47: goto st9;
|
1899
|
-
case 73: goto tr2;
|
1900
|
-
case 78: goto tr2;
|
1901
|
-
case 91: goto tr2;
|
1902
|
-
case 102: goto tr2;
|
1903
|
-
case 110: goto tr2;
|
1904
|
-
case 116: goto tr2;
|
1905
|
-
case 123: goto tr2;
|
1906
|
-
}
|
1907
|
-
if ( (*p) > 10 ) {
|
1908
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
1909
|
-
goto tr2;
|
1910
|
-
} else if ( (*p) >= 9 )
|
1911
|
-
goto st8;
|
1912
|
-
goto st0;
|
1913
|
-
st9:
|
1914
|
-
if ( ++p == pe )
|
1915
|
-
goto _test_eof9;
|
1916
|
-
case 9:
|
1917
|
-
switch( (*p) ) {
|
1918
|
-
case 42: goto st10;
|
1919
|
-
case 47: goto st12;
|
1920
|
-
}
|
1921
|
-
goto st0;
|
1922
|
-
st10:
|
1923
|
-
if ( ++p == pe )
|
1924
|
-
goto _test_eof10;
|
1925
|
-
case 10:
|
1926
|
-
if ( (*p) == 42 )
|
1927
|
-
goto st11;
|
1928
|
-
goto st10;
|
1929
|
-
st11:
|
1930
|
-
if ( ++p == pe )
|
1931
|
-
goto _test_eof11;
|
1932
|
-
case 11:
|
1933
|
-
switch( (*p) ) {
|
1934
|
-
case 42: goto st11;
|
1935
|
-
case 47: goto st8;
|
1936
|
-
}
|
1937
|
-
goto st10;
|
1938
|
-
st12:
|
1939
|
-
if ( ++p == pe )
|
1940
|
-
goto _test_eof12;
|
1941
|
-
case 12:
|
1942
|
-
if ( (*p) == 10 )
|
1943
|
-
goto st8;
|
1944
|
-
goto st12;
|
1945
|
-
st13:
|
1946
|
-
if ( ++p == pe )
|
1947
|
-
goto _test_eof13;
|
1948
|
-
case 13:
|
1949
|
-
_widec = (*p);
|
1950
|
-
if ( (*p) < 13 ) {
|
1951
|
-
if ( (*p) > 9 ) {
|
1952
|
-
if ( 10 <= (*p) && (*p) <= 10 ) {
|
1953
|
-
_widec = (short)(128 + ((*p) - -128));
|
1954
|
-
if (
|
1955
|
-
#line 823 "parser.rl"
|
1956
|
-
json->allow_trailing_comma ) _widec += 256;
|
1957
|
-
}
|
1958
|
-
} else if ( (*p) >= 9 ) {
|
1959
|
-
_widec = (short)(128 + ((*p) - -128));
|
1960
|
-
if (
|
1961
|
-
#line 823 "parser.rl"
|
1962
|
-
json->allow_trailing_comma ) _widec += 256;
|
1963
|
-
}
|
1964
|
-
} else if ( (*p) > 13 ) {
|
1965
|
-
if ( (*p) > 32 ) {
|
1966
|
-
if ( 47 <= (*p) && (*p) <= 47 ) {
|
1967
|
-
_widec = (short)(128 + ((*p) - -128));
|
1968
|
-
if (
|
1969
|
-
#line 823 "parser.rl"
|
1970
|
-
json->allow_trailing_comma ) _widec += 256;
|
1971
|
-
}
|
1972
|
-
} else if ( (*p) >= 32 ) {
|
1973
|
-
_widec = (short)(128 + ((*p) - -128));
|
1974
|
-
if (
|
1975
|
-
#line 823 "parser.rl"
|
1976
|
-
json->allow_trailing_comma ) _widec += 256;
|
1977
|
-
}
|
1978
|
-
} else {
|
1979
|
-
_widec = (short)(128 + ((*p) - -128));
|
1980
|
-
if (
|
1981
|
-
#line 823 "parser.rl"
|
1982
|
-
json->allow_trailing_comma ) _widec += 256;
|
1983
|
-
}
|
1984
|
-
switch( _widec ) {
|
1985
|
-
case 34: goto tr2;
|
1986
|
-
case 45: goto tr2;
|
1987
|
-
case 73: goto tr2;
|
1988
|
-
case 78: goto tr2;
|
1989
|
-
case 91: goto tr2;
|
1990
|
-
case 93: goto tr4;
|
1991
|
-
case 102: goto tr2;
|
1992
|
-
case 110: goto tr2;
|
1993
|
-
case 116: goto tr2;
|
1994
|
-
case 123: goto tr2;
|
1995
|
-
case 269: goto st8;
|
1996
|
-
case 288: goto st8;
|
1997
|
-
case 303: goto st9;
|
1998
|
-
case 525: goto st13;
|
1999
|
-
case 544: goto st13;
|
2000
|
-
case 559: goto st14;
|
2001
|
-
}
|
2002
|
-
if ( _widec < 265 ) {
|
2003
|
-
if ( 48 <= _widec && _widec <= 57 )
|
2004
|
-
goto tr2;
|
2005
|
-
} else if ( _widec > 266 ) {
|
2006
|
-
if ( 521 <= _widec && _widec <= 522 )
|
2007
|
-
goto st13;
|
2008
|
-
} else
|
2009
|
-
goto st8;
|
2010
|
-
goto st0;
|
2011
|
-
st14:
|
2012
|
-
if ( ++p == pe )
|
2013
|
-
goto _test_eof14;
|
2014
|
-
case 14:
|
2015
|
-
_widec = (*p);
|
2016
|
-
if ( (*p) > 42 ) {
|
2017
|
-
if ( 47 <= (*p) && (*p) <= 47 ) {
|
2018
|
-
_widec = (short)(128 + ((*p) - -128));
|
2019
|
-
if (
|
2020
|
-
#line 823 "parser.rl"
|
2021
|
-
json->allow_trailing_comma ) _widec += 256;
|
2022
|
-
}
|
2023
|
-
} else if ( (*p) >= 42 ) {
|
2024
|
-
_widec = (short)(128 + ((*p) - -128));
|
2025
|
-
if (
|
2026
|
-
#line 823 "parser.rl"
|
2027
|
-
json->allow_trailing_comma ) _widec += 256;
|
2028
|
-
}
|
2029
|
-
switch( _widec ) {
|
2030
|
-
case 298: goto st10;
|
2031
|
-
case 303: goto st12;
|
2032
|
-
case 554: goto st15;
|
2033
|
-
case 559: goto st17;
|
2034
|
-
}
|
2035
|
-
goto st0;
|
2036
|
-
st15:
|
2037
|
-
if ( ++p == pe )
|
2038
|
-
goto _test_eof15;
|
2039
|
-
case 15:
|
2040
|
-
_widec = (*p);
|
2041
|
-
if ( (*p) < 42 ) {
|
2042
|
-
if ( (*p) <= 41 ) {
|
2043
|
-
_widec = (short)(128 + ((*p) - -128));
|
2044
|
-
if (
|
2045
|
-
#line 823 "parser.rl"
|
2046
|
-
json->allow_trailing_comma ) _widec += 256;
|
2047
|
-
}
|
2048
|
-
} else if ( (*p) > 42 ) {
|
2049
|
-
if ( 43 <= (*p) )
|
2050
|
-
{ _widec = (short)(128 + ((*p) - -128));
|
2051
|
-
if (
|
2052
|
-
#line 823 "parser.rl"
|
2053
|
-
json->allow_trailing_comma ) _widec += 256;
|
2054
|
-
}
|
2055
|
-
} else {
|
2056
|
-
_widec = (short)(128 + ((*p) - -128));
|
2057
|
-
if (
|
2058
|
-
#line 823 "parser.rl"
|
2059
|
-
json->allow_trailing_comma ) _widec += 256;
|
2060
|
-
}
|
2061
|
-
switch( _widec ) {
|
2062
|
-
case 298: goto st11;
|
2063
|
-
case 554: goto st16;
|
2064
|
-
}
|
2065
|
-
if ( _widec > 383 ) {
|
2066
|
-
if ( 384 <= _widec && _widec <= 639 )
|
2067
|
-
goto st15;
|
2068
|
-
} else if ( _widec >= 128 )
|
2069
|
-
goto st10;
|
2070
|
-
goto st0;
|
2071
|
-
st16:
|
2072
|
-
if ( ++p == pe )
|
2073
|
-
goto _test_eof16;
|
2074
|
-
case 16:
|
2075
|
-
_widec = (*p);
|
2076
|
-
if ( (*p) < 43 ) {
|
2077
|
-
if ( (*p) > 41 ) {
|
2078
|
-
if ( 42 <= (*p) && (*p) <= 42 ) {
|
2079
|
-
_widec = (short)(128 + ((*p) - -128));
|
2080
|
-
if (
|
2081
|
-
#line 823 "parser.rl"
|
2082
|
-
json->allow_trailing_comma ) _widec += 256;
|
2083
|
-
}
|
2084
|
-
} else {
|
2085
|
-
_widec = (short)(128 + ((*p) - -128));
|
2086
|
-
if (
|
2087
|
-
#line 823 "parser.rl"
|
2088
|
-
json->allow_trailing_comma ) _widec += 256;
|
2089
|
-
}
|
2090
|
-
} else if ( (*p) > 46 ) {
|
2091
|
-
if ( (*p) > 47 ) {
|
2092
|
-
if ( 48 <= (*p) )
|
2093
|
-
{ _widec = (short)(128 + ((*p) - -128));
|
2094
|
-
if (
|
2095
|
-
#line 823 "parser.rl"
|
2096
|
-
json->allow_trailing_comma ) _widec += 256;
|
2097
|
-
}
|
2098
|
-
} else if ( (*p) >= 47 ) {
|
2099
|
-
_widec = (short)(128 + ((*p) - -128));
|
2100
|
-
if (
|
2101
|
-
#line 823 "parser.rl"
|
2102
|
-
json->allow_trailing_comma ) _widec += 256;
|
2103
|
-
}
|
2104
|
-
} else {
|
2105
|
-
_widec = (short)(128 + ((*p) - -128));
|
2106
|
-
if (
|
2107
|
-
#line 823 "parser.rl"
|
2108
|
-
json->allow_trailing_comma ) _widec += 256;
|
2109
|
-
}
|
2110
|
-
switch( _widec ) {
|
2111
|
-
case 298: goto st11;
|
2112
|
-
case 303: goto st8;
|
2113
|
-
case 554: goto st16;
|
2114
|
-
case 559: goto st13;
|
2115
|
-
}
|
2116
|
-
if ( _widec > 383 ) {
|
2117
|
-
if ( 384 <= _widec && _widec <= 639 )
|
2118
|
-
goto st15;
|
2119
|
-
} else if ( _widec >= 128 )
|
2120
|
-
goto st10;
|
2121
|
-
goto st0;
|
2122
|
-
st17:
|
2123
|
-
if ( ++p == pe )
|
2124
|
-
goto _test_eof17;
|
2125
|
-
case 17:
|
2126
|
-
_widec = (*p);
|
2127
|
-
if ( (*p) < 10 ) {
|
2128
|
-
if ( (*p) <= 9 ) {
|
2129
|
-
_widec = (short)(128 + ((*p) - -128));
|
2130
|
-
if (
|
2131
|
-
#line 823 "parser.rl"
|
2132
|
-
json->allow_trailing_comma ) _widec += 256;
|
2133
|
-
}
|
2134
|
-
} else if ( (*p) > 10 ) {
|
2135
|
-
if ( 11 <= (*p) )
|
2136
|
-
{ _widec = (short)(128 + ((*p) - -128));
|
2137
|
-
if (
|
2138
|
-
#line 823 "parser.rl"
|
2139
|
-
json->allow_trailing_comma ) _widec += 256;
|
2140
|
-
}
|
2141
|
-
} else {
|
2142
|
-
_widec = (short)(128 + ((*p) - -128));
|
2143
|
-
if (
|
2144
|
-
#line 823 "parser.rl"
|
2145
|
-
json->allow_trailing_comma ) _widec += 256;
|
2146
|
-
}
|
2147
|
-
switch( _widec ) {
|
2148
|
-
case 266: goto st8;
|
2149
|
-
case 522: goto st13;
|
2150
|
-
}
|
2151
|
-
if ( _widec > 383 ) {
|
2152
|
-
if ( 384 <= _widec && _widec <= 639 )
|
2153
|
-
goto st17;
|
2154
|
-
} else if ( _widec >= 128 )
|
2155
|
-
goto st12;
|
2156
|
-
goto st0;
|
2157
|
-
st18:
|
2158
|
-
if ( ++p == pe )
|
2159
|
-
goto _test_eof18;
|
2160
|
-
case 18:
|
2161
|
-
switch( (*p) ) {
|
2162
|
-
case 42: goto st19;
|
2163
|
-
case 47: goto st21;
|
2164
|
-
}
|
2165
|
-
goto st0;
|
2166
|
-
st19:
|
2167
|
-
if ( ++p == pe )
|
2168
|
-
goto _test_eof19;
|
2169
|
-
case 19:
|
2170
|
-
if ( (*p) == 42 )
|
2171
|
-
goto st20;
|
2172
|
-
goto st19;
|
2173
|
-
st20:
|
2174
|
-
if ( ++p == pe )
|
2175
|
-
goto _test_eof20;
|
2176
|
-
case 20:
|
2177
|
-
switch( (*p) ) {
|
2178
|
-
case 42: goto st20;
|
2179
|
-
case 47: goto st2;
|
2180
|
-
}
|
2181
|
-
goto st19;
|
2182
|
-
st21:
|
2183
|
-
if ( ++p == pe )
|
2184
|
-
goto _test_eof21;
|
2185
|
-
case 21:
|
2186
|
-
if ( (*p) == 10 )
|
2187
|
-
goto st2;
|
2188
|
-
goto st21;
|
2189
|
-
}
|
2190
|
-
_test_eof2: cs = 2; goto _test_eof;
|
2191
|
-
_test_eof3: cs = 3; goto _test_eof;
|
2192
|
-
_test_eof4: cs = 4; goto _test_eof;
|
2193
|
-
_test_eof5: cs = 5; goto _test_eof;
|
2194
|
-
_test_eof6: cs = 6; goto _test_eof;
|
2195
|
-
_test_eof7: cs = 7; goto _test_eof;
|
2196
|
-
_test_eof22: cs = 22; goto _test_eof;
|
2197
|
-
_test_eof8: cs = 8; goto _test_eof;
|
2198
|
-
_test_eof9: cs = 9; goto _test_eof;
|
2199
|
-
_test_eof10: cs = 10; goto _test_eof;
|
2200
|
-
_test_eof11: cs = 11; goto _test_eof;
|
2201
|
-
_test_eof12: cs = 12; goto _test_eof;
|
2202
|
-
_test_eof13: cs = 13; goto _test_eof;
|
2203
|
-
_test_eof14: cs = 14; goto _test_eof;
|
2204
|
-
_test_eof15: cs = 15; goto _test_eof;
|
2205
|
-
_test_eof16: cs = 16; goto _test_eof;
|
2206
|
-
_test_eof17: cs = 17; goto _test_eof;
|
2207
|
-
_test_eof18: cs = 18; goto _test_eof;
|
2208
|
-
_test_eof19: cs = 19; goto _test_eof;
|
2209
|
-
_test_eof20: cs = 20; goto _test_eof;
|
2210
|
-
_test_eof21: cs = 21; goto _test_eof;
|
2211
|
-
|
2212
|
-
_test_eof: {}
|
2213
|
-
_out: {}
|
2214
|
-
}
|
2215
|
-
|
2216
|
-
#line 846 "parser.rl"
|
2217
|
-
|
2218
|
-
if(cs >= JSON_array_first_final) {
|
2219
|
-
long count = json->stack->head - stack_head;
|
2220
|
-
|
2221
|
-
if (RB_UNLIKELY(json->array_class)) {
|
2222
|
-
VALUE array = rb_class_new_instance(0, 0, json->array_class);
|
2223
|
-
VALUE *items = rvalue_stack_peek(json->stack, count);
|
2224
|
-
long index;
|
2225
|
-
for (index = 0; index < count; index++) {
|
2226
|
-
rb_funcall(array, i_leftshift, 1, items[index]);
|
882
|
+
state->cursor++;
|
883
|
+
const char *start = state->cursor;
|
884
|
+
bool escaped = false;
|
885
|
+
|
886
|
+
while (state->cursor < state->end) {
|
887
|
+
if (RB_UNLIKELY(string_scan[(unsigned char)*state->cursor])) {
|
888
|
+
switch (*state->cursor) {
|
889
|
+
case '"': {
|
890
|
+
VALUE string = json_decode_string(state, config, start, state->cursor, escaped, is_name);
|
891
|
+
state->cursor++;
|
892
|
+
return PUSH(string);
|
893
|
+
}
|
894
|
+
case '\\': {
|
895
|
+
state->cursor++;
|
896
|
+
escaped = true;
|
897
|
+
if ((unsigned char)*state->cursor < 0x20) {
|
898
|
+
raise_parse_error("invalid ASCII control character in string: %s", state->cursor);
|
899
|
+
}
|
900
|
+
break;
|
901
|
+
}
|
902
|
+
default:
|
903
|
+
raise_parse_error("invalid ASCII control character in string: %s", state->cursor);
|
904
|
+
break;
|
2227
905
|
}
|
2228
|
-
*result = array;
|
2229
|
-
} else {
|
2230
|
-
VALUE array = rb_ary_new_from_values(count, rvalue_stack_peek(json->stack, count));
|
2231
|
-
*result = array;
|
2232
906
|
}
|
2233
|
-
rvalue_stack_pop(json->stack, count);
|
2234
907
|
|
2235
|
-
|
2236
|
-
} else {
|
2237
|
-
raise_parse_error("unexpected token at '%s'", p);
|
2238
|
-
return NULL;
|
908
|
+
state->cursor++;
|
2239
909
|
}
|
910
|
+
|
911
|
+
raise_parse_error("unexpected end of input, expected closing \"", state->cursor);
|
912
|
+
return Qfalse;
|
2240
913
|
}
|
2241
914
|
|
2242
|
-
static
|
915
|
+
static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config)
|
2243
916
|
{
|
2244
|
-
|
2245
|
-
|
2246
|
-
|
2247
|
-
VALUE result;
|
2248
|
-
# ifdef HAVE_RB_ENC_INTERNED_STR
|
2249
|
-
if (intern) {
|
2250
|
-
result = rb_enc_interned_str(start, (long)(end - start), enc_utf8);
|
2251
|
-
} else {
|
2252
|
-
result = rb_utf8_str_new(start, (long)(end - start));
|
2253
|
-
}
|
2254
|
-
# else
|
2255
|
-
result = rb_utf8_str_new(start, (long)(end - start));
|
2256
|
-
if (intern) {
|
2257
|
-
result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
|
917
|
+
json_eat_whitespace(state);
|
918
|
+
if (state->cursor >= state->end) {
|
919
|
+
raise_parse_error("unexpected end of input", state->cursor);
|
2258
920
|
}
|
2259
|
-
# endif
|
2260
921
|
|
2261
|
-
|
2262
|
-
|
2263
|
-
|
922
|
+
switch (*state->cursor) {
|
923
|
+
case 'n':
|
924
|
+
if ((state->end - state->cursor >= 4) && (memcmp(state->cursor, "null", 4) == 0)) {
|
925
|
+
state->cursor += 4;
|
926
|
+
return PUSH(Qnil);
|
927
|
+
}
|
2264
928
|
|
2265
|
-
|
2266
|
-
|
929
|
+
raise_parse_error("unexpected token at '%s'", state->cursor);
|
930
|
+
break;
|
931
|
+
case 't':
|
932
|
+
if ((state->end - state->cursor >= 4) && (memcmp(state->cursor, "true", 4) == 0)) {
|
933
|
+
state->cursor += 4;
|
934
|
+
return PUSH(Qtrue);
|
935
|
+
}
|
2267
936
|
|
2268
|
-
|
2269
|
-
|
2270
|
-
|
937
|
+
raise_parse_error("unexpected token at '%s'", state->cursor);
|
938
|
+
break;
|
939
|
+
case 'f':
|
940
|
+
// Note: memcmp with a small power of two compile to an integer comparison
|
941
|
+
if ((state->end - state->cursor >= 5) && (memcmp(state->cursor + 1, "alse", 4) == 0)) {
|
942
|
+
state->cursor += 5;
|
943
|
+
return PUSH(Qfalse);
|
944
|
+
}
|
2271
945
|
|
2272
|
-
|
2273
|
-
|
2274
|
-
|
2275
|
-
|
2276
|
-
|
2277
|
-
|
2278
|
-
|
946
|
+
raise_parse_error("unexpected token at '%s'", state->cursor);
|
947
|
+
break;
|
948
|
+
case 'N':
|
949
|
+
// Note: memcmp with a small power of two compile to an integer comparison
|
950
|
+
if (config->allow_nan && (state->end - state->cursor >= 3) && (memcmp(state->cursor + 1, "aN", 2) == 0)) {
|
951
|
+
state->cursor += 3;
|
952
|
+
return PUSH(CNaN);
|
953
|
+
}
|
2279
954
|
|
2280
|
-
|
2281
|
-
|
2282
|
-
|
2283
|
-
|
955
|
+
raise_parse_error("unexpected token at '%s'", state->cursor);
|
956
|
+
break;
|
957
|
+
case 'I':
|
958
|
+
if (config->allow_nan && (state->end - state->cursor >= 8) && (memcmp(state->cursor, "Infinity", 8) == 0)) {
|
959
|
+
state->cursor += 8;
|
960
|
+
return PUSH(CInfinity);
|
961
|
+
}
|
2284
962
|
|
2285
|
-
|
2286
|
-
|
963
|
+
raise_parse_error("unexpected token at '%s'", state->cursor);
|
964
|
+
break;
|
965
|
+
case '-':
|
966
|
+
// Note: memcmp with a small power of two compile to an integer comparison
|
967
|
+
if ((state->end - state->cursor >= 9) && (memcmp(state->cursor + 1, "Infinity", 8) == 0)) {
|
968
|
+
if (config->allow_nan) {
|
969
|
+
state->cursor += 9;
|
970
|
+
return PUSH(CMinusInfinity);
|
971
|
+
} else {
|
972
|
+
raise_parse_error("unexpected token at '%s'", state->cursor);
|
973
|
+
}
|
974
|
+
}
|
975
|
+
// Fallthrough
|
976
|
+
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': {
|
977
|
+
bool integer = true;
|
2287
978
|
|
2288
|
-
|
2289
|
-
|
2290
|
-
|
2291
|
-
char *p = string, *pe = string, *unescape, *bufferStart, *buffer;
|
2292
|
-
int unescape_len;
|
2293
|
-
char buf[4];
|
979
|
+
// /\A-?(0|[1-9]\d*)(\.\d+)?([Ee][-+]?\d+)?/
|
980
|
+
const char *start = state->cursor;
|
981
|
+
state->cursor++;
|
2294
982
|
|
2295
|
-
|
2296
|
-
|
2297
|
-
|
2298
|
-
cached_key = rsymbol_cache_fetch(&json->name_cache, string, bufferSize);
|
2299
|
-
} else {
|
2300
|
-
cached_key = rstring_cache_fetch(&json->name_cache, string, bufferSize);
|
2301
|
-
}
|
983
|
+
while ((state->cursor < state->end) && (*state->cursor >= '0') && (*state->cursor <= '9')) {
|
984
|
+
state->cursor++;
|
985
|
+
}
|
2302
986
|
|
2303
|
-
|
2304
|
-
return cached_key;
|
2305
|
-
}
|
2306
|
-
}
|
987
|
+
long integer_length = state->cursor - start;
|
2307
988
|
|
2308
|
-
|
2309
|
-
|
2310
|
-
|
2311
|
-
|
989
|
+
if (RB_UNLIKELY(start[0] == '0' && integer_length > 1)) {
|
990
|
+
raise_parse_error("invalid number: %s", start);
|
991
|
+
} else if (RB_UNLIKELY(integer_length > 2 && start[0] == '-' && start[1] == '0')) {
|
992
|
+
raise_parse_error("invalid number: %s", start);
|
993
|
+
} else if (RB_UNLIKELY(integer_length == 1 && start[0] == '-')) {
|
994
|
+
raise_parse_error("invalid number: %s", start);
|
995
|
+
}
|
2312
996
|
|
2313
|
-
|
2314
|
-
|
2315
|
-
|
2316
|
-
|
2317
|
-
|
2318
|
-
|
2319
|
-
|
2320
|
-
|
2321
|
-
|
2322
|
-
|
2323
|
-
|
997
|
+
if ((state->cursor < state->end) && (*state->cursor == '.')) {
|
998
|
+
integer = false;
|
999
|
+
state->cursor++;
|
1000
|
+
|
1001
|
+
if (state->cursor == state->end || *state->cursor < '0' || *state->cursor > '9') {
|
1002
|
+
raise_parse_error("invalid number: %s", state->cursor);
|
1003
|
+
}
|
1004
|
+
|
1005
|
+
while ((state->cursor < state->end) && (*state->cursor >= '0') && (*state->cursor <= '9')) {
|
1006
|
+
state->cursor++;
|
1007
|
+
}
|
2324
1008
|
}
|
2325
|
-
|
2326
|
-
|
2327
|
-
|
2328
|
-
|
2329
|
-
|
2330
|
-
|
2331
|
-
|
2332
|
-
|
2333
|
-
|
2334
|
-
|
2335
|
-
|
2336
|
-
|
2337
|
-
|
2338
|
-
|
2339
|
-
|
2340
|
-
|
2341
|
-
|
2342
|
-
|
2343
|
-
|
2344
|
-
|
2345
|
-
|
2346
|
-
|
2347
|
-
|
2348
|
-
|
2349
|
-
|
2350
|
-
|
2351
|
-
|
2352
|
-
|
2353
|
-
|
2354
|
-
|
2355
|
-
|
2356
|
-
|
2357
|
-
|
2358
|
-
|
2359
|
-
|
2360
|
-
|
2361
|
-
|
2362
|
-
|
2363
|
-
|
2364
|
-
|
2365
|
-
|
2366
|
-
|
2367
|
-
|
2368
|
-
|
2369
|
-
|
2370
|
-
|
2371
|
-
|
2372
|
-
|
2373
|
-
|
2374
|
-
|
2375
|
-
|
1009
|
+
|
1010
|
+
if ((state->cursor < state->end) && ((*state->cursor == 'e') || (*state->cursor == 'E'))) {
|
1011
|
+
integer = false;
|
1012
|
+
state->cursor++;
|
1013
|
+
if ((state->cursor < state->end) && ((*state->cursor == '+') || (*state->cursor == '-'))) {
|
1014
|
+
state->cursor++;
|
1015
|
+
}
|
1016
|
+
|
1017
|
+
if (state->cursor == state->end || *state->cursor < '0' || *state->cursor > '9') {
|
1018
|
+
raise_parse_error("invalid number: %s", state->cursor);
|
1019
|
+
}
|
1020
|
+
|
1021
|
+
while ((state->cursor < state->end) && (*state->cursor >= '0') && (*state->cursor <= '9')) {
|
1022
|
+
state->cursor++;
|
1023
|
+
}
|
1024
|
+
}
|
1025
|
+
|
1026
|
+
if (integer) {
|
1027
|
+
return PUSH(json_decode_integer(start, state->cursor));
|
1028
|
+
}
|
1029
|
+
return PUSH(json_decode_float(config, start, state->cursor));
|
1030
|
+
}
|
1031
|
+
case '"': {
|
1032
|
+
// %r{\A"[^"\\\t\n\x00]*(?:\\[bfnrtu\\/"][^"\\]*)*"}
|
1033
|
+
return json_parse_string(state, config, false);
|
1034
|
+
break;
|
1035
|
+
}
|
1036
|
+
case '[': {
|
1037
|
+
state->cursor++;
|
1038
|
+
json_eat_whitespace(state);
|
1039
|
+
long stack_head = state->stack->head;
|
1040
|
+
|
1041
|
+
if ((state->cursor < state->end) && (*state->cursor == ']')) {
|
1042
|
+
state->cursor++;
|
1043
|
+
return PUSH(json_decode_array(state, config, 0));
|
1044
|
+
} else {
|
1045
|
+
state->current_nesting++;
|
1046
|
+
if (RB_UNLIKELY(config->max_nesting && (config->max_nesting < state->current_nesting))) {
|
1047
|
+
rb_raise(eNestingError, "nesting of %d is too deep", state->current_nesting);
|
1048
|
+
}
|
1049
|
+
state->in_array++;
|
1050
|
+
json_parse_any(state, config);
|
1051
|
+
}
|
1052
|
+
|
1053
|
+
while (true) {
|
1054
|
+
json_eat_whitespace(state);
|
1055
|
+
|
1056
|
+
if (state->cursor < state->end) {
|
1057
|
+
if (*state->cursor == ']') {
|
1058
|
+
state->cursor++;
|
1059
|
+
long count = state->stack->head - stack_head;
|
1060
|
+
state->current_nesting--;
|
1061
|
+
state->in_array--;
|
1062
|
+
return PUSH(json_decode_array(state, config, count));
|
1063
|
+
}
|
1064
|
+
|
1065
|
+
if (*state->cursor == ',') {
|
1066
|
+
state->cursor++;
|
1067
|
+
if (config->allow_trailing_comma) {
|
1068
|
+
json_eat_whitespace(state);
|
1069
|
+
if ((state->cursor < state->end) && (*state->cursor == ']')) {
|
1070
|
+
continue;
|
2376
1071
|
}
|
2377
1072
|
}
|
2378
|
-
|
2379
|
-
|
1073
|
+
json_parse_any(state, config);
|
1074
|
+
continue;
|
2380
1075
|
}
|
2381
|
-
|
2382
|
-
|
2383
|
-
|
2384
|
-
continue;
|
1076
|
+
}
|
1077
|
+
|
1078
|
+
raise_parse_error("expected ',' or ']' after array value", state->cursor);
|
2385
1079
|
}
|
2386
|
-
|
2387
|
-
buffer += unescape_len;
|
2388
|
-
p = ++pe;
|
2389
|
-
} else {
|
2390
|
-
pe++;
|
1080
|
+
break;
|
2391
1081
|
}
|
2392
|
-
|
1082
|
+
case '{': {
|
1083
|
+
state->cursor++;
|
1084
|
+
json_eat_whitespace(state);
|
1085
|
+
long stack_head = state->stack->head;
|
1086
|
+
|
1087
|
+
if ((state->cursor < state->end) && (*state->cursor == '}')) {
|
1088
|
+
state->cursor++;
|
1089
|
+
return PUSH(json_decode_object(state, config, 0));
|
1090
|
+
} else {
|
1091
|
+
state->current_nesting++;
|
1092
|
+
if (RB_UNLIKELY(config->max_nesting && (config->max_nesting < state->current_nesting))) {
|
1093
|
+
rb_raise(eNestingError, "nesting of %d is too deep", state->current_nesting);
|
1094
|
+
}
|
2393
1095
|
|
2394
|
-
|
2395
|
-
|
2396
|
-
|
2397
|
-
|
2398
|
-
rb_str_set_len(result, buffer - bufferStart);
|
1096
|
+
if (*state->cursor != '"') {
|
1097
|
+
raise_parse_error("expected object key, got '%s", state->cursor);
|
1098
|
+
}
|
1099
|
+
json_parse_string(state, config, true);
|
2399
1100
|
|
2400
|
-
|
2401
|
-
|
2402
|
-
|
2403
|
-
|
2404
|
-
|
1101
|
+
json_eat_whitespace(state);
|
1102
|
+
if ((state->cursor >= state->end) || (*state->cursor != ':')) {
|
1103
|
+
raise_parse_error("expected ':' after object key", state->cursor);
|
1104
|
+
}
|
1105
|
+
state->cursor++;
|
2405
1106
|
|
2406
|
-
|
2407
|
-
}
|
1107
|
+
json_parse_any(state, config);
|
1108
|
+
}
|
2408
1109
|
|
1110
|
+
while (true) {
|
1111
|
+
json_eat_whitespace(state);
|
2409
1112
|
|
2410
|
-
|
2411
|
-
|
2412
|
-
|
2413
|
-
|
1113
|
+
if (state->cursor < state->end) {
|
1114
|
+
if (*state->cursor == '}') {
|
1115
|
+
state->cursor++;
|
1116
|
+
state->current_nesting--;
|
1117
|
+
long count = state->stack->head - stack_head;
|
1118
|
+
return PUSH(json_decode_object(state, config, count));
|
1119
|
+
}
|
2414
1120
|
|
2415
|
-
|
1121
|
+
if (*state->cursor == ',') {
|
1122
|
+
state->cursor++;
|
1123
|
+
json_eat_whitespace(state);
|
2416
1124
|
|
1125
|
+
if (config->allow_trailing_comma) {
|
1126
|
+
if ((state->cursor < state->end) && (*state->cursor == '}')) {
|
1127
|
+
continue;
|
1128
|
+
}
|
1129
|
+
}
|
2417
1130
|
|
2418
|
-
|
1131
|
+
if (*state->cursor != '"') {
|
1132
|
+
raise_parse_error("expected object key, got: '%s'", state->cursor);
|
1133
|
+
}
|
1134
|
+
json_parse_string(state, config, true);
|
2419
1135
|
|
1136
|
+
json_eat_whitespace(state);
|
1137
|
+
if ((state->cursor >= state->end) || (*state->cursor != ':')) {
|
1138
|
+
raise_parse_error("expected ':' after object key, got: '%s", state->cursor);
|
1139
|
+
}
|
1140
|
+
state->cursor++;
|
2420
1141
|
|
2421
|
-
|
2422
|
-
match_i(VALUE regexp, VALUE klass, VALUE memo)
|
2423
|
-
{
|
2424
|
-
if (regexp == Qundef) return ST_STOP;
|
2425
|
-
if (RTEST(rb_funcall(klass, i_json_creatable_p, 0)) &&
|
2426
|
-
RTEST(rb_funcall(regexp, i_match, 1, rb_ary_entry(memo, 0)))) {
|
2427
|
-
rb_ary_push(memo, klass);
|
2428
|
-
return ST_STOP;
|
2429
|
-
}
|
2430
|
-
return ST_CONTINUE;
|
2431
|
-
}
|
1142
|
+
json_parse_any(state, config);
|
2432
1143
|
|
2433
|
-
|
2434
|
-
|
2435
|
-
|
2436
|
-
VALUE match_string;
|
1144
|
+
continue;
|
1145
|
+
}
|
1146
|
+
}
|
2437
1147
|
|
1148
|
+
raise_parse_error("expected ',' or '}' after object value, got: '%s'", state->cursor);
|
1149
|
+
}
|
1150
|
+
break;
|
1151
|
+
}
|
2438
1152
|
|
2439
|
-
|
2440
|
-
|
2441
|
-
|
2442
|
-
}
|
2443
|
-
|
2444
|
-
#line 1089 "parser.rl"
|
2445
|
-
json->memo = p;
|
2446
|
-
|
2447
|
-
#line 2448 "parser.c"
|
2448
|
-
{
|
2449
|
-
if ( p == pe )
|
2450
|
-
goto _test_eof;
|
2451
|
-
switch ( cs )
|
2452
|
-
{
|
2453
|
-
case 1:
|
2454
|
-
if ( (*p) == 34 )
|
2455
|
-
goto st2;
|
2456
|
-
goto st0;
|
2457
|
-
st0:
|
2458
|
-
cs = 0;
|
2459
|
-
goto _out;
|
2460
|
-
st2:
|
2461
|
-
if ( ++p == pe )
|
2462
|
-
goto _test_eof2;
|
2463
|
-
case 2:
|
2464
|
-
switch( (*p) ) {
|
2465
|
-
case 34: goto tr2;
|
2466
|
-
case 92: goto st3;
|
2467
|
-
}
|
2468
|
-
if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 )
|
2469
|
-
goto st0;
|
2470
|
-
goto st2;
|
2471
|
-
tr2:
|
2472
|
-
#line 1051 "parser.rl"
|
2473
|
-
{
|
2474
|
-
*result = json_string_fastpath(json, json->memo + 1, p, json->parsing_name, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
|
2475
|
-
{p = (( p + 1))-1;}
|
2476
|
-
p--;
|
2477
|
-
{p++; cs = 9; goto _out;}
|
2478
|
-
}
|
2479
|
-
#line 1044 "parser.rl"
|
2480
|
-
{
|
2481
|
-
*result = json_string_unescape(json, json->memo + 1, p, json->parsing_name, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
|
2482
|
-
{p = (( p + 1))-1;}
|
2483
|
-
p--;
|
2484
|
-
{p++; cs = 9; goto _out;}
|
2485
|
-
}
|
2486
|
-
goto st9;
|
2487
|
-
tr6:
|
2488
|
-
#line 1044 "parser.rl"
|
2489
|
-
{
|
2490
|
-
*result = json_string_unescape(json, json->memo + 1, p, json->parsing_name, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
|
2491
|
-
{p = (( p + 1))-1;}
|
2492
|
-
p--;
|
2493
|
-
{p++; cs = 9; goto _out;}
|
2494
|
-
}
|
2495
|
-
goto st9;
|
2496
|
-
st9:
|
2497
|
-
if ( ++p == pe )
|
2498
|
-
goto _test_eof9;
|
2499
|
-
case 9:
|
2500
|
-
#line 2501 "parser.c"
|
2501
|
-
goto st0;
|
2502
|
-
st3:
|
2503
|
-
if ( ++p == pe )
|
2504
|
-
goto _test_eof3;
|
2505
|
-
case 3:
|
2506
|
-
if ( (*p) == 117 )
|
2507
|
-
goto st5;
|
2508
|
-
if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 )
|
2509
|
-
goto st0;
|
2510
|
-
goto st4;
|
2511
|
-
st4:
|
2512
|
-
if ( ++p == pe )
|
2513
|
-
goto _test_eof4;
|
2514
|
-
case 4:
|
2515
|
-
switch( (*p) ) {
|
2516
|
-
case 34: goto tr6;
|
2517
|
-
case 92: goto st3;
|
2518
|
-
}
|
2519
|
-
if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 )
|
2520
|
-
goto st0;
|
2521
|
-
goto st4;
|
2522
|
-
st5:
|
2523
|
-
if ( ++p == pe )
|
2524
|
-
goto _test_eof5;
|
2525
|
-
case 5:
|
2526
|
-
if ( (*p) < 65 ) {
|
2527
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
2528
|
-
goto st6;
|
2529
|
-
} else if ( (*p) > 70 ) {
|
2530
|
-
if ( 97 <= (*p) && (*p) <= 102 )
|
2531
|
-
goto st6;
|
2532
|
-
} else
|
2533
|
-
goto st6;
|
2534
|
-
goto st0;
|
2535
|
-
st6:
|
2536
|
-
if ( ++p == pe )
|
2537
|
-
goto _test_eof6;
|
2538
|
-
case 6:
|
2539
|
-
if ( (*p) < 65 ) {
|
2540
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
2541
|
-
goto st7;
|
2542
|
-
} else if ( (*p) > 70 ) {
|
2543
|
-
if ( 97 <= (*p) && (*p) <= 102 )
|
2544
|
-
goto st7;
|
2545
|
-
} else
|
2546
|
-
goto st7;
|
2547
|
-
goto st0;
|
2548
|
-
st7:
|
2549
|
-
if ( ++p == pe )
|
2550
|
-
goto _test_eof7;
|
2551
|
-
case 7:
|
2552
|
-
if ( (*p) < 65 ) {
|
2553
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
2554
|
-
goto st8;
|
2555
|
-
} else if ( (*p) > 70 ) {
|
2556
|
-
if ( 97 <= (*p) && (*p) <= 102 )
|
2557
|
-
goto st8;
|
2558
|
-
} else
|
2559
|
-
goto st8;
|
2560
|
-
goto st0;
|
2561
|
-
st8:
|
2562
|
-
if ( ++p == pe )
|
2563
|
-
goto _test_eof8;
|
2564
|
-
case 8:
|
2565
|
-
if ( (*p) < 65 ) {
|
2566
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
2567
|
-
goto st4;
|
2568
|
-
} else if ( (*p) > 70 ) {
|
2569
|
-
if ( 97 <= (*p) && (*p) <= 102 )
|
2570
|
-
goto st4;
|
2571
|
-
} else
|
2572
|
-
goto st4;
|
2573
|
-
goto st0;
|
2574
|
-
}
|
2575
|
-
_test_eof2: cs = 2; goto _test_eof;
|
2576
|
-
_test_eof9: cs = 9; goto _test_eof;
|
2577
|
-
_test_eof3: cs = 3; goto _test_eof;
|
2578
|
-
_test_eof4: cs = 4; goto _test_eof;
|
2579
|
-
_test_eof5: cs = 5; goto _test_eof;
|
2580
|
-
_test_eof6: cs = 6; goto _test_eof;
|
2581
|
-
_test_eof7: cs = 7; goto _test_eof;
|
2582
|
-
_test_eof8: cs = 8; goto _test_eof;
|
2583
|
-
|
2584
|
-
_test_eof: {}
|
2585
|
-
_out: {}
|
2586
|
-
}
|
2587
|
-
|
2588
|
-
#line 1091 "parser.rl"
|
2589
|
-
|
2590
|
-
if (json->create_additions && RTEST(match_string = json->match_string)) {
|
2591
|
-
VALUE klass;
|
2592
|
-
VALUE memo = rb_ary_new2(2);
|
2593
|
-
rb_ary_push(memo, *result);
|
2594
|
-
rb_hash_foreach(match_string, match_i, memo);
|
2595
|
-
klass = rb_ary_entry(memo, 1);
|
2596
|
-
if (RTEST(klass)) {
|
2597
|
-
*result = rb_funcall(klass, i_json_create, 1, *result);
|
2598
|
-
}
|
1153
|
+
default:
|
1154
|
+
raise_parse_error("unexpected character: '%s'", state->cursor);
|
1155
|
+
break;
|
2599
1156
|
}
|
2600
1157
|
|
2601
|
-
|
2602
|
-
|
2603
|
-
|
2604
|
-
|
1158
|
+
raise_parse_error("unreacheable: '%s'", state->cursor);
|
1159
|
+
}
|
1160
|
+
|
1161
|
+
static void json_ensure_eof(JSON_ParserState *state)
|
1162
|
+
{
|
1163
|
+
json_eat_whitespace(state);
|
1164
|
+
if (state->cursor != state->end) {
|
1165
|
+
raise_parse_error("unexpected token at end of stream '%s'", state->cursor);
|
2605
1166
|
}
|
2606
1167
|
}
|
2607
1168
|
|
@@ -2633,72 +1194,90 @@ static VALUE convert_encoding(VALUE source)
|
|
2633
1194
|
return rb_funcall(source, i_encode, 1, Encoding_UTF_8);
|
2634
1195
|
}
|
2635
1196
|
|
2636
|
-
static int
|
1197
|
+
static int parser_config_init_i(VALUE key, VALUE val, VALUE data)
|
2637
1198
|
{
|
2638
|
-
|
2639
|
-
|
2640
|
-
if (key == sym_max_nesting) {
|
2641
|
-
else if (key == sym_allow_nan) {
|
2642
|
-
else if (key == sym_allow_trailing_comma) {
|
2643
|
-
else if (key == sym_symbolize_names) {
|
2644
|
-
else if (key == sym_freeze) {
|
2645
|
-
else if (key == sym_create_id) {
|
2646
|
-
else if (key == sym_object_class) {
|
2647
|
-
else if (key == sym_array_class) {
|
2648
|
-
else if (key ==
|
2649
|
-
else if (key ==
|
1199
|
+
JSON_ParserConfig *config = (JSON_ParserConfig *)data;
|
1200
|
+
|
1201
|
+
if (key == sym_max_nesting) { config->max_nesting = RTEST(val) ? FIX2INT(val) : 0; }
|
1202
|
+
else if (key == sym_allow_nan) { config->allow_nan = RTEST(val); }
|
1203
|
+
else if (key == sym_allow_trailing_comma) { config->allow_trailing_comma = RTEST(val); }
|
1204
|
+
else if (key == sym_symbolize_names) { config->symbolize_names = RTEST(val); }
|
1205
|
+
else if (key == sym_freeze) { config->freeze = RTEST(val); }
|
1206
|
+
else if (key == sym_create_id) { config->create_id = RTEST(val) ? val : Qfalse; }
|
1207
|
+
else if (key == sym_object_class) { config->object_class = RTEST(val) ? val : Qfalse; }
|
1208
|
+
else if (key == sym_array_class) { config->array_class = RTEST(val) ? val : Qfalse; }
|
1209
|
+
else if (key == sym_match_string) { config->match_string = RTEST(val) ? val : Qfalse; }
|
1210
|
+
else if (key == sym_decimal_class) {
|
1211
|
+
if (RTEST(val)) {
|
1212
|
+
if (rb_respond_to(val, i_try_convert)) {
|
1213
|
+
config->decimal_class = val;
|
1214
|
+
config->decimal_method_id = i_try_convert;
|
1215
|
+
} else if (rb_respond_to(val, i_new)) {
|
1216
|
+
config->decimal_class = val;
|
1217
|
+
config->decimal_method_id = i_new;
|
1218
|
+
} else if (RB_TYPE_P(val, T_CLASS)) {
|
1219
|
+
VALUE name = rb_class_name(val);
|
1220
|
+
const char *name_cstr = RSTRING_PTR(name);
|
1221
|
+
const char *last_colon = strrchr(name_cstr, ':');
|
1222
|
+
if (last_colon) {
|
1223
|
+
const char *mod_path_end = last_colon - 1;
|
1224
|
+
VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr);
|
1225
|
+
config->decimal_class = rb_path_to_class(mod_path);
|
1226
|
+
|
1227
|
+
const char *method_name_beg = last_colon + 1;
|
1228
|
+
long before_len = method_name_beg - name_cstr;
|
1229
|
+
long len = RSTRING_LEN(name) - before_len;
|
1230
|
+
VALUE method_name = rb_str_substr(name, before_len, len);
|
1231
|
+
config->decimal_method_id = SYM2ID(rb_str_intern(method_name));
|
1232
|
+
} else {
|
1233
|
+
config->decimal_class = rb_mKernel;
|
1234
|
+
config->decimal_method_id = SYM2ID(rb_str_intern(name));
|
1235
|
+
}
|
1236
|
+
}
|
1237
|
+
}
|
1238
|
+
}
|
2650
1239
|
else if (key == sym_create_additions) {
|
2651
1240
|
if (NIL_P(val)) {
|
2652
|
-
|
2653
|
-
|
1241
|
+
config->create_additions = true;
|
1242
|
+
config->deprecated_create_additions = true;
|
2654
1243
|
} else {
|
2655
|
-
|
2656
|
-
|
1244
|
+
config->create_additions = RTEST(val);
|
1245
|
+
config->deprecated_create_additions = false;
|
2657
1246
|
}
|
2658
1247
|
}
|
2659
1248
|
|
2660
1249
|
return ST_CONTINUE;
|
2661
1250
|
}
|
2662
1251
|
|
2663
|
-
static void
|
1252
|
+
static void parser_config_init(JSON_ParserConfig *config, VALUE opts)
|
2664
1253
|
{
|
2665
|
-
|
2666
|
-
rb_raise(rb_eTypeError, "already initialized instance");
|
2667
|
-
}
|
2668
|
-
|
2669
|
-
json->fbuffer.initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT;
|
2670
|
-
json->max_nesting = 100;
|
1254
|
+
config->max_nesting = 100;
|
2671
1255
|
|
2672
1256
|
if (!NIL_P(opts)) {
|
2673
1257
|
Check_Type(opts, T_HASH);
|
2674
1258
|
if (RHASH_SIZE(opts) > 0) {
|
2675
1259
|
// We assume in most cases few keys are set so it's faster to go over
|
2676
1260
|
// the provided keys than to check all possible keys.
|
2677
|
-
rb_hash_foreach(opts,
|
1261
|
+
rb_hash_foreach(opts, parser_config_init_i, (VALUE)config);
|
2678
1262
|
|
2679
|
-
if (
|
1263
|
+
if (config->symbolize_names && config->create_additions) {
|
2680
1264
|
rb_raise(rb_eArgError,
|
2681
1265
|
"options :symbolize_names and :create_additions cannot be "
|
2682
1266
|
" used in conjunction");
|
2683
1267
|
}
|
2684
1268
|
|
2685
|
-
if (
|
2686
|
-
|
1269
|
+
if (config->create_additions && !config->create_id) {
|
1270
|
+
config->create_id = rb_funcall(mJSON, i_create_id, 0);
|
2687
1271
|
}
|
2688
1272
|
}
|
2689
1273
|
|
2690
1274
|
}
|
2691
|
-
source = convert_encoding(StringValue(source));
|
2692
|
-
StringValue(source);
|
2693
|
-
json->len = RSTRING_LEN(source);
|
2694
|
-
json->source = RSTRING_PTR(source);
|
2695
|
-
json->Vsource = source;
|
2696
1275
|
}
|
2697
1276
|
|
2698
1277
|
/*
|
2699
|
-
* call-seq: new(
|
1278
|
+
* call-seq: new(opts => {})
|
2700
1279
|
*
|
2701
|
-
* Creates a new JSON::Ext::
|
1280
|
+
* Creates a new JSON::Ext::ParserConfig instance.
|
2702
1281
|
*
|
2703
1282
|
* It will be configured by the _opts_ hash. _opts_ can have the following
|
2704
1283
|
* keys:
|
@@ -2727,443 +1306,112 @@ static void parser_init(JSON_Parser *json, VALUE source, VALUE opts)
|
|
2727
1306
|
* (Float) when parsing decimal numbers. This class must accept a single
|
2728
1307
|
* string argument in its constructor.
|
2729
1308
|
*/
|
2730
|
-
static VALUE
|
1309
|
+
static VALUE cParserConfig_initialize(VALUE self, VALUE opts)
|
2731
1310
|
{
|
2732
|
-
|
1311
|
+
GET_PARSER_CONFIG;
|
2733
1312
|
|
2734
|
-
|
1313
|
+
parser_config_init(config, opts);
|
1314
|
+
|
1315
|
+
RB_OBJ_WRITTEN(self, Qundef, config->create_id);
|
1316
|
+
RB_OBJ_WRITTEN(self, Qundef, config->object_class);
|
1317
|
+
RB_OBJ_WRITTEN(self, Qundef, config->array_class);
|
1318
|
+
RB_OBJ_WRITTEN(self, Qundef, config->decimal_class);
|
1319
|
+
RB_OBJ_WRITTEN(self, Qundef, config->match_string);
|
2735
1320
|
|
2736
|
-
parser_init(json, argv[0], argc == 2 ? argv[1] : Qnil);
|
2737
1321
|
return self;
|
2738
1322
|
}
|
2739
1323
|
|
1324
|
+
static VALUE cParser_parse(JSON_ParserConfig *config, VALUE Vsource)
|
1325
|
+
{
|
1326
|
+
Vsource = convert_encoding(StringValue(Vsource));
|
1327
|
+
StringValue(Vsource);
|
2740
1328
|
|
2741
|
-
|
2742
|
-
|
2743
|
-
|
2744
|
-
|
1329
|
+
VALUE rvalue_stack_buffer[RVALUE_STACK_INITIAL_CAPA];
|
1330
|
+
rvalue_stack stack = {
|
1331
|
+
.type = RVALUE_STACK_STACK_ALLOCATED,
|
1332
|
+
.ptr = rvalue_stack_buffer,
|
1333
|
+
.capa = RVALUE_STACK_INITIAL_CAPA,
|
1334
|
+
};
|
1335
|
+
|
1336
|
+
JSON_ParserState _state = {
|
1337
|
+
.cursor = RSTRING_PTR(Vsource),
|
1338
|
+
.end = RSTRING_END(Vsource),
|
1339
|
+
.stack = &stack,
|
1340
|
+
};
|
1341
|
+
JSON_ParserState *state = &_state;
|
2745
1342
|
|
2746
|
-
|
1343
|
+
VALUE result = json_parse_any(state, config);
|
2747
1344
|
|
1345
|
+
// This may be skipped in case of exception, but
|
1346
|
+
// it won't cause a leak.
|
1347
|
+
rvalue_stack_eagerly_release(state->stack_handle);
|
2748
1348
|
|
2749
|
-
|
1349
|
+
json_ensure_eof(state);
|
2750
1350
|
|
1351
|
+
return result;
|
1352
|
+
}
|
2751
1353
|
|
2752
1354
|
/*
|
2753
|
-
* call-seq: parse()
|
1355
|
+
* call-seq: parse(source)
|
2754
1356
|
*
|
2755
1357
|
* Parses the current JSON text _source_ and returns the complete data
|
2756
1358
|
* structure as a result.
|
2757
1359
|
* It raises JSON::ParserError if fail to parse.
|
2758
1360
|
*/
|
2759
|
-
static VALUE
|
1361
|
+
static VALUE cParserConfig_parse(VALUE self, VALUE Vsource)
|
2760
1362
|
{
|
2761
|
-
|
2762
|
-
|
2763
|
-
VALUE result = Qnil;
|
2764
|
-
GET_PARSER;
|
2765
|
-
|
2766
|
-
char stack_buffer[FBUFFER_STACK_SIZE];
|
2767
|
-
fbuffer_stack_init(&json->fbuffer, FBUFFER_INITIAL_LENGTH_DEFAULT, stack_buffer, FBUFFER_STACK_SIZE);
|
2768
|
-
|
2769
|
-
VALUE rvalue_stack_buffer[RVALUE_STACK_INITIAL_CAPA];
|
2770
|
-
rvalue_stack stack = {
|
2771
|
-
.type = RVALUE_STACK_STACK_ALLOCATED,
|
2772
|
-
.ptr = rvalue_stack_buffer,
|
2773
|
-
.capa = RVALUE_STACK_INITIAL_CAPA,
|
2774
|
-
};
|
2775
|
-
json->stack = &stack;
|
2776
|
-
|
2777
|
-
|
2778
|
-
#line 2779 "parser.c"
|
2779
|
-
{
|
2780
|
-
cs = JSON_start;
|
2781
|
-
}
|
2782
|
-
|
2783
|
-
#line 1285 "parser.rl"
|
2784
|
-
p = json->source;
|
2785
|
-
pe = p + json->len;
|
2786
|
-
|
2787
|
-
#line 2788 "parser.c"
|
2788
|
-
{
|
2789
|
-
if ( p == pe )
|
2790
|
-
goto _test_eof;
|
2791
|
-
switch ( cs )
|
2792
|
-
{
|
2793
|
-
st1:
|
2794
|
-
if ( ++p == pe )
|
2795
|
-
goto _test_eof1;
|
2796
|
-
case 1:
|
2797
|
-
switch( (*p) ) {
|
2798
|
-
case 13: goto st1;
|
2799
|
-
case 32: goto st1;
|
2800
|
-
case 34: goto tr2;
|
2801
|
-
case 45: goto tr2;
|
2802
|
-
case 47: goto st6;
|
2803
|
-
case 73: goto tr2;
|
2804
|
-
case 78: goto tr2;
|
2805
|
-
case 91: goto tr2;
|
2806
|
-
case 102: goto tr2;
|
2807
|
-
case 110: goto tr2;
|
2808
|
-
case 116: goto tr2;
|
2809
|
-
case 123: goto tr2;
|
2810
|
-
}
|
2811
|
-
if ( (*p) > 10 ) {
|
2812
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
2813
|
-
goto tr2;
|
2814
|
-
} else if ( (*p) >= 9 )
|
2815
|
-
goto st1;
|
2816
|
-
goto st0;
|
2817
|
-
st0:
|
2818
|
-
cs = 0;
|
2819
|
-
goto _out;
|
2820
|
-
tr2:
|
2821
|
-
#line 1249 "parser.rl"
|
2822
|
-
{
|
2823
|
-
char *np = JSON_parse_value(json, p, pe, &result, 0);
|
2824
|
-
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
|
2825
|
-
}
|
2826
|
-
goto st10;
|
2827
|
-
st10:
|
2828
|
-
if ( ++p == pe )
|
2829
|
-
goto _test_eof10;
|
2830
|
-
case 10:
|
2831
|
-
#line 2832 "parser.c"
|
2832
|
-
switch( (*p) ) {
|
2833
|
-
case 13: goto st10;
|
2834
|
-
case 32: goto st10;
|
2835
|
-
case 47: goto st2;
|
2836
|
-
}
|
2837
|
-
if ( 9 <= (*p) && (*p) <= 10 )
|
2838
|
-
goto st10;
|
2839
|
-
goto st0;
|
2840
|
-
st2:
|
2841
|
-
if ( ++p == pe )
|
2842
|
-
goto _test_eof2;
|
2843
|
-
case 2:
|
2844
|
-
switch( (*p) ) {
|
2845
|
-
case 42: goto st3;
|
2846
|
-
case 47: goto st5;
|
2847
|
-
}
|
2848
|
-
goto st0;
|
2849
|
-
st3:
|
2850
|
-
if ( ++p == pe )
|
2851
|
-
goto _test_eof3;
|
2852
|
-
case 3:
|
2853
|
-
if ( (*p) == 42 )
|
2854
|
-
goto st4;
|
2855
|
-
goto st3;
|
2856
|
-
st4:
|
2857
|
-
if ( ++p == pe )
|
2858
|
-
goto _test_eof4;
|
2859
|
-
case 4:
|
2860
|
-
switch( (*p) ) {
|
2861
|
-
case 42: goto st4;
|
2862
|
-
case 47: goto st10;
|
2863
|
-
}
|
2864
|
-
goto st3;
|
2865
|
-
st5:
|
2866
|
-
if ( ++p == pe )
|
2867
|
-
goto _test_eof5;
|
2868
|
-
case 5:
|
2869
|
-
if ( (*p) == 10 )
|
2870
|
-
goto st10;
|
2871
|
-
goto st5;
|
2872
|
-
st6:
|
2873
|
-
if ( ++p == pe )
|
2874
|
-
goto _test_eof6;
|
2875
|
-
case 6:
|
2876
|
-
switch( (*p) ) {
|
2877
|
-
case 42: goto st7;
|
2878
|
-
case 47: goto st9;
|
2879
|
-
}
|
2880
|
-
goto st0;
|
2881
|
-
st7:
|
2882
|
-
if ( ++p == pe )
|
2883
|
-
goto _test_eof7;
|
2884
|
-
case 7:
|
2885
|
-
if ( (*p) == 42 )
|
2886
|
-
goto st8;
|
2887
|
-
goto st7;
|
2888
|
-
st8:
|
2889
|
-
if ( ++p == pe )
|
2890
|
-
goto _test_eof8;
|
2891
|
-
case 8:
|
2892
|
-
switch( (*p) ) {
|
2893
|
-
case 42: goto st8;
|
2894
|
-
case 47: goto st1;
|
2895
|
-
}
|
2896
|
-
goto st7;
|
2897
|
-
st9:
|
2898
|
-
if ( ++p == pe )
|
2899
|
-
goto _test_eof9;
|
2900
|
-
case 9:
|
2901
|
-
if ( (*p) == 10 )
|
2902
|
-
goto st1;
|
2903
|
-
goto st9;
|
2904
|
-
}
|
2905
|
-
_test_eof1: cs = 1; goto _test_eof;
|
2906
|
-
_test_eof10: cs = 10; goto _test_eof;
|
2907
|
-
_test_eof2: cs = 2; goto _test_eof;
|
2908
|
-
_test_eof3: cs = 3; goto _test_eof;
|
2909
|
-
_test_eof4: cs = 4; goto _test_eof;
|
2910
|
-
_test_eof5: cs = 5; goto _test_eof;
|
2911
|
-
_test_eof6: cs = 6; goto _test_eof;
|
2912
|
-
_test_eof7: cs = 7; goto _test_eof;
|
2913
|
-
_test_eof8: cs = 8; goto _test_eof;
|
2914
|
-
_test_eof9: cs = 9; goto _test_eof;
|
2915
|
-
|
2916
|
-
_test_eof: {}
|
2917
|
-
_out: {}
|
2918
|
-
}
|
2919
|
-
|
2920
|
-
#line 1288 "parser.rl"
|
2921
|
-
|
2922
|
-
if (json->stack_handle) {
|
2923
|
-
rvalue_stack_eagerly_release(json->stack_handle);
|
2924
|
-
}
|
2925
|
-
|
2926
|
-
if (cs >= JSON_first_final && p == pe) {
|
2927
|
-
return result;
|
2928
|
-
} else {
|
2929
|
-
raise_parse_error("unexpected token at '%s'", p);
|
2930
|
-
return Qnil;
|
2931
|
-
}
|
1363
|
+
GET_PARSER_CONFIG;
|
1364
|
+
return cParser_parse(config, Vsource);
|
2932
1365
|
}
|
2933
1366
|
|
2934
|
-
static VALUE cParser_m_parse(VALUE klass, VALUE
|
1367
|
+
static VALUE cParser_m_parse(VALUE klass, VALUE Vsource, VALUE opts)
|
2935
1368
|
{
|
2936
|
-
|
2937
|
-
|
2938
|
-
VALUE result = Qnil;
|
2939
|
-
|
2940
|
-
JSON_Parser _parser = {0};
|
2941
|
-
JSON_Parser *json = &_parser;
|
2942
|
-
parser_init(json, source, opts);
|
1369
|
+
Vsource = convert_encoding(StringValue(Vsource));
|
1370
|
+
StringValue(Vsource);
|
2943
1371
|
|
2944
|
-
|
2945
|
-
|
1372
|
+
JSON_ParserConfig _config = {0};
|
1373
|
+
JSON_ParserConfig *config = &_config;
|
1374
|
+
parser_config_init(config, opts);
|
2946
1375
|
|
2947
|
-
|
2948
|
-
rvalue_stack stack = {
|
2949
|
-
.type = RVALUE_STACK_STACK_ALLOCATED,
|
2950
|
-
.ptr = rvalue_stack_buffer,
|
2951
|
-
.capa = RVALUE_STACK_INITIAL_CAPA,
|
2952
|
-
};
|
2953
|
-
json->stack = &stack;
|
2954
|
-
|
2955
|
-
|
2956
|
-
#line 2957 "parser.c"
|
2957
|
-
{
|
2958
|
-
cs = JSON_start;
|
2959
|
-
}
|
2960
|
-
|
2961
|
-
#line 1323 "parser.rl"
|
2962
|
-
p = json->source;
|
2963
|
-
pe = p + json->len;
|
2964
|
-
|
2965
|
-
#line 2966 "parser.c"
|
2966
|
-
{
|
2967
|
-
if ( p == pe )
|
2968
|
-
goto _test_eof;
|
2969
|
-
switch ( cs )
|
2970
|
-
{
|
2971
|
-
st1:
|
2972
|
-
if ( ++p == pe )
|
2973
|
-
goto _test_eof1;
|
2974
|
-
case 1:
|
2975
|
-
switch( (*p) ) {
|
2976
|
-
case 13: goto st1;
|
2977
|
-
case 32: goto st1;
|
2978
|
-
case 34: goto tr2;
|
2979
|
-
case 45: goto tr2;
|
2980
|
-
case 47: goto st6;
|
2981
|
-
case 73: goto tr2;
|
2982
|
-
case 78: goto tr2;
|
2983
|
-
case 91: goto tr2;
|
2984
|
-
case 102: goto tr2;
|
2985
|
-
case 110: goto tr2;
|
2986
|
-
case 116: goto tr2;
|
2987
|
-
case 123: goto tr2;
|
2988
|
-
}
|
2989
|
-
if ( (*p) > 10 ) {
|
2990
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
2991
|
-
goto tr2;
|
2992
|
-
} else if ( (*p) >= 9 )
|
2993
|
-
goto st1;
|
2994
|
-
goto st0;
|
2995
|
-
st0:
|
2996
|
-
cs = 0;
|
2997
|
-
goto _out;
|
2998
|
-
tr2:
|
2999
|
-
#line 1249 "parser.rl"
|
3000
|
-
{
|
3001
|
-
char *np = JSON_parse_value(json, p, pe, &result, 0);
|
3002
|
-
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
|
3003
|
-
}
|
3004
|
-
goto st10;
|
3005
|
-
st10:
|
3006
|
-
if ( ++p == pe )
|
3007
|
-
goto _test_eof10;
|
3008
|
-
case 10:
|
3009
|
-
#line 3010 "parser.c"
|
3010
|
-
switch( (*p) ) {
|
3011
|
-
case 13: goto st10;
|
3012
|
-
case 32: goto st10;
|
3013
|
-
case 47: goto st2;
|
3014
|
-
}
|
3015
|
-
if ( 9 <= (*p) && (*p) <= 10 )
|
3016
|
-
goto st10;
|
3017
|
-
goto st0;
|
3018
|
-
st2:
|
3019
|
-
if ( ++p == pe )
|
3020
|
-
goto _test_eof2;
|
3021
|
-
case 2:
|
3022
|
-
switch( (*p) ) {
|
3023
|
-
case 42: goto st3;
|
3024
|
-
case 47: goto st5;
|
3025
|
-
}
|
3026
|
-
goto st0;
|
3027
|
-
st3:
|
3028
|
-
if ( ++p == pe )
|
3029
|
-
goto _test_eof3;
|
3030
|
-
case 3:
|
3031
|
-
if ( (*p) == 42 )
|
3032
|
-
goto st4;
|
3033
|
-
goto st3;
|
3034
|
-
st4:
|
3035
|
-
if ( ++p == pe )
|
3036
|
-
goto _test_eof4;
|
3037
|
-
case 4:
|
3038
|
-
switch( (*p) ) {
|
3039
|
-
case 42: goto st4;
|
3040
|
-
case 47: goto st10;
|
3041
|
-
}
|
3042
|
-
goto st3;
|
3043
|
-
st5:
|
3044
|
-
if ( ++p == pe )
|
3045
|
-
goto _test_eof5;
|
3046
|
-
case 5:
|
3047
|
-
if ( (*p) == 10 )
|
3048
|
-
goto st10;
|
3049
|
-
goto st5;
|
3050
|
-
st6:
|
3051
|
-
if ( ++p == pe )
|
3052
|
-
goto _test_eof6;
|
3053
|
-
case 6:
|
3054
|
-
switch( (*p) ) {
|
3055
|
-
case 42: goto st7;
|
3056
|
-
case 47: goto st9;
|
3057
|
-
}
|
3058
|
-
goto st0;
|
3059
|
-
st7:
|
3060
|
-
if ( ++p == pe )
|
3061
|
-
goto _test_eof7;
|
3062
|
-
case 7:
|
3063
|
-
if ( (*p) == 42 )
|
3064
|
-
goto st8;
|
3065
|
-
goto st7;
|
3066
|
-
st8:
|
3067
|
-
if ( ++p == pe )
|
3068
|
-
goto _test_eof8;
|
3069
|
-
case 8:
|
3070
|
-
switch( (*p) ) {
|
3071
|
-
case 42: goto st8;
|
3072
|
-
case 47: goto st1;
|
3073
|
-
}
|
3074
|
-
goto st7;
|
3075
|
-
st9:
|
3076
|
-
if ( ++p == pe )
|
3077
|
-
goto _test_eof9;
|
3078
|
-
case 9:
|
3079
|
-
if ( (*p) == 10 )
|
3080
|
-
goto st1;
|
3081
|
-
goto st9;
|
3082
|
-
}
|
3083
|
-
_test_eof1: cs = 1; goto _test_eof;
|
3084
|
-
_test_eof10: cs = 10; goto _test_eof;
|
3085
|
-
_test_eof2: cs = 2; goto _test_eof;
|
3086
|
-
_test_eof3: cs = 3; goto _test_eof;
|
3087
|
-
_test_eof4: cs = 4; goto _test_eof;
|
3088
|
-
_test_eof5: cs = 5; goto _test_eof;
|
3089
|
-
_test_eof6: cs = 6; goto _test_eof;
|
3090
|
-
_test_eof7: cs = 7; goto _test_eof;
|
3091
|
-
_test_eof8: cs = 8; goto _test_eof;
|
3092
|
-
_test_eof9: cs = 9; goto _test_eof;
|
3093
|
-
|
3094
|
-
_test_eof: {}
|
3095
|
-
_out: {}
|
3096
|
-
}
|
3097
|
-
|
3098
|
-
#line 1326 "parser.rl"
|
3099
|
-
|
3100
|
-
if (json->stack_handle) {
|
3101
|
-
rvalue_stack_eagerly_release(json->stack_handle);
|
3102
|
-
}
|
3103
|
-
|
3104
|
-
if (cs >= JSON_first_final && p == pe) {
|
3105
|
-
return result;
|
3106
|
-
} else {
|
3107
|
-
raise_parse_error("unexpected token at '%s'", p);
|
3108
|
-
return Qnil;
|
3109
|
-
}
|
1376
|
+
return cParser_parse(config, Vsource);
|
3110
1377
|
}
|
3111
1378
|
|
3112
|
-
static void
|
1379
|
+
static void JSON_ParserConfig_mark(void *ptr)
|
3113
1380
|
{
|
3114
|
-
|
3115
|
-
rb_gc_mark(
|
3116
|
-
rb_gc_mark(
|
3117
|
-
rb_gc_mark(
|
3118
|
-
rb_gc_mark(
|
3119
|
-
rb_gc_mark(
|
3120
|
-
rb_gc_mark(json->match_string);
|
3121
|
-
rb_gc_mark(json->stack_handle);
|
3122
|
-
|
3123
|
-
long index;
|
3124
|
-
for (index = 0; index < json->name_cache.length; index++) {
|
3125
|
-
rb_gc_mark(json->name_cache.entries[index]);
|
3126
|
-
}
|
1381
|
+
JSON_ParserConfig *config = ptr;
|
1382
|
+
rb_gc_mark(config->create_id);
|
1383
|
+
rb_gc_mark(config->object_class);
|
1384
|
+
rb_gc_mark(config->array_class);
|
1385
|
+
rb_gc_mark(config->decimal_class);
|
1386
|
+
rb_gc_mark(config->match_string);
|
3127
1387
|
}
|
3128
1388
|
|
3129
|
-
static void
|
1389
|
+
static void JSON_ParserConfig_free(void *ptr)
|
3130
1390
|
{
|
3131
|
-
|
3132
|
-
|
3133
|
-
ruby_xfree(json);
|
1391
|
+
JSON_ParserConfig *config = ptr;
|
1392
|
+
ruby_xfree(config);
|
3134
1393
|
}
|
3135
1394
|
|
3136
|
-
static size_t
|
1395
|
+
static size_t JSON_ParserConfig_memsize(const void *ptr)
|
3137
1396
|
{
|
3138
|
-
|
3139
|
-
return sizeof(*json) + FBUFFER_CAPA(&json->fbuffer);
|
1397
|
+
return sizeof(JSON_ParserConfig);
|
3140
1398
|
}
|
3141
1399
|
|
3142
|
-
static const rb_data_type_t
|
3143
|
-
"JSON/
|
3144
|
-
{
|
1400
|
+
static const rb_data_type_t JSON_ParserConfig_type = {
|
1401
|
+
"JSON::Ext::Parser/ParserConfig",
|
1402
|
+
{
|
1403
|
+
JSON_ParserConfig_mark,
|
1404
|
+
JSON_ParserConfig_free,
|
1405
|
+
JSON_ParserConfig_memsize,
|
1406
|
+
},
|
3145
1407
|
0, 0,
|
3146
|
-
RUBY_TYPED_FREE_IMMEDIATELY,
|
1408
|
+
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
3147
1409
|
};
|
3148
1410
|
|
3149
1411
|
static VALUE cJSON_parser_s_allocate(VALUE klass)
|
3150
1412
|
{
|
3151
|
-
|
3152
|
-
|
3153
|
-
fbuffer_stack_init(&json->fbuffer, 0, NULL, 0);
|
3154
|
-
return obj;
|
3155
|
-
}
|
3156
|
-
|
3157
|
-
/*
|
3158
|
-
* call-seq: source()
|
3159
|
-
*
|
3160
|
-
* Returns a copy of the current _source_ string, that was used to construct
|
3161
|
-
* this Parser.
|
3162
|
-
*/
|
3163
|
-
static VALUE cParser_source(VALUE self)
|
3164
|
-
{
|
3165
|
-
GET_PARSER;
|
3166
|
-
return rb_str_dup(json->Vsource);
|
1413
|
+
JSON_ParserConfig *config;
|
1414
|
+
return TypedData_Make_Struct(klass, JSON_ParserConfig, &JSON_ParserConfig_type, config);
|
3167
1415
|
}
|
3168
1416
|
|
3169
1417
|
void Init_parser(void)
|
@@ -3175,15 +1423,15 @@ void Init_parser(void)
|
|
3175
1423
|
#undef rb_intern
|
3176
1424
|
rb_require("json/common");
|
3177
1425
|
mJSON = rb_define_module("JSON");
|
3178
|
-
mExt = rb_define_module_under(mJSON, "Ext");
|
3179
|
-
|
1426
|
+
VALUE mExt = rb_define_module_under(mJSON, "Ext");
|
1427
|
+
VALUE cParserConfig = rb_define_class_under(mExt, "ParserConfig", rb_cObject);
|
3180
1428
|
eNestingError = rb_path2class("JSON::NestingError");
|
3181
1429
|
rb_gc_register_mark_object(eNestingError);
|
3182
|
-
rb_define_alloc_func(
|
3183
|
-
rb_define_method(
|
3184
|
-
rb_define_method(
|
3185
|
-
rb_define_method(cParser, "source", cParser_source, 0);
|
1430
|
+
rb_define_alloc_func(cParserConfig, cJSON_parser_s_allocate);
|
1431
|
+
rb_define_method(cParserConfig, "initialize", cParserConfig_initialize, 1);
|
1432
|
+
rb_define_method(cParserConfig, "parse", cParserConfig_parse, 1);
|
3186
1433
|
|
1434
|
+
VALUE cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
|
3187
1435
|
rb_define_singleton_method(cParser, "parse", cParser_m_parse, 2);
|
3188
1436
|
|
3189
1437
|
CNaN = rb_const_get(mJSON, rb_intern("NaN"));
|
@@ -3228,11 +1476,3 @@ void Init_parser(void)
|
|
3228
1476
|
utf8_encindex = rb_utf8_encindex();
|
3229
1477
|
enc_utf8 = rb_utf8_encoding();
|
3230
1478
|
}
|
3231
|
-
|
3232
|
-
/*
|
3233
|
-
* Local variables:
|
3234
|
-
* mode: c
|
3235
|
-
* c-file-style: ruby
|
3236
|
-
* indent-tabs-mode: nil
|
3237
|
-
* End:
|
3238
|
-
*/
|