json_pure 2.0.3 → 2.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.3
1
+ 2.3.1
@@ -12,9 +12,6 @@
12
12
  #define RFLOAT_VALUE(val) (RFLOAT(val)->value)
13
13
  #endif
14
14
 
15
- #ifndef RARRAY_PTR
16
- #define RARRAY_PTR(ARRAY) RARRAY(ARRAY)->ptr
17
- #endif
18
15
  #ifndef RARRAY_LEN
19
16
  #define RARRAY_LEN(ARRAY) RARRAY(ARRAY)->len
20
17
  #endif
@@ -15,7 +15,7 @@ static VALUE mJSON, mExt, mGenerator, cState, mGeneratorMethods, mObject,
15
15
  #endif
16
16
  mFloat, mString, mString_Extend,
17
17
  mTrueClass, mFalseClass, mNilClass, eGeneratorError,
18
- eNestingError, CRegexp_MULTILINE, CJSON_SAFE_STATE_PROTOTYPE,
18
+ eNestingError,
19
19
  i_SAFE_STATE_PROTOTYPE;
20
20
 
21
21
  static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before,
@@ -237,6 +237,7 @@ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string)
237
237
  int escape_len;
238
238
  unsigned char c;
239
239
  char buf[6] = { '\\', 'u' };
240
+ int ascii_only = rb_enc_str_asciionly_p(string);
240
241
 
241
242
  for (start = 0, end = 0; end < len;) {
242
243
  p = ptr + end;
@@ -281,14 +282,17 @@ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string)
281
282
  break;
282
283
  default:
