json 2.7.2 → 2.7.3.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,33 +3,11 @@
3
3
 
4
4
  #include "ruby.h"
5
5
 
6
- #ifndef HAVE_RUBY_RE_H
7
- #include "re.h"
8
- #endif
9
-
10
- #ifdef HAVE_RUBY_ST_H
11
- #include "ruby/st.h"
12
- #else
13
- #include "st.h"
14
- #endif
15
-
16
6
  #ifndef MAYBE_UNUSED
17
7
  # define MAYBE_UNUSED(x) x
18
8
  #endif
19
9
 
20
- #define option_given_p(opts, key) RTEST(rb_funcall(opts, i_key_p, 1, key))
21
-
22
- /* unicode */
23
-
24
- typedef unsigned long UTF32; /* at least 32 bits */
25
- typedef unsigned short UTF16; /* at least 16 bits */
26
- typedef unsigned char UTF8; /* typically 8 bits */
27
-
28
- #define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
29
- #define UNI_SUR_HIGH_START (UTF32)0xD800
30
- #define UNI_SUR_HIGH_END (UTF32)0xDBFF
31
- #define UNI_SUR_LOW_START (UTF32)0xDC00
32
- #define UNI_SUR_LOW_END (UTF32)0xDFFF
10
+ #define option_given_p(opts, key) (rb_hash_lookup2(opts, key, Qundef) != Qundef)
33
11
 
