json 1.2.0 → 2.19.8

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 (145) hide show
  1. checksums.yaml +7 -0
  2. data/BSDL +22 -0
  3. data/CHANGES.md +783 -0
  4. data/COPYING +14 -16
  5. data/LEGAL +20 -0
  6. data/README.md +310 -0
  7. data/ext/json/ext/fbuffer/fbuffer.h +260 -0
  8. data/ext/json/ext/generator/extconf.rb +15 -8
  9. data/ext/json/ext/generator/generator.c +1675 -613
  10. data/ext/json/ext/json.h +116 -0
  11. data/ext/json/ext/parser/extconf.rb +16 -7
  12. data/ext/json/ext/parser/parser.c +1649 -1772
  13. data/ext/json/ext/simd/conf.rb +24 -0
  14. data/ext/json/ext/simd/simd.h +208 -0
  15. data/ext/json/ext/vendor/fpconv.c +480 -0
  16. data/ext/json/ext/vendor/jeaiii-ltoa.h +267 -0
  17. data/ext/json/ext/vendor/ryu.h +819 -0
  18. data/json.gemspec +62 -0
  19. data/lib/json/add/bigdecimal.rb +58 -0
  20. data/lib/json/add/complex.rb +51 -0
  21. data/lib/json/add/core.rb +11 -133
  22. data/lib/json/add/date.rb +54 -0
  23. data/lib/json/add/date_time.rb +67 -0
  24. data/lib/json/add/exception.rb +49 -0
  25. data/lib/json/add/ostruct.rb +54 -0
  26. data/lib/json/add/range.rb +54 -0
  27. data/lib/json/add/rational.rb +49 -0
  28. data/lib/json/add/regexp.rb +48 -0
  29. data/lib/json/add/set.rb +48 -0
  30. data/lib/json/add/string.rb +35 -0
  31. data/lib/json/add/struct.rb +52 -0
  32. data/lib/json/add/symbol.rb +52 -0
  33. data/lib/json/add/time.rb +52 -0
  34. data/lib/json/common.rb +1056 -254
  35. data/lib/json/ext/generator/state.rb +103 -0
  36. data/lib/json/ext.rb +35 -5
  37. data/lib/json/generic_object.rb +67 -0
  38. data/lib/json/truffle_ruby/generator.rb +755 -0
  39. data/lib/json/version.rb +3 -6
  40. data/lib/json.rb +671 -6
  41. metadata +68 -159
  42. data/CHANGES +0 -136
  43. data/GPL +0 -340
  44. data/README +0 -360
  45. data/Rakefile +0 -287
  46. data/TODO +0 -1
  47. data/VERSION +0 -1
  48. data/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkComparison.log +0 -52
  49. data/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_fast-autocorrelation.dat +0 -1000
  50. data/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_fast.dat +0 -1001
  51. data/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_pretty-autocorrelation.dat +0 -900
  52. data/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_pretty.dat +0 -901
  53. data/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_safe-autocorrelation.dat +0 -1000
  54. data/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_safe.dat +0 -1001
  55. data/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt.log +0 -261
  56. data/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_fast-autocorrelation.dat +0 -1000
  57. data/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_fast.dat +0 -1001
  58. data/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_pretty-autocorrelation.dat +0 -1000
  59. data/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_pretty.dat +0 -1001
  60. data/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_safe-autocorrelation.dat +0 -1000
  61. data/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_safe.dat +0 -1001
  62. data/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure.log +0 -262
  63. data/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails#generator-autocorrelation.dat +0 -1000
  64. data/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails#generator.dat +0 -1001
  65. data/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails.log +0 -82
  66. data/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkComparison.log +0 -34
  67. data/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt#parser-autocorrelation.dat +0 -900
  68. data/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt#parser.dat +0 -901
  69. data/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt.log +0 -81
  70. data/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure#parser-autocorrelation.dat +0 -1000
  71. data/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure#parser.dat +0 -1001
  72. data/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure.log +0 -82
  73. data/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails#parser-autocorrelation.dat +0 -1000
  74. data/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails#parser.dat +0 -1001
  75. data/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails.log +0 -82
  76. data/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML#parser-autocorrelation.dat +0 -1000
  77. data/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML#parser.dat +0 -1001
  78. data/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML.log +0 -82
  79. data/benchmarks/generator_benchmark.rb +0 -165
  80. data/benchmarks/parser_benchmark.rb +0 -197
  81. data/bin/edit_json.rb +0 -9
  82. data/bin/prettify_json.rb +0 -75
  83. data/data/example.json +0 -1
  84. data/data/index.html +0 -38
  85. data/data/prototype.js +0 -4184
  86. data/ext/json/ext/generator/unicode.c +0 -180
  87. data/ext/json/ext/generator/unicode.h +0 -53
  88. data/ext/json/ext/parser/parser.rl +0 -737
  89. data/ext/json/ext/parser/unicode.c +0 -154
  90. data/ext/json/ext/parser/unicode.h +0 -58
  91. data/install.rb +0 -26
  92. data/lib/json/Array.xpm +0 -21
  93. data/lib/json/FalseClass.xpm +0 -21
  94. data/lib/json/Hash.xpm +0 -21
  95. data/lib/json/Key.xpm +0 -73
  96. data/lib/json/NilClass.xpm +0 -21
  97. data/lib/json/Numeric.xpm +0 -28
  98. data/lib/json/String.xpm +0 -96
  99. data/lib/json/TrueClass.xpm +0 -21
  100. data/lib/json/add/rails.rb +0 -58
  101. data/lib/json/editor.rb +0 -1371
  102. data/lib/json/json.xpm +0 -1499
  103. data/lib/json/pure/generator.rb +0 -443
  104. data/lib/json/pure/parser.rb +0 -303
  105. data/lib/json/pure.rb +0 -77
  106. data/tests/fixtures/fail1.json +0 -1
  107. data/tests/fixtures/fail10.json +0 -1
  108. data/tests/fixtures/fail11.json +0 -1
  109. data/tests/fixtures/fail12.json +0 -1
  110. data/tests/fixtures/fail13.json +0 -1
  111. data/tests/fixtures/fail14.json +0 -1
  112. data/tests/fixtures/fail18.json +0 -1
  113. data/tests/fixtures/fail19.json +0 -1
  114. data/tests/fixtures/fail2.json +0 -1
  115. data/tests/fixtures/fail20.json +0 -1
  116. data/tests/fixtures/fail21.json +0 -1
  117. data/tests/fixtures/fail22.json +0 -1
  118. data/tests/fixtures/fail23.json +0 -1
  119. data/tests/fixtures/fail24.json +0 -1
  120. data/tests/fixtures/fail25.json +0 -1
  121. data/tests/fixtures/fail27.json +0 -2
  122. data/tests/fixtures/fail28.json +0 -2
  123. data/tests/fixtures/fail3.json +0 -1
  124. data/tests/fixtures/fail4.json +0 -1
  125. data/tests/fixtures/fail5.json +0 -1
  126. data/tests/fixtures/fail6.json +0 -1
  127. data/tests/fixtures/fail7.json +0 -1
  128. data/tests/fixtures/fail8.json +0 -1
  129. data/tests/fixtures/fail9.json +0 -1
  130. data/tests/fixtures/pass1.json +0 -56
  131. data/tests/fixtures/pass15.json +0 -1
  132. data/tests/fixtures/pass16.json +0 -1
  133. data/tests/fixtures/pass17.json +0 -1
  134. data/tests/fixtures/pass2.json +0 -1
  135. data/tests/fixtures/pass26.json +0 -1
  136. data/tests/fixtures/pass3.json +0 -6
  137. data/tests/test_json.rb +0 -320
  138. data/tests/test_json_addition.rb +0 -164
  139. data/tests/test_json_encoding.rb +0 -67
  140. data/tests/test_json_fixtures.rb +0 -34
  141. data/tests/test_json_generate.rb +0 -120
  142. data/tests/test_json_rails.rb +0 -146
  143. data/tests/test_json_unicode.rb +0 -62
  144. data/tools/fuzz.rb +0 -139
  145. data/tools/server.rb +0 -61
