json 2.9.1 → 2.10.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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 "../fbuffer/fbuffer.h"
2
+ #include "ruby/encoding.h"
5
3
 
6
- static VALUE mJSON, mExt, cParser, eNestingError, Encoding_UTF_8;
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 rb_hash_bulk_insert(long count, const VALUE *pairs, VALUE hash)
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 void rvalue_stack_push(rvalue_stack *stack, VALUE value, VALUE *handle, rvalue_stack **stack_ref)
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
- rvalue_stack *stack;
305
- TypedData_Get_Struct(handle, rvalue_stack, &JSON_Parser_rvalue_stack_type, stack);
306
- RTYPEDDATA_DATA(handle) = NULL;
307
- rvalue_stack_free(stack);
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
- rvalue_cache name_cache;
397
- rvalue_stack *stack;
398
- VALUE stack_handle;
399
- } JSON_Parser;
425
+ } JSON_ParserConfig;
400
426
 
401
- #define GET_PARSER \
402
- GET_PARSER_INIT; \
403
- if (!json->Vsource) rb_raise(rb_eTypeError, "uninitialized instance")
404
-
405
- #define GET_PARSER_INIT \
406
- JSON_Parser *json; \
407
- TypedData_Get_Struct(self, JSON_Parser, &JSON_Parser_type, json)
408
-
409
- #define MinusInfinity "-Infinity"
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
- static const rb_data_type_t JSON_Parser_type;
413
- static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
414
- static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
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
- #line 473 "parser.rl"
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
- int cs = EVIL;
470
-
471
- if (json->max_nesting && current_nesting > json->max_nesting) {
472
- rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
473
- }
474
-
475
- long stack_head = json->stack->head;
476
-
477
-
478
- #line 479 "parser.c"
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
- if (!NIL_P(klassname)) {
1054
- VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname);
1055
- if (RTEST(rb_funcall(klass, i_json_creatable_p, 0))) {
1056
- if (json->deprecated_create_additions) {
1057
- json_deprecated(deprecated_create_additions_warning);
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
- return NULL;
515
+ raise_parse_error("unexpected token at '%s'", state->cursor);
1066
516
  }
1067
517
  }
1068
518
 
1069
-
1070
- #line 1071 "parser.c"
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
- int cs = EVIL;
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
- {p = (( np))-1;}
526
+ json_eat_comments(state);
1135
527
  }
1136
528
  }