34
12
  typedef struct JSON_ParserStruct {
35
13
  VALUE Vsource;
@@ -60,8 +38,8 @@ typedef struct JSON_ParserStruct {
60
38
  #define MinusInfinity "-Infinity"
61
39
  #define EVIL 0x666
62
40
 
63
- static UTF32 unescape_unicode(const unsigned char *p);
64
- static int convert_UTF32_to_UTF8(char *buf, UTF32 ch);
41
+ static uint32_t unescape_unicode(const unsigned char *p);
42
+ static int convert_UTF32_to_UTF8(char *buf, uint32_t ch);
65
43
  static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
66
44
  static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
67
45
  static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result);
@@ -76,21 +54,7 @@ static void JSON_mark(void *json);
76
54
  static void JSON_free(void *json);
77
55
  static VALUE cJSON_parser_s_allocate(VALUE klass);
78
56
  static VALUE cParser_source(VALUE self);
79
- #ifndef ZALLOC
80
- #define ZALLOC(type) ((type *)ruby_zalloc(sizeof(type)))
81
- static inline void *ruby_zalloc(size_t n)
82
- {
83
- void *p = ruby_xmalloc(n);
84
- memset(p, 0, n);
85
- return p;
86
- }
87
- #endif
88
- #ifdef TypedData_Make_Struct
57
+
89
58
  static const rb_data_type_t JSON_Parser_type;
90
- #define NEW_TYPEDDATA_WRAPPER 1
91
- #else
92
- #define TypedData_Make_Struct(klass, type, ignore, json) Data_Make_Struct(klass, type, NULL, JSON_free, json)
93
- #define TypedData_Get_Struct(self, JSON_Parser, ignore, json) Data_Get_Struct(self, JSON_Parser, json)
94
- #endif
95
59
 
96
60
  #endif
@@ -1,28 +1,6 @@
1
1
  #include "../fbuffer/fbuffer.h"
2
2
  #include "parser.h"
3
3
 
4
- #if defined HAVE_RUBY_ENCODING_H
5
- # define EXC_ENCODING rb_utf8_encoding(),
6
- # ifndef HAVE_RB_ENC_RAISE
7
- static void
8
- enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
9
- {
10
- va_list args;
11
- VALUE mesg;
12
-
13
- va_start(args, fmt);
14
- mesg = rb_enc_vsprintf(enc, fmt, args);
15
- va_end(args);
16
-
17
- rb_exc_raise(rb_exc_new3(exc, mesg));
18
- }
19
- # define rb_enc_raise enc_raise
20
- # endif
21
- #else
22
- # define EXC_ENCODING /* nothing */
23
- # define rb_enc_raise rb_raise
24
- #endif
25
-
26
4
  /* unicode */
27
5
 
28
6
  static const signed char digit_values[256] = {
@@ -42,26 +20,28 @@ static const signed char digit_values[256] = {
42
20
  -1, -1, -1, -1, -1, -1, -1
43
21
  };
44
22
 
45
- static UTF32 unescape_unicode(const unsigned char *p)
23
+ static uint32_t unescape_unicode(const unsigned char *p)
46
24
  {
25
+ const uint32_t replacement_char = 0xFFFD;
26
+
47
27
  signed char b;
48
- UTF32 result = 0;
28
+ uint32_t result = 0;
49
29
  b = digit_values[p[0]];
50
- if (b < 0) return UNI_REPLACEMENT_CHAR;
30
+ if (b < 0) return replacement_char;
51
31
  result = (result << 4) | (unsigned char)b;
52
32
  b = digit_values[p[1]];
53
- if (b < 0) return UNI_REPLACEMENT_CHAR;
33
+ if (b < 0) return replacement_char;
54
34
  result = (result << 4) | (unsigned char)b;
55
35
  b = digit_values[p[2]];
56
- if (b < 0) return UNI_REPLACEMENT_CHAR;
36
+ if (b < 0) return replacement_char;
57
37
  result = (result << 4) | (unsigned char)b;
58
38
  b = digit_values[p[3]];
59
- if (b < 0) return UNI_REPLACEMENT_CHAR;
39
+ if (b < 0) return replacement_char;
60
40
  result = (result << 4) | (unsigned char)b;
61
41
  return result;
62
42
  }
63
43
 
64
- static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
44
+ static int convert_UTF32_to_UTF8(char *buf, uint32_t ch)
65
45
  {
66
46
  int len = 1;
67
47
  if (ch <= 0x7F) {
@@ -87,15 +67,39 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
87
67
  return len;
88
68
  }
89
69
 
90
- static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
70
+ #define PARSE_ERROR_FRAGMENT_LEN 32
71
+ #ifdef RBIMPL_ATTR_NORETURN
72
+ RBIMPL_ATTR_NORETURN()
73
+ #endif
74
+ static void raise_parse_error(const char *format, const char *start)
75
+ {
76
+ char buffer[PARSE_ERROR_FRAGMENT_LEN + 1];
77
+
78
+ size_t len = strnlen(start, PARSE_ERROR_FRAGMENT_LEN);
79
+ const char *ptr = start;
80
+
81
+ if (len == PARSE_ERROR_FRAGMENT_LEN) {
82
+ MEMCPY(buffer, start, char, PARSE_ERROR_FRAGMENT_LEN);
83
+ buffer[PARSE_ERROR_FRAGMENT_LEN] = '\0';
84
+ ptr = buffer;
85
+ }
86
+
87
+ rb_enc_raise(rb_utf8_encoding(), rb_path2class("JSON::ParserError"), format, ptr);
88
+ }
89
+
90
+ static VALUE mJSON, mExt, cParser, eNestingError;
91
91
  static VALUE CNaN, CInfinity, CMinusInfinity;
92
92
 
93
93
  static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
94
94
  i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
95
- i_object_class, i_array_class, i_decimal_class, i_key_p,
95
+ i_object_class, i_array_class, i_decimal_class,
96
96
  i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
97
97
  i_leftshift, i_new, i_try_convert, i_freeze, i_uminus;
98
98
 
99
+ static int binary_encindex;
100
+ static int utf8_encindex;
101
+
102
+
99
103
  %%{
100
104
  machine JSON_common;
101
105
 
@@ -222,14 +226,14 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
222
226
  if (json->allow_nan) {
223
227
  *result = CNaN;
224
228
  } else {
225
- rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p - 2);
229
+ raise_parse_error("unexpected token at '%s'", p - 2);
226
230
  }
227
231
  }
228
232
  action parse_infinity {
229
233
  if (json->allow_nan) {
230
234
  *result = CInfinity;
231
235
  } else {
232
- rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p - 7);
236
+ raise_parse_error("unexpected token at '%s'", p - 7);
233
237
  }
234
238
  }
235
239
  action parse_string {
@@ -245,7 +249,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
245
249
  fexec p + 10;
246
250
  fhold; fbreak;
247
251
  } else {
248
- rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p);
252
+ raise_parse_error("unexpected token at '%s'", p);
249
253
  }
250
254
  }
251
255
  np = JSON_parse_float(json, fpc, pe, result);
