json 2.7.2 → 2.7.5

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.
@@ -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
  /*