283
284
  {
284
- unsigned short clen = trailingBytesForUTF8[c] + 1;
285
- if (end + clen > len) {
286
- rb_raise(rb_path2class("JSON::GeneratorError"),
287
- "partial character in source, but hit end");
288
- }
289
- if (!isLegalUTF8((UTF8 *) p, clen)) {
290
- rb_raise(rb_path2class("JSON::GeneratorError"),
291
- "source sequence is illegal/malformed utf-8");
285
+ unsigned short clen = 1;
286
+ if (!ascii_only) {
287
+ clen += trailingBytesForUTF8[c];
288
+ if (end + clen > len) {
289
+ rb_raise(rb_path2class("JSON::GeneratorError"),
290
+ "partial character in source, but hit end");
291
+ }
292
+ if (!isLegalUTF8((UTF8 *) p, clen)) {
293
+ rb_raise(rb_path2class("JSON::GeneratorError"),
294
+ "source sequence is illegal/malformed utf-8");
295
+ }
292
296
  }
293
297
  end += clen;
294
298
  }
@@ -308,7 +312,7 @@ static char *fstrndup(const char *ptr, unsigned long len) {
308
312
  char *result;
309
313
  if (len <= 0) return NULL;
310
314
  result = ALLOC_N(char, len);
311
- memccpy(result, ptr, 0, len);
315
+ memcpy(result, ptr, len);
312
316
  return result;
313
317
  }
314
318
 
@@ -324,6 +328,76 @@ static char *fstrndup(const char *ptr, unsigned long len) {
324
328
  *
325
329
  */
326
330
 
331
+ /* Explanation of the following: that's the only way to not pollute
332
+ * standard library's docs with GeneratorMethods::<ClassName> which
333
+ * are uninformative and take a large place in a list of classes
334
+ */
335
+
336
+ /*
337
+ * Document-module: JSON::Ext::Generator::GeneratorMethods
338
+ * :nodoc:
339
+ */
340
+
341
+ /*
342
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::Array
343
+ * :nodoc:
344
+ */
345
+
346
+ /*
347
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::Bignum
348
+ * :nodoc:
349
+ */
350
+
351
+ /*
352
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::FalseClass
353
+ * :nodoc:
354
+ */
355
+
356
+ /*
357
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::Fixnum
358
+ * :nodoc:
359
+ */
360
+
361
+ /*
362
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::Float
363
+ * :nodoc:
364
+ */
365
+
366
+ /*
367
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::Hash
368
+ * :nodoc:
369
+ */
370
+
371
+ /*
372
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::Integer
373
+ * :nodoc:
374
+ */
375
+
376
+ /*
377
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::NilClass
378
+ * :nodoc:
379
+ */
380
+
381
+ /*
382
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::Object
383
+ * :nodoc:
384
+ */
385
+
386
+ /*
387
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::String
388
+ * :nodoc:
389
+ */
390
+
391
+ /*
392
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::String::Extend
393
+ * :nodoc:
394
+ */
395
+
396
+ /*
397
+ * Document-module: JSON::Ext::Generator::GeneratorMethods::TrueClass
398
+ * :nodoc:
399
+ */
400
+
327
401
  /*
328
402
  * call-seq: to_json(state = nil)
329
403
  *
@@ -692,7 +766,7 @@ static VALUE cState_aref(VALUE self, VALUE name)
692
766
  if (RTEST(rb_funcall(self, i_respond_to_p, 1, name))) {
693
767
  return rb_funcall(self, i_send, 1, name);
694
768
  } else {
695
- return rb_ivar_get(self, rb_intern_str(rb_str_concat(rb_str_new2("@"), name)));
769
+ return rb_attr_get(self, rb_intern_str(rb_str_concat(rb_str_new2("@"), name)));
696
770
  }
697
771
  }
698
772
 
@@ -715,43 +789,83 @@ static VALUE cState_aset(VALUE self, VALUE name, VALUE value)
715
789
  return Qnil;
716
790
  }
717
791
 
718
- static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
792
+ struct hash_foreach_arg {
793
+ FBuffer *buffer;
794
+ JSON_Generator_State *state;
795
+ VALUE Vstate;
796
+ int iter;
797
+ };
798
+
799
+ static int
800
+ json_object_i(VALUE key, VALUE val, VALUE _arg)
719
801
  {
802
+ struct hash_foreach_arg *arg = (struct hash_foreach_arg *)_arg;
803
+ FBuffer *buffer = arg->buffer;
804
+ JSON_Generator_State *state = arg->state;
805
+ VALUE Vstate = arg->Vstate;
806
+
720
807
  char *object_nl = state->object_nl;
721
808
  long object_nl_len = state->object_nl_len;
722
809
  char *indent = state->indent;
723
810
  long indent_len = state->indent_len;
724
- long max_nesting = state->max_nesting;
725
811
  char *delim = FBUFFER_PTR(state->object_delim);
726
812
  long delim_len = FBUFFER_LEN(state->object_delim);
727
813
  char *delim2 = FBUFFER_PTR(state->object_delim2);
728
814
  long delim2_len = FBUFFER_LEN(state->object_delim2);
815
+ long depth = state->depth;
816
+ int j;
817
+ VALUE klass, key_to_s;
818
+
819
+ if (arg->iter > 0) fbuffer_append(buffer, delim, delim_len);
820
+ if (object_nl) {
821
+ fbuffer_append(buffer, object_nl, object_nl_len);
822
+ }
823
+ if (indent) {
824
+ for (j = 0; j < depth; j++) {
825
+ fbuffer_append(buffer, indent, indent_len);
826
+ }
827
+ }
828
+
829
+ klass = CLASS_OF(key);
830
+ if (klass == rb_cString) {
831
+ key_to_s = key;
832
+ } else if (klass == rb_cSymbol) {
833
+ key_to_s = rb_id2str(SYM2ID(key));
834
+ } else {
835
+ key_to_s = rb_funcall(key, i_to_s, 0);
836
+ }
837
+ Check_Type(key_to_s, T_STRING);
838
+ generate_json(buffer, Vstate, state, key_to_s);
839
+ fbuffer_append(buffer, delim2, delim2_len);
840
+ generate_json(buffer, Vstate, state, val);
841
+
842
+ arg->iter++;
843
+ return ST_CONTINUE;
844
+ }
845
+
846
+ static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
847
+ {
848
+ char *object_nl = state->object_nl;
849
+ long object_nl_len = state->object_nl_len;
850
+ char *indent = state->indent;
851
+ long indent_len = state->indent_len;
852
+ long max_nesting = state->max_nesting;
729
853
  long depth = ++state->depth;
730
- int i, j;
731
- VALUE key, key_to_s, keys;
854
+ int j;
855
+ struct hash_foreach_arg arg;
856
+
732
857
  if (max_nesting != 0 && depth > max_nesting) {
733
858
  fbuffer_free(buffer);
734
859
  rb_raise(eNestingError, "nesting of %ld is too deep", --state->depth);
735
860
  }
736
861
  fbuffer_append_char(buffer, '{');
737
- keys = rb_funcall(obj, i_keys, 0);
738
- for(i = 0; i < RARRAY_LEN(keys); i++) {
739
- if (i > 0) fbuffer_append(buffer, delim, delim_len);
740
- if (object_nl) {
741
- fbuffer_append(buffer, object_nl, object_nl_len);
742
- }
743
- if (indent) {
744
- for (j = 0; j < depth; j++) {
745
- fbuffer_append(buffer, indent, indent_len);
746
- }
747
- }
748
- key = rb_ary_entry(keys, i);
749
- key_to_s = rb_funcall(key, i_to_s, 0);
750
- Check_Type(key_to_s, T_STRING);
751
- generate_json(buffer, Vstate, state, key_to_s);
752
- fbuffer_append(buffer, delim2, delim2_len);
753
- generate_json(buffer, Vstate, state, rb_hash_aref(obj, key));
754
- }
862
+
863
+ arg.buffer = buffer;
864
+ arg.state = state;
865
+ arg.Vstate = Vstate;
866
+ arg.iter = 0;
867
+ rb_hash_foreach(obj, json_object_i, (VALUE)&arg);
868
+
755
869
  depth = --state->depth;
756
870
  if (object_nl) {
757
871
  fbuffer_append(buffer, object_nl, object_nl_len);
@@ -802,11 +916,22 @@ static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_St
802
916
  fbuffer_append_char(buffer, ']');
803
917
  }
804
918
 
919
+ #ifdef HAVE_RUBY_ENCODING_H
920
+ static int enc_utf8_compatible_p(rb_encoding *enc)
921
+ {
922
+ if (enc == rb_usascii_encoding()) return 1;
923
+ if (enc == rb_utf8_encoding()) return 1;
924
+ return 0;
925
+ }
926
+ #endif
927
+
805
928
  static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
806
929
  {
807
930
  fbuffer_append_char(buffer, '"');
808
931
  #ifdef HAVE_RUBY_ENCODING_H
809
- obj = rb_funcall(obj, i_encode, 1, CEncoding_UTF_8);
932
+ if (!enc_utf8_compatible_p(rb_enc_get(obj))) {
933
+ obj = rb_str_encode(obj, CEncoding_UTF_8, 0, Qnil);
934
+ }
810
935
  #endif
811
936
  if (state->ascii_only) {
812
937
  convert_UTF8_to_JSON_ASCII(buffer, obj);
@@ -970,6 +1095,8 @@ static VALUE cState_generate(VALUE self, VALUE obj)
970
1095
  * * *allow_nan*: true if NaN, Infinity, and -Infinity should be
971
1096
  * generated, otherwise an exception is thrown, if these values are
972
1097
  * encountered. This options defaults to false.
1098
+ * * *ascii_only*: true if only ASCII characters should be generated. This
1099
+ * option defaults to false.
973
1100
  * * *buffer_initial_length*: sets the initial length of the generator's
974
1101
  * internal buffer.
975
1102
  */
@@ -1025,10 +1152,8 @@ static VALUE cState_from_state_s(VALUE self, VALUE opts)
1025
1152
  } else if (rb_obj_is_kind_of(opts, rb_cHash)) {
1026
1153
  return rb_funcall(self, i_new, 1, opts);
1027
1154
  } else {
1028
- if (NIL_P(CJSON_SAFE_STATE_PROTOTYPE)) {
1029
- CJSON_SAFE_STATE_PROTOTYPE = rb_const_get(mJSON, i_SAFE_STATE_PROTOTYPE);
1030
- }
1031
- return rb_funcall(CJSON_SAFE_STATE_PROTOTYPE, i_dup, 0);
1155
+ VALUE prototype = rb_const_get(mJSON, i_SAFE_STATE_PROTOTYPE);
1156
+ return rb_funcall(prototype, i_dup, 0);
1032
1157
  }
1033
1158
  }