@@ -355,29 +359,31 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
355
359
  if (cs >= JSON_float_first_final) {
356
360
  VALUE mod = Qnil;
357
361
  ID method_id = 0;
358
- if (rb_respond_to(json->decimal_class, i_try_convert)) {
359
- mod = json->decimal_class;
360
- method_id = i_try_convert;
361
- } else if (rb_respond_to(json->decimal_class, i_new)) {
362
- mod = json->decimal_class;
363
- method_id = i_new;
364
- } else if (RB_TYPE_P(json->decimal_class, T_CLASS)) {
365
- VALUE name = rb_class_name(json->decimal_class);
366
- const char *name_cstr = RSTRING_PTR(name);
367
- const char *last_colon = strrchr(name_cstr, ':');
368
- if (last_colon) {
369
- const char *mod_path_end = last_colon - 1;
370
- VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr);
371
- mod = rb_path_to_class(mod_path);
372
-
373
- const char *method_name_beg = last_colon + 1;
374
- long before_len = method_name_beg - name_cstr;
375
- long len = RSTRING_LEN(name) - before_len;
376
- VALUE method_name = rb_str_substr(name, before_len, len);
377
- method_id = SYM2ID(rb_str_intern(method_name));
378
- } else {
379
- mod = rb_mKernel;
380
- method_id = SYM2ID(rb_str_intern(name));
362
+ if (!NIL_P(json->decimal_class)) {
363
+ if (rb_respond_to(json->decimal_class, i_try_convert)) {
364
+ mod = json->decimal_class;
365
+ method_id = i_try_convert;
366
+ } else if (rb_respond_to(json->decimal_class, i_new)) {
367
+ mod = json->decimal_class;
368
+ method_id = i_new;
369
+ } else if (RB_TYPE_P(json->decimal_class, T_CLASS)) {
370
+ VALUE name = rb_class_name(json->decimal_class);
371
+ const char *name_cstr = RSTRING_PTR(name);
372
+ const char *last_colon = strrchr(name_cstr, ':');
373
+ if (last_colon) {
374
+ const char *mod_path_end = last_colon - 1;
375
+ VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr);
376
+ mod = rb_path_to_class(mod_path);
377
+
378
+ const char *method_name_beg = last_colon + 1;
379
+ long before_len = method_name_beg - name_cstr;
380
+ long len = RSTRING_LEN(name) - before_len;
381
+ VALUE method_name = rb_str_substr(name, before_len, len);
382
+ method_id = SYM2ID(rb_str_intern(method_name));
383
+ } else {
384
+ mod = rb_mKernel;
385
+ method_id = SYM2ID(rb_str_intern(name));
386
+ }
381
387
  }
382
388
  }
383
389
 
@@ -447,7 +453,7 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
447
453
  if(cs >= JSON_array_first_final) {
448
454
  return p + 1;
449
455
  } else {
450
- rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p);
456
+ raise_parse_error("unexpected token at '%s'", p);
451
457
  return NULL;
452
458
  }
453
459
  }
@@ -510,26 +516,30 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
510
516
  if (bufferSize > MAX_STACK_BUFFER_SIZE) {
511
517
  ruby_xfree(bufferStart);
512
518
  }
