json 1.0.0 → 2.7.2

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.
Files changed (109) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES.md +503 -0
  3. data/LICENSE +56 -0
  4. data/README.md +416 -0
  5. data/ext/json/ext/fbuffer/fbuffer.h +187 -0
  6. data/ext/json/ext/generator/depend +1 -0
  7. data/ext/json/ext/generator/extconf.rb +2 -7
  8. data/ext/json/ext/generator/generator.c +1312 -338
  9. data/ext/json/ext/generator/generator.h +177 -0
  10. data/ext/json/ext/parser/depend +1 -0
  11. data/ext/json/ext/parser/extconf.rb +28 -5
  12. data/ext/json/ext/parser/parser.c +1349 -689
  13. data/ext/json/ext/parser/parser.h +96 -0
  14. data/ext/json/ext/parser/parser.rl +644 -188
  15. data/ext/json/extconf.rb +3 -0
  16. data/json.gemspec +68 -0
  17. data/lib/json/add/bigdecimal.rb +58 -0
  18. data/lib/json/add/complex.rb +51 -0
  19. data/lib/json/add/core.rb +12 -0
  20. data/lib/json/add/date.rb +54 -0
  21. data/lib/json/add/date_time.rb +67 -0
  22. data/lib/json/add/exception.rb +49 -0
  23. data/lib/json/add/ostruct.rb +54 -0
  24. data/lib/json/add/range.rb +54 -0
  25. data/lib/json/add/rational.rb +49 -0
  26. data/lib/json/add/regexp.rb +48 -0
  27. data/lib/json/add/set.rb +48 -0
  28. data/lib/json/add/struct.rb +52 -0
  29. data/lib/json/add/symbol.rb +48 -0
  30. data/lib/json/add/time.rb +59 -0
  31. data/lib/json/common.rb +588 -74
  32. data/lib/json/ext.rb +3 -1
  33. data/lib/json/generic_object.rb +75 -0
  34. data/lib/json/pure/generator.rb +311 -119
  35. data/lib/json/pure/parser.rb +182 -55
  36. data/lib/json/pure.rb +5 -65
  37. data/lib/json/version.rb +2 -1
  38. data/lib/json.rb +583 -196
  39. metadata +78 -137
  40. data/CHANGES +0 -25
  41. data/GPL +0 -340
  42. data/README +0 -77
  43. data/Rakefile +0 -250
  44. data/TODO +0 -1
  45. data/VERSION +0 -1
  46. data/benchmarks/benchmark.txt +0 -133
  47. data/benchmarks/benchmark_generator.rb +0 -44
  48. data/benchmarks/benchmark_parser.rb +0 -22
  49. data/benchmarks/benchmark_rails.rb +0 -26
  50. data/bin/edit_json.rb +0 -11
  51. data/data/example.json +0 -1
  52. data/data/index.html +0 -37
  53. data/data/prototype.js +0 -2515
  54. data/ext/json/ext/generator/Makefile +0 -149
  55. data/ext/json/ext/generator/unicode.c +0 -184
  56. data/ext/json/ext/generator/unicode.h +0 -40
  57. data/ext/json/ext/parser/Makefile +0 -149
  58. data/ext/json/ext/parser/unicode.c +0 -156
  59. data/ext/json/ext/parser/unicode.h +0 -44
  60. data/install.rb +0 -26
  61. data/lib/json/Array.xpm +0 -21
  62. data/lib/json/FalseClass.xpm +0 -21
  63. data/lib/json/Hash.xpm +0 -21
  64. data/lib/json/Key.xpm +0 -73
  65. data/lib/json/NilClass.xpm +0 -21
  66. data/lib/json/Numeric.xpm +0 -28
  67. data/lib/json/String.xpm +0 -96
  68. data/lib/json/TrueClass.xpm +0 -21
  69. data/lib/json/editor.rb +0 -1207
  70. data/lib/json/json.xpm +0 -1499
  71. data/tests/fixtures/fail1.json +0 -1
  72. data/tests/fixtures/fail10.json +0 -1
  73. data/tests/fixtures/fail11.json +0 -1
  74. data/tests/fixtures/fail12.json +0 -1
  75. data/tests/fixtures/fail13.json +0 -1
  76. data/tests/fixtures/fail14.json +0 -1
  77. data/tests/fixtures/fail15.json +0 -1
  78. data/tests/fixtures/fail16.json +0 -1
  79. data/tests/fixtures/fail17.json +0 -1
  80. data/tests/fixtures/fail19.json +0 -1
  81. data/tests/fixtures/fail2.json +0 -1
  82. data/tests/fixtures/fail20.json +0 -1
  83. data/tests/fixtures/fail21.json +0 -1
  84. data/tests/fixtures/fail22.json +0 -1
  85. data/tests/fixtures/fail23.json +0 -1
  86. data/tests/fixtures/fail24.json +0 -1
  87. data/tests/fixtures/fail25.json +0 -1
  88. data/tests/fixtures/fail26.json +0 -1
  89. data/tests/fixtures/fail27.json +0 -2
  90. data/tests/fixtures/fail28.json +0 -2
  91. data/tests/fixtures/fail3.json +0 -1
  92. data/tests/fixtures/fail4.json +0 -1
  93. data/tests/fixtures/fail5.json +0 -1
  94. data/tests/fixtures/fail6.json +0 -1
  95. data/tests/fixtures/fail7.json +0 -1
  96. data/tests/fixtures/fail8.json +0 -1
  97. data/tests/fixtures/fail9.json +0 -1
  98. data/tests/fixtures/pass1.json +0 -56
  99. data/tests/fixtures/pass18.json +0 -1
  100. data/tests/fixtures/pass2.json +0 -1
  101. data/tests/fixtures/pass3.json +0 -6
  102. data/tests/runner.rb +0 -24
  103. data/tests/test_json.rb +0 -235
  104. data/tests/test_json_addition.rb +0 -94
  105. data/tests/test_json_fixtures.rb +0 -30
  106. data/tests/test_json_generate.rb +0 -81
  107. data/tests/test_json_unicode.rb +0 -55
  108. data/tools/fuzz.rb +0 -133
  109. data/tools/server.rb +0 -62
@@ -1,104 +1,181 @@
1
+ /* This file is automatically generated from parser.rl by using ragel */
1
2
  #line 1 "parser.rl"
2
- /* vim: set cin et sw=4 ts=4: */
3
+ #include "../fbuffer/fbuffer.h"
4
+ #include "parser.h"
5
+
6
+ #if defined HAVE_RUBY_ENCODING_H
7
+ # define EXC_ENCODING rb_utf8_encoding(),
8
+ # ifndef HAVE_RB_ENC_RAISE
9
+ static void
10
+ enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
11
+ {
12
+ va_list args;
13
+ VALUE mesg;
3
14
 
4
- #include "ruby.h"
5
- #include "re.h"
6
- #include "unicode.h"
15
+ va_start(args, fmt);
16
+ mesg = rb_enc_vsprintf(enc, fmt, args);
17
+ va_end(args);
7
18
 
8
- #ifndef swap16
9
- #define swap16(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
19
+ rb_exc_raise(rb_exc_new3(exc, mesg));
20
+ }
21
+ # define rb_enc_raise enc_raise
22
+ # endif
23
+ #else
24
+ # define EXC_ENCODING /* nothing */
25
+ # define rb_enc_raise rb_raise
10
26
  #endif
11
27
 
12
- #define EVIL 0x666
13
-
14
- static VALUE mJSON, mExt, cParser, eParserError;
28
+ /* unicode */
29
+
30
+ static const signed char digit_values[256] = {
31
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
32
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
33
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
34
+ -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1,
35
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
36
+ 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
37
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
38
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
39
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
40
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
41
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
42
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
43
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
44
+ -1, -1, -1, -1, -1, -1, -1
45
+ };
46
+
47
+ static UTF32 unescape_unicode(const unsigned char *p)
48
+ {
49
+ signed char b;
50
+ UTF32 result = 0;
51
+ b = digit_values[p[0]];
52
+ if (b < 0) return UNI_REPLACEMENT_CHAR;
53
+ result = (result << 4) | (unsigned char)b;
54
+ b = digit_values[p[1]];
55
+ if (b < 0) return UNI_REPLACEMENT_CHAR;
56
+ result = (result << 4) | (unsigned char)b;
57
+ b = digit_values[p[2]];
58
+ if (b < 0) return UNI_REPLACEMENT_CHAR;
59
+ result = (result << 4) | (unsigned char)b;
60
+ b = digit_values[p[3]];
61
+ if (b < 0) return UNI_REPLACEMENT_CHAR;
62
+ result = (result << 4) | (unsigned char)b;
63
+ return result;
64
+ }
15
65
 
16
- static ID i_json_creatable_p, i_json_create, i_create_id, i_chr;
66
+ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
67
+ {
68
+ int len = 1;
69
+ if (ch <= 0x7F) {
70
+ buf[0] = (char) ch;
71
+ } else if (ch <= 0x07FF) {
72
+ buf[0] = (char) ((ch >> 6) | 0xC0);
73
+ buf[1] = (char) ((ch & 0x3F) | 0x80);
74
+ len++;
75
+ } else if (ch <= 0xFFFF) {
76
+ buf[0] = (char) ((ch >> 12) | 0xE0);
77
+ buf[1] = (char) (((ch >> 6) & 0x3F) | 0x80);
78
+ buf[2] = (char) ((ch & 0x3F) | 0x80);
79
+ len += 2;
80
+ } else if (ch <= 0x1fffff) {
81
+ buf[0] =(char) ((ch >> 18) | 0xF0);
82
+ buf[1] =(char) (((ch >> 12) & 0x3F) | 0x80);
83
+ buf[2] =(char) (((ch >> 6) & 0x3F) | 0x80);
84
+ buf[3] =(char) ((ch & 0x3F) | 0x80);
85
+ len += 3;
86
+ } else {
87
+ buf[0] = '?';
88
+ }
89
+ return len;
90
+ }
17
91
 
18
- typedef struct JSON_ParserStruct {
19
- VALUE Vsource;
20
- char *source;
21
- long len;
22
- char *memo;
23
- VALUE create_id;
24
- } JSON_Parser;
92
+ static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
93
+ static VALUE CNaN, CInfinity, CMinusInfinity;
25
94
 
26
- static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result);
27
- static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result);
28
- static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result);
29
- static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
30
- static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result);
31
- static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result);
95
+ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
96
+ i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
97
+ i_object_class, i_array_class, i_decimal_class, i_key_p,
98
+ i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
99
+ i_leftshift, i_new, i_try_convert, i_freeze, i_uminus;
32
100
 
33
- #define GET_STRUCT \
34
- JSON_Parser *json; \
35
- Data_Get_Struct(self, JSON_Parser, json);
36
101
 
37
- #line 59 "parser.rl"
102
+ #line 125 "parser.rl"
38
103
 
39
104
 
40
105
 
41
- #line 42 "parser.c"
42
- static const int JSON_object_start = 0;
106
+ #line 107 "parser.c"
107
+ enum {JSON_object_start = 1};
108
+ enum {JSON_object_first_final = 27};
109
+ enum {JSON_object_error = 0};
43
110
 
44
- static const int JSON_object_first_final = 27;
111
+ enum {JSON_object_en_main = 1};
45
112
 
46
- static const int JSON_object_error = 1;
47
113
 
48
- #line 92 "parser.rl"
114
+ #line 167 "parser.rl"
49
115
 
50
116
 