1034
1159
 
@@ -1062,7 +1187,7 @@ static VALUE cState_indent_set(VALUE self, VALUE indent)
1062
1187
  }
1063
1188
  } else {
1064
1189
  if (state->indent) ruby_xfree(state->indent);
1065
- state->indent = strdup(RSTRING_PTR(indent));
1190
+ state->indent = fstrndup(RSTRING_PTR(indent), len);
1066
1191
  state->indent_len = len;
1067
1192
  }
1068
1193
  return Qnil;
@@ -1100,7 +1225,7 @@ static VALUE cState_space_set(VALUE self, VALUE space)
1100
1225
  }
1101
1226
  } else {
1102
1227
  if (state->space) ruby_xfree(state->space);
1103
- state->space = strdup(RSTRING_PTR(space));
1228
+ state->space = fstrndup(RSTRING_PTR(space), len);
1104
1229
  state->space_len = len;
1105
1230
  }
1106
1231
  return Qnil;
@@ -1136,7 +1261,7 @@ static VALUE cState_space_before_set(VALUE self, VALUE space_before)
1136
1261
  }
1137
1262
  } else {
1138
1263
  if (state->space_before) ruby_xfree(state->space_before);
1139
- state->space_before = strdup(RSTRING_PTR(space_before));
1264
+ state->space_before = fstrndup(RSTRING_PTR(space_before), len);
1140
1265
  state->space_before_len = len;
1141
1266
  }
1142
1267
  return Qnil;
@@ -1173,7 +1298,7 @@ static VALUE cState_object_nl_set(VALUE self, VALUE object_nl)
1173
1298
  }
1174
1299
  } else {
1175
1300
  if (state->object_nl) ruby_xfree(state->object_nl);
1176
- state->object_nl = strdup(RSTRING_PTR(object_nl));
1301
+ state->object_nl = fstrndup(RSTRING_PTR(object_nl), len);
1177
1302
  state->object_nl_len = len;
1178
1303
  }
1179
1304
  return Qnil;
@@ -1208,7 +1333,7 @@ static VALUE cState_array_nl_set(VALUE self, VALUE array_nl)
1208
1333
  }
1209
1334
  } else {
1210
1335
  if (state->array_nl) ruby_xfree(state->array_nl);
1211
- state->array_nl = strdup(RSTRING_PTR(array_nl));
1336
+ state->array_nl = fstrndup(RSTRING_PTR(array_nl), len);
1212
1337
  state->array_nl_len = len;
1213
1338
  }
1214
1339
  return Qnil;
@@ -1267,7 +1392,7 @@ static VALUE cState_allow_nan_p(VALUE self)
1267
1392
  /*
1268
1393
  * call-seq: ascii_only?
1269
1394
  *
1270
- * Returns true, if NaN, Infinity, and -Infinity should be generated, otherwise
1395
+ * Returns true, if only ASCII characters should be generated. Otherwise
1271
1396
  * returns false.
1272
1397
  */
1273
1398
  static VALUE cState_ascii_only_p(VALUE self)
