json 2.9.1 → 2.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
- */