51
- static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
117
+ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
52
118
  {
53
119
  int cs = EVIL;
54
120
  VALUE last_name = Qnil;
55
- *result = rb_hash_new();
121
+ VALUE object_class = json->object_class;
122
+
123
+ if (json->max_nesting && current_nesting > json->max_nesting) {
124
+ rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
125
+ }
126
+
127
+ *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
56
128
 
57
-
58
- #line 59 "parser.c"
129
+
130
+ #line 131 "parser.c"
59
131
  {
60
132
  cs = JSON_object_start;
61
133
  }
62
- #line 101 "parser.rl"
63
-
64
- #line 65 "parser.c"
134
+
135
+ #line 182 "parser.rl"
136
+
137
+ #line 138 "parser.c"
65
138
  {
66
139
  if ( p == pe )
67
- goto _out;
140
+ goto _test_eof;
68
141
  switch ( cs )
69
142
  {
70
- case 0:
143
+ case 1:
71
144
  if ( (*p) == 123 )
72
145
  goto st2;
73
- goto st1;
74
- st1:
75
- goto _out1;
146
+ goto st0;
147
+ st0:
148
+ cs = 0;
149
+ goto _out;
76
150
  st2:
77
151
  if ( ++p == pe )
78
- goto _out2;
152
+ goto _test_eof2;
79
153
  case 2:
80
154
  switch( (*p) ) {
81
155
  case 13: goto st2;
82
156
  case 32: goto st2;
83
- case 34: goto tr13;
157
+ case 34: goto tr2;
84
158
  case 47: goto st23;
85
- case 125: goto tr10;
159
+ case 125: goto tr4;
86
160
  }
87
161
  if ( 9 <= (*p) && (*p) <= 10 )
88
162
  goto st2;
89
- goto st1;
90
- tr13:
91
- #line 78 "parser.rl"
163
+ goto st0;
164
+ tr2:
165
+ #line 149 "parser.rl"
92
166
  {
93
- char *np = JSON_parse_string(json, p, pe, &last_name);
94
- if (np == NULL) goto _out3; else {p = (( np))-1;}
167
+ char *np;
168
+ json->parsing_name = 1;
169
+ np = JSON_parse_string(json, p, pe, &last_name);
170
+ json->parsing_name = 0;
171
+ if (np == NULL) { p--; {p++; cs = 3; goto _out;} } else {p = (( np))-1;}
95
172
  }
96
173
  goto st3;
97
174
  st3:
98
175
  if ( ++p == pe )
99
- goto _out3;
176
+ goto _test_eof3;
100
177
  case 3:
101
- #line 102 "parser.c"
178
+ #line 179 "parser.c"
102
179
  switch( (*p) ) {
103
180
  case 13: goto st3;
104
181
  case 32: goto st3;
@@ -107,26 +184,26 @@ case 3:
107
184
  }
108
185
  if ( 9 <= (*p) && (*p) <= 10 )
109
186
  goto st3;
110
- goto st1;
187
+ goto st0;
111
188
  st4:
112
189
  if ( ++p == pe )
113
- goto _out4;
190
+ goto _test_eof4;
114
191
  case 4:
115
192
  switch( (*p) ) {
116
193
  case 42: goto st5;
117
194
  case 47: goto st7;
118
195
  }
119
- goto st1;
196
+ goto st0;
120
197
  st5:
121
198
  if ( ++p == pe )
122
- goto _out5;
199
+ goto _test_eof5;
123
200
  case 5:
124
201
  if ( (*p) == 42 )
125
202
  goto st6;
126
203
  goto st5;
127
204
  st6:
128
205
  if ( ++p == pe )
129
- goto _out6;
206
+ goto _test_eof6;
130
207
  case 6:
131
208
  switch( (*p) ) {
132
209
  case 42: goto st6;
@@ -135,14 +212,14 @@ case 6:
135
212
  goto st5;
136
213
  st7:
137
214
  if ( ++p == pe )
138
- goto _out7;
215
+ goto _test_eof7;
139
216
  case 7:
140
217
  if ( (*p) == 10 )
141
218
  goto st3;
142
219
  goto st7;
143
220
  st8:
144
221
  if ( ++p == pe )
145
- goto _out8;
222
+ goto _test_eof8;
146
223
  case 8:
147
224
  switch( (*p) ) {
148
225
  case 13: goto st8;
@@ -150,6 +227,8 @@ case 8:
150
227
  case 34: goto tr11;
151
228
  case 45: goto tr11;
152
229
  case 47: goto st19;
230
+ case 73: goto tr11;
231
+ case 78: goto tr11;
153
232
  case 91: goto tr11;
154
233
  case 102: goto tr11;
155
234
  case 110: goto tr11;
@@ -161,67 +240,72 @@ case 8:
161
240
  goto tr11;
162
241
  } else if ( (*p) >= 9 )
163
242
  goto st8;
164
- goto st1;
243
+ goto st0;
165
244
  tr11:
166
- #line 67 "parser.rl"
245
+ #line 133 "parser.rl"
167
246
  {
168
247
  VALUE v = Qnil;
169
- char *np = JSON_parse_value(json, p, pe, &v);
248
+ char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
170
249
  if (np == NULL) {
171
- goto _out9;
250
+ p--; {p++; cs = 9; goto _out;}
172
251
  } else {
173
- rb_hash_aset(*result, last_name, v);
252
+ if (NIL_P(json->object_class)) {
253
+ OBJ_FREEZE(last_name);
254
+ rb_hash_aset(*result, last_name, v);
255
+ } else {
256
+ rb_funcall(*result, i_aset, 2, last_name, v);
257
+ }
174
258
  {p = (( np))-1;}
175
259
  }
176
260
  }
177
261
  goto st9;
178
262
  st9:
179
263
  if ( ++p == pe )
180
- goto _out9;
264
+ goto _test_eof9;
181
265
  case 9:
182
- #line 183 "parser.c"
266
+ #line 267 "parser.c"
183
267
  switch( (*p) ) {
184
268
  case 13: goto st9;
185
269
  case 32: goto st9;
186
270
  case 44: goto st10;
187
271
  case 47: goto st15;
188
- case 125: goto tr10;
272
+ case 125: goto tr4;
189
273
  }
190
274
  if ( 9 <= (*p) && (*p) <= 10 )
191
275
  goto st9;
192
- goto st1;
276
+ goto st0;
193
277
  st10:
194
278
  if ( ++p == pe )
195
- goto _out10;
279
+ goto _test_eof10;
196
280
  case 10:
197
281
  switch( (*p) ) {
198
282
  case 13: goto st10;
199
283
  case 32: goto st10;
200
- case 34: goto tr13;
284
+ case 34: goto tr2;
201
285
  case 47: goto st11;
202
286
  }
203
287
  if ( 9 <= (*p) && (*p) <= 10 )
204
288
  goto st10;
205
- goto st1;
289
+ goto st0;
206
290
  st11:
207
291
  if ( ++p == pe )
208
- goto _out11;
292
+ goto _test_eof11;
209
293
  case 11:
210
294
  switch( (*p) ) {
211
295
  case 42: goto st12;
212
296
  case 47: goto st14;
213
297
  }
214
- goto st1;
298
+ goto st0;
215
299
  st12:
216
300
  if ( ++p == pe )
217
- goto _out12;
301
+ goto _test_eof12;
218
302
  case 12:
219
303
  if ( (*p) == 42 )
220
304
  goto st13;
221
305
  goto st12;
222
306
  st13:
223
307
  if ( ++p == pe )
224
- goto _out13;
308
+ goto _test_eof13;
225
309
  case 13:
226
310
  switch( (*p) ) {
227
311
  case 42: goto st13;
@@ -230,30 +314,30 @@ case 13:
230
314
  goto st12;
231
315
  st14:
232
316
  if ( ++p == pe )
233
- goto _out14;
317
+ goto _test_eof14;
234
318
  case 14:
235
319
  if ( (*p) == 10 )
236
320
  goto st10;
237
321
  goto st14;
238
322
  st15:
239
323
  if ( ++p == pe )
240
- goto _out15;
324
+ goto _test_eof15;
241
325
  case 15:
242
326
  switch( (*p) ) {
243
327
  case 42: goto st16;
244
328
  case 47: goto st18;
245
329
  }
246
- goto st1;
330
+ goto st0;
247
331
  st16:
248
332
  if ( ++p == pe )
249
- goto _out16;
333
+ goto _test_eof16;
250
334
  case 16:
251
335
  if ( (*p) == 42 )
252
336
  goto st17;
253
337
  goto st16;
254
338
  st17:
255
339
  if ( ++p == pe )
256
- goto _out17;
340
+ goto _test_eof17;
257
341
  case 17:
258
342
  switch( (*p) ) {
259
343
  case 42: goto st17;
@@ -262,40 +346,40 @@ case 17:
262
346
  goto st16;
263
347
  st18:
264
348
  if ( ++p == pe )
265
- goto _out18;
349
+ goto _test_eof18;
266
350
  case 18:
267
351
  if ( (*p) == 10 )
268
352
  goto st9;
269
353
  goto st18;
270
- tr10:
271
- #line 83 "parser.rl"
272
- { goto _out27; }
354
+ tr4:
355
+ #line 157 "parser.rl"
356
+ { p--; {p++; cs = 27; goto _out;} }
273
357
  goto st27;
274
358
  st27:
275
359
  if ( ++p == pe )
276
- goto _out27;
360
+ goto _test_eof27;
277
361
  case 27:
278
- #line 279 "parser.c"
279
- goto st1;
362
+ #line 363 "parser.c"
363
+ goto st0;
280
364
  st19:
281
365
  if ( ++p == pe )
282
- goto _out19;
366
+ goto _test_eof19;
283
367
  case 19:
284
368
  switch( (*p) ) {
285
369
  case 42: goto st20;
286
370
  case 47: goto st22;
287
371
  }
288
- goto st1;
372
+ goto st0;
289
373
  st20:
290
374
  if ( ++p == pe )
291
- goto _out20;
375
+ goto _test_eof20;
292
376
  case 20:
293
377
  if ( (*p) == 42 )
294
378
  goto st21;
295
379
  goto st20;
296
380
  st21:
297
381
  if ( ++p == pe )
298
- goto _out21;
382
+ goto _test_eof21;
299
383
  case 21:
300
384
  switch( (*p) ) {
301
385
  case 42: goto st21;
@@ -304,30 +388,30 @@ case 21:
304
388
  goto st20;
305
389
  st22:
306
390
  if ( ++p == pe )
307
- goto _out22;
391
+ goto _test_eof22;
308
392
  case 22:
309
393
  if ( (*p) == 10 )
310
394
  goto st8;
311
395
  goto st22;
312
396
  st23:
313
397
  if ( ++p == pe )
314
- goto _out23;
398
+ goto _test_eof23;
315
399
  case 23:
316
400
  switch( (*p) ) {
317
401
  case 42: goto st24;
318
402
  case 47: goto st26;
319
403
  }
320
- goto st1;
404
+ goto st0;
321
405
  st24:
322
406
  if ( ++p == pe )
323
- goto _out24;
407
+ goto _test_eof24;
324
408
  case 24:
325
409
  if ( (*p) == 42 )
326
410
  goto st25;
327
411
  goto st24;
328
412
  st25:
329
413
  if ( ++p == pe )
330
- goto _out25;
414
+ goto _test_eof25;
331
415
  case 25:
332
416
  switch( (*p) ) {
333
417
  case 42: goto st25;
@@ -336,50 +420,58 @@ case 25:
336
420
  goto st24;
337
421
  st26:
338
422
  if ( ++p == pe )
339
- goto _out26;
423
+ goto _test_eof26;
340
424
  case 26:
341
425
  if ( (*p) == 10 )
342
426
  goto st2;
343
427
  goto st26;
344
428
  }
345
- _out1: cs = 1; goto _out;
346
- _out2: cs = 2; goto _out;
347
- _out3: cs = 3; goto _out;
348
- _out4: cs = 4; goto _out;
349
- _out5: cs = 5; goto _out;
350
- _out6: cs = 6; goto _out;
351
- _out7: cs = 7; goto _out;
352
- _out8: cs = 8; goto _out;
353
- _out9: cs = 9; goto _out;
354
- _out10: cs = 10; goto _out;
355
- _out11: cs = 11; goto _out;
356
- _out12: cs = 12; goto _out;
357
- _out13: cs = 13; goto _out;
358
- _out14: cs = 14; goto _out;
359
- _out15: cs = 15; goto _out;
360
- _out16: cs = 16; goto _out;
361
- _out17: cs = 17; goto _out;
362
- _out18: cs = 18; goto _out;
363
- _out27: cs = 27; goto _out;
364
- _out19: cs = 19; goto _out;
365
- _out20: cs = 20; goto _out;
366
- _out21: cs = 21; goto _out;
367
- _out22: cs = 22; goto _out;
368
- _out23: cs = 23; goto _out;
369
- _out24: cs = 24; goto _out;
370
- _out25: cs = 25; goto _out;
371
- _out26: cs = 26; goto _out;
372
-
429
+ _test_eof2: cs = 2; goto _test_eof;
430
+ _test_eof3: cs = 3; goto _test_eof;
431
+ _test_eof4: cs = 4; goto _test_eof;
432
+ _test_eof5: cs = 5; goto _test_eof;
433
+ _test_eof6: cs = 6; goto _test_eof;
434
+ _test_eof7: cs = 7; goto _test_eof;
435
+ _test_eof8: cs = 8; goto _test_eof;
436
+ _test_eof9: cs = 9; goto _test_eof;
437
+ _test_eof10: cs = 10; goto _test_eof;
438
+ _test_eof11: cs = 11; goto _test_eof;
439
+ _test_eof12: cs = 12; goto _test_eof;
440
+ _test_eof13: cs = 13; goto _test_eof;
441
+ _test_eof14: cs = 14; goto _test_eof;
442
+ _test_eof15: cs = 15; goto _test_eof;
443
+ _test_eof16: cs = 16; goto _test_eof;
444
+ _test_eof17: cs = 17; goto _test_eof;
445
+ _test_eof18: cs = 18; goto _test_eof;
446
+ _test_eof27: cs = 27; goto _test_eof;
447
+ _test_eof19: cs = 19; goto _test_eof;
448
+ _test_eof20: cs = 20; goto _test_eof;
449
+ _test_eof21: cs = 21; goto _test_eof;
450
+ _test_eof22: cs = 22; goto _test_eof;
451
+ _test_eof23: cs = 23; goto _test_eof;
452
+ _test_eof24: cs = 24; goto _test_eof;
453
+ _test_eof25: cs = 25; goto _test_eof;
454
+ _test_eof26: cs = 26; goto _test_eof;
455
+
456
+ _test_eof: {}
373
457
  _out: {}
374
458
  }
375
- #line 102 "parser.rl"
459
+
460
+ #line 183 "parser.rl"
376
461
 
377
462
  if (cs >= JSON_object_first_final) {
378
- VALUE klassname = rb_hash_aref(*result, json->create_id);
379
- if (!NIL_P(klassname)) {
380
- VALUE klass = rb_path2class(StringValueCStr(klassname));
381
- if RTEST(rb_funcall(klass, i_json_creatable_p, 0)) {
382
- *result = rb_funcall(klass, i_json_create, 1, *result);
463
+ if (json->create_additions) {
464
+ VALUE klassname;
465
+ if (NIL_P(json->object_class)) {
466
+ klassname = rb_hash_aref(*result, json->create_id);
467
+ } else {
468
+ klassname = rb_funcall(*result, i_aref, 1, json->create_id);
469
+ }
470
+ if (!NIL_P(klassname)) {
471
+ VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname);
472
+ if (RTEST(rb_funcall(klass, i_json_creatable_p, 0))) {
473
+ *result = rb_funcall(klass, i_json_create, 1, *result);
474
+ }
383
475
  }
384
476
  }
385
477
  return p + 1;
@@ -389,193 +481,396 @@ case 26:
389
481
  }
390
482
 
391
483
 
392
- #line 393 "parser.c"
393
- static const int JSON_value_start = 0;
394
484
 
395
- static const int JSON_value_first_final = 12;
485
+ #line 486 "parser.c"
486
+ enum {JSON_value_start = 1};
487
+ enum {JSON_value_first_final = 29};
488
+ enum {JSON_value_error = 0};
396
489
 
397
- static const int JSON_value_error = 1;
490
+ enum {JSON_value_en_main = 1};
398
491
 
399
- #line 167 "parser.rl"
492
+
493
+ #line 283 "parser.rl"
400
494
 
401
495
 
402
- static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
496
+ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
403
497
  {
404
498
  int cs = EVIL;
405
499
 
406
-
407
- #line 408 "parser.c"
500
+
501
+ #line 502 "parser.c"
408
502
  {
409
503
  cs = JSON_value_start;
410
504
  }
411
- #line 174 "parser.rl"
412
-
413
- #line 414 "parser.c"
505
+
506
+ #line 290 "parser.rl"
507
+
508
+ #line 509 "parser.c"
414
509
  {
415
510
  if ( p == pe )
416
- goto _out;
511
+ goto _test_eof;
417
512
  switch ( cs )
418
513
  {
419
- case 0:
514
+ st1:
515
+ if ( ++p == pe )
516
+ goto _test_eof1;
517
+ case 1:
420
518
  switch( (*p) ) {
421
- case 34: goto tr9;
422
- case 45: goto tr10;
423
- case 91: goto tr11;
424
- case 102: goto st2;
425
- case 110: goto st6;
426
- case 116: goto st9;
427
- case 123: goto tr15;
519
+ case 13: goto st1;
520
+ case 32: goto st1;
521
+ case 34: goto tr2;
522
+ case 45: goto tr3;
523
+ case 47: goto st6;
524
+ case 73: goto st10;
525
+ case 78: goto st17;
526
+ case 91: goto tr7;
527
+ case 102: goto st19;
528
+ case 110: goto st23;
529
+ case 116: goto st26;
530
+ case 123: goto tr11;
428
531
  }
429
- if ( 48 <= (*p) && (*p) <= 57 )
430
- goto tr10;
431
- goto st1;
432
- st1:
433
- goto _out1;
434
- tr5:
435
- #line 123 "parser.rl"
436
- {
437
- *result = Qnil;
438
- }
439
- goto st12;
440
- tr6:
441
- #line 126 "parser.rl"
442
- {
443
- *result = Qfalse;
444
- }
445
- goto st12;
446
- tr7:
447
- #line 129 "parser.rl"
448
- {
449
- *result = Qtrue;
450
- }
451
- goto st12;
452
- tr9:
453
- #line 132 "parser.rl"
532
+ if ( (*p) > 10 ) {
533
+ if ( 48 <= (*p) && (*p) <= 57 )
534
+ goto tr3;
535
+ } else if ( (*p) >= 9 )
536
+ goto st1;
537
+ goto st0;
538
+ st0:
539
+ cs = 0;
540
+ goto _out;
541
+ tr2:
542
+ #line 235 "parser.rl"
454
543
  {
455
544
  char *np = JSON_parse_string(json, p, pe, result);
456
- if (np == NULL) goto _out12; else {p = (( np))-1;}
545
+ if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
457
546
  }
458
- goto st12;
459
- tr10:
460
- #line 137 "parser.rl"
547
+ goto st29;
548
+ tr3:
549
+ #line 240 "parser.rl"
461
550
  {
462
551
  char *np;
552
+ if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) {
553
+ if (json->allow_nan) {
554
+ *result = CMinusInfinity;
555
+ {p = (( p + 10))-1;}
556
+ p--; {p++; cs = 29; goto _out;}
557
+ } else {
558
+ rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p);
559
+ }
560
+ }
463
561
  np = JSON_parse_float(json, p, pe, result);
464
562
  if (np != NULL) {p = (( np))-1;}
465
563
  np = JSON_parse_integer(json, p, pe, result);
466
564
  if (np != NULL) {p = (( np))-1;}
467
- goto _out12;
565
+ p--; {p++; cs = 29; goto _out;}
468
566
  }
469
- goto st12;
567
+ goto st29;
568
+ tr7:
569
+ #line 258 "parser.rl"
570
+ {
571
+ char *np;
572
+ np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
573
+ if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
574
+ }
575
+ goto st29;
470
576
  tr11:
471
- #line 146 "parser.rl"
472
- {
473
- char *np = JSON_parse_array(json, p, pe, result);
474
- if (np == NULL) goto _out12; else {p = (( np))-1;}
577
+ #line 264 "parser.rl"
578
+ {
579
+ char *np;
580
+ np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
581
+ if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
475
582
  }
476
- goto st12;
477
- tr15:
478
- #line 151 "parser.rl"
479
- {
480
- char *np = JSON_parse_object(json, p, pe, result);
481
- if (np == NULL) goto _out12; else {p = (( np))-1;}
583
+ goto st29;
584
+ tr25:
585
+ #line 228 "parser.rl"
586
+ {
587
+ if (json->allow_nan) {
588
+ *result = CInfinity;
589
+ } else {
590
+ rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p - 7);
591
+ }
482
592
  }
483
- goto st12;
484
- st12:
485
- if ( ++p == pe )
486
- goto _out12;
487
- case 12:
488
- #line 156 "parser.rl"
489
- { goto _out12; }
490
- #line 491 "parser.c"
491
- goto st1;
593
+ goto st29;
594
+ tr27:
595
+ #line 221 "parser.rl"
596
+ {
597
+ if (json->allow_nan) {
598
+ *result = CNaN;
599
+ } else {
600
+ rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p - 2);
601
+ }
602
+ }
603
+ goto st29;
604
+ tr31:
605
+ #line 215 "parser.rl"
606
+ {
607
+ *result = Qfalse;
608
+ }
609
+ goto st29;
610
+ tr34:
611
+ #line 212 "parser.rl"
612
+ {
613
+ *result = Qnil;
614
+ }
615
+ goto st29;
616
+ tr37:
617
+ #line 218 "parser.rl"
618
+ {
619
+ *result = Qtrue;
620
+ }
621
+ goto st29;
622
+ st29:
623
+ if ( ++p == pe )
624
+ goto _test_eof29;
625
+ case 29:
626
+ #line 270 "parser.rl"
627
+ { p--; {p++; cs = 29; goto _out;} }
628
+ #line 629 "parser.c"
629
+ switch( (*p) ) {
630
+ case 13: goto st29;
631
+ case 32: goto st29;
632
+ case 47: goto st2;
633
+ }
634
+ if ( 9 <= (*p) && (*p) <= 10 )
635
+ goto st29;
636
+ goto st0;
492
637
  st2:
493
638
  if ( ++p == pe )
494
- goto _out2;
639
+ goto _test_eof2;
495
640
  case 2:
496
- if ( (*p) == 97 )
497
- goto st3;
498
- goto st1;
641
+ switch( (*p) ) {
642
+ case 42: goto st3;
643
+ case 47: goto st5;
644
+ }
645
+ goto st0;
499
646
  st3:
500
647
  if ( ++p == pe )
501
- goto _out3;
648
+ goto _test_eof3;
502
649
  case 3:
503
- if ( (*p) == 108 )
650
+ if ( (*p) == 42 )
504
651
  goto st4;
505
- goto st1;
652
+ goto st3;
506
653
  st4:
507
654
  if ( ++p == pe )
508
- goto _out4;
655
+ goto _test_eof4;
509
656
  case 4:
510
- if ( (*p) == 115 )
511
- goto st5;
512
- goto st1;
657
+ switch( (*p) ) {
658
+ case 42: goto st4;
659
+ case 47: goto st29;
660
+ }
661
+ goto st3;
513
662
  st5:
514
663
  if ( ++p == pe )
515
- goto _out5;
664
+ goto _test_eof5;
516
665
  case 5:
517
- if ( (*p) == 101 )
518
- goto tr6;
519
- goto st1;
666
+ if ( (*p) == 10 )
667
+ goto st29;
668
+ goto st5;
520
669
  st6:
521
670
  if ( ++p == pe )
522
- goto _out6;
671
+ goto _test_eof6;
523
672
  case 6:
524
- if ( (*p) == 117 )
525
- goto st7;
526
- goto st1;
673
+ switch( (*p) ) {
674
+ case 42: goto st7;
675
+ case 47: goto st9;
676
+ }
677
+ goto st0;
527
678
  st7:
528
679
  if ( ++p == pe )
529
- goto _out7;
680
+ goto _test_eof7;
530
681
  case 7:
531
- if ( (*p) == 108 )
682
+ if ( (*p) == 42 )
532
683
  goto st8;
533
- goto st1;
684
+ goto st7;
534
685
  st8:
535
686
  if ( ++p == pe )
536
- goto _out8;
687
+ goto _test_eof8;
537
688
  case 8:
538
- if ( (*p) == 108 )
539
- goto tr5;
540
- goto st1;
689
+ switch( (*p) ) {
690
+ case 42: goto st8;
691
+ case 47: goto st1;
692
+ }
693
+ goto st7;
541
694
  st9:
542
695
  if ( ++p == pe )
543
- goto _out9;
696
+ goto _test_eof9;
544
697
  case 9:
545
- if ( (*p) == 114 )
546
- goto st10;
547
- goto st1;
698
+ if ( (*p) == 10 )
699
+ goto st1;
700
+ goto st9;
548
701
  st10:
549
702
  if ( ++p == pe )
550
- goto _out10;
703
+ goto _test_eof10;
551
704
  case 10:
552
- if ( (*p) == 117 )
705
+ if ( (*p) == 110 )
553
706
  goto st11;
554
- goto st1;
707
+ goto st0;
555
708
  st11:
556
709
  if ( ++p == pe )
557
- goto _out11;
710
+ goto _test_eof11;
558
711
  case 11:
712
+ if ( (*p) == 102 )
713
+ goto st12;
714
+ goto st0;
715
+ st12:
716
+ if ( ++p == pe )
717
+ goto _test_eof12;
718
+ case 12:
719
+ if ( (*p) == 105 )
720
+ goto st13;
721
+ goto st0;
722
+ st13:
723
+ if ( ++p == pe )
724
+ goto _test_eof13;
725
+ case 13:
726
+ if ( (*p) == 110 )
727
+ goto st14;
728
+ goto st0;
729
+ st14:
730
+ if ( ++p == pe )
731
+ goto _test_eof14;
732
+ case 14:
733
+ if ( (*p) == 105 )
734
+ goto st15;
735
+ goto st0;
736
+ st15:
737
+ if ( ++p == pe )
738
+ goto _test_eof15;
739
+ case 15:
740
+ if ( (*p) == 116 )
741
+ goto st16;
742
+ goto st0;
743
+ st16:
744
+ if ( ++p == pe )
745
+ goto _test_eof16;
746
+ case 16:
747
+ if ( (*p) == 121 )
748
+ goto tr25;
749
+ goto st0;
750
+ st17:
751
+ if ( ++p == pe )
752
+ goto _test_eof17;
753
+ case 17:
754
+ if ( (*p) == 97 )
755
+ goto st18;
756
+ goto st0;
757
+ st18:
758
+ if ( ++p == pe )
759
+ goto _test_eof18;
760
+ case 18:
761
+ if ( (*p) == 78 )
762
+ goto tr27;
763
+ goto st0;
764
+ st19:
765
+ if ( ++p == pe )
766
+ goto _test_eof19;
767
+ case 19:
768
+ if ( (*p) == 97 )
769
+ goto st20;
770
+ goto st0;
771
+ st20:
772
+ if ( ++p == pe )
773
+ goto _test_eof20;
774
+ case 20:
775
+ if ( (*p) == 108 )
776
+ goto st21;
777
+ goto st0;
778
+ st21:
779
+ if ( ++p == pe )
780
+ goto _test_eof21;
781
+ case 21:
782
+ if ( (*p) == 115 )
783
+ goto st22;
784
+ goto st0;
785
+ st22:
786
+ if ( ++p == pe )
787
+ goto _test_eof22;
788
+ case 22:
559
789
  if ( (*p) == 101 )
560
- goto tr7;
561
- goto st1;
562
- }
563
- _out1: cs = 1; goto _out;
564
- _out12: cs = 12; goto _out;
565
- _out2: cs = 2; goto _out;
566
- _out3: cs = 3; goto _out;
567
- _out4: cs = 4; goto _out;
568
- _out5: cs = 5; goto _out;
569
- _out6: cs = 6; goto _out;
570
- _out7: cs = 7; goto _out;
571
- _out8: cs = 8; goto _out;
572
- _out9: cs = 9; goto _out;
573
- _out10: cs = 10; goto _out;
574
- _out11: cs = 11; goto _out;
575
-
790
+ goto tr31;
791
+ goto st0;
792
+ st23:
793
+ if ( ++p == pe )
794
+ goto _test_eof23;
795
+ case 23:
796
+ if ( (*p) == 117 )
797
+ goto st24;
798
+ goto st0;
799
+ st24:
800
+ if ( ++p == pe )
801
+ goto _test_eof24;
802
+ case 24:
803
+ if ( (*p) == 108 )
804
+ goto st25;
805
+ goto st0;
806
+ st25:
807
+ if ( ++p == pe )
808
+ goto _test_eof25;
809
+ case 25:
810
+ if ( (*p) == 108 )
811
+ goto tr34;
812
+ goto st0;
813
+ st26:
814
+ if ( ++p == pe )
815
+ goto _test_eof26;
816
+ case 26:
817
+ if ( (*p) == 114 )
818
+ goto st27;
819
+ goto st0;
820
+ st27:
821
+ if ( ++p == pe )
822
+ goto _test_eof27;
823
+ case 27:
824
+ if ( (*p) == 117 )
825
+ goto st28;
826
+ goto st0;
827
+ st28:
828
+ if ( ++p == pe )
829
+ goto _test_eof28;
830
+ case 28:
831
+ if ( (*p) == 101 )
832
+ goto tr37;
833
+ goto st0;
834
+ }
835
+ _test_eof1: cs = 1; goto _test_eof;
836
+ _test_eof29: cs = 29; goto _test_eof;
837
+ _test_eof2: cs = 2; goto _test_eof;
838
+ _test_eof3: cs = 3; goto _test_eof;
839
+ _test_eof4: cs = 4; goto _test_eof;
840
+ _test_eof5: cs = 5; goto _test_eof;
841
+ _test_eof6: cs = 6; goto _test_eof;
842
+ _test_eof7: cs = 7; goto _test_eof;
843
+ _test_eof8: cs = 8; goto _test_eof;
844
+ _test_eof9: cs = 9; goto _test_eof;
845
+ _test_eof10: cs = 10; goto _test_eof;
846
+ _test_eof11: cs = 11; goto _test_eof;
847
+ _test_eof12: cs = 12; goto _test_eof;
848
+ _test_eof13: cs = 13; goto _test_eof;
849
+ _test_eof14: cs = 14; goto _test_eof;
850
+ _test_eof15: cs = 15; goto _test_eof;
851
+ _test_eof16: cs = 16; goto _test_eof;
852
+ _test_eof17: cs = 17; goto _test_eof;
853
+ _test_eof18: cs = 18; goto _test_eof;
854
+ _test_eof19: cs = 19; goto _test_eof;
855
+ _test_eof20: cs = 20; goto _test_eof;
856
+ _test_eof21: cs = 21; goto _test_eof;
857
+ _test_eof22: cs = 22; goto _test_eof;
858
+ _test_eof23: cs = 23; goto _test_eof;
859
+ _test_eof24: cs = 24; goto _test_eof;
860
+ _test_eof25: cs = 25; goto _test_eof;
861
+ _test_eof26: cs = 26; goto _test_eof;
862
+ _test_eof27: cs = 27; goto _test_eof;
863
+ _test_eof28: cs = 28; goto _test_eof;
864
+
865
+ _test_eof: {}
576
866
  _out: {}
577
867
  }
578
- #line 175 "parser.rl"
868
+
869
+ #line 291 "parser.rl"
870
+
871
+ if (json->freeze) {
872
+ OBJ_FREEZE(*result);
873
+ }
579
874
 
580
875
  if (cs >= JSON_value_first_final) {
581
876
  return p;
@@ -585,91 +880,98 @@ case 11:
585
880
  }
586
881
 
587
882
 
588
- #line 589 "parser.c"
589
- static const int JSON_integer_start = 0;
883
+ #line 884 "parser.c"
884
+ enum {JSON_integer_start = 1};
885
+ enum {JSON_integer_first_final = 3};
886
+ enum {JSON_integer_error = 0};
590
887
 
591
- static const int JSON_integer_first_final = 5;
888
+ enum {JSON_integer_en_main = 1};
592
889
 
593
- static const int JSON_integer_error = 1;
594
890
 
595
- #line 191 "parser.rl"
891
+ #line 311 "parser.rl"
596
892
 
597
893
 
598
894
  static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
599
895
  {
600
896
  int cs = EVIL;
601
897
 
602
-
603
- #line 604 "parser.c"
898
+
899
+ #line 900 "parser.c"
604
900
  {
605
901
  cs = JSON_integer_start;
606
902
  }
607
- #line 198 "parser.rl"
903
+
904
+ #line 318 "parser.rl"
608
905
  json->memo = p;
609
-
610
- #line 611 "parser.c"
906
+
907
+ #line 908 "parser.c"
611
908
  {
612
909
  if ( p == pe )
613
- goto _out;
910
+ goto _test_eof;
614
911
  switch ( cs )
615
912
  {
616
- case 0:
913
+ case 1:
617
914
  switch( (*p) ) {
618
915
  case 45: goto st2;
619
916
  case 48: goto st3;
620
917
  }
621
918
  if ( 49 <= (*p) && (*p) <= 57 )
622
- goto st4;
623
- goto st1;
624
- st1:
625
- goto _out1;
919
+ goto st5;
920
+ goto st0;
921
+ st0:
922
+ cs = 0;
923
+ goto _out;
626
924
  st2:
627
925
  if ( ++p == pe )
628
- goto _out2;
926
+ goto _test_eof2;
629
927
  case 2:
630
928
  if ( (*p) == 48 )
631
929
  goto st3;
632
930
  if ( 49 <= (*p) && (*p) <= 57 )
633
- goto st4;
634
- goto st1;
931
+ goto st5;
932
+ goto st0;
635
933
  st3:
636
934
  if ( ++p == pe )
637
- goto _out3;
935
+ goto _test_eof3;
638
936
  case 3:
639
937
  if ( 48 <= (*p) && (*p) <= 57 )
640
- goto st1;
938
+ goto st0;
641
939
  goto tr4;
642
940
  tr4:
643
- #line 188 "parser.rl"
644
- { goto _out5; }
645
- goto st5;
646
- st5:
647
- if ( ++p == pe )
648
- goto _out5;
649
- case 5:
650
- #line 651 "parser.c"
651
- goto st1;
941
+ #line 308 "parser.rl"
942
+ { p--; {p++; cs = 4; goto _out;} }
943
+ goto st4;
652
944
  st4:
653
945
  if ( ++p == pe )
654
- goto _out4;
946
+ goto _test_eof4;
655
947
  case 4:
948
+ #line 949 "parser.c"
949
+ goto st0;
950
+ st5:
951
+ if ( ++p == pe )
952
+ goto _test_eof5;
953
+ case 5:
656
954
  if ( 48 <= (*p) && (*p) <= 57 )
657
- goto st4;
955
+ goto st5;
658
956
  goto tr4;
659
957
  }
660
- _out1: cs = 1; goto _out;
661
- _out2: cs = 2; goto _out;
662
- _out3: cs = 3; goto _out;
663
- _out5: cs = 5; goto _out;
664
- _out4: cs = 4; goto _out;
958
+ _test_eof2: cs = 2; goto _test_eof;
959
+ _test_eof3: cs = 3; goto _test_eof;
960
+ _test_eof4: cs = 4; goto _test_eof;
961
+ _test_eof5: cs = 5; goto _test_eof;
665
962
 
963
+ _test_eof: {}
666
964
  _out: {}
667
965
  }
668
- #line 200 "parser.rl"
966
+
967
+ #line 320 "parser.rl"
669
968
 
670
969
  if (cs >= JSON_integer_first_final) {
671
970
  long len = p - json->memo;
672
- *result = rb_Integer(rb_str_new(json->memo, len));
971
+ fbuffer_clear(json->fbuffer);
972
+ fbuffer_append(json->fbuffer, json->memo, len);
973
+ fbuffer_append_char(json->fbuffer, '\0');
974
+ *result = rb_cstr2inum(FBUFFER_PTR(json->fbuffer), 10);
673
975
  return p + 1;
674
976
  } else {
675
977
  return NULL;
@@ -677,154 +979,199 @@ case 4:
677
979
  }
678
980
 
679
981
 
680
- #line 681 "parser.c"
681
- static const int JSON_float_start = 0;
982
+ #line 983 "parser.c"
983
+ enum {JSON_float_start = 1};
984
+ enum {JSON_float_first_final = 8};
985
+ enum {JSON_float_error = 0};
682
986
 
683
- static const int JSON_float_first_final = 10;
987
+ enum {JSON_float_en_main = 1};
684
988
 
685
- static const int JSON_float_error = 1;
686
989
 
687
- #line 222 "parser.rl"
990
+ #line 345 "parser.rl"
688
991
 
689
992
 
690
993
  static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
691
994
  {
692
995
  int cs = EVIL;
693
996
 
694
-
695
- #line 696 "parser.c"
997
+
998
+ #line 999 "parser.c"
696
999
  {
697
1000
  cs = JSON_float_start;
698
1001
  }
699
- #line 229 "parser.rl"
1002
+
1003
+ #line 352 "parser.rl"
700
1004
  json->memo = p;
701
-
702
- #line 703 "parser.c"
1005
+
1006
+ #line 1007 "parser.c"
703
1007
  {
704
1008
  if ( p == pe )
705
- goto _out;
1009
+ goto _test_eof;
706
1010
  switch ( cs )
707
1011
  {
708
- case 0:
1012
+ case 1:
709
1013
  switch( (*p) ) {
710
1014
  case 45: goto st2;
711
1015
  case 48: goto st3;
712
1016
  }
713
1017
  if ( 49 <= (*p) && (*p) <= 57 )
714
- goto st9;
715
- goto st1;
716
- st1:
717
- goto _out1;
1018
+ goto st7;
1019
+ goto st0;
1020
+ st0:
1021
+ cs = 0;
1022
+ goto _out;
718
1023
  st2:
719
1024
  if ( ++p == pe )
720
- goto _out2;
1025
+ goto _test_eof2;
721
1026
  case 2:
722
1027
  if ( (*p) == 48 )
723
1028
  goto st3;
724
1029
  if ( 49 <= (*p) && (*p) <= 57 )
725
- goto st9;
726
- goto st1;
1030
+ goto st7;
1031
+ goto st0;
727
1032
  st3:
728
1033
  if ( ++p == pe )
729
- goto _out3;
1034
+ goto _test_eof3;
730
1035
  case 3:
731
- if ( (*p) == 46 )
732
- goto st4;
733
- goto st1;
1036
+ switch( (*p) ) {
1037
+ case 46: goto st4;
1038
+ case 69: goto st5;
1039
+ case 101: goto st5;
1040
+ }
1041
+ goto st0;
734
1042
  st4:
735
1043
  if ( ++p == pe )
736
- goto _out4;
1044
+ goto _test_eof4;
737
1045
  case 4:
738
1046
  if ( 48 <= (*p) && (*p) <= 57 )
739
- goto st5;
740
- goto st1;
741
- st5:
1047
+ goto st8;
1048
+ goto st0;
1049
+ st8:
742
1050
  if ( ++p == pe )
743
- goto _out5;
744
- case 5:
1051
+ goto _test_eof8;
1052
+ case 8:
745
1053
  switch( (*p) ) {
746
- case 69: goto st6;
747
- case 101: goto st6;
1054
+ case 69: goto st5;
1055
+ case 101: goto st5;
748
1056
  }
749
1057
  if ( (*p) > 46 ) {
750
1058
  if ( 48 <= (*p) && (*p) <= 57 )
751
- goto st5;
1059
+ goto st8;
752
1060
  } else if ( (*p) >= 45 )
753
- goto st1;
754
- goto tr8;
755
- tr8:
756
- #line 216 "parser.rl"
757
- { goto _out10; }
758
- goto st10;
759
- st10:
1061
+ goto st0;
1062
+ goto tr9;
1063
+ tr9:
1064
+ #line 339 "parser.rl"
1065
+ { p--; {p++; cs = 9; goto _out;} }
1066
+ goto st9;
1067
+ st9:
760
1068
  if ( ++p == pe )
761
- goto _out10;
762
- case 10:
763
- #line 764 "parser.c"
764
- goto st1;
765
- st6:
1069
+ goto _test_eof9;
1070
+ case 9:
1071
+ #line 1072 "parser.c"
1072
+ goto st0;
1073
+ st5:
766
1074
  if ( ++p == pe )
767
- goto _out6;
768
- case 6:
1075
+ goto _test_eof5;
1076
+ case 5:
769
1077
  switch( (*p) ) {
770
- case 43: goto st7;
771
- case 45: goto st7;
1078
+ case 43: goto st6;
1079
+ case 45: goto st6;
772
1080
  }
773
1081
  if ( 48 <= (*p) && (*p) <= 57 )
774
- goto st8;
775
- goto st1;
776
- st7:
1082
+ goto st10;
1083
+ goto st0;
1084
+ st6:
777
1085
  if ( ++p == pe )
778
- goto _out7;
779
- case 7:
1086
+ goto _test_eof6;
1087
+ case 6:
780
1088
  if ( 48 <= (*p) && (*p) <= 57 )
781
- goto st8;
782
- goto st1;
783
- st8:
1089
+ goto st10;
1090
+ goto st0;
1091
+ st10:
784
1092
  if ( ++p == pe )
785
- goto _out8;
786
- case 8:
1093
+ goto _test_eof10;
1094
+ case 10:
787
1095
  switch( (*p) ) {
788
- case 69: goto st1;
789
- case 101: goto st1;
1096
+ case 69: goto st0;
1097
+ case 101: goto st0;
790
1098
  }
791
1099
  if ( (*p) > 46 ) {
792
1100
  if ( 48 <= (*p) && (*p) <= 57 )
793
- goto st8;
1101
+ goto st10;
794
1102
  } else if ( (*p) >= 45 )
795
- goto st1;
796
- goto tr8;
797
- st9:
1103
+ goto st0;
1104
+ goto tr9;
1105
+ st7:
798
1106
  if ( ++p == pe )
799
- goto _out9;
800
- case 9:
1107
+ goto _test_eof7;
1108
+ case 7:
801
1109
  switch( (*p) ) {
802
1110
  case 46: goto st4;
803
- case 69: goto st6;
804
- case 101: goto st6;
1111
+ case 69: goto st5;
1112
+ case 101: goto st5;
805
1113
  }
806
1114
  if ( 48 <= (*p) && (*p) <= 57 )
807
- goto st9;
808
- goto st1;
809
- }
810
- _out1: cs = 1; goto _out;
811
- _out2: cs = 2; goto _out;
812
- _out3: cs = 3; goto _out;
813
- _out4: cs = 4; goto _out;
814
- _out5: cs = 5; goto _out;
815
- _out10: cs = 10; goto _out;
816
- _out6: cs = 6; goto _out;
817
- _out7: cs = 7; goto _out;
818
- _out8: cs = 8; goto _out;
819
- _out9: cs = 9; goto _out;
820
-
1115
+ goto st7;
1116
+ goto st0;
1117
+ }
1118
+ _test_eof2: cs = 2; goto _test_eof;
1119
+ _test_eof3: cs = 3; goto _test_eof;
1120
+ _test_eof4: cs = 4; goto _test_eof;
1121
+ _test_eof8: cs = 8; goto _test_eof;
1122
+ _test_eof9: cs = 9; goto _test_eof;
1123
+ _test_eof5: cs = 5; goto _test_eof;
1124
+ _test_eof6: cs = 6; goto _test_eof;
1125
+ _test_eof10: cs = 10; goto _test_eof;
1126
+ _test_eof7: cs = 7; goto _test_eof;
1127
+
1128
+ _test_eof: {}
821
1129
  _out: {}
822
1130
  }
823
- #line 231 "parser.rl"
1131
+
1132
+ #line 354 "parser.rl"
824
1133
 
825
1134
  if (cs >= JSON_float_first_final) {
1135
+ VALUE mod = Qnil;
1136
+ ID method_id = 0;
1137
+ if (rb_respond_to(json->decimal_class, i_try_convert)) {
1138
+ mod = json->decimal_class;
1139
+ method_id = i_try_convert;
1140
+ } else if (rb_respond_to(json->decimal_class, i_new)) {
1141
+ mod = json->decimal_class;
1142
+ method_id = i_new;
1143
+ } else if (RB_TYPE_P(json->decimal_class, T_CLASS)) {
1144
+ VALUE name = rb_class_name(json->decimal_class);
1145
+ const char *name_cstr = RSTRING_PTR(name);
1146
+ const char *last_colon = strrchr(name_cstr, ':');
1147
+ if (last_colon) {
1148
+ const char *mod_path_end = last_colon - 1;
1149
+ VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr);
1150
+ mod = rb_path_to_class(mod_path);
1151
+
1152
+ const char *method_name_beg = last_colon + 1;
1153
+ long before_len = method_name_beg - name_cstr;
1154
+ long len = RSTRING_LEN(name) - before_len;
1155
+ VALUE method_name = rb_str_substr(name, before_len, len);
1156
+ method_id = SYM2ID(rb_str_intern(method_name));
1157
+ } else {
1158
+ mod = rb_mKernel;
1159
+ method_id = SYM2ID(rb_str_intern(name));
1160
+ }
1161
+ }
1162
+
826
1163
  long len = p - json->memo;
827
- *result = rb_Float(rb_str_new(json->memo, len));
1164
+ fbuffer_clear(json->fbuffer);
1165
+ fbuffer_append(json->fbuffer, json->memo, len);
1166
+ fbuffer_append_char(json->fbuffer, '\0');
1167
+
1168
+ if (method_id) {
1169
+ VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
1170
+ *result = rb_funcallv(mod, method_id, 1, &text);
1171
+ } else {
1172
+ *result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
1173
+ }
1174
+
828
1175
  return p + 1;
829
1176
  } else {
830
1177
  return NULL;
@@ -833,132 +1180,148 @@ case 9:
833
1180
 
834
1181
 
835
1182
 
836
- #line 837 "parser.c"
837
- static const int JSON_array_start = 0;
1183
+ #line 1184 "parser.c"
1184
+ enum {JSON_array_start = 1};
1185
+ enum {JSON_array_first_final = 17};
1186
+ enum {JSON_array_error = 0};
838
1187
 
839
- static const int JSON_array_first_final = 17;
1188
+ enum {JSON_array_en_main = 1};
840
1189
 
841
- static const int JSON_array_error = 1;
842
1190
 
843
- #line 267 "parser.rl"
1191
+ #line 432 "parser.rl"
844
1192
 
845
1193
 
846
- static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
1194
+ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
847
1195
  {
848
1196
  int cs = EVIL;
849
- *result = rb_ary_new();
1197
+ VALUE array_class = json->array_class;
1198
+
1199
+ if (json->max_nesting && current_nesting > json->max_nesting) {
1200
+ rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
1201
+ }
1202
+ *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
1203
+
850
1204
 
851
-
852
- #line 853 "parser.c"
1205
+ #line 1206 "parser.c"
853
1206
  {
854
1207
  cs = JSON_array_start;
855
1208
  }
856
- #line 275 "parser.rl"
857
-
858
- #line 859 "parser.c"
1209
+
1210
+ #line 445 "parser.rl"
1211
+
1212
+ #line 1213 "parser.c"
859
1213
  {
860
1214
  if ( p == pe )
861
- goto _out;
1215
+ goto _test_eof;
862
1216
  switch ( cs )
863
1217
  {
864
- case 0:
1218
+ case 1:
865
1219
  if ( (*p) == 91 )
866
1220
  goto st2;
867
- goto st1;
868
- st1:
869
- goto _out1;
1221
+ goto st0;
1222
+ st0:
1223
+ cs = 0;
1224
+ goto _out;
870
1225
  st2:
871
1226
  if ( ++p == pe )
872
- goto _out2;
1227
+ goto _test_eof2;
873
1228
  case 2:
874
1229
  switch( (*p) ) {
875
1230
  case 13: goto st2;
876
1231
  case 32: goto st2;
877
- case 34: goto tr8;
878
- case 45: goto tr8;
1232
+ case 34: goto tr2;
1233
+ case 45: goto tr2;
879
1234
  case 47: goto st13;
880
- case 91: goto tr8;
881
- case 93: goto tr7;
882
- case 102: goto tr8;
883
- case 110: goto tr8;
884
- case 116: goto tr8;
885
- case 123: goto tr8;
1235
+ case 73: goto tr2;
1236
+ case 78: goto tr2;
1237
+ case 91: goto tr2;
1238
+ case 93: goto tr4;
1239
+ case 102: goto tr2;
1240
+ case 110: goto tr2;
1241
+ case 116: goto tr2;
1242
+ case 123: goto tr2;
886
1243
  }
887
1244
  if ( (*p) > 10 ) {
888
1245
  if ( 48 <= (*p) && (*p) <= 57 )
889
- goto tr8;
1246
+ goto tr2;
890
1247
  } else if ( (*p) >= 9 )
891
1248
  goto st2;
892
- goto st1;
893
- tr8:
894
- #line 248 "parser.rl"
1249
+ goto st0;
1250
+ tr2:
1251
+ #line 409 "parser.rl"
895
1252
  {
896
1253
  VALUE v = Qnil;
897
- char *np = JSON_parse_value(json, p, pe, &v);
1254
+ char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
898
1255
  if (np == NULL) {
899
- goto _out3;
1256
+ p--; {p++; cs = 3; goto _out;}
900
1257
  } else {
901
- rb_ary_push(*result, v);
1258
+ if (NIL_P(json->array_class)) {
1259
+ rb_ary_push(*result, v);
1260
+ } else {
1261
+ rb_funcall(*result, i_leftshift, 1, v);
1262
+ }
902
1263
  {p = (( np))-1;}
903
1264
  }
904
1265
  }
905
1266
  goto st3;
906
1267
  st3:
907
1268
  if ( ++p == pe )
908
- goto _out3;
1269
+ goto _test_eof3;
909
1270
  case 3:
910
- #line 911 "parser.c"
1271
+ #line 1272 "parser.c"
911
1272
  switch( (*p) ) {
912
1273
  case 13: goto st3;
913
1274
  case 32: goto st3;
914
1275
  case 44: goto st4;
915
1276
  case 47: goto st9;
916
- case 93: goto tr7;
1277
+ case 93: goto tr4;
917
1278
  }
918
1279
  if ( 9 <= (*p) && (*p) <= 10 )
919
1280
  goto st3;
920
- goto st1;
1281
+ goto st0;
921
1282
  st4:
922
1283
  if ( ++p == pe )
923
- goto _out4;
1284
+ goto _test_eof4;
924
1285
  case 4:
925
1286
  switch( (*p) ) {
926
1287
  case 13: goto st4;
927
1288
  case 32: goto st4;
928
- case 34: goto tr8;
929
- case 45: goto tr8;
1289
+ case 34: goto tr2;
1290
+ case 45: goto tr2;
930
1291
  case 47: goto st5;
931
- case 91: goto tr8;
932
- case 102: goto tr8;
933
- case 110: goto tr8;
934
- case 116: goto tr8;
935
- case 123: goto tr8;
1292
+ case 73: goto tr2;
1293
+ case 78: goto tr2;
1294
+ case 91: goto tr2;
1295
+ case 102: goto tr2;
1296
+ case 110: goto tr2;
1297
+ case 116: goto tr2;
1298
+ case 123: goto tr2;
936
1299
  }
937
1300
  if ( (*p) > 10 ) {
938
1301
  if ( 48 <= (*p) && (*p) <= 57 )
939
- goto tr8;
1302
+ goto tr2;
940
1303
  } else if ( (*p) >= 9 )
941
1304
  goto st4;
942
- goto st1;
1305
+ goto st0;
943
1306
  st5:
944
1307
  if ( ++p == pe )
945
- goto _out5;
1308
+ goto _test_eof5;
946
1309
  case 5:
947
1310
  switch( (*p) ) {
948
1311
  case 42: goto st6;
949
1312
  case 47: goto st8;
950
1313
  }
951
- goto st1;
1314
+ goto st0;
952
1315
  st6:
953
1316
  if ( ++p == pe )
954
- goto _out6;
1317
+ goto _test_eof6;
955
1318
  case 6:
956
1319
  if ( (*p) == 42 )
957
1320
  goto st7;
958
1321
  goto st6;
959
1322
  st7:
960
1323
  if ( ++p == pe )
961
- goto _out7;
1324
+ goto _test_eof7;
962
1325
  case 7:
963
1326
  switch( (*p) ) {
964
1327
  case 42: goto st7;
@@ -967,30 +1330,30 @@ case 7:
967
1330
  goto st6;
968
1331
  st8:
969
1332
  if ( ++p == pe )
970
- goto _out8;
1333
+ goto _test_eof8;
971
1334
  case 8:
972
1335
  if ( (*p) == 10 )
973
1336
  goto st4;
974
1337
  goto st8;
975
1338
  st9:
976
1339
  if ( ++p == pe )
977
- goto _out9;
1340
+ goto _test_eof9;
978
1341
  case 9:
979
1342
  switch( (*p) ) {
980
1343
  case 42: goto st10;
981
1344
  case 47: goto st12;
982
1345
  }
983
- goto st1;
1346
+ goto st0;
984
1347
  st10:
985
1348
  if ( ++p == pe )
986
- goto _out10;
1349
+ goto _test_eof10;
987
1350
  case 10:
988
1351
  if ( (*p) == 42 )
989
1352
  goto st11;
990
1353
  goto st10;
991
1354
  st11:
992
1355
  if ( ++p == pe )
993
- goto _out11;
1356
+ goto _test_eof11;
994
1357
  case 11:
995
1358
  switch( (*p) ) {
996
1359
  case 42: goto st11;
@@ -999,40 +1362,40 @@ case 11:
999
1362
  goto st10;
1000
1363
  st12:
1001
1364
  if ( ++p == pe )
1002
- goto _out12;
1365
+ goto _test_eof12;
1003
1366
  case 12:
1004
1367
  if ( (*p) == 10 )
1005
1368
  goto st3;
1006
1369
  goto st12;
1007
- tr7:
1008
- #line 259 "parser.rl"
1009
- { goto _out17; }
1370
+ tr4:
1371
+ #line 424 "parser.rl"
1372
+ { p--; {p++; cs = 17; goto _out;} }
1010
1373
  goto st17;
1011
1374
  st17:
1012
1375
  if ( ++p == pe )
1013
- goto _out17;
1376
+ goto _test_eof17;
1014
1377
  case 17:
1015
- #line 1016 "parser.c"
1016
- goto st1;
1378
+ #line 1379 "parser.c"
1379
+ goto st0;
1017
1380
  st13:
1018
1381
  if ( ++p == pe )
1019
- goto _out13;
1382
+ goto _test_eof13;
1020
1383
  case 13:
1021
1384
  switch( (*p) ) {
1022
1385
  case 42: goto st14;
1023
1386
  case 47: goto st16;
1024
1387
  }
1025
- goto st1;
1388
+ goto st0;
1026
1389
  st14:
1027
1390
  if ( ++p == pe )
1028
- goto _out14;
1391
+ goto _test_eof14;
1029
1392
  case 14:
1030
1393
  if ( (*p) == 42 )
1031
1394
  goto st15;
1032
1395
  goto st14;
1033
1396
  st15:
1034
1397
  if ( ++p == pe )
1035
- goto _out15;
1398
+ goto _test_eof15;
1036
1399
  case 15:
1037
1400
  switch( (*p) ) {
1038
1401
  case 42: goto st15;
@@ -1041,174 +1404,283 @@ case 15:
1041
1404
  goto st14;
1042
1405
  st16:
1043
1406
  if ( ++p == pe )
1044
- goto _out16;
1407
+ goto _test_eof16;
1045
1408
  case 16:
1046
1409
  if ( (*p) == 10 )
1047
1410
  goto st2;
1048
1411
  goto st16;
1049
1412
  }
1050
- _out1: cs = 1; goto _out;
1051
- _out2: cs = 2; goto _out;
1052
- _out3: cs = 3; goto _out;
1053
- _out4: cs = 4; goto _out;
1054
- _out5: cs = 5; goto _out;
1055
- _out6: cs = 6; goto _out;
1056
- _out7: cs = 7; goto _out;
1057
- _out8: cs = 8; goto _out;
1058
- _out9: cs = 9; goto _out;
1059
- _out10: cs = 10; goto _out;
1060
- _out11: cs = 11; goto _out;
1061
- _out12: cs = 12; goto _out;
1062
- _out17: cs = 17; goto _out;
1063
- _out13: cs = 13; goto _out;
1064
- _out14: cs = 14; goto _out;
1065
- _out15: cs = 15; goto _out;
1066
- _out16: cs = 16; goto _out;
1067
-
1413
+ _test_eof2: cs = 2; goto _test_eof;
1414
+ _test_eof3: cs = 3; goto _test_eof;
1415
+ _test_eof4: cs = 4; goto _test_eof;
1416
+ _test_eof5: cs = 5; goto _test_eof;
1417
+ _test_eof6: cs = 6; goto _test_eof;
1418
+ _test_eof7: cs = 7; goto _test_eof;
1419
+ _test_eof8: cs = 8; goto _test_eof;
1420
+ _test_eof9: cs = 9; goto _test_eof;
1421
+ _test_eof10: cs = 10; goto _test_eof;
1422
+ _test_eof11: cs = 11; goto _test_eof;
1423
+ _test_eof12: cs = 12; goto _test_eof;
1424
+ _test_eof17: cs = 17; goto _test_eof;
1425
+ _test_eof13: cs = 13; goto _test_eof;
1426
+ _test_eof14: cs = 14; goto _test_eof;
1427
+ _test_eof15: cs = 15; goto _test_eof;
1428
+ _test_eof16: cs = 16; goto _test_eof;
1429
+
1430
+ _test_eof: {}
1068
1431
  _out: {}
1069
1432
  }
1070
- #line 276 "parser.rl"
1433
+
1434
+ #line 446 "parser.rl"
1071
1435
 
1072
1436
  if(cs >= JSON_array_first_final) {
1073
1437
  return p + 1;
1074
1438
  } else {
1075
- rb_raise(eParserError, "unexpected token at '%s'", p);
1439
+ rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p);
1440
+ return NULL;
1076
1441
  }
1077
1442
  }
1078
1443
 
1079
- static VALUE json_string_escape(char *p, char *pe)
1444
+ static const size_t MAX_STACK_BUFFER_SIZE = 128;
1445
+ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int symbolize)
1080
1446
  {
1081
- VALUE result = rb_str_buf_new(pe - p + 1);
1447
+ VALUE result = Qnil;
1448
+ size_t bufferSize = stringEnd - string;
1449
+ char *p = string, *pe = string, *unescape, *bufferStart, *buffer;
1450
+ int unescape_len;
1451
+ char buf[4];
1452
+
1453
+ if (bufferSize > MAX_STACK_BUFFER_SIZE) {
1454
+ # ifdef HAVE_RB_ENC_INTERNED_STR
1455
+ bufferStart = buffer = ALLOC_N(char, bufferSize ? bufferSize : 1);
1456
+ # else
1457
+ bufferStart = buffer = ALLOC_N(char, bufferSize);
1458
+ # endif
1459
+ } else {
1460
+ # ifdef HAVE_RB_ENC_INTERNED_STR
1461
+ bufferStart = buffer = ALLOCA_N(char, bufferSize ? bufferSize : 1);
1462
+ # else
1463
+ bufferStart = buffer = ALLOCA_N(char, bufferSize);
1464
+ # endif
1465
+ }
1082
1466
 
1083
- while (p < pe) {
1084
- if (*p == '\\') {
1085
- p++;
1086
- if (p >= pe) return Qnil; /* raise an exception later, \ at end */
1087
- switch (*p) {
1467
+ while (pe < stringEnd) {
1468
+ if (*pe == '\\') {
1469
+ unescape = (char *) "?";
1470
+ unescape_len = 1;
1471
+ if (pe > p) {
1472
+ MEMCPY(buffer, p, char, pe - p);
1473
+ buffer += pe - p;
1474
+ }
1475
+ switch (*++pe) {
1476
+ case 'n':
1477
+ unescape = (char *) "\n";
1478
+ break;
1479
+ case 'r':
1480
+ unescape = (char *) "\r";
1481
+ break;
1482
+ case 't':
1483
+ unescape = (char *) "\t";
1484
+ break;
1088
1485
  case '"':
1486
+ unescape = (char *) "\"";
1487
+ break;
1089
1488
  case '\\':
1090
- rb_str_buf_cat(result, p, 1);
1091
- p++;
1489
+ unescape = (char *) "\\";
1092
1490
  break;
1093
1491
  case 'b':
1094
- rb_str_buf_cat2(result, "\b");
1095
- p++;
1492
+ unescape = (char *) "\b";
1096
1493
  break;
1097
1494
  case 'f':
1098
- rb_str_buf_cat2(result, "\f");
1099
- p++;
1100
- break;
1101
- case 'n':
1102
- rb_str_buf_cat2(result, "\n");
1103
- p++;
1104
- break;
1105
- case 'r':
1106
- rb_str_buf_cat2(result, "\r");
1107
- p++;
1108
- break;
1109
- case 't':
1110
- rb_str_buf_cat2(result, "\t");
1111
- p++;
1495
+ unescape = (char *) "\f";
1112
1496
  break;
1113
1497
  case 'u':
1114
- if (p > pe - 4) {
1115
- return Qnil;
1498
+ if (pe > stringEnd - 4) {
1499
+ if (bufferSize > MAX_STACK_BUFFER_SIZE) {
1500
+ ruby_xfree(bufferStart);
1501
+ }
1502
+ rb_enc_raise(
1503
+ EXC_ENCODING eParserError,
1504
+ "incomplete unicode character escape sequence at '%s'", p
1505
+ );
1116
1506
  } else {
1117
- p = JSON_convert_UTF16_to_UTF8(result, p, pe, strictConversion);
1507
+ UTF32 ch = unescape_unicode((unsigned char *) ++pe);
1508
+ pe += 3;
1509
+ if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
1510
+ pe++;
1511
+ if (pe > stringEnd - 6) {
1512
+ if (bufferSize > MAX_STACK_BUFFER_SIZE) {
1513
+ ruby_xfree(bufferStart);
1514
+ }
1515
+ rb_enc_raise(
1516
+ EXC_ENCODING eParserError,
1517
+ "incomplete surrogate pair at '%s'", p
1518
+ );
1519
+ }
1520
+ if (pe[0] == '\\' && pe[1] == 'u') {
1521
+ UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
1522
+ ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
1523
+ | (sur & 0x3FF));
1524
+ pe += 5;
1525
+ } else {
1526
+ unescape = (char *) "?";
1527
+ break;
1528
+ }
1529
+ }
1530
+ unescape_len = convert_UTF32_to_UTF8(buf, ch);
1531
+ unescape = buf;
1118
1532
  }
1119
1533
  break;
1534
+ default:
1535
+ p = pe;
1536
+ continue;
1120
1537
  }
1538
+ MEMCPY(buffer, unescape, char, unescape_len);
1539
+ buffer += unescape_len;
1540
+ p = ++pe;
1121
1541
  } else {
1122
- char *q = p;
1123
- while (*q != '\\' && q < pe) q++;
1124
- rb_str_buf_cat(result, p, q - p);
1125
- p = q;
1542
+ pe++;
1126
1543
  }
1127
1544
  }
1545
+
1546
+ if (pe > p) {
1547
+ MEMCPY(buffer, p, char, pe - p);
1548
+ buffer += pe - p;
1549
+ }
1550
+
1551
+ # ifdef HAVE_RB_ENC_INTERNED_STR
1552
+ if (intern) {
1553
+ result = rb_enc_interned_str(bufferStart, (long)(buffer - bufferStart), rb_utf8_encoding());
1554
+ } else {
1555
+ result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
1556
+ }
1557
+ if (bufferSize > MAX_STACK_BUFFER_SIZE) {
1558
+ ruby_xfree(bufferStart);
1559
+ }
1560
+ # else
1561
+ result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
1562
+
1563
+ if (bufferSize > MAX_STACK_BUFFER_SIZE) {
1564
+ ruby_xfree(bufferStart);
1565
+ }
1566
+
1567
+ if (intern) {
1568
+ # if STR_UMINUS_DEDUPE_FROZEN
1569
+ // Starting from MRI 2.8 it is preferable to freeze the string
1570
+ // before deduplication so that it can be interned directly
1571
+ // otherwise it would be duplicated first which is wasteful.
1572
+ result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
1573
+ # elif STR_UMINUS_DEDUPE
1574
+ // MRI 2.5 and older do not deduplicate strings that are already
1575
+ // frozen.
1576
+ result = rb_funcall(result, i_uminus, 0);
1577
+ # else
1578
+ result = rb_str_freeze(result);
1579
+ # endif
1580
+ }
1581
+ # endif
1582
+
1583
+ if (symbolize) {
1584
+ result = rb_str_intern(result);
1585
+ }
1586
+
1128
1587
  return result;
1129
1588
  }
1130
1589
 
1131
1590
 
1132
- #line 1133 "parser.c"
1133
- static const int JSON_string_start = 0;
1591
+ #line 1592 "parser.c"
1592
+ enum {JSON_string_start = 1};
1593
+ enum {JSON_string_first_final = 8};
1594
+ enum {JSON_string_error = 0};
1134
1595
 
1135
- static const int JSON_string_first_final = 8;
1596
+ enum {JSON_string_en_main = 1};
1136
1597
 
1137
- static const int JSON_string_error = 1;
1138
1598
 
1139
- #line 350 "parser.rl"
1599
+ #line 620 "parser.rl"
1140
1600
 
1141
1601
 
1602
+ static int
1603
+ match_i(VALUE regexp, VALUE klass, VALUE memo)
1604
+ {
1605
+ if (regexp == Qundef) return ST_STOP;
1606
+ if (RTEST(rb_funcall(klass, i_json_creatable_p, 0)) &&
1607
+ RTEST(rb_funcall(regexp, i_match, 1, rb_ary_entry(memo, 0)))) {
1608
+ rb_ary_push(memo, klass);
1609
+ return ST_STOP;
1610
+ }
1611
+ return ST_CONTINUE;
1612
+ }
1613
+
1142
1614
  static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
1143
1615
  {
1144
1616
  int cs = EVIL;
1617
+ VALUE match_string;
1618
+
1145
1619
 
1146
- *result = rb_str_new("", 0);
1147
-
1148
- #line 1149 "parser.c"
1620
+ #line 1621 "parser.c"
1149
1621
  {
1150
1622
  cs = JSON_string_start;
1151
1623
  }
1152
- #line 358 "parser.rl"
1624
+
1625
+ #line 640 "parser.rl"
1153
1626
  json->memo = p;
1154
-
1155
- #line 1156 "parser.c"
1627
+
1628
+ #line 1629 "parser.c"
1156
1629
  {
1157
1630
  if ( p == pe )
1158
- goto _out;
1631
+ goto _test_eof;
1159
1632
  switch ( cs )
1160
1633
  {
1161
- case 0:
1634
+ case 1:
1162
1635
  if ( (*p) == 34 )
1163
1636
  goto st2;
1164
- goto st1;
1165
- st1:
1166
- goto _out1;
1637
+ goto st0;
1638
+ st0:
1639
+ cs = 0;
1640
+ goto _out;
1167
1641
  st2:
1168
1642
  if ( ++p == pe )
1169
- goto _out2;
1643
+ goto _test_eof2;
1170
1644
  case 2:
1171
1645
  switch( (*p) ) {
1172
- case 34: goto tr4;
1646
+ case 34: goto tr2;
1173
1647
  case 92: goto st3;
1174
1648
  }
1175
- if ( 0 <= (*p) && (*p) <= 31 )
1176
- goto st1;
1649
+ if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 )
1650
+ goto st0;
1177
1651
  goto st2;
1178
- tr4:
1179
- #line 342 "parser.rl"
1652
+ tr2:
1653
+ #line 607 "parser.rl"
1180
1654
  {
1181
- *result = json_string_escape(json->memo + 1, p);
1182
- if (NIL_P(*result)) goto _out8; else {p = (( p + 1))-1;}
1655
+ *result = json_string_unescape(json->memo + 1, p, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
1656
+ if (NIL_P(*result)) {
1657
+ p--;
1658
+ {p++; cs = 8; goto _out;}
1659
+ } else {
1660
+ {p = (( p + 1))-1;}
1661
+ }
1183
1662
  }
1184
- #line 347 "parser.rl"
1185
- { goto _out8; }
1663
+ #line 617 "parser.rl"
1664
+ { p--; {p++; cs = 8; goto _out;} }
1186
1665
  goto st8;
1187
1666
  st8:
1188
1667
  if ( ++p == pe )
1189
- goto _out8;
1668
+ goto _test_eof8;
1190
1669
  case 8:
1191
- #line 1192 "parser.c"
1192
- goto st1;
1670
+ #line 1671 "parser.c"
1671
+ goto st0;
1193
1672
  st3:
1194
1673
  if ( ++p == pe )
1195
- goto _out3;
1674
+ goto _test_eof3;
1196
1675
  case 3:
1197
- switch( (*p) ) {
1198
- case 34: goto st2;
1199
- case 47: goto st2;
1200
- case 92: goto st2;
1201
- case 98: goto st2;
1202
- case 102: goto st2;
1203
- case 110: goto st2;
1204
- case 114: goto st2;
1205
- case 116: goto st2;
1206
- case 117: goto st4;
1207
- }
1208
- goto st1;
1676
+ if ( (*p) == 117 )
1677
+ goto st4;
1678
+ if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 )
1679
+ goto st0;
1680
+ goto st2;
1209
1681
  st4:
1210
1682
  if ( ++p == pe )
1211
- goto _out4;
1683
+ goto _test_eof4;
1212
1684
  case 4:
1213
1685
  if ( (*p) < 65 ) {
1214
1686
  if ( 48 <= (*p) && (*p) <= 57 )
@@ -1218,10 +1690,10 @@ case 4:
1218
1690
  goto st5;
1219
1691
  } else
1220
1692
  goto st5;
1221
- goto st1;
1693
+ goto st0;
1222
1694
  st5:
1223
1695
  if ( ++p == pe )
1224
- goto _out5;
1696
+ goto _test_eof5;
1225
1697
  case 5:
1226
1698
  if ( (*p) < 65 ) {
1227
1699
  if ( 48 <= (*p) && (*p) <= 57 )
@@ -1231,10 +1703,10 @@ case 5:
1231
1703
  goto st6;
1232
1704
  } else
1233
1705
  goto st6;
1234
- goto st1;
1706
+ goto st0;
1235
1707
  st6:
1236
1708
  if ( ++p == pe )
1237
- goto _out6;
1709
+ goto _test_eof6;
1238
1710
  case 6:
1239
1711
  if ( (*p) < 65 ) {
1240
1712
  if ( 48 <= (*p) && (*p) <= 57 )
@@ -1244,10 +1716,10 @@ case 6:
1244
1716
  goto st7;
1245
1717
  } else
1246
1718
  goto st7;
1247
- goto st1;
1719
+ goto st0;
1248
1720
  st7:
1249
1721
  if ( ++p == pe )
1250
- goto _out7;
1722
+ goto _test_eof7;
1251
1723
  case 7:
1252
1724
  if ( (*p) < 65 ) {
1253
1725
  if ( 48 <= (*p) && (*p) <= 57 )
@@ -1257,20 +1729,32 @@ case 7:
1257
1729
  goto st2;
1258
1730
  } else
1259
1731
  goto st2;
1260
- goto st1;
1732
+ goto st0;
1261
1733
  }
1262
- _out1: cs = 1; goto _out;
1263
- _out2: cs = 2; goto _out;
1264
- _out8: cs = 8; goto _out;
1265
- _out3: cs = 3; goto _out;
1266
- _out4: cs = 4; goto _out;
1267
- _out5: cs = 5; goto _out;
1268
- _out6: cs = 6; goto _out;
1269
- _out7: cs = 7; goto _out;
1270
-
1734
+ _test_eof2: cs = 2; goto _test_eof;
1735
+ _test_eof8: cs = 8; goto _test_eof;
1736
+ _test_eof3: cs = 3; goto _test_eof;
1737
+ _test_eof4: cs = 4; goto _test_eof;
1738
+ _test_eof5: cs = 5; goto _test_eof;
1739
+ _test_eof6: cs = 6; goto _test_eof;
1740
+ _test_eof7: cs = 7; goto _test_eof;
1741
+
1742
+ _test_eof: {}
1271
1743
  _out: {}
1272
1744
  }
1273
- #line 360 "parser.rl"
1745
+
1746
+ #line 642 "parser.rl"
1747
+
1748
+ if (json->create_additions && RTEST(match_string = json->match_string)) {
1749
+ VALUE klass;
1750
+ VALUE memo = rb_ary_new2(2);
1751
+ rb_ary_push(memo, *result);
1752
+ rb_hash_foreach(match_string, match_i, memo);
1753
+ klass = rb_ary_entry(memo, 1);
1754
+ if (RTEST(klass)) {
1755
+ *result = rb_funcall(klass, i_json_create, 1, *result);
1756
+ }
1757
+ }
1274
1758
 
1275
1759
  if (cs >= JSON_string_first_final) {
1276
1760
  return p + 1;
@@ -1279,19 +1763,7 @@ case 7:
1279
1763
  }
1280
1764
  }
1281
1765
 
1282
-
1283
-
1284
- #line 1285 "parser.c"
1285
- static const int JSON_start = 0;
1286
-
1287
- static const int JSON_first_final = 10;
1288
-
1289
- static const int JSON_error = 1;
1290
-
1291
- #line 390 "parser.rl"
1292
-
1293
-
1294
- /*
1766
+ /*
1295
1767
  * Document-class: JSON::Ext::Parser
1296
1768
  *
1297
1769
  * This is the JSON parser implemented as a C extension. It can be configured
@@ -1303,222 +1775,366 @@ static const int JSON_error = 1;
1303
1775
  *
1304
1776
  */
1305
1777
 
1778
+ static VALUE convert_encoding(VALUE source)
1779
+ {
1780
+ #ifdef HAVE_RUBY_ENCODING_H
1781
+ rb_encoding *enc = rb_enc_get(source);
1782
+ if (enc == rb_ascii8bit_encoding()) {
1783
+ if (OBJ_FROZEN(source)) {
1784
+ source = rb_str_dup(source);
1785
+ }
1786
+ FORCE_UTF8(source);
1787
+ } else {
1788
+ source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
1789
+ }
1790
+ #endif
1791
+ return source;
1792
+ }
1793
+
1306
1794
  /*
1307
- * call-seq: new(source)
1795
+ * call-seq: new(source, opts => {})
1308
1796
  *
1309
1797
  * Creates a new JSON::Ext::Parser instance for the string _source_.
1798
+ *
1799
+ * It will be configured by the _opts_ hash. _opts_ can have the following
1800
+ * keys:
1801
+ *
1802
+ * _opts_ can have the following keys:
1803
+ * * *max_nesting*: The maximum depth of nesting allowed in the parsed data
1804
+ * structures. Disable depth checking with :max_nesting => false|nil|0, it
1805
+ * defaults to 100.
1806
+ * * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
1807
+ * defiance of RFC 4627 to be parsed by the Parser. This option defaults to
1808
+ * false.
1809
+ * * *symbolize_names*: If set to true, returns symbols for the names
1810
+ * (keys) in a JSON object. Otherwise strings are returned, which is
1811
+ * also the default. It's not possible to use this option in
1812
+ * conjunction with the *create_additions* option.
1813
+ * * *create_additions*: If set to false, the Parser doesn't create
1814
+ * additions even if a matching class and create_id was found. This option
1815
+ * defaults to false.
1816
+ * * *object_class*: Defaults to Hash
1817
+ * * *array_class*: Defaults to Array
1310
1818
  */
1311
- static VALUE cParser_initialize(VALUE self, VALUE source)
1819
+ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1312
1820
  {
1313
- char *ptr;
1314
- long len;
1315
- GET_STRUCT;
1316
- source = StringValue(source);
1317
- ptr = RSTRING(source)->ptr;
1318
- len = RSTRING(source)->len;
1319
- if (len < 2) {
1320
- rb_raise(eParserError, "A JSON text must at least contain two octets!");
1821
+ VALUE source, opts;
1822
+ GET_PARSER_INIT;
1823
+
1824
+ if (json->Vsource) {
1825
+ rb_raise(rb_eTypeError, "already initialized instance");
1321
1826
  }
1322
- /*
1323
- Convert these?
1324
- if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
1325
- rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
1326
- } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
1327
- rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
1328
- } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
1329
- rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
1330
- } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
1331
- rb_raise(eParserError, "Only UTF8 octet streams are supported atm!");
1827
+ rb_scan_args(argc, argv, "1:", &source, &opts);
1828
+ if (!NIL_P(opts)) {
1829
+ VALUE tmp = ID2SYM(i_max_nesting);
1830
+ if (option_given_p(opts, tmp)) {
1831
+ VALUE max_nesting = rb_hash_aref(opts, tmp);
1832
+ if (RTEST(max_nesting)) {
1833
+ Check_Type(max_nesting, T_FIXNUM);
1834
+ json->max_nesting = FIX2INT(max_nesting);
1835
+ } else {
1836
+ json->max_nesting = 0;
1837
+ }
1838
+ } else {
1839
+ json->max_nesting = 100;
1840
+ }
1841
+ tmp = ID2SYM(i_allow_nan);
1842
+ if (option_given_p(opts, tmp)) {
1843
+ json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
1844
+ } else {
1845
+ json->allow_nan = 0;
1846
+ }
1847
+ tmp = ID2SYM(i_symbolize_names);
1848
+ if (option_given_p(opts, tmp)) {
1849
+ json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
1850
+ } else {
1851
+ json->symbolize_names = 0;
1852
+ }
1853
+ tmp = ID2SYM(i_freeze);
1854
+ if (option_given_p(opts, tmp)) {
1855
+ json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
1856
+ } else {
1857
+ json->freeze = 0;
1858
+ }
1859
+ tmp = ID2SYM(i_create_additions);
1860
+ if (option_given_p(opts, tmp)) {
1861
+ json->create_additions = RTEST(rb_hash_aref(opts, tmp));
1862
+ } else {
1863
+ json->create_additions = 0;
1864
+ }
1865
+ if (json->symbolize_names && json->create_additions) {
1866
+ rb_raise(rb_eArgError,
1867
+ "options :symbolize_names and :create_additions cannot be "
1868
+ " used in conjunction");
1869
+ }
1870
+ tmp = ID2SYM(i_create_id);
1871
+ if (option_given_p(opts, tmp)) {
1872
+ json->create_id = rb_hash_aref(opts, tmp);
1873
+ } else {
1874
+ json->create_id = rb_funcall(mJSON, i_create_id, 0);
1875
+ }
1876
+ tmp = ID2SYM(i_object_class);
1877
+ if (option_given_p(opts, tmp)) {
1878
+ json->object_class = rb_hash_aref(opts, tmp);
1879
+ } else {
1880
+ json->object_class = Qnil;
1881
+ }
1882
+ tmp = ID2SYM(i_array_class);
1883
+ if (option_given_p(opts, tmp)) {
1884
+ json->array_class = rb_hash_aref(opts, tmp);
1885
+ } else {
1886
+ json->array_class = Qnil;
1887
+ }
1888
+ tmp = ID2SYM(i_decimal_class);
1889
+ if (option_given_p(opts, tmp)) {
1890
+ json->decimal_class = rb_hash_aref(opts, tmp);
1891
+ } else {
1892
+ json->decimal_class = Qnil;
1893
+ }
1894
+ tmp = ID2SYM(i_match_string);
1895
+ if (option_given_p(opts, tmp)) {
1896
+ VALUE match_string = rb_hash_aref(opts, tmp);
1897
+ json->match_string = RTEST(match_string) ? match_string : Qnil;
1898
+ } else {
1899
+ json->match_string = Qnil;
1900
+ }
1901
+ } else {
1902
+ json->max_nesting = 100;
1903
+ json->allow_nan = 0;
1904
+ json->create_additions = 0;
1905
+ json->create_id = Qnil;
1906
+ json->object_class = Qnil;
1907
+ json->array_class = Qnil;
1908
+ json->decimal_class = Qnil;
1332
1909
  }
1333
- */
1334
- json->len = len;
1335
- json->source = ptr;
1910
+ source = convert_encoding(StringValue(source));
1911
+ StringValue(source);
1912
+ json->len = RSTRING_LEN(source);
1913
+ json->source = RSTRING_PTR(source);;
1336
1914
  json->Vsource = source;
1337
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
1338
1915
  return self;
1339
1916
  }
1340
1917
 
1918
+
1919
+ #line 1920 "parser.c"
1920
+ enum {JSON_start = 1};
1921
+ enum {JSON_first_final = 10};
1922
+ enum {JSON_error = 0};
1923
+
1924
+ enum {JSON_en_main = 1};
1925
+
1926
+
1927
+ #line 828 "parser.rl"
1928
+
1929
+
1341
1930
  /*
1342
1931
  * call-seq: parse()
1343
1932
  *
1344
1933
  * Parses the current JSON text _source_ and returns the complete data
1345
1934
  * structure as a result.
1935
+ * It raises JSON::ParserError if fail to parse.
1346
1936
  */
1347
1937
  static VALUE cParser_parse(VALUE self)
1348
1938
  {
1349
- GET_STRUCT;
1350
- char *p, *pe;
1351
- int cs = EVIL;
1352
- VALUE result = Qnil;
1939
+ char *p, *pe;
1940
+ int cs = EVIL;
1941
+ VALUE result = Qnil;
1942
+ GET_PARSER;
1943
+
1353
1944
 
1354
-
1355
- #line 1356 "parser.c"
1945
+ #line 1946 "parser.c"
1356
1946
  {
1357
1947
  cs = JSON_start;
1358
1948
  }
1359
- #line 453 "parser.rl"
1360
- p = json->source;
1361
- pe = p + json->len;
1362
-
1363
- #line 1364 "parser.c"
1949
+
1950
+ #line 845 "parser.rl"
1951
+ p = json->source;
1952
+ pe = p + json->len;
1953
+
1954
+ #line 1955 "parser.c"
1364
1955
  {
1365
1956
  if ( p == pe )
1366
- goto _out;
1957
+ goto _test_eof;
1367
1958
  switch ( cs )
1368
1959
  {
1960
+ st1:
1961
+ if ( ++p == pe )
1962
+ goto _test_eof1;
1963
+ case 1:
1964
+ switch( (*p) ) {
1965
+ case 13: goto st1;
1966
+ case 32: goto st1;
1967
+ case 34: goto tr2;
1968
+ case 45: goto tr2;
1969
+ case 47: goto st6;
1970
+ case 73: goto tr2;
1971
+ case 78: goto tr2;
1972
+ case 91: goto tr2;
1973
+ case 102: goto tr2;
1974
+ case 110: goto tr2;
1975
+ case 116: goto tr2;
1976
+ case 123: goto tr2;
1977
+ }
1978
+ if ( (*p) > 10 ) {
1979
+ if ( 48 <= (*p) && (*p) <= 57 )
1980
+ goto tr2;
1981
+ } else if ( (*p) >= 9 )
1982
+ goto st1;
1983
+ goto st0;
1369
1984
  st0:
1985
+ cs = 0;
1986
+ goto _out;
1987
+ tr2:
1988
+ #line 820 "parser.rl"
1989
+ {
1990
+ char *np = JSON_parse_value(json, p, pe, &result, 0);
1991
+ if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
1992
+ }
1993
+ goto st10;
1994
+ st10:
1370
1995
  if ( ++p == pe )
1371
- goto _out0;
1372
- case 0:
1996
+ goto _test_eof10;
1997
+ case 10:
1998
+ #line 1999 "parser.c"
1373
1999
  switch( (*p) ) {
1374
- case 13: goto st0;
1375
- case 32: goto st0;
2000
+ case 13: goto st10;
2001
+ case 32: goto st10;
1376
2002
  case 47: goto st2;
1377
- case 91: goto tr7;
1378
- case 123: goto tr8;
1379
2003
  }
1380
2004
  if ( 9 <= (*p) && (*p) <= 10 )
1381
- goto st0;
1382
- goto st1;
1383
- st1:
1384
- goto _out1;
2005
+ goto st10;
2006
+ goto st0;
1385
2007
  st2:
1386
2008
  if ( ++p == pe )
1387
- goto _out2;
2009
+ goto _test_eof2;
1388
2010
  case 2:
1389
2011
  switch( (*p) ) {
1390
2012
  case 42: goto st3;
1391
2013
  case 47: goto st5;
1392
2014
  }
1393
- goto st1;
2015
+ goto st0;
1394
2016
  st3:
1395
2017
  if ( ++p == pe )
1396
- goto _out3;
2018
+ goto _test_eof3;
1397
2019
  case 3:
1398
2020
  if ( (*p) == 42 )
1399
2021
  goto st4;
1400
2022
  goto st3;
1401
2023
  st4:
1402
2024
  if ( ++p == pe )
1403
- goto _out4;
2025
+ goto _test_eof4;
1404
2026
  case 4:
1405
2027
  switch( (*p) ) {
1406
2028
  case 42: goto st4;
1407
- case 47: goto st0;
2029
+ case 47: goto st10;
1408
2030
  }
1409
2031
  goto st3;
1410
2032
  st5:
1411
2033
  if ( ++p == pe )
1412
- goto _out5;
2034
+ goto _test_eof5;
1413
2035
  case 5:
1414
2036
  if ( (*p) == 10 )
1415
- goto st0;
1416
- goto st5;
1417
- tr7:
1418
- #line 381 "parser.rl"
1419
- {
1420
- char *np = JSON_parse_array(json, p, pe, &result);
1421
- if (np == NULL) goto _out10; else {p = (( np))-1;}
1422
- }
1423
- goto st10;
1424
- tr8:
1425
- #line 376 "parser.rl"
1426
- {
1427
- char *np = JSON_parse_object(json, p, pe, &result);
1428
- if (np == NULL) goto _out10; else {p = (( np))-1;}
1429
- }
1430
- goto st10;
1431
- st10:
1432
- if ( ++p == pe )
1433
- goto _out10;
1434
- case 10:
1435
- #line 1436 "parser.c"
1436
- switch( (*p) ) {
1437
- case 13: goto st10;
1438
- case 32: goto st10;
1439
- case 47: goto st6;
1440
- }
1441
- if ( 9 <= (*p) && (*p) <= 10 )
1442
2037
  goto st10;
1443
- goto st1;
2038
+ goto st5;
1444
2039
  st6:
1445
2040
  if ( ++p == pe )
1446
- goto _out6;
2041
+ goto _test_eof6;
1447
2042
  case 6:
1448
2043
  switch( (*p) ) {
1449
2044
  case 42: goto st7;
1450
2045
  case 47: goto st9;
1451
2046
  }
1452
- goto st1;
2047
+ goto st0;
1453
2048
  st7:
1454
2049
  if ( ++p == pe )
1455
- goto _out7;
2050
+ goto _test_eof7;
1456
2051
  case 7:
1457
2052
  if ( (*p) == 42 )
1458
2053
  goto st8;
1459
2054
  goto st7;
1460
2055
  st8:
1461
2056
  if ( ++p == pe )
1462
- goto _out8;
2057
+ goto _test_eof8;
1463
2058
  case 8:
1464
2059
  switch( (*p) ) {
1465
2060
  case 42: goto st8;
1466
- case 47: goto st10;
2061
+ case 47: goto st1;
1467
2062
  }
1468
2063
  goto st7;
1469
2064
  st9:
1470
2065
  if ( ++p == pe )
1471
- goto _out9;
2066
+ goto _test_eof9;
1472
2067
  case 9:
1473
2068
  if ( (*p) == 10 )
1474
- goto st10;
2069
+ goto st1;
1475
2070
  goto st9;
1476
2071
  }
1477
- _out0: cs = 0; goto _out;
1478
- _out1: cs = 1; goto _out;
1479
- _out2: cs = 2; goto _out;
1480
- _out3: cs = 3; goto _out;
1481
- _out4: cs = 4; goto _out;
1482
- _out5: cs = 5; goto _out;
1483
- _out10: cs = 10; goto _out;
1484
- _out6: cs = 6; goto _out;
1485
- _out7: cs = 7; goto _out;
1486
- _out8: cs = 8; goto _out;
1487
- _out9: cs = 9; goto _out;
1488
-
2072
+ _test_eof1: cs = 1; goto _test_eof;
2073
+ _test_eof10: cs = 10; goto _test_eof;
2074
+ _test_eof2: cs = 2; goto _test_eof;
2075
+ _test_eof3: cs = 3; goto _test_eof;
2076
+ _test_eof4: cs = 4; goto _test_eof;
2077
+ _test_eof5: cs = 5; goto _test_eof;
2078
+ _test_eof6: cs = 6; goto _test_eof;
2079
+ _test_eof7: cs = 7; goto _test_eof;
2080
+ _test_eof8: cs = 8; goto _test_eof;
2081
+ _test_eof9: cs = 9; goto _test_eof;
2082
+
2083
+ _test_eof: {}
1489
2084
  _out: {}
1490
2085
  }
1491
- #line 456 "parser.rl"
1492
2086
 
1493
- if (cs >= JSON_first_final && p == pe) {
1494
- return result;
1495
- } else {
1496
- rb_raise(eParserError, "unexpected token at '%s'", p);
1497
- }
1498
- }
2087
+ #line 848 "parser.rl"
1499
2088
 
1500
- static JSON_Parser *JSON_allocate()
1501
- {
1502
- JSON_Parser *json = ALLOC(JSON_Parser);
1503
- MEMZERO(json, JSON_Parser, 1);
1504
- return json;
2089
+ if (cs >= JSON_first_final && p == pe) {
2090
+ return result;
2091
+ } else {
2092
+ rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p);
2093
+ return Qnil;
2094
+ }
1505
2095
  }
1506
2096
 
1507
- static void JSON_mark(JSON_Parser *json)
2097
+ static void JSON_mark(void *ptr)
1508
2098
  {
2099
+ JSON_Parser *json = ptr;
1509
2100
  rb_gc_mark_maybe(json->Vsource);
1510
2101
  rb_gc_mark_maybe(json->create_id);
2102
+ rb_gc_mark_maybe(json->object_class);
2103
+ rb_gc_mark_maybe(json->array_class);
2104
+ rb_gc_mark_maybe(json->decimal_class);
2105
+ rb_gc_mark_maybe(json->match_string);
1511
2106
  }
1512
2107
 
1513
- static void JSON_free(JSON_Parser *json)
2108
+ static void JSON_free(void *ptr)
1514
2109
  {
1515
- free(json);
2110
+ JSON_Parser *json = ptr;
2111
+ fbuffer_free(json->fbuffer);
2112
+ ruby_xfree(json);
1516
2113
  }
1517
2114
 
2115
+ static size_t JSON_memsize(const void *ptr)
2116
+ {
2117
+ const JSON_Parser *json = ptr;
2118
+ return sizeof(*json) + FBUFFER_CAPA(json->fbuffer);
2119
+ }
2120
+
2121
+ #ifdef NEW_TYPEDDATA_WRAPPER
2122
+ static const rb_data_type_t JSON_Parser_type = {
2123
+ "JSON/Parser",
2124
+ {JSON_mark, JSON_free, JSON_memsize,},
2125
+ #ifdef RUBY_TYPED_FREE_IMMEDIATELY
2126
+ 0, 0,
2127
+ RUBY_TYPED_FREE_IMMEDIATELY,
2128
+ #endif
2129
+ };
2130
+ #endif
2131
+
1518
2132
  static VALUE cJSON_parser_s_allocate(VALUE klass)
1519
2133
  {
1520
- JSON_Parser *json = JSON_allocate();
1521
- return Data_Wrap_Struct(klass, JSON_mark, JSON_free, json);
2134
+ JSON_Parser *json;
2135
+ VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json);
2136
+ json->fbuffer = fbuffer_alloc(0);
2137
+ return obj;
1522
2138
  }
1523
2139
 
1524
2140
  /*
@@ -1529,23 +2145,67 @@ static VALUE cJSON_parser_s_allocate(VALUE klass)
1529
2145
  */
1530
2146
  static VALUE cParser_source(VALUE self)
1531
2147
  {
1532
- GET_STRUCT;
2148
+ GET_PARSER;
1533
2149
  return rb_str_dup(json->Vsource);
1534
2150
  }
1535
2151
 
1536
- void Init_parser()
2152
+ void Init_parser(void)
1537
2153
  {
2154
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
2155
+ rb_ext_ractor_safe(true);
2156
+ #endif
2157
+
2158
+ #undef rb_intern
2159
+ rb_require("json/common");
1538
2160
  mJSON = rb_define_module("JSON");
1539
2161
  mExt = rb_define_module_under(mJSON, "Ext");
1540
2162
  cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
1541
2163
  eParserError = rb_path2class("JSON::ParserError");
2164
+ eNestingError = rb_path2class("JSON::NestingError");
2165
+ rb_gc_register_mark_object(eParserError);
2166
+ rb_gc_register_mark_object(eNestingError);
1542
2167
  rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
1543
- rb_define_method(cParser, "initialize", cParser_initialize, 1);
2168
+ rb_define_method(cParser, "initialize", cParser_initialize, -1);
1544
2169
  rb_define_method(cParser, "parse", cParser_parse, 0);
1545
2170
  rb_define_method(cParser, "source", cParser_source, 0);
1546
2171
 
2172
+ CNaN = rb_const_get(mJSON, rb_intern("NaN"));
2173
+ rb_gc_register_mark_object(CNaN);
2174
+
2175
+ CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
2176
+ rb_gc_register_mark_object(CInfinity);
2177
+
2178
+ CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
2179
+ rb_gc_register_mark_object(CMinusInfinity);
2180
+
1547
2181
  i_json_creatable_p = rb_intern("json_creatable?");
1548
2182
  i_json_create = rb_intern("json_create");
1549
2183
  i_create_id = rb_intern("create_id");
2184
+ i_create_additions = rb_intern("create_additions");
1550
2185
  i_chr = rb_intern("chr");
2186
+ i_max_nesting = rb_intern("max_nesting");
2187
+ i_allow_nan = rb_intern("allow_nan");
2188
+ i_symbolize_names = rb_intern("symbolize_names");
2189
+ i_object_class = rb_intern("object_class");
2190
+ i_array_class = rb_intern("array_class");
2191
+ i_decimal_class = rb_intern("decimal_class");
2192
+ i_match = rb_intern("match");
2193
+ i_match_string = rb_intern("match_string");
2194
+ i_key_p = rb_intern("key?");
2195
+ i_deep_const_get = rb_intern("deep_const_get");
2196
+ i_aset = rb_intern("[]=");
2197
+ i_aref = rb_intern("[]");
2198
+ i_leftshift = rb_intern("<<");
2199
+ i_new = rb_intern("new");
2200
+ i_try_convert = rb_intern("try_convert");
2201
+ i_freeze = rb_intern("freeze");
2202
+ i_uminus = rb_intern("-@");
1551
2203
  }
2204
+
2205
+ /*
2206
+ * Local variables:
2207
+ * mode: c
2208
+ * c-file-style: ruby
2209
+ * indent-tabs-mode: nil
2210
+ * End:
2211
+ */