@@ -1,737 +0,0 @@
1
- #include "ruby.h"
2
- #include "unicode.h"
3
- #if HAVE_RE_H
4
- #include "re.h"
5
- #endif
6
- #if HAVE_RUBY_ST_H
7
- #include "ruby/st.h"
8
- #endif
9
- #if HAVE_ST_H
10
- #include "st.h"
11
- #endif
12
-
13
- #define EVIL 0x666
14
-
15
- #ifndef RHASH_TBL
16
- #define RHASH_TBL(hsh) (RHASH(hsh)->tbl)
17
- #endif
18
-
19
- #ifdef HAVE_RUBY_ENCODING_H
20
- #include "ruby/encoding.h"
21
- #define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding())
22
- static VALUE mEncoding_ASCII_8BIT, mEncoding_UTF_8, mEncoding_UTF_16BE,
23
- mEncoding_UTF_16LE, mEncoding_UTF_32BE, mEncoding_UTF_32LE;
24
- static ID i_encoding, i_encode, i_encode_bang, i_force_encoding;
25
- #else
26
- #define FORCE_UTF8(obj)
27
- static ID i_iconv;
28
- #endif
29
-
30
- static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
31
- static VALUE CNaN, CInfinity, CMinusInfinity;
32
-
33
- static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
34
- i_chr, i_max_nesting, i_allow_nan, i_object_class, i_array_class;
35
-
36
- #define MinusInfinity "-Infinity"
37
-
38
- typedef struct JSON_ParserStruct {
39
- VALUE Vsource;
40
- char *source;
41
- long len;
42
- char *memo;
43
- VALUE create_id;
44
- int max_nesting;
45
- int current_nesting;
46
- int allow_nan;
47
- VALUE object_class;
48
- VALUE array_class;
49
- } JSON_Parser;
50
-
51
- static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result);
52
- static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result);
53
- static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result);
54
- static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
55
- static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result);
56
- static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result);
57
-
58
- #define GET_STRUCT \
59
- JSON_Parser *json; \
60
- Data_Get_Struct(self, JSON_Parser, json);
61
-
62
- %%{
63
- machine JSON_common;
64
-
65
- cr = '\n';
66
- cr_neg = [^\n];
67
- ws = [ \t\r\n];
68
- c_comment = '/*' ( any* - (any* '*/' any* ) ) '*/';
69
- cpp_comment = '//' cr_neg* cr;
70
- comment = c_comment | cpp_comment;
71
- ignore = ws | comment;
72
- name_separator = ':';
73
- value_separator = ',';
74
- Vnull = 'null';
75
- Vfalse = 'false';
76
- Vtrue = 'true';
77
- VNaN = 'NaN';
78
- VInfinity = 'Infinity';
79
- VMinusInfinity = '-Infinity';
80
- begin_value = [nft"\-[{NI] | digit;
81
- begin_object = '{';
82
- end_object = '}';
83
- begin_array = '[';
84
- end_array = ']';
85
- begin_string = '"';
86
- begin_name = begin_string;
87
- begin_number = digit | '-';
88
- }%%
89
-
90
- %%{
91
- machine JSON_object;
92
- include JSON_common;
93
-
94
- write data;
95
-
96
- action parse_value {
97
- VALUE v = Qnil;
98
- char *np = JSON_parse_value(json, fpc, pe, &v);
99
- if (np == NULL) {
100
- fhold; fbreak;
101
- } else {
102
- rb_hash_aset(*result, last_name, v);
103
- fexec np;
104
- }
105
- }
106
-
107
- action parse_name {
108
- char *np = JSON_parse_string(json, fpc, pe, &last_name);
109
- if (np == NULL) { fhold; fbreak; } else fexec np;
110
- }
111
-
112
- action exit { fhold; fbreak; }
113
-
114
- a_pair = ignore* begin_name >parse_name
115
- ignore* name_separator ignore*
116
- begin_value >parse_value;
117
-
118
- main := begin_object
119
- (a_pair (ignore* value_separator a_pair)*)?
120
- ignore* end_object @exit;
121
- }%%
122
-
123
- static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
124
- {
125
- int cs = EVIL;
126
- VALUE last_name = Qnil;
127
- VALUE object_class = json->object_class;
128
-
129
- if (json->max_nesting && json->current_nesting > json->max_nesting) {
130
- rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
131
- }
132
-
133
- *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
134
-
135
- %% write init;
136
- %% write exec;
137
-
138
- if (cs >= JSON_object_first_final) {
139
- if (RTEST(json->create_id)) {
140
- VALUE klassname = rb_hash_aref(*result, json->create_id);
141
- if (!NIL_P(klassname)) {
142
- VALUE klass = rb_path2class(StringValueCStr(klassname));
143
- if RTEST(rb_funcall(klass, i_json_creatable_p, 0)) {
144
- *result = rb_funcall(klass, i_json_create, 1, *result);
145
- }
146
- }
147
- }
148
- return p + 1;
149
- } else {
150
- return NULL;
151
- }
152
- }
153
-
154
- %%{
155
- machine JSON_value;
156
- include JSON_common;
157
-
158
- write data;
159
-
160
- action parse_null {
161
- *result = Qnil;
162
- }
163
- action parse_false {
164
- *result = Qfalse;
165
- }
166
- action parse_true {
167
- *result = Qtrue;
168
- }
169
- action parse_nan {
170
- if (json->allow_nan) {
171
- *result = CNaN;
172
- } else {
173
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
174
- }
175
- }
176
- action parse_infinity {
177
- if (json->allow_nan) {
178
- *result = CInfinity;
179
- } else {
180
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
181
- }
182
- }
183
- action parse_string {
184
- char *np = JSON_parse_string(json, fpc, pe, result);
185
- if (np == NULL) { fhold; fbreak; } else fexec np;
186
- }
187
-
188
- action parse_number {
189
- char *np;
190
- if(pe > fpc + 9 && !strncmp(MinusInfinity, fpc, 9)) {
191
- if (json->allow_nan) {
192
- *result = CMinusInfinity;
193
- fexec p + 10;
194
- fhold; fbreak;
195
- } else {
196
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
197
- }
198
- }
199
- np = JSON_parse_float(json, fpc, pe, result);
200
- if (np != NULL) fexec np;
201
- np = JSON_parse_integer(json, fpc, pe, result);
202
- if (np != NULL) fexec np;
203
- fhold; fbreak;
204
- }
205
-
206
- action parse_array {
207
- char *np;
208
- json->current_nesting++;
209
- np = JSON_parse_array(json, fpc, pe, result);
210
- json->current_nesting--;
211
- if (np == NULL) { fhold; fbreak; } else fexec np;
212
- }
213
-
214
- action parse_object {
215
- char *np;
216
- json->current_nesting++;
217
- np = JSON_parse_object(json, fpc, pe, result);
218
- json->current_nesting--;
219
- if (np == NULL) { fhold; fbreak; } else fexec np;
220
- }
221
-
222
- action exit { fhold; fbreak; }
223
-
224
- main := (
225
- Vnull @parse_null |
226
- Vfalse @parse_false |
227
- Vtrue @parse_true |
228
- VNaN @parse_nan |
229
- VInfinity @parse_infinity |
230
- begin_number >parse_number |
231
- begin_string >parse_string |
232
- begin_array >parse_array |
233
- begin_object >parse_object
234
- ) %*exit;
235
- }%%
236
-
237
- static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
238
- {
239
- int cs = EVIL;
240
-
241
- %% write init;
242
- %% write exec;
243
-
244
- if (cs >= JSON_value_first_final) {
245
- return p;
246
- } else {
247
- return NULL;
248
- }
249
- }
250
-
251
- %%{
252
- machine JSON_integer;
253
-
254
- write data;
255
-
256
- action exit { fhold; fbreak; }
257
-
258
- main := '-'? ('0' | [1-9][0-9]*) (^[0-9] @exit);
259
- }%%
260
-
261
- static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
262
- {
263
- int cs = EVIL;
264
-
265
- %% write init;
266
- json->memo = p;
267
- %% write exec;
268
-
269
- if (cs >= JSON_integer_first_final) {
270
- long len = p - json->memo;
271
- *result = rb_Integer(rb_str_new(json->memo, len));
272
- return p + 1;
273
- } else {
274
- return NULL;
275
- }
276
- }
277
-
278
- %%{
279
- machine JSON_float;
280
- include JSON_common;
281
-
282
- write data;
283
-
284
- action exit { fhold; fbreak; }
285
-
286
- main := '-'? (
287
- (('0' | [1-9][0-9]*) '.' [0-9]+ ([Ee] [+\-]?[0-9]+)?)
288
- | (('0' | [1-9][0-9]*) ([Ee] [+\-]?[0-9]+))
289
- ) (^[0-9Ee.\-] @exit );
290
- }%%
291
-
292
- static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
293
- {
294
- int cs = EVIL;
295
-
296
- %% write init;
297
- json->memo = p;
298
- %% write exec;
299
-
300
- if (cs >= JSON_float_first_final) {
301
- long len = p - json->memo;
302
- *result = rb_Float(rb_str_new(json->memo, len));
303
- return p + 1;
304
- } else {
305
- return NULL;
306
- }
307
- }
308
-
309
-
310
- %%{
311
- machine JSON_array;
312
- include JSON_common;
313
-
314
- write data;
315
-
316
- action parse_value {
317
- VALUE v = Qnil;
318
- char *np = JSON_parse_value(json, fpc, pe, &v);
319
- if (np == NULL) {
320
- fhold; fbreak;
321
- } else {
322
- rb_ary_push(*result, v);
323
- fexec np;
324
- }
325
- }
326
-
327
- action exit { fhold; fbreak; }
328
-
329
- next_element = value_separator ignore* begin_value >parse_value;
330
-
331
- main := begin_array ignore*
332
- ((begin_value >parse_value ignore*)
333
- (ignore* next_element ignore*)*)?
334
- end_array @exit;
335
- }%%
336
-
337
- static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
338
- {
339
- int cs = EVIL;
340
- VALUE array_class = json->array_class;
341
-
342
- if (json->max_nesting && json->current_nesting > json->max_nesting) {
343
- rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
344
- }
345
- *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
346
-
347
- %% write init;
348
- %% write exec;
349
-
350
- if(cs >= JSON_array_first_final) {
351
- return p + 1;
352
- } else {
353
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
354
- }
355
- }
356
-
357
- static VALUE json_string_unescape(char *p, char *pe)
358
- {
359
- VALUE result = rb_str_buf_new(pe - p + 1);
360
-
361
- while (p < pe) {
362
- if (*p == '\\') {
363
- p++;
364
- if (p >= pe) return Qnil; /* raise an exception later, \ at end */
365
- switch (*p) {
366
- case '"':
367
- case '\\':
368
- rb_str_buf_cat(result, p, 1);
369
- p++;
370
- break;
371
- case 'b':
372
- rb_str_buf_cat2(result, "\b");
373
- p++;
374
- break;
375
- case 'f':
376
- rb_str_buf_cat2(result, "\f");
377
- p++;
378
- break;
379
- case 'n':
380
- rb_str_buf_cat2(result, "\n");
381
- p++;
382
- break;
383
- case 'r':
384
- rb_str_buf_cat2(result, "\r");
385
- p++;
386
- break;
387
- case 't':
388
- rb_str_buf_cat2(result, "\t");
389
- p++;
390
- break;
391
- case 'u':
392
- if (p > pe - 4) {
393
- return Qnil;
394
- } else {
395
- p = JSON_convert_UTF16_to_UTF8(result, p, pe, strictConversion);
396
- }
397
- break;
398
- default:
399
- rb_str_buf_cat(result, p, 1);
400
- p++;
401
- break;
402
- }
403
- } else {
404
- char *q = p;
405
- while (*q != '\\' && q < pe) q++;
406
- rb_str_buf_cat(result, p, q - p);
407
- p = q;
408
- }
409
- }
410
- return result;
411
- }
412
-
413
- %%{
414
- machine JSON_string;
415
- include JSON_common;
416
-
417
- write data;
418
-
419
- action parse_string {
420
- *result = json_string_unescape(json->memo + 1, p);
421
- if (NIL_P(*result)) {
422
- fhold;
423
- fbreak;
424
- } else {
425
- FORCE_UTF8(*result);
426
- fexec p + 1;
427
- }
428
- }
429
-
430
- action exit { fhold; fbreak; }
431
-
432
- main := '"' ((^(["\\] | 0..0x1f) | '\\'["\\/bfnrt] | '\\u'[0-9a-fA-F]{4} | '\\'^(["\\/bfnrtu]|0..0x1f))* %parse_string) '"' @exit;
433
- }%%
434
-
435
- static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
436
- {
437
- int cs = EVIL;
438
-
439
- *result = rb_str_new("", 0);
440
- %% write init;
441
- json->memo = p;
442
- %% write exec;
443
-
444
- if (cs >= JSON_string_first_final) {
445
- return p + 1;
446
- } else {
447
- return NULL;
448
- }
449
- }
450
-
451
-
452
- %%{
453
- machine JSON;
454
-
455
- write data;
456
-
457
- include JSON_common;
458
-
459
- action parse_object {
460
- char *np;
461
- json->current_nesting = 1;
462
- np = JSON_parse_object(json, fpc, pe, &result);
463
- if (np == NULL) { fhold; fbreak; } else fexec np;
464
- }
465
-
466
- action parse_array {
467
- char *np;
468
- json->current_nesting = 1;
469
- np = JSON_parse_array(json, fpc, pe, &result);
470
- if (np == NULL) { fhold; fbreak; } else fexec np;
471
- }
472
-
473
- main := ignore* (
474
- begin_object >parse_object |
475
- begin_array >parse_array
476
- ) ignore*;
477
- }%%
478
-
479
- /*
480
- * Document-class: JSON::Ext::Parser
481
- *
482
- * This is the JSON parser implemented as a C extension. It can be configured
483
- * to be used by setting
484
- *
485
- * JSON.parser = JSON::Ext::Parser
486
- *
487
- * with the method parser= in JSON.
488
- *
489
- */
490
-
491
- inline static VALUE convert_encoding(VALUE source)
492
- {
493
- char *ptr = RSTRING_PTR(source);
494
- long len = RSTRING_LEN(source);
495
- if (len < 2) {
496
- rb_raise(eParserError, "A JSON text must at least contain two octets!");
497
- }
498
- #ifdef HAVE_RUBY_ENCODING_H
499
- {
500
- VALUE encoding = rb_funcall(source, i_encoding, 0);
501
- if (encoding == mEncoding_ASCII_8BIT) {
502
- if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
503
- source = rb_str_dup(source);
504
- rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_32BE);
505
- source = rb_funcall(source, i_encode_bang, 1, mEncoding_UTF_8);
506
- } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
507
- source = rb_str_dup(source);
508
- rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_16BE);
509
- source = rb_funcall(source, i_encode_bang, 1, mEncoding_UTF_8);
510
- } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
511
- source = rb_str_dup(source);
512
- rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_32LE);
513
- source = rb_funcall(source, i_encode_bang, 1, mEncoding_UTF_8);
514
- } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
515
- source = rb_str_dup(source);
516
- rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_16LE);
517
- source = rb_funcall(source, i_encode_bang, 1, mEncoding_UTF_8);
518
- } else {
519
- source = rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_8);
520
- }
521
- } else {
522
- source = rb_funcall(source, i_encode, 1, mEncoding_UTF_8);
523
- }
524
- }
525
- #else
526
- if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
527
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32be"), source);
528
- } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
529
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16be"), source);
530
- } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
531
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32le"), source);
532
- } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
533
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16le"), source);
534
- }
535
- #endif
536
- return source;
537
- }
538
-
539
- /*
540
- * call-seq: new(source, opts => {})
541
- *
542
- * Creates a new JSON::Ext::Parser instance for the string _source_.
543
- *
544
- * Creates a new JSON::Ext::Parser instance for the string _source_.
545
- *
546
- * It will be configured by the _opts_ hash. _opts_ can have the following
547
- * keys:
548
- *
549
- * _opts_ can have the following keys:
550
- * * *max_nesting*: The maximum depth of nesting allowed in the parsed data
551
- * structures. Disable depth checking with :max_nesting => false|nil|0, it
552
- * defaults to 19.
553
- * * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
554
- * defiance of RFC 4627 to be parsed by the Parser. This option defaults to
555
- * false.
556
- * * *create_additions*: If set to false, the Parser doesn't create
557
- * additions even if a matchin class and create_id was found. This option
558
- * defaults to true.
559
- * * *object_class*: Defaults to Hash
560
- * * *array_class*: Defaults to Array
561
- */
562
- static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
563
- {
564
- char *ptr;
565
- long len;
566
- VALUE source, opts;
567
- GET_STRUCT;
568
- rb_scan_args(argc, argv, "11", &source, &opts);
569
- source = convert_encoding(StringValue(source));
570
- ptr = RSTRING_PTR(source);
571
- len = RSTRING_LEN(source);
572
- if (!NIL_P(opts)) {
573
- opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
574
- if (NIL_P(opts)) {
575
- rb_raise(rb_eArgError, "opts needs to be like a hash");
576
- } else {
577
- VALUE tmp = ID2SYM(i_max_nesting);
578
- if (st_lookup(RHASH_TBL(opts), tmp, 0)) {
579
- VALUE max_nesting = rb_hash_aref(opts, tmp);
580
- if (RTEST(max_nesting)) {
581
- Check_Type(max_nesting, T_FIXNUM);
582
- json->max_nesting = FIX2INT(max_nesting);
583
- } else {
584
- json->max_nesting = 0;
585
- }
586
- } else {
587
- json->max_nesting = 19;
588
- }
589
- tmp = ID2SYM(i_allow_nan);
590
- if (st_lookup(RHASH_TBL(opts), tmp, 0)) {
591
- VALUE allow_nan = rb_hash_aref(opts, tmp);
592
- json->allow_nan = RTEST(allow_nan) ? 1 : 0;
593
- } else {
594
- json->allow_nan = 0;
595
- }
596
- tmp = ID2SYM(i_create_additions);
597
- if (st_lookup(RHASH_TBL(opts), tmp, 0)) {
598
- VALUE create_additions = rb_hash_aref(opts, tmp);
599
- if (RTEST(create_additions)) {
600
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
601
- } else {
602
- json->create_id = Qnil;
603
- }
604
- } else {
605
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
606
- }
607
- tmp = ID2SYM(i_object_class);
608
- if (st_lookup(RHASH_TBL(opts), tmp, 0)) {
609
- json->object_class = rb_hash_aref(opts, tmp);
610
- } else {
611
- json->object_class = Qnil;
612
- }
613
- tmp = ID2SYM(i_array_class);
614
- if (st_lookup(RHASH_TBL(opts), tmp, 0)) {
615
- json->array_class = rb_hash_aref(opts, tmp);
616
- } else {
617
- json->array_class = Qnil;
618
- }
619
- }
620
- } else {
621
- json->max_nesting = 19;
622
- json->allow_nan = 0;
623
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
624
- json->object_class = Qnil;
625
- json->array_class = Qnil;
626
- }
627
- json->current_nesting = 0;
628
- json->len = len;
629
- json->source = ptr;
630
- json->Vsource = source;
631
- return self;
632
- }
633
-
634
- /*
635
- * call-seq: parse()
636
- *
637
- * Parses the current JSON text _source_ and returns the complete data
638
- * structure as a result.
639
- */
640
- static VALUE cParser_parse(VALUE self)
641
- {
642
- char *p, *pe;
643
- int cs = EVIL;
644
- VALUE result = Qnil;
645
- GET_STRUCT;
646
-
647
- %% write init;
648
- p = json->source;
649
- pe = p + json->len;
650
- %% write exec;
651
-
652
- if (cs >= JSON_first_final && p == pe) {
653
- return result;
654
- } else {
655
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
656
- }
657
- }
658
-
659
- inline static JSON_Parser *JSON_allocate()
660
- {
661
- JSON_Parser *json = ALLOC(JSON_Parser);
662
- MEMZERO(json, JSON_Parser, 1);
663
- return json;
664
- }
665
-
666
- static void JSON_mark(JSON_Parser *json)
667
- {
668
- rb_gc_mark_maybe(json->Vsource);
669
- rb_gc_mark_maybe(json->create_id);
670
- rb_gc_mark_maybe(json->object_class);
671
- rb_gc_mark_maybe(json->array_class);
672
- }
673
-
674
- static void JSON_free(JSON_Parser *json)
675
- {
676
- ruby_xfree(json);
677
- }
678
-
679
- static VALUE cJSON_parser_s_allocate(VALUE klass)
680
- {
681
- JSON_Parser *json = JSON_allocate();
682
- return Data_Wrap_Struct(klass, JSON_mark, JSON_free, json);
683
- }
684
-
685
- /*
686
- * call-seq: source()
687
- *
688
- * Returns a copy of the current _source_ string, that was used to construct
689
- * this Parser.
690
- */
691
- static VALUE cParser_source(VALUE self)
692
- {
693
- GET_STRUCT;
694
- return rb_str_dup(json->Vsource);
695
- }
696
-
697
- void Init_parser()
698
- {
699
- rb_require("json/common");
700
- mJSON = rb_define_module("JSON");
701
- mExt = rb_define_module_under(mJSON, "Ext");
702
- cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
703
- eParserError = rb_path2class("JSON::ParserError");
704
- eNestingError = rb_path2class("JSON::NestingError");
705
- rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
706
- rb_define_method(cParser, "initialize", cParser_initialize, -1);
707
- rb_define_method(cParser, "parse", cParser_parse, 0);
708
- rb_define_method(cParser, "source", cParser_source, 0);
709
-
710
- CNaN = rb_const_get(mJSON, rb_intern("NaN"));
711
- CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
712
- CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
713
-
714
- i_json_creatable_p = rb_intern("json_creatable?");
715
- i_json_create = rb_intern("json_create");
716
- i_create_id = rb_intern("create_id");
717
- i_create_additions = rb_intern("create_additions");
718
- i_chr = rb_intern("chr");
719
- i_max_nesting = rb_intern("max_nesting");
720
- i_allow_nan = rb_intern("allow_nan");
721
- i_object_class = rb_intern("object_class");
722
- i_array_class = rb_intern("array_class");
723
- #ifdef HAVE_RUBY_ENCODING_H
724
- mEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
725
- mEncoding_UTF_16BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16be"));
726
- mEncoding_UTF_16LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16le"));
727
- mEncoding_UTF_32BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32be"));
728
- mEncoding_UTF_32LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32le"));
729
- mEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit"));
730
- i_encoding = rb_intern("encoding");
731
- i_encode = rb_intern("encode");
732
- i_encode_bang = rb_intern("encode!");
733
- i_force_encoding = rb_intern("force_encoding");
734
- #else
735
- i_iconv = rb_intern("iconv");
736
- #endif
737
- }