1137
- goto st29;
1138
- tr3:
1139
- #line 617 "parser.rl"
1140
- {
1141
- char *np;
1142
- if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) {
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
- goto st29;
1158
- tr7:
1159
- #line 635 "parser.rl"
1160
- {
1161
- char *np;
1162
- json->in_array++;
1163
- np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
1164
- json->in_array--;
1165
- if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
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
- goto st29;
1168
- tr11:
1169
- #line 643 "parser.rl"
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
- goto st29;
1176
- tr25:
1177
- #line 600 "parser.rl"
1178
- {
1179
- if (json->allow_nan) {
1180
- *result = CInfinity;
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
- raise_parse_error("unexpected token at '%s'", p - 7);
566
+ cached_key = rstring_cache_fetch(&state->name_cache, string, bufferSize);
1183
567
  }
1184
- }
1185
- goto st29;
1186
- tr27:
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
- if (cs >= JSON_value_first_final) {
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
- #line 1477 "parser.c"
1477
- enum {JSON_integer_start = 1};
1478
- enum {JSON_integer_first_final = 3};
1479
- enum {JSON_integer_error = 0};
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
- enum {JSON_integer_en_main = 1};
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
- #line 691 "parser.rl"
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 fast_parse_integer(char *p, char *pe)
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 char *JSON_decode_integer(JSON_Parser *json, char *p, VALUE *result)
713
+ static VALUE json_decode_large_integer(const char *start, long len)
1510
714
  {
1511
- long len = p - json->memo;
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
- *result = fast_parse_integer(json->memo, p);
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 p + 1;
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
- #line 1525 "parser.c"
1525
- enum {JSON_float_start = 1};
1526
- enum {JSON_float_first_final = 6};
1527
- enum {JSON_float_error = 0};
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
- enum {JSON_float_en_main = 1};
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
- #line 743 "parser.rl"
778
+ if (config->freeze) {
779
+ RB_OBJ_FREEZE(array);
780
+ }
1533
781
 
782
+ return array;
783
+ }
1534
784
 
1535
- static char *JSON_parse_number(JSON_Parser *json, char *p, char *pe, VALUE *result)
785
+ static inline VALUE json_decode_object(JSON_ParserState *state, JSON_ParserConfig *config, long count)
1536
786
  {
1537
- int cs = EVIL;
1538
- bool is_float = false;
1539
-
1540
-
1541
- #line 1542 "parser.c"
1542
- {
1543
- cs = JSON_float_start;
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
- VALUE mod = Qnil;
1696
- ID method_id = 0;
1697
- if (json->decimal_class) {
1698
- if (rb_respond_to(json->decimal_class, i_try_convert)) {
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
- const char *method_name_beg = last_colon + 1;
1714
- long before_len = method_name_beg - name_cstr;
1715
- long len = RSTRING_LEN(name) - before_len;
1716
- VALUE method_name = rb_str_substr(name, before_len, len);
1717
- method_id = SYM2ID(rb_str_intern(method_name));
1718
- } else {
1719
- mod = rb_mKernel;
1720
- method_id = SYM2ID(rb_str_intern(name));
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
- long len = p - json->memo;
1726
- fbuffer_clear(&json->fbuffer);
1727
- fbuffer_append(&json->fbuffer, json->memo, len);
1728
- fbuffer_append_char(&json->fbuffer, '\0');
822
+ if (config->freeze) {
823
+ RB_OBJ_FREEZE(object);
824
+ }
1729
825
 
1730
- if (method_id) {
1731
- VALUE text = rb_str_new2(FBUFFER_PTR(&json->fbuffer));
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
- return p + 1;
1738
- } else {
1739
- return NULL;
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
- #line 1746 "parser.c"
1746
- enum {JSON_array_start = 1};
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 char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
880
+ static inline VALUE json_parse_string(JSON_ParserState *state, JSON_ParserConfig *config, bool is_name)
1757
881
  {
1758
- int cs = EVIL;
1759
-
1760
- if (json->max_nesting && current_nesting > json->max_nesting) {
1761
- rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
1762
- }
1763
- long stack_head = json->stack->head;
1764
-
1765
-
1766
- #line 1767 "parser.c"
1767
- {
1768
- cs = JSON_array_start;
1769
- }
1770
-
1771
- #line 845 "parser.rl"
1772
-
1773
- #line 1774 "parser.c"
1774
- {
1775
- short _widec;
1776
- if ( p == pe )
1777
- goto _test_eof;
1778
- switch ( cs )
1779
- {
1780
- case 1:
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
- return p + 1;
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 inline VALUE build_string(const char *start, const char *end, bool intern, bool symbolize)
915
+ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config)
2243
916
  {
2244
- if (symbolize) {
2245
- intern = true;
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
- if (symbolize) {
2262
- result = rb_str_intern(result);
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
- return result;
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
- static VALUE json_string_fastpath(JSON_Parser *json, char *string, char *stringEnd, bool is_name, bool intern, bool symbolize)
2269
- {
2270
- size_t bufferSize = stringEnd - string;
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
- if (is_name && json->in_array) {
2273
- VALUE cached_key;
2274
- if (RB_UNLIKELY(symbolize)) {
2275
- cached_key = rsymbol_cache_fetch(&json->name_cache, string, bufferSize);
2276
- } else {
2277
- cached_key = rstring_cache_fetch(&json->name_cache, string, bufferSize);
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
- if (RB_LIKELY(cached_key)) {
2281
- return cached_key;
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
- return build_string(string, stringEnd, intern, symbolize);
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
- static VALUE json_string_unescape(JSON_Parser *json, char *string, char *stringEnd, bool is_name, bool intern, bool symbolize)
2289
- {
2290
- size_t bufferSize = stringEnd - string;
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
- if (is_name && json->in_array) {
2296
- VALUE cached_key;
2297
- if (RB_UNLIKELY(symbolize)) {
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
- if (RB_LIKELY(cached_key)) {
2304
- return cached_key;
2305
- }
2306
- }
987
+ long integer_length = state->cursor - start;
2307
988
 
2308
- pe = memchr(p, '\\', bufferSize);
2309
- if (RB_UNLIKELY(pe == NULL)) {
2310
- return build_string(string, stringEnd, intern, symbolize);
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
- VALUE result = rb_str_buf_new(bufferSize);
2314
- rb_enc_associate_index(result, utf8_encindex);
2315
- buffer = bufferStart = RSTRING_PTR(result);
2316
-
2317
- while (pe < stringEnd) {
2318
- if (*pe == '\\') {
2319
- unescape = (char *) "?";
2320
- unescape_len = 1;
2321
- if (pe > p) {
2322
- MEMCPY(buffer, p, char, pe - p);
2323
- buffer += pe - p;
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
- switch (*++pe) {
2326
- case 'n':
2327
- unescape = (char *) "\n";
2328
- break;
2329
- case 'r':
2330
- unescape = (char *) "\r";
2331
- break;
2332
- case 't':
2333
- unescape = (char *) "\t";
2334
- break;
2335
- case '"':
2336
- unescape = (char *) "\"";
2337
- break;
2338
- case '\\':
2339
- unescape = (char *) "\\";
2340
- break;
2341
- case 'b':
2342
- unescape = (char *) "\b";
2343
- break;
2344
- case 'f':
2345
- unescape = (char *) "\f";
2346
- break;
2347
- case 'u':
2348
- if (pe > stringEnd - 4) {
2349
- raise_parse_error("incomplete unicode character escape sequence at '%s'", p);
2350
- } else {
2351
- uint32_t ch = unescape_unicode((unsigned char *) ++pe);
2352
- pe += 3;
2353
- /* To handle values above U+FFFF, we take a sequence of
2354
- * \uXXXX escapes in the U+D800..U+DBFF then
2355
- * U+DC00..U+DFFF ranges, take the low 10 bits from each
2356
- * to make a 20-bit number, then add 0x10000 to get the
2357
- * final codepoint.
2358
- *
2359
- * See Unicode 15: 3.8 "Surrogates", 5.3 "Handling
2360
- * Surrogate Pairs in UTF-16", and 23.6 "Surrogates
2361
- * Area".
2362
- */
2363
- if ((ch & 0xFC00) == 0xD800) {
2364
- pe++;
2365
- if (pe > stringEnd - 6) {
2366
- raise_parse_error("incomplete surrogate pair at '%s'", p);
2367
- }
2368
- if (pe[0] == '\\' && pe[1] == 'u') {
2369
- uint32_t sur = unescape_unicode((unsigned char *) pe + 2);
2370
- ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
2371
- | (sur & 0x3FF));
2372
- pe += 5;
2373
- } else {
2374
- unescape = (char *) "?";
2375
- break;
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
- unescape_len = convert_UTF32_to_UTF8(buf, ch);
2379
- unescape = buf;
1073
+ json_parse_any(state, config);
1074
+ continue;
2380
1075
  }
2381
- break;
2382
- default:
2383
- p = pe;
2384
- continue;
1076
+ }
1077
+
1078
+ raise_parse_error("expected ',' or ']' after array value", state->cursor);
2385
1079
  }
2386
- MEMCPY(buffer, unescape, char, unescape_len);
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
- if (pe > p) {
2395
- MEMCPY(buffer, p, char, pe - p);
2396
- buffer += pe - p;
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
- if (symbolize) {
2401
- result = rb_str_intern(result);
2402
- } else if (intern) {
2403
- result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
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
- return result;
2407
- }
1107
+ json_parse_any(state, config);
1108
+ }
2408
1109
 
1110
+ while (true) {
1111
+ json_eat_whitespace(state);
2409
1112
 
2410
- #line 2411 "parser.c"
2411
- enum {JSON_string_start = 1};
2412
- enum {JSON_string_first_final = 9};
2413
- enum {JSON_string_error = 0};
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
- enum {JSON_string_en_main = 1};
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
- #line 1069 "parser.rl"
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
- static int
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
- static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
2434
- {
2435
- int cs = EVIL;
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
- #line 2440 "parser.c"
2440
- {
2441
- cs = JSON_string_start;
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
- if (cs >= JSON_string_first_final) {
2602
- return p + 1;
2603
- } else {
2604
- return NULL;
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 configure_parser_i(VALUE key, VALUE val, VALUE data)
1197
+ static int parser_config_init_i(VALUE key, VALUE val, VALUE data)
2637
1198
  {
2638
- JSON_Parser *json = (JSON_Parser *)data;
2639
-
2640
- if (key == sym_max_nesting) { json->max_nesting = RTEST(val) ? FIX2INT(val) : 0; }
2641
- else if (key == sym_allow_nan) { json->allow_nan = RTEST(val); }
2642
- else if (key == sym_allow_trailing_comma) { json->allow_trailing_comma = RTEST(val); }
2643
- else if (key == sym_symbolize_names) { json->symbolize_names = RTEST(val); }
2644
- else if (key == sym_freeze) { json->freeze = RTEST(val); }
2645
- else if (key == sym_create_id) { json->create_id = RTEST(val) ? val : Qfalse; }
2646
- else if (key == sym_object_class) { json->object_class = RTEST(val) ? val : Qfalse; }
2647
- else if (key == sym_array_class) { json->array_class = RTEST(val) ? val : Qfalse; }
2648
- else if (key == sym_decimal_class) { json->decimal_class = RTEST(val) ? val : Qfalse; }
2649
- else if (key == sym_match_string) { json->match_string = RTEST(val) ? val : Qfalse; }
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
- json->create_additions = true;
2653
- json->deprecated_create_additions = true;
1241
+ config->create_additions = true;
1242
+ config->deprecated_create_additions = true;
2654
1243
  } else {
2655
- json->create_additions = RTEST(val);
2656
- json->deprecated_create_additions = false;
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 parser_init(JSON_Parser *json, VALUE source, VALUE opts)
1252
+ static void parser_config_init(JSON_ParserConfig *config, VALUE opts)
2664
1253
  {
2665
- if (json->Vsource) {
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, configure_parser_i, (VALUE)json);
1261
+ rb_hash_foreach(opts, parser_config_init_i, (VALUE)config);
2678
1262
 
2679
- if (json->symbolize_names && json->create_additions) {
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 (json->create_additions && !json->create_id) {
2686
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
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(source, opts => {})
1278
+ * call-seq: new(opts => {})
2700
1279
  *
2701
- * Creates a new JSON::Ext::Parser instance for the string _source_.
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 cParser_initialize(int argc, VALUE *argv, VALUE self)
1309
+ static VALUE cParserConfig_initialize(VALUE self, VALUE opts)
2731
1310
  {
2732
- GET_PARSER_INIT;
1311
+ GET_PARSER_CONFIG;
2733
1312
 
2734
- rb_check_arity(argc, 1, 2);
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
- #line 2742 "parser.c"
2742
- enum {JSON_start = 1};
2743
- enum {JSON_first_final = 10};
2744
- enum {JSON_error = 0};
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
- enum {JSON_en_main = 1};
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
- #line 1257 "parser.rl"
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 cParser_parse(VALUE self)
1361
+ static VALUE cParserConfig_parse(VALUE self, VALUE Vsource)
2760
1362
  {
2761
- char *p, *pe;
2762
- int cs = EVIL;
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 source, VALUE opts)
1367
+ static VALUE cParser_m_parse(VALUE klass, VALUE Vsource, VALUE opts)
2935
1368
  {
2936
- char *p, *pe;
2937
- int cs = EVIL;
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
- char stack_buffer[FBUFFER_STACK_SIZE];
2945
- fbuffer_stack_init(&json->fbuffer, FBUFFER_INITIAL_LENGTH_DEFAULT, stack_buffer, FBUFFER_STACK_SIZE);
1372
+ JSON_ParserConfig _config = {0};
1373
+ JSON_ParserConfig *config = &_config;
1374
+ parser_config_init(config, opts);
2946
1375
 
2947
- VALUE rvalue_stack_buffer[RVALUE_STACK_INITIAL_CAPA];
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 JSON_mark(void *ptr)
1379
+ static void JSON_ParserConfig_mark(void *ptr)
3113
1380
  {
3114
- JSON_Parser *json = ptr;
3115
- rb_gc_mark(json->Vsource);
3116
- rb_gc_mark(json->create_id);
3117
- rb_gc_mark(json->object_class);
3118
- rb_gc_mark(json->array_class);
3119
- rb_gc_mark(json->decimal_class);
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 JSON_free(void *ptr)
1389
+ static void JSON_ParserConfig_free(void *ptr)
3130
1390
  {
3131
- JSON_Parser *json = ptr;
3132
- fbuffer_free(&json->fbuffer);
3133
- ruby_xfree(json);
1391
+ JSON_ParserConfig *config = ptr;
1392
+ ruby_xfree(config);
3134
1393
  }
3135
1394
 
3136
- static size_t JSON_memsize(const void *ptr)
1395
+ static size_t JSON_ParserConfig_memsize(const void *ptr)
3137
1396
  {
3138
- const JSON_Parser *json = ptr;
3139
- return sizeof(*json) + FBUFFER_CAPA(&json->fbuffer);
1397
+ return sizeof(JSON_ParserConfig);
3140
1398
  }
3141
1399
 
3142
- static const rb_data_type_t JSON_Parser_type = {
3143
- "JSON/Parser",
3144
- {JSON_mark, JSON_free, JSON_memsize,},
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
- JSON_Parser *json;
3152
- VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json);
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
- cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
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(cParser, cJSON_parser_s_allocate);
3183
- rb_define_method(cParser, "initialize", cParser_initialize, -1);
3184
- rb_define_method(cParser, "parse", cParser_parse, 0);
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
- */