@@ -1335,6 +1460,7 @@ static VALUE cState_buffer_initial_length_set(VALUE self, VALUE buffer_initial_l
1335
1460
  */
1336
1461
  void Init_generator(void)
1337
1462
  {
1463
+ #undef rb_intern
1338
1464
  rb_require("json/common");
1339
1465
 
1340
1466
  mJSON = rb_define_module("JSON");
@@ -1343,6 +1469,8 @@ void Init_generator(void)
1343
1469
 
1344
1470
  eGeneratorError = rb_path2class("JSON::GeneratorError");
1345
1471
  eNestingError = rb_path2class("JSON::NestingError");
1472
+ rb_gc_register_mark_object(eGeneratorError);
1473
+ rb_gc_register_mark_object(eNestingError);
1346
1474
 
1347
1475
  cState = rb_define_class_under(mGenerator, "State", rb_cObject);
1348
1476
  rb_define_alloc_func(cState, cState_s_allocate);
@@ -1408,7 +1536,6 @@ void Init_generator(void)
1408
1536
  mNilClass = rb_define_module_under(mGeneratorMethods, "NilClass");
1409
1537
  rb_define_method(mNilClass, "to_json", mNilClass_to_json, -1);
1410
1538
 
1411
- CRegexp_MULTILINE = rb_const_get(rb_cRegexp, rb_intern("MULTILINE"));
1412
1539
  i_to_s = rb_intern("to_s");
1413
1540
  i_to_json = rb_intern("to_json");
1414
1541
  i_new = rb_intern("new");
@@ -1439,5 +1566,4 @@ void Init_generator(void)
1439
1566
  i_encode = rb_intern("encode");
1440
1567
  #endif
1441
1568
  i_SAFE_STATE_PROTOTYPE = rb_intern("SAFE_STATE_PROTOTYPE");
1442
- CJSON_SAFE_STATE_PROTOTYPE = Qnil;
1443
1569
  }
@@ -1,7 +1,6 @@
1
1
  #ifndef _GENERATOR_H_
2
2
  #define _GENERATOR_H_
3
3
 
4
- #include <string.h>
5
4
  #include <math.h>
6
5
  #include <ctype.h>
7
6
 
@@ -1,4 +1,4 @@
1
-
1
+ /* This file is automatically generated from parser.rl by using ragel */
2
2
  #line 1 "parser.rl"
3
3
  #include "../fbuffer/fbuffer.h"
4
4
  #include "parser.h"
@@ -27,7 +27,7 @@ enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
27
27
 
28
28
  /* unicode */
29
29
 
30
- static const char digit_values[256] = {
30
+ static const signed char digit_values[256] = {
31
31
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
32
32
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
33
33
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
@@ -46,7 +46,7 @@ static const char digit_values[256] = {
46
46
 
47
47
  static UTF32 unescape_unicode(const unsigned char *p)
48
48
  {
49
- char b;
49
+ signed char b;
50
50
  UTF32 result = 0;
51
51
  b = digit_values[p[0]];
52
52
  if (b < 0) return UNI_REPLACEMENT_CHAR;
@@ -91,18 +91,20 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
91
91
 
92
92
  static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
93
93
  static VALUE CNaN, CInfinity, CMinusInfinity;
94
+ static VALUE cBigDecimal = Qundef;
94
95
 
95
96
  static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
96
97
  i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
97
- i_object_class, i_array_class, i_key_p, i_deep_const_get, i_match,
98
- i_match_string, i_aset, i_aref, i_leftshift;
98
+ i_object_class, i_array_class, i_decimal_class, i_key_p,
99
+ i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
100
+ i_leftshift, i_new, i_BigDecimal;
99
101
 
100
102
 
101
- #line 124 "parser.rl"
103
+ #line 126 "parser.rl"
102
104
 
103
105
 
104
106
 
105
- #line 106 "parser.c"
107
+ #line 108 "parser.c"
106
108
  enum {JSON_object_start = 1};
107
109
  enum {JSON_object_first_final = 27};
108
110
  enum {JSON_object_error = 0};
@@ -110,7 +112,7 @@ enum {JSON_object_error = 0};
110
112
  enum {JSON_object_en_main = 1};
111
113
 
112
114
 
113
- #line 165 "parser.rl"
115
+ #line 168 "parser.rl"
114
116
 
115
117
 
116
118
  static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
@@ -126,14 +128,14 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
126
128
  *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
127
129
 
128
130
 
129
- #line 130 "parser.c"
131
+ #line 132 "parser.c"
130
132
  {
131
133
  cs = JSON_object_start;
132
134
  }
133
135
 
134
- #line 180 "parser.rl"
136
+ #line 183 "parser.rl"
135
137
 
136
- #line 137 "parser.c"
138
+ #line 139 "parser.c"
137
139
  {
138
140
  if ( p == pe )
139
141
  goto _test_eof;
@@ -161,7 +163,7 @@ case 2:
161
163
  goto st2;
162
164
  goto st0;
163
165
  tr2:
164
- #line 147 "parser.rl"
166
+ #line 150 "parser.rl"
165
167
  {
166
168
  char *np;
167
169
  json->parsing_name = 1;
@@ -174,7 +176,7 @@ st3:
174
176
  if ( ++p == pe )
175
177
  goto _test_eof3;
176
178
  case 3:
177
- #line 178 "parser.c"
179
+ #line 180 "parser.c"
178
180
  switch( (*p) ) {
179
181
  case 13: goto st3;
180
182
  case 32: goto st3;
@@ -241,7 +243,7 @@ case 8:
241
243
  goto st8;
242
244
  goto st0;
243
245
  tr11:
244
- #line 132 "parser.rl"
246
+ #line 134 "parser.rl"
245
247
  {
246
248
  VALUE v = Qnil;
247
249
  char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
@@ -249,6 +251,7 @@ tr11:
249
251
  p--; {p++; cs = 9; goto _out;}
250
252
  } else {
251
253
  if (NIL_P(json->object_class)) {
254
+ OBJ_FREEZE(last_name);
252
255
  rb_hash_aset(*result, last_name, v);
253
256
  } else {
254
257
  rb_funcall(*result, i_aset, 2, last_name, v);
@@ -261,7 +264,7 @@ st9:
261
264
  if ( ++p == pe )
262
265
  goto _test_eof9;
263
266
  case 9:
264
- #line 265 "parser.c"
267
+ #line 268 "parser.c"
265
268
  switch( (*p) ) {
266
269
  case 13: goto st9;
267
270
  case 32: goto st9;
@@ -350,14 +353,14 @@ case 18:
350
353
  goto st9;
351
354
  goto st18;
352
355
  tr4:
353
- #line 155 "parser.rl"
356
+ #line 158 "parser.rl"
354
357
  { p--; {p++; cs = 27; goto _out;} }
355
358
  goto st27;
356
359
  st27:
357
360
  if ( ++p == pe )
358
361
  goto _test_eof27;
359
362
  case 27:
360
- #line 361 "parser.c"
363
+ #line 364 "parser.c"
361
364
  goto st0;
362
365
  st19:
363
366
  if ( ++p == pe )
@@ -455,7 +458,7 @@ case 26:
455
458
  _out: {}
456
459
  }
457
460
 
458
- #line 181 "parser.rl"
461
+ #line 184 "parser.rl"
459
462
 
460
463
  if (cs >= JSON_object_first_final) {
461
464
  if (json->create_additions) {
@@ -480,7 +483,7 @@ case 26:
480
483
 
481
484
 
482
485
 
483
- #line 484 "parser.c"
486
+ #line 487 "parser.c"
484
487
  enum {JSON_value_start = 1};
485
488
  enum {JSON_value_first_final = 29};
486
489
  enum {JSON_value_error = 0};
@@ -488,7 +491,7 @@ enum {JSON_value_error = 0};
488
491
  enum {JSON_value_en_main = 1};
489
492
 
490
493
 
491
- #line 281 "parser.rl"
494
+ #line 284 "parser.rl"
492
495
 
493
496
 
494
497
  static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
@@ -496,14 +499,14 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
496
499
  int cs = EVIL;
497
500
 
498
501
 
499
- #line 500 "parser.c"
502
+ #line 503 "parser.c"
500
503
  {
501
504
  cs = JSON_value_start;
502
505
  }
503
506
 
504
- #line 288 "parser.rl"
507
+ #line 291 "parser.rl"
505
508
 
506
- #line 507 "parser.c"
509
+ #line 510 "parser.c"
507
510
  {
508
511
  if ( p == pe )
509
512
  goto _test_eof;
@@ -537,14 +540,14 @@ st0:
537
540
  cs = 0;
538
541
  goto _out;
539
542
  tr2:
540
- #line 233 "parser.rl"
543
+ #line 236 "parser.rl"
541
544
  {
542
545
  char *np = JSON_parse_string(json, p, pe, result);
543
546
  if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
544
547
  }
545
548
  goto st29;
546
549
  tr3:
547
- #line 238 "parser.rl"
550
+ #line 241 "parser.rl"
548
551
  {
549
552
  char *np;
550
553
  if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) {
@@ -564,7 +567,7 @@ tr3:
564
567
  }
565
568
  goto st29;
566
569
  tr7:
567
- #line 256 "parser.rl"
570
+ #line 259 "parser.rl"
568
571
  {
569
572
  char *np;
570
573
  np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
@@ -572,7 +575,7 @@ tr7:
572
575
  }
573
576
  goto st29;
574
577
  tr11:
575
- #line 262 "parser.rl"
578
+ #line 265 "parser.rl"
576
579
  {
577
580
  char *np;
578
581
  np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
@@ -580,7 +583,7 @@ tr11:
580
583
  }
581
584
  goto st29;
582
585
  tr25:
583
- #line 226 "parser.rl"
586
+ #line 229 "parser.rl"
584
587
  {
585
588
  if (json->allow_nan) {
586
589
  *result = CInfinity;
@@ -590,7 +593,7 @@ tr25:
590
593
  }
591
594
  goto st29;
592
595
  tr27:
593
- #line 219 "parser.rl"
596
+ #line 222 "parser.rl"
594
597
  {
595
598
  if (json->allow_nan) {
596
599
  *result = CNaN;
@@ -600,19 +603,19 @@ tr27:
600
603
  }
601
604
  goto st29;
602
605
  tr31:
603
- #line 213 "parser.rl"
606
+ #line 216 "parser.rl"
604
607
  {
605
608
  *result = Qfalse;
606
609
  }
607
610
  goto st29;
608
611
  tr34:
609
- #line 210 "parser.rl"
612
+ #line 213 "parser.rl"
610
613
  {
611
614
  *result = Qnil;
612
615
  }
613
616
  goto st29;
614
617
  tr37:
615
- #line 216 "parser.rl"
618
+ #line 219 "parser.rl"
616
619
  {
617
620
  *result = Qtrue;
618
621
  }
@@ -621,9 +624,9 @@ st29:
621
624
  if ( ++p == pe )
622
625
  goto _test_eof29;
623
626
  case 29:
624
- #line 268 "parser.rl"
627
+ #line 271 "parser.rl"
625
628
  { p--; {p++; cs = 29; goto _out;} }
626
- #line 627 "parser.c"
629
+ #line 630 "parser.c"
627
630
  switch( (*p) ) {
628
631
  case 13: goto st29;
629
632
  case 32: goto st29;
@@ -864,7 +867,7 @@ case 28:
864
867
  _out: {}
865
868
  }
866
869
 
867
- #line 289 "parser.rl"
870
+ #line 292 "parser.rl"
868
871
 
869
872
  if (cs >= JSON_value_first_final) {
870
873
  return p;
@@ -874,7 +877,7 @@ case 28:
874
877
  }
875
878
 
876
879
 
877
- #line 878 "parser.c"
880
+ #line 881 "parser.c"
878
881
  enum {JSON_integer_start = 1};
879
882
  enum {JSON_integer_first_final = 3};
880
883
  enum {JSON_integer_error = 0};
@@ -882,7 +885,7 @@ enum {JSON_integer_error = 0};
882
885
  enum {JSON_integer_en_main = 1};
883
886
 
884
887
 
885
- #line 305 "parser.rl"
888
+ #line 308 "parser.rl"
886
889
 
887
890
 
888
891
  static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -890,15 +893,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
890
893
  int cs = EVIL;
891
894
 
892
895
 
893
- #line 894 "parser.c"
896
+ #line 897 "parser.c"
894
897
  {
895
898
  cs = JSON_integer_start;
896
899
  }
897
900
 
898
- #line 312 "parser.rl"
901
+ #line 315 "parser.rl"
899
902
  json->memo = p;
900
903
 
901
- #line 902 "parser.c"
904
+ #line 905 "parser.c"
902
905
  {
903
906
  if ( p == pe )
904
907
  goto _test_eof;
@@ -932,14 +935,14 @@ case 3:
932
935
  goto st0;
933
936
  goto tr4;
934
937
  tr4:
935
- #line 302 "parser.rl"
938
+ #line 305 "parser.rl"
936
939
  { p--; {p++; cs = 4; goto _out;} }
937
940
  goto st4;
938
941
  st4:
939
942
  if ( ++p == pe )
940
943
  goto _test_eof4;
941
944
  case 4:
942
- #line 943 "parser.c"
945
+ #line 946 "parser.c"
943
946
  goto st0;
944
947
  st5:
945
948
  if ( ++p == pe )
@@ -958,7 +961,7 @@ case 5:
958
961
  _out: {}
959
962
  }
960
963
 
961
- #line 314 "parser.rl"
964
+ #line 317 "parser.rl"
962
965
 
963
966
  if (cs >= JSON_integer_first_final) {
964
967
  long len = p - json->memo;
@@ -973,7 +976,7 @@ case 5:
973
976
  }
974
977
 
975
978
 
976
- #line 977 "parser.c"
979
+ #line 980 "parser.c"
977
980
  enum {JSON_float_start = 1};
978
981
  enum {JSON_float_first_final = 8};
979
982
  enum {JSON_float_error = 0};
@@ -981,23 +984,36 @@ enum {JSON_float_error = 0};
981
984
  enum {JSON_float_en_main = 1};
982
985
 
983
986
 
984
- #line 339 "parser.rl"
987
+ #line 342 "parser.rl"
985
988
 
986
989
 
990
+ static int is_bigdecimal_class(VALUE obj)
991
+ {
992
+ if (cBigDecimal == Qundef) {
993
+ if (rb_const_defined(rb_cObject, i_BigDecimal)) {
994
+ cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal);
995
+ }
996
+ else {
997
+ return 0;
998
+ }
999
+ }
1000
+ return obj == cBigDecimal;
1001
+ }
1002
+
987
1003
  static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
988
1004
  {
989
1005
  int cs = EVIL;
990
1006
 
991
1007
 
992
- #line 993 "parser.c"
1008
+ #line 1009 "parser.c"
993
1009
  {
994
1010
  cs = JSON_float_start;
995
1011
  }
996
1012
 
997
- #line 346 "parser.rl"
1013
+ #line 362 "parser.rl"
998
1014
  json->memo = p;
999
1015
 
1000
- #line 1001 "parser.c"
1016
+ #line 1017 "parser.c"
1001
1017
  {
1002
1018
  if ( p == pe )
1003
1019
  goto _test_eof;
@@ -1055,14 +1071,14 @@ case 8:
1055
1071
  goto st0;
1056
1072
  goto tr9;
1057
1073
  tr9:
1058
- #line 333 "parser.rl"
1074
+ #line 336 "parser.rl"
1059
1075
  { p--; {p++; cs = 9; goto _out;} }
1060
1076
  goto st9;
1061
1077
  st9:
1062
1078
  if ( ++p == pe )
1063
1079
  goto _test_eof9;
1064
1080
  case 9:
1065
- #line 1066 "parser.c"
1081
+ #line 1082 "parser.c"
1066
1082
  goto st0;
1067
1083
  st5:
1068
1084
  if ( ++p == pe )
@@ -1123,14 +1139,24 @@ case 7:
1123
1139
  _out: {}
1124
1140
  }
1125
1141
 
1126
- #line 348 "parser.rl"
1142
+ #line 364 "parser.rl"
1127
1143
 
1128
1144
  if (cs >= JSON_float_first_final) {
1129
1145
  long len = p - json->memo;
1130
1146
  fbuffer_clear(json->fbuffer);
1131
1147
  fbuffer_append(json->fbuffer, json->memo, len);
1132
1148
  fbuffer_append_char(json->fbuffer, '\0');
1133
- *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
1149
+ if (NIL_P(json->decimal_class)) {
1150
+ *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
1151
+ } else {
1152
+ VALUE text;
1153
+ text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
1154
+ if (is_bigdecimal_class(json->decimal_class)) {
1155
+ *result = rb_funcall(Qnil, i_BigDecimal, 1, text);
1156
+ } else {
1157
+ *result = rb_funcall(json->decimal_class, i_new, 1, text);
1158
+ }
1159
+ }
1134
1160
  return p + 1;
1135
1161
  } else {
1136
1162
  return NULL;
@@ -1139,7 +1165,7 @@ case 7:
1139
1165
 
1140
1166
 
1141
1167
 
1142
- #line 1143 "parser.c"
1168
+ #line 1169 "parser.c"
1143
1169
  enum {JSON_array_start = 1};
1144
1170
  enum {JSON_array_first_final = 17};
1145
1171
  enum {JSON_array_error = 0};
@@ -1147,7 +1173,7 @@ enum {JSON_array_error = 0};
1147
1173
  enum {JSON_array_en_main = 1};
1148
1174
 
1149
1175
 
1150
- #line 391 "parser.rl"
1176
+ #line 417 "parser.rl"
1151
1177
 
1152
1178
 
1153
1179
  static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
@@ -1161,14 +1187,14 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
1161
1187
  *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
1162
1188
 
1163
1189
 
1164
- #line 1165 "parser.c"
1190
+ #line 1191 "parser.c"
1165
1191
  {
1166
1192
  cs = JSON_array_start;
1167
1193
  }
1168
1194
 
1169
- #line 404 "parser.rl"
1195
+ #line 430 "parser.rl"
1170
1196
 
1171
- #line 1172 "parser.c"
1197
+ #line 1198 "parser.c"
1172
1198
  {
1173
1199
  if ( p == pe )
1174
1200
  goto _test_eof;
@@ -1207,7 +1233,7 @@ case 2:
1207
1233
  goto st2;
1208
1234
  goto st0;
1209
1235
  tr2:
1210
- #line 368 "parser.rl"
1236
+ #line 394 "parser.rl"
1211
1237
  {
1212
1238
  VALUE v = Qnil;
1213
1239
  char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
@@ -1227,7 +1253,7 @@ st3:
1227
1253
  if ( ++p == pe )
1228
1254
  goto _test_eof3;
1229
1255
  case 3:
1230
- #line 1231 "parser.c"
1256
+ #line 1257 "parser.c"
1231
1257
  switch( (*p) ) {
1232
1258
  case 13: goto st3;
1233
1259
  case 32: goto st3;
@@ -1327,14 +1353,14 @@ case 12:
1327
1353
  goto st3;
1328
1354
  goto st12;
1329
1355
  tr4:
1330
- #line 383 "parser.rl"
1356
+ #line 409 "parser.rl"
1331
1357
  { p--; {p++; cs = 17; goto _out;} }
1332
1358
  goto st17;
1333
1359
  st17:
1334
1360
  if ( ++p == pe )
1335
1361
  goto _test_eof17;
1336
1362
  case 17:
1337
- #line 1338 "parser.c"
1363
+ #line 1364 "parser.c"
1338
1364
  goto st0;
1339
1365
  st13:
1340
1366
  if ( ++p == pe )
@@ -1390,7 +1416,7 @@ case 16:
1390
1416
  _out: {}
1391
1417
  }
1392
1418
 
1393
- #line 405 "parser.rl"
1419
+ #line 431 "parser.rl"
1394
1420
 
1395
1421
  if(cs >= JSON_array_first_final) {
1396
1422
  return p + 1;
@@ -1435,13 +1461,21 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
1435
1461
  break;
1436
1462
  case 'u':
1437
1463
  if (pe > stringEnd - 4) {
1438
- return Qnil;
1464
+ rb_enc_raise(
1465
+ EXC_ENCODING eParserError,
1466
+ "%u: incomplete unicode character escape sequence at '%s'", __LINE__, p
1467
+ );
1439
1468
  } else {
1440
1469
  UTF32 ch = unescape_unicode((unsigned char *) ++pe);
1441
1470
  pe += 3;
1442
1471
  if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
1443
1472
  pe++;
1444
- if (pe > stringEnd - 6) return Qnil;
1473
+ if (pe > stringEnd - 6) {
1474
+ rb_enc_raise(
1475
+ EXC_ENCODING eParserError,
1476
+ "%u: incomplete surrogate pair at '%s'", __LINE__, p
1477
+ );
1478
+ }
1445
1479
  if (pe[0] == '\\' && pe[1] == 'u') {
1446
1480
  UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
1447
1481
  ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
@@ -1471,7 +1505,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
1471
1505
  }
1472
1506
 
1473
1507
 
1474
- #line 1475 "parser.c"
1508
+ #line 1509 "parser.c"
1475
1509
  enum {JSON_string_start = 1};
1476
1510
  enum {JSON_string_first_final = 8};
1477
1511
  enum {JSON_string_error = 0};
@@ -1479,7 +1513,7 @@ enum {JSON_string_error = 0};
1479
1513
  enum {JSON_string_en_main = 1};
1480
1514
 
1481
1515
 
1482
- #line 504 "parser.rl"
1516
+ #line 538 "parser.rl"
1483
1517
 
1484
1518
 
1485
1519
  static int
@@ -1501,15 +1535,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
1501
1535
 
1502
1536
  *result = rb_str_buf_new(0);
1503
1537
 
1504
- #line 1505 "parser.c"
1538
+ #line 1539 "parser.c"
1505
1539
  {
1506
1540
  cs = JSON_string_start;
1507
1541
  }
1508
1542
 
1509
- #line 525 "parser.rl"
1543
+ #line 559 "parser.rl"
1510
1544
  json->memo = p;
1511
1545
 
1512
- #line 1513 "parser.c"
1546
+ #line 1547 "parser.c"
1513
1547
  {
1514
1548
  if ( p == pe )
1515
1549
  goto _test_eof;
@@ -1530,11 +1564,11 @@ case 2:
1530
1564
  case 34: goto tr2;
1531
1565
  case 92: goto st3;
1532
1566
  }
1533
- if ( 0 <= (*p) && (*p) <= 31 )
1567
+ if ( 0 <= (signed char)(*p) && (*p) <= 31 )
1534
1568
  goto st0;
1535
1569
  goto st2;
1536
1570
  tr2:
1537
- #line 490 "parser.rl"
1571
+ #line 524 "parser.rl"
1538
1572
  {
1539
1573
  *result = json_string_unescape(*result, json->memo + 1, p);
1540
1574
  if (NIL_P(*result)) {
@@ -1545,14 +1579,14 @@ tr2:
1545
1579
  {p = (( p + 1))-1;}
1546
1580
  }
1547
1581
  }
1548
- #line 501 "parser.rl"
1582
+ #line 535 "parser.rl"
1549
1583
  { p--; {p++; cs = 8; goto _out;} }
1550
1584
  goto st8;
1551
1585
  st8:
1552
1586
  if ( ++p == pe )
1553
1587
  goto _test_eof8;
1554
1588
  case 8:
1555
- #line 1556 "parser.c"
1589
+ #line 1590 "parser.c"
1556
1590
  goto st0;
1557
1591
  st3:
1558
1592
  if ( ++p == pe )
@@ -1560,7 +1594,7 @@ st3:
1560
1594
  case 3:
1561
1595
  if ( (*p) == 117 )
1562
1596
  goto st4;
1563
- if ( 0 <= (*p) && (*p) <= 31 )
1597
+ if ( 0 <= (signed char)(*p) && (*p) <= 31 )
1564
1598
  goto st0;
1565
1599
  goto st2;
1566
1600
  st4:
@@ -1628,7 +1662,7 @@ case 7:
1628
1662
  _out: {}
1629
1663
  }
1630
1664
 
1631
- #line 527 "parser.rl"
1665
+ #line 561 "parser.rl"
1632
1666
 
1633
1667
  if (json->create_additions && RTEST(match_string = json->match_string)) {
1634
1668
  VALUE klass;
@@ -1643,7 +1677,7 @@ case 7:
1643
1677
 
1644
1678
  if (json->symbolize_names && json->parsing_name) {
1645
1679
  *result = rb_str_intern(*result);
1646
- } else {
1680
+ } else if (RB_TYPE_P(*result, T_STRING)) {
1647
1681
  rb_str_resize(*result, RSTRING_LEN(*result));
1648
1682
  }
1649
1683
  if (cs >= JSON_string_first_final) {
@@ -1781,6 +1815,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1781
1815
  } else {
1782
1816
  json->array_class = Qnil;
1783
1817
  }
1818
+ tmp = ID2SYM(i_decimal_class);
1819
+ if (option_given_p(opts, tmp)) {
1820
+ json->decimal_class = rb_hash_aref(opts, tmp);
1821
+ } else {
1822
+ json->decimal_class = Qnil;
1823
+ }
1784
1824
  tmp = ID2SYM(i_match_string);
1785
1825
  if (option_given_p(opts, tmp)) {
1786
1826
  VALUE match_string = rb_hash_aref(opts, tmp);
@@ -1794,10 +1834,11 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1794
1834
  } else {
1795
1835
  json->max_nesting = 100;
1796
1836
  json->allow_nan = 0;
1797
- json->create_additions = 1;
1837
+ json->create_additions = 0;
1798
1838
  json->create_id = rb_funcall(mJSON, i_create_id, 0);
1799
1839
  json->object_class = Qnil;
1800
1840
  json->array_class = Qnil;
1841
+ json->decimal_class = Qnil;
1801
1842
  }
1802
1843
  source = convert_encoding(StringValue(source));
1803
1844
  StringValue(source);
@@ -1808,7 +1849,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1808
1849
  }
1809
1850
 
1810
1851
 
1811
- #line 1812 "parser.c"
1852
+ #line 1853 "parser.c"
1812
1853
  enum {JSON_start = 1};
1813
1854
  enum {JSON_first_final = 10};
1814
1855
  enum {JSON_error = 0};
@@ -1816,7 +1857,7 @@ enum {JSON_error = 0};
1816
1857
  enum {JSON_en_main = 1};
1817
1858
 
1818
1859
 
1819
- #line 720 "parser.rl"
1860
+ #line 761 "parser.rl"
1820
1861
 
1821
1862
 
1822
1863
  /*
@@ -1833,16 +1874,16 @@ static VALUE cParser_parse(VALUE self)
1833
1874
  GET_PARSER;
1834
1875
 
1835
1876
 
1836
- #line 1837 "parser.c"
1877
+ #line 1878 "parser.c"
1837
1878
  {
1838
1879
  cs = JSON_start;
1839
1880
  }
1840
1881
 
1841
- #line 736 "parser.rl"
1882
+ #line 777 "parser.rl"
1842
1883
  p = json->source;
1843
1884
  pe = p + json->len;
1844
1885
 
1845
- #line 1846 "parser.c"
1886
+ #line 1887 "parser.c"
1846
1887
  {
1847
1888
  if ( p == pe )
1848
1889
  goto _test_eof;
@@ -1876,7 +1917,7 @@ st0:
1876
1917
  cs = 0;
1877
1918
  goto _out;
1878
1919
  tr2:
1879
- #line 712 "parser.rl"
1920
+ #line 753 "parser.rl"
1880
1921
  {
1881
1922
  char *np = JSON_parse_value(json, p, pe, &result, 0);
1882
1923
  if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
@@ -1886,7 +1927,7 @@ st10:
1886
1927
  if ( ++p == pe )
1887
1928
  goto _test_eof10;
1888
1929
  case 10:
1889
- #line 1890 "parser.c"
1930
+ #line 1931 "parser.c"
1890
1931
  switch( (*p) ) {
1891
1932
  case 13: goto st10;
1892
1933
  case 32: goto st10;
@@ -1975,7 +2016,7 @@ case 9:
1975
2016
  _out: {}
1976
2017
  }
1977
2018
 
1978
- #line 739 "parser.rl"
2019
+ #line 780 "parser.rl"
1979
2020
 
1980
2021
  if (cs >= JSON_first_final && p == pe) {
1981
2022
  return result;
@@ -1992,6 +2033,7 @@ static void JSON_mark(void *ptr)
1992
2033
  rb_gc_mark_maybe(json->create_id);
1993
2034
  rb_gc_mark_maybe(json->object_class);
1994
2035
  rb_gc_mark_maybe(json->array_class);
2036
+ rb_gc_mark_maybe(json->decimal_class);
1995
2037
  rb_gc_mark_maybe(json->match_string);
1996
2038
  }
1997
2039
 
@@ -2041,20 +2083,28 @@ static VALUE cParser_source(VALUE self)
2041
2083
 
2042
2084
  void Init_parser(void)
2043
2085
  {
2086
+ #undef rb_intern
2044
2087
  rb_require("json/common");
2045
2088
  mJSON = rb_define_module("JSON");
2046
2089
  mExt = rb_define_module_under(mJSON, "Ext");
2047
2090
  cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
2048
2091
  eParserError = rb_path2class("JSON::ParserError");
2049
2092
  eNestingError = rb_path2class("JSON::NestingError");
2093
+ rb_gc_register_mark_object(eParserError);
2094
+ rb_gc_register_mark_object(eNestingError);
2050
2095
  rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
2051
2096
  rb_define_method(cParser, "initialize", cParser_initialize, -1);
2052
2097
  rb_define_method(cParser, "parse", cParser_parse, 0);
2053
2098
  rb_define_method(cParser, "source", cParser_source, 0);
2054
2099
 
2055
2100
  CNaN = rb_const_get(mJSON, rb_intern("NaN"));
2101
+ rb_gc_register_mark_object(CNaN);
2102
+
2056
2103
  CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
2104
+ rb_gc_register_mark_object(CInfinity);
2105
+
2057
2106
  CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
2107
+ rb_gc_register_mark_object(CMinusInfinity);
2058
2108
 
2059
2109
  i_json_creatable_p = rb_intern("json_creatable?");
2060
2110
  i_json_create = rb_intern("json_create");
@@ -2066,6 +2116,7 @@ void Init_parser(void)
2066
2116
  i_symbolize_names = rb_intern("symbolize_names");
2067
2117
  i_object_class = rb_intern("object_class");
2068
2118
  i_array_class = rb_intern("array_class");
2119
+ i_decimal_class = rb_intern("decimal_class");
2069
2120
  i_match = rb_intern("match");
2070
2121
  i_match_string = rb_intern("match_string");
2071
2122
  i_key_p = rb_intern("key?");
@@ -2073,6 +2124,8 @@ void Init_parser(void)
2073
2124
  i_aset = rb_intern("[]=");
2074
2125
  i_aref = rb_intern("[]");
2075
2126
  i_leftshift = rb_intern("<<");
2127
+ i_new = rb_intern("new");
2128
+ i_BigDecimal = rb_intern("BigDecimal");
2076
2129
  }
2077
2130
 
2078
2131
  /*