513
- rb_enc_raise(
514
- EXC_ENCODING eParserError,
515
- "incomplete unicode character escape sequence at '%s'", p
516
- );
519
+ raise_parse_error("incomplete unicode character escape sequence at '%s'", p);
517
520
  } else {
518
- UTF32 ch = unescape_unicode((unsigned char *) ++pe);
521
+ uint32_t ch = unescape_unicode((unsigned char *) ++pe);
519
522
  pe += 3;
520
- if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
523
+ /* To handle values above U+FFFF, we take a sequence of
524
+ * \uXXXX escapes in the U+D800..U+DBFF then
525
+ * U+DC00..U+DFFF ranges, take the low 10 bits from each
526
+ * to make a 20-bit number, then add 0x10000 to get the
527
+ * final codepoint.
528
+ *
529
+ * See Unicode 15: 3.8 "Surrogates", 5.3 "Handling
530
+ * Surrogate Pairs in UTF-16", and 23.6 "Surrogates
531
+ * Area".
532
+ */
533
+ if ((ch & 0xFC00) == 0xD800) {
521
534
  pe++;
522
535
  if (pe > stringEnd - 6) {
523
536
  if (bufferSize > MAX_STACK_BUFFER_SIZE) {
524
537
  ruby_xfree(bufferStart);
525
538
  }
526
- rb_enc_raise(
527
- EXC_ENCODING eParserError,
528
- "incomplete surrogate pair at '%s'", p
529
- );
539
+ raise_parse_error("incomplete surrogate pair at '%s'", p);
530
540
  }
531
541
  if (pe[0] == '\\' && pe[1] == 'u') {
532
- UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
542
+ uint32_t sur = unescape_unicode((unsigned char *) pe + 2);
533
543
  ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
534
544
  | (sur & 0x3FF));
535
545
  pe += 5;
@@ -672,18 +682,20 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
672
682
 
673
683
  static VALUE convert_encoding(VALUE source)
674
684
  {
675
- #ifdef HAVE_RUBY_ENCODING_H
676
- rb_encoding *enc = rb_enc_get(source);
677
- if (enc == rb_ascii8bit_encoding()) {
678
- if (OBJ_FROZEN(source)) {
679
- source = rb_str_dup(source);
680
- }
681
- FORCE_UTF8(source);
682
- } else {
683
- source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
684
- }
685
- #endif
685
+ int encindex = RB_ENCODING_GET(source);
686
+
687
+ if (encindex == utf8_encindex) {
686
688
  return source;
689
+ }
690
+
691
+ if (encindex == binary_encindex) {
692
+ // For historical reason, we silently reinterpret binary strings as UTF-8 if it would work.
693
+ // TODO: Deprecate in 2.8.0
694
+ // TODO: Remove in 3.0.0
695
+ return rb_enc_associate_index(rb_str_dup(source), utf8_encindex);
696
+ }
697
+
698
+ return rb_str_conv_enc(source, rb_enc_from_index(encindex), rb_utf8_encoding());
687
699
  }
688
700
 
689
701
  /*
@@ -708,8 +720,15 @@ static VALUE convert_encoding(VALUE source)
708
720
  * * *create_additions*: If set to false, the Parser doesn't create
709
721
  * additions even if a matching class and create_id was found. This option
710
722
  * defaults to false.
711
- * * *object_class*: Defaults to Hash
712
- * * *array_class*: Defaults to Array
723
+ * * *object_class*: Defaults to Hash. If another type is provided, it will be used
724
+ * instead of Hash to represent JSON objects. The type must respond to
725
+ * +new+ without arguments, and return an object that respond to +[]=+.
726
+ * * *array_class*: Defaults to Array If another type is provided, it will be used
727
+ * instead of Hash to represent JSON arrays. The type must respond to
728
+ * +new+ without arguments, and return an object that respond to +<<+.
729
+ * * *decimal_class*: Specifies which class to use instead of the default
730
+ * (Float) when parsing decimal numbers. This class must accept a single
731
+ * string argument in its constructor.
713
732
  */
714
733
  static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
715
734
  {
@@ -719,80 +738,91 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
719
738
  if (json->Vsource) {
720
739
  rb_raise(rb_eTypeError, "already initialized instance");
721
740
  }
722
- rb_scan_args(argc, argv, "1:", &source, &opts);
741
+
742
+ rb_check_arity(argc, 1, 2);
743
+ source = argv[0];
744
+ opts = Qnil;
745
+ if (argc == 2) {
746
+ opts = argv[1];
747
+ Check_Type(argv[1], T_HASH);
748
+ if (RHASH_SIZE(argv[1]) > 0) {
749
+ opts = argv[1];
750
+ }
751
+ }
752
+
723
753
  if (!NIL_P(opts)) {
724
- VALUE tmp = ID2SYM(i_max_nesting);
725
- if (option_given_p(opts, tmp)) {
726
- VALUE max_nesting = rb_hash_aref(opts, tmp);
727
- if (RTEST(max_nesting)) {
728
- Check_Type(max_nesting, T_FIXNUM);
729
- json->max_nesting = FIX2INT(max_nesting);
730
- } else {
731
- json->max_nesting = 0;
732
- }
733
- } else {
734
- json->max_nesting = 100;
735
- }
736
- tmp = ID2SYM(i_allow_nan);
737
- if (option_given_p(opts, tmp)) {
738
- json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
739
- } else {
740
- json->allow_nan = 0;
741
- }
742
- tmp = ID2SYM(i_symbolize_names);
743
- if (option_given_p(opts, tmp)) {
744
- json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
745
- } else {
746
- json->symbolize_names = 0;
747
- }
748
- tmp = ID2SYM(i_freeze);
749
- if (option_given_p(opts, tmp)) {
750
- json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
751
- } else {
752
- json->freeze = 0;
753
- }
754
- tmp = ID2SYM(i_create_additions);
755
- if (option_given_p(opts, tmp)) {
756
- json->create_additions = RTEST(rb_hash_aref(opts, tmp));
757
- } else {
758
- json->create_additions = 0;
759
- }
760
- if (json->symbolize_names && json->create_additions) {
761
- rb_raise(rb_eArgError,
762
- "options :symbolize_names and :create_additions cannot be "
763
- " used in conjunction");
764
- }
765
- tmp = ID2SYM(i_create_id);
766
- if (option_given_p(opts, tmp)) {
767
- json->create_id = rb_hash_aref(opts, tmp);
768
- } else {
769
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
770
- }
771
- tmp = ID2SYM(i_object_class);
772
- if (option_given_p(opts, tmp)) {
773
- json->object_class = rb_hash_aref(opts, tmp);
774
- } else {
775
- json->object_class = Qnil;
776
- }
777
- tmp = ID2SYM(i_array_class);
778
- if (option_given_p(opts, tmp)) {
779
- json->array_class = rb_hash_aref(opts, tmp);
780
- } else {
781
- json->array_class = Qnil;
782
- }
783
- tmp = ID2SYM(i_decimal_class);
784
- if (option_given_p(opts, tmp)) {
785
- json->decimal_class = rb_hash_aref(opts, tmp);
786
- } else {
787
- json->decimal_class = Qnil;
788
- }
789
- tmp = ID2SYM(i_match_string);
790
- if (option_given_p(opts, tmp)) {
791
- VALUE match_string = rb_hash_aref(opts, tmp);
792
- json->match_string = RTEST(match_string) ? match_string : Qnil;
793
- } else {
794
- json->match_string = Qnil;
795
- }
754
+ VALUE tmp = ID2SYM(i_max_nesting);
755
+ if (option_given_p(opts, tmp)) {
756
+ VALUE max_nesting = rb_hash_aref(opts, tmp);
757
+ if (RTEST(max_nesting)) {
758
+ Check_Type(max_nesting, T_FIXNUM);
759
+ json->max_nesting = FIX2INT(max_nesting);
760
+ } else {
761
+ json->max_nesting = 0;
762
+ }
763
+ } else {
764
+ json->max_nesting = 100;
765
+ }
766
+ tmp = ID2SYM(i_allow_nan);
767
+ if (option_given_p(opts, tmp)) {
768
+ json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
769
+ } else {
770
+ json->allow_nan = 0;
771
+ }
772
+ tmp = ID2SYM(i_symbolize_names);
773
+ if (option_given_p(opts, tmp)) {
774
+ json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
775
+ } else {
776
+ json->symbolize_names = 0;
777
+ }
778
+ tmp = ID2SYM(i_freeze);
779
+ if (option_given_p(opts, tmp)) {
780
+ json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
781
+ } else {
782
+ json->freeze = 0;
783
+ }
784
+ tmp = ID2SYM(i_create_additions);
785
+ if (option_given_p(opts, tmp)) {
786
+ json->create_additions = RTEST(rb_hash_aref(opts, tmp));
787
+ } else {
788
+ json->create_additions = 0;
789
+ }
790
+ if (json->symbolize_names && json->create_additions) {
791
+ rb_raise(rb_eArgError,
792
+ "options :symbolize_names and :create_additions cannot be "
793
+ " used in conjunction");
794
+ }
795
+ tmp = ID2SYM(i_create_id);
796
+ if (option_given_p(opts, tmp)) {
797
+ json->create_id = rb_hash_aref(opts, tmp);
798
+ } else {
799
+ json->create_id = rb_funcall(mJSON, i_create_id, 0);
800
+ }
801
+ tmp = ID2SYM(i_object_class);
802
+ if (option_given_p(opts, tmp)) {
803
+ json->object_class = rb_hash_aref(opts, tmp);
804
+ } else {
805
+ json->object_class = Qnil;
806
+ }
807
+ tmp = ID2SYM(i_array_class);
808
+ if (option_given_p(opts, tmp)) {
809
+ json->array_class = rb_hash_aref(opts, tmp);
810
+ } else {
811
+ json->array_class = Qnil;
812
+ }
813
+ tmp = ID2SYM(i_decimal_class);
814
+ if (option_given_p(opts, tmp)) {
815
+ json->decimal_class = rb_hash_aref(opts, tmp);
816
+ } else {
817
+ json->decimal_class = Qnil;
818
+ }
819
+ tmp = ID2SYM(i_match_string);
820
+ if (option_given_p(opts, tmp)) {
821
+ VALUE match_string = rb_hash_aref(opts, tmp);
822
+ json->match_string = RTEST(match_string) ? match_string : Qnil;
823
+ } else {
824
+ json->match_string = Qnil;
825
+ }
796
826
  } else {
797
827
  json->max_nesting = 100;
798
828
  json->allow_nan = 0;
@@ -836,33 +866,33 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
836
866
  */
837
867
  static VALUE cParser_parse(VALUE self)
838
868
  {
839
- char *p, *pe;
840
- int cs = EVIL;
841
- VALUE result = Qnil;
842
- GET_PARSER;
869
+ char *p, *pe;
870
+ int cs = EVIL;
871
+ VALUE result = Qnil;
872
+ GET_PARSER;
843
873
 
844
- %% write init;
845
- p = json->source;
846
- pe = p + json->len;
847
- %% write exec;
874
+ %% write init;
875
+ p = json->source;
876
+ pe = p + json->len;
877
+ %% write exec;
848
878
 
849
- if (cs >= JSON_first_final && p == pe) {
850
- return result;
851
- } else {
852
- rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p);
853
- return Qnil;
854
- }
879
+ if (cs >= JSON_first_final && p == pe) {
880
+ return result;
881
+ } else {
882
+ raise_parse_error("unexpected token at '%s'", p);
883
+ return Qnil;
884
+ }
855
885
  }
856
886
 
857
887
  static void JSON_mark(void *ptr)
858
888
  {
859
889
  JSON_Parser *json = ptr;
860
- rb_gc_mark_maybe(json->Vsource);
861
- rb_gc_mark_maybe(json->create_id);
862
- rb_gc_mark_maybe(json->object_class);
863
- rb_gc_mark_maybe(json->array_class);
864
- rb_gc_mark_maybe(json->decimal_class);
865
- rb_gc_mark_maybe(json->match_string);
890
+ rb_gc_mark(json->Vsource);
891
+ rb_gc_mark(json->create_id);
892
+ rb_gc_mark(json->object_class);
893
+ rb_gc_mark(json->array_class);
894
+ rb_gc_mark(json->decimal_class);
895
+ rb_gc_mark(json->match_string);
866
896
  }
867
897
 
868
898
  static void JSON_free(void *ptr)
@@ -878,16 +908,12 @@ static size_t JSON_memsize(const void *ptr)
878
908
  return sizeof(*json) + FBUFFER_CAPA(json->fbuffer);
879
909
  }
880
910
 
881
- #ifdef NEW_TYPEDDATA_WRAPPER
882
911
  static const rb_data_type_t JSON_Parser_type = {
883
912
  "JSON/Parser",
884
913
  {JSON_mark, JSON_free, JSON_memsize,},
885
- #ifdef RUBY_TYPED_FREE_IMMEDIATELY
886
914
  0, 0,
887
915
  RUBY_TYPED_FREE_IMMEDIATELY,
888
- #endif
889
916
  };
890
- #endif
891
917
 
892
918
  static VALUE cJSON_parser_s_allocate(VALUE klass)
893
919
  {
@@ -920,9 +946,7 @@ void Init_parser(void)
920
946
  mJSON = rb_define_module("JSON");
921
947
  mExt = rb_define_module_under(mJSON, "Ext");
922
948
  cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
923
- eParserError = rb_path2class("JSON::ParserError");
924
949
  eNestingError = rb_path2class("JSON::NestingError");
925
- rb_gc_register_mark_object(eParserError);
926
950
  rb_gc_register_mark_object(eNestingError);
927
951
  rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
928
952
  rb_define_method(cParser, "initialize", cParser_initialize, -1);
@@ -951,7 +975,6 @@ void Init_parser(void)
951
975
  i_decimal_class = rb_intern("decimal_class");
952
976
  i_match = rb_intern("match");
953
977
  i_match_string = rb_intern("match_string");
954
- i_key_p = rb_intern("key?");
955
978
  i_deep_const_get = rb_intern("deep_const_get");
956
979
  i_aset = rb_intern("[]=");
957
980
  i_aref = rb_intern("[]");
@@ -960,6 +983,9 @@ void Init_parser(void)
960
983
  i_try_convert = rb_intern("try_convert");
961
984
  i_freeze = rb_intern("freeze");
962
985
  i_uminus = rb_intern("-@");
986
+
987
+ binary_encindex = rb_ascii8bit_encindex();
988
+ utf8_encindex = rb_utf8_encindex();
963
989
  }
964
990
 
965
991
  /*