json_pure 2.3.0 → 2.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +55 -0
  3. data/README.md +16 -0
  4. data/VERSION +1 -1
  5. data/json_pure.gemspec +49 -26
  6. data/lib/json.rb +549 -29
  7. data/lib/json/add/complex.rb +0 -1
  8. data/lib/json/add/rational.rb +0 -1
  9. data/lib/json/common.rb +370 -123
  10. data/lib/json/pure/generator.rb +29 -9
  11. data/lib/json/pure/parser.rb +22 -4
  12. data/lib/json/version.rb +1 -1
  13. data/tests/fixtures/fail29.json +1 -0
  14. data/tests/fixtures/fail30.json +1 -0
  15. data/tests/fixtures/fail31.json +1 -0
  16. data/tests/fixtures/fail32.json +1 -0
  17. data/tests/json_addition_test.rb +0 -4
  18. data/tests/json_common_interface_test.rb +43 -0
  19. data/tests/json_fixtures_test.rb +9 -1
  20. data/tests/json_generator_test.rb +16 -38
  21. data/tests/json_parser_test.rb +25 -0
  22. data/tests/lib/core_assertions.rb +763 -0
  23. data/tests/lib/envutil.rb +365 -0
  24. data/tests/lib/find_executable.rb +22 -0
  25. data/tests/lib/helper.rb +4 -0
  26. data/tests/ractor_test.rb +30 -0
  27. data/tests/test_helper.rb +3 -3
  28. metadata +27 -48
  29. data/.gitignore +0 -18
  30. data/.travis.yml +0 -24
  31. data/README-json-jruby.md +0 -33
  32. data/Rakefile +0 -413
  33. data/diagrams/.keep +0 -0
  34. data/ext/json/ext/fbuffer/fbuffer.h +0 -187
  35. data/ext/json/ext/generator/depend +0 -1
  36. data/ext/json/ext/generator/extconf.rb +0 -4
  37. data/ext/json/ext/generator/generator.c +0 -1499
  38. data/ext/json/ext/generator/generator.h +0 -171
  39. data/ext/json/ext/parser/depend +0 -1
  40. data/ext/json/ext/parser/extconf.rb +0 -6
  41. data/ext/json/ext/parser/parser.c +0 -2136
  42. data/ext/json/ext/parser/parser.h +0 -91
  43. data/ext/json/ext/parser/parser.rl +0 -896
  44. data/ext/json/extconf.rb +0 -2
  45. data/install.rb +0 -23
  46. data/java/src/json/ext/ByteListTranscoder.java +0 -166
  47. data/java/src/json/ext/Generator.java +0 -466
  48. data/java/src/json/ext/GeneratorMethods.java +0 -231
  49. data/java/src/json/ext/GeneratorService.java +0 -42
  50. data/java/src/json/ext/GeneratorState.java +0 -490
  51. data/java/src/json/ext/OptionsReader.java +0 -113
  52. data/java/src/json/ext/Parser.java +0 -2362
  53. data/java/src/json/ext/Parser.rl +0 -893
  54. data/java/src/json/ext/ParserService.java +0 -34
  55. data/java/src/json/ext/RuntimeInfo.java +0 -116
  56. data/java/src/json/ext/StringDecoder.java +0 -166
  57. data/java/src/json/ext/StringEncoder.java +0 -111
  58. data/java/src/json/ext/Utils.java +0 -88
  59. data/json-java.gemspec +0 -37
  60. data/json.gemspec +0 -0
  61. data/references/rfc7159.txt +0 -899
  62. data/tools/diff.sh +0 -18
  63. data/tools/fuzz.rb +0 -131
  64. data/tools/server.rb +0 -62
@@ -1,91 +0,0 @@
1
- #ifndef _PARSER_H_
2
- #define _PARSER_H_
3
-
4
- #include "ruby.h"
5
-
6
- #ifndef HAVE_RUBY_RE_H
7
- #include "re.h"
8
- #endif
9
-
10
- #ifdef HAVE_RUBY_ST_H
11
- #include "ruby/st.h"
12
- #else
13
- #include "st.h"
14
- #endif
15
-
16
- #define option_given_p(opts, key) RTEST(rb_funcall(opts, i_key_p, 1, key))
17
-
18
- /* unicode */
19
-
20
- typedef unsigned long UTF32; /* at least 32 bits */
21
- typedef unsigned short UTF16; /* at least 16 bits */
22
- typedef unsigned char UTF8; /* typically 8 bits */
23
-
24
- #define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
25
- #define UNI_SUR_HIGH_START (UTF32)0xD800
26
- #define UNI_SUR_HIGH_END (UTF32)0xDBFF
27
- #define UNI_SUR_LOW_START (UTF32)0xDC00
28
- #define UNI_SUR_LOW_END (UTF32)0xDFFF
29
-
30
- typedef struct JSON_ParserStruct {
31
- VALUE Vsource;
32
- char *source;
33
- long len;
34
- char *memo;
35
- VALUE create_id;
36
- int max_nesting;
37
- int allow_nan;
38
- int parsing_name;
39
- int symbolize_names;
40
- VALUE object_class;
41
- VALUE array_class;
42
- VALUE decimal_class;
43
- int create_additions;
44
- VALUE match_string;
45
- FBuffer *fbuffer;
46
- } JSON_Parser;
47
-
48
- #define GET_PARSER \
49
- GET_PARSER_INIT; \
50
- if (!json->Vsource) rb_raise(rb_eTypeError, "uninitialized instance")
51
- #define GET_PARSER_INIT \
52
- JSON_Parser *json; \
53
- TypedData_Get_Struct(self, JSON_Parser, &JSON_Parser_type, json)
54
-
55
- #define MinusInfinity "-Infinity"
56
- #define EVIL 0x666
57
-
58
- static UTF32 unescape_unicode(const unsigned char *p);
59
- static int convert_UTF32_to_UTF8(char *buf, UTF32 ch);
60
- static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
61
- static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
62
- static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result);
63
- static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result);
64
- static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
65
- static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd);
66
- static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
67
- static VALUE convert_encoding(VALUE source);
68
- static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self);
69
- static VALUE cParser_parse(VALUE self);
70
- static void JSON_mark(void *json);
71
- static void JSON_free(void *json);
72
- static VALUE cJSON_parser_s_allocate(VALUE klass);
73
- static VALUE cParser_source(VALUE self);
74
- #ifndef ZALLOC
75
- #define ZALLOC(type) ((type *)ruby_zalloc(sizeof(type)))
76
- static inline void *ruby_zalloc(size_t n)
77
- {
78
- void *p = ruby_xmalloc(n);
79
- memset(p, 0, n);
80
- return p;
81
- }
82
- #endif
83
- #ifdef TypedData_Make_Struct
84
- static const rb_data_type_t JSON_Parser_type;
85
- #define NEW_TYPEDDATA_WRAPPER 1
86
- #else
87
- #define TypedData_Make_Struct(klass, type, ignore, json) Data_Make_Struct(klass, type, NULL, JSON_free, json)
88
- #define TypedData_Get_Struct(self, JSON_Parser, ignore, json) Data_Get_Struct(self, JSON_Parser, json)
89
- #endif
90
-
91
- #endif
@@ -1,896 +0,0 @@
1
- #include "../fbuffer/fbuffer.h"
2
- #include "parser.h"
3
-
4
- #if defined HAVE_RUBY_ENCODING_H
5
- # define EXC_ENCODING rb_utf8_encoding(),
6
- # ifndef HAVE_RB_ENC_RAISE
7
- static void
8
- enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
9
- {
10
- va_list args;
11
- VALUE mesg;
12
-
13
- va_start(args, fmt);
14
- mesg = rb_enc_vsprintf(enc, fmt, args);
15
- va_end(args);
16
-
17
- rb_exc_raise(rb_exc_new3(exc, mesg));
18
- }
19
- # define rb_enc_raise enc_raise
20
- # endif
21
- #else
22
- # define EXC_ENCODING /* nothing */
23
- # define rb_enc_raise rb_raise
24
- #endif
25
-
26
- /* unicode */
27
-
28
- static const signed char digit_values[256] = {
29
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
30
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
31
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
32
- -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1,
33
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
34
- 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -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
- -1, -1, -1, -1, -1, -1, -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
43
- };
44
-
45
- static UTF32 unescape_unicode(const unsigned char *p)
46
- {
47
- signed char b;
48
- UTF32 result = 0;
49
- b = digit_values[p[0]];
50
- if (b < 0) return UNI_REPLACEMENT_CHAR;
51
- result = (result << 4) | (unsigned char)b;
52
- b = digit_values[p[1]];
53
- if (b < 0) return UNI_REPLACEMENT_CHAR;
54
- result = (result << 4) | (unsigned char)b;
55
- b = digit_values[p[2]];
56
- if (b < 0) return UNI_REPLACEMENT_CHAR;
57
- result = (result << 4) | (unsigned char)b;
58
- b = digit_values[p[3]];
59
- if (b < 0) return UNI_REPLACEMENT_CHAR;
60
- result = (result << 4) | (unsigned char)b;
61
- return result;
62
- }
63
-
64
- static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
65
- {
66
- int len = 1;
67
- if (ch <= 0x7F) {
68
- buf[0] = (char) ch;
69
- } else if (ch <= 0x07FF) {
70
- buf[0] = (char) ((ch >> 6) | 0xC0);
71
- buf[1] = (char) ((ch & 0x3F) | 0x80);
72
- len++;
73
- } else if (ch <= 0xFFFF) {
74
- buf[0] = (char) ((ch >> 12) | 0xE0);
75
- buf[1] = (char) (((ch >> 6) & 0x3F) | 0x80);
76
- buf[2] = (char) ((ch & 0x3F) | 0x80);
77
- len += 2;
78
- } else if (ch <= 0x1fffff) {
79
- buf[0] =(char) ((ch >> 18) | 0xF0);
80
- buf[1] =(char) (((ch >> 12) & 0x3F) | 0x80);
81
- buf[2] =(char) (((ch >> 6) & 0x3F) | 0x80);
82
- buf[3] =(char) ((ch & 0x3F) | 0x80);
83
- len += 3;
84
- } else {
85
- buf[0] = '?';
86
- }
87
- return len;
88
- }
89
-
90
- static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
91
- static VALUE CNaN, CInfinity, CMinusInfinity;
92
- static VALUE cBigDecimal = Qundef;
93
-
94
- static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
95
- i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
96
- i_object_class, i_array_class, i_decimal_class, i_key_p,
97
- i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
98
- i_leftshift, i_new, i_BigDecimal;
99
-
100
- %%{
101
- machine JSON_common;
102
-
103
- cr = '\n';
104
- cr_neg = [^\n];
105
- ws = [ \t\r\n];
106
- c_comment = '/*' ( any* - (any* '*/' any* ) ) '*/';
107
- cpp_comment = '//' cr_neg* cr;
108
- comment = c_comment | cpp_comment;
109
- ignore = ws | comment;
110
- name_separator = ':';
111
- value_separator = ',';
112
- Vnull = 'null';
113
- Vfalse = 'false';
114
- Vtrue = 'true';
115
- VNaN = 'NaN';
116
- VInfinity = 'Infinity';
117
- VMinusInfinity = '-Infinity';
118
- begin_value = [nft\"\-\[\{NI] | digit;
119
- begin_object = '{';
120
- end_object = '}';
121
- begin_array = '[';
122
- end_array = ']';
123
- begin_string = '"';
124
- begin_name = begin_string;
125
- begin_number = digit | '-';
126
- }%%
127
-
128
- %%{
129
- machine JSON_object;
130
- include JSON_common;
131
-
132
- write data;
133
-
134
- action parse_value {
135
- VALUE v = Qnil;
136
- char *np = JSON_parse_value(json, fpc, pe, &v, current_nesting);
137
- if (np == NULL) {
138
- fhold; fbreak;
139
- } else {
140
- if (NIL_P(json->object_class)) {
141
- rb_hash_aset(*result, last_name, v);
142
- } else {
143
- rb_funcall(*result, i_aset, 2, last_name, v);
144
- }
145
- fexec np;
146
- }
147
- }
148
-
149
- action parse_name {
150
- char *np;
151
- json->parsing_name = 1;
152
- np = JSON_parse_string(json, fpc, pe, &last_name);
153
- json->parsing_name = 0;
154
- if (np == NULL) { fhold; fbreak; } else fexec np;
155
- }
156
-
157
- action exit { fhold; fbreak; }
158
-
159
- pair = ignore* begin_name >parse_name ignore* name_separator ignore* begin_value >parse_value;
160
- next_pair = ignore* value_separator pair;
161
-
162
- main := (
163
- begin_object
164
- (pair (next_pair)*)? ignore*
165
- end_object
166
- ) @exit;
167
- }%%
168
-
169
- static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
170
- {
171
- int cs = EVIL;
172
- VALUE last_name = Qnil;
173
- VALUE object_class = json->object_class;
174
-
175
- if (json->max_nesting && current_nesting > json->max_nesting) {
176
- rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
177
- }
178
-
179
- *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
180
-
181
- %% write init;
182
- %% write exec;
183
-
184
- if (cs >= JSON_object_first_final) {
185
- if (json->create_additions) {
186
- VALUE klassname;
187
- if (NIL_P(json->object_class)) {
188
- klassname = rb_hash_aref(*result, json->create_id);
189
- } else {
190
- klassname = rb_funcall(*result, i_aref, 1, json->create_id);
191
- }
192
- if (!NIL_P(klassname)) {
193
- VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname);
194
- if (RTEST(rb_funcall(klass, i_json_creatable_p, 0))) {
195
- *result = rb_funcall(klass, i_json_create, 1, *result);
196
- }
197
- }
198
- }
199
- return p + 1;
200
- } else {
201
- return NULL;
202
- }
203
- }
204
-
205
-
206
- %%{
207
- machine JSON_value;
208
- include JSON_common;
209
-
210
- write data;
211
-
212
- action parse_null {
213
- *result = Qnil;
214
- }
215
- action parse_false {
216
- *result = Qfalse;
217
- }
218
- action parse_true {
219
- *result = Qtrue;
220
- }
221
- action parse_nan {
222
- if (json->allow_nan) {
223
- *result = CNaN;
224
- } else {
225
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
226
- }
227
- }
228
- action parse_infinity {
229
- if (json->allow_nan) {
230
- *result = CInfinity;
231
- } else {
232
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
233
- }
234
- }
235
- action parse_string {
236
- char *np = JSON_parse_string(json, fpc, pe, result);
237
- if (np == NULL) { fhold; fbreak; } else fexec np;
238
- }
239
-
240
- action parse_number {
241
- char *np;
242
- if(pe > fpc + 8 && !strncmp(MinusInfinity, fpc, 9)) {
243
- if (json->allow_nan) {
244
- *result = CMinusInfinity;
245
- fexec p + 10;
246
- fhold; fbreak;
247
- } else {
248
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
249
- }
250
- }
251
- np = JSON_parse_float(json, fpc, pe, result);
252
- if (np != NULL) fexec np;
253
- np = JSON_parse_integer(json, fpc, pe, result);
254
- if (np != NULL) fexec np;
255
- fhold; fbreak;
256
- }
257
-
258
- action parse_array {
259
- char *np;
260
- np = JSON_parse_array(json, fpc, pe, result, current_nesting + 1);
261
- if (np == NULL) { fhold; fbreak; } else fexec np;
262
- }
263
-
264
- action parse_object {
265
- char *np;
266
- np = JSON_parse_object(json, fpc, pe, result, current_nesting + 1);
267
- if (np == NULL) { fhold; fbreak; } else fexec np;
268
- }
269
-
270
- action exit { fhold; fbreak; }
271
-
272
- main := ignore* (
273
- Vnull @parse_null |
274
- Vfalse @parse_false |
275
- Vtrue @parse_true |
276
- VNaN @parse_nan |
277
- VInfinity @parse_infinity |
278
- begin_number >parse_number |
279
- begin_string >parse_string |
280
- begin_array >parse_array |
281
- begin_object >parse_object
282
- ) ignore* %*exit;
283
- }%%
284
-
285
- static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
286
- {
287
- int cs = EVIL;
288
-
289
- %% write init;
290
- %% write exec;
291
-
292
- if (cs >= JSON_value_first_final) {
293
- return p;
294
- } else {
295
- return NULL;
296
- }
297
- }
298
-
299
- %%{
300
- machine JSON_integer;
301
-
302
- write data;
303
-
304
- action exit { fhold; fbreak; }
305
-
306
- main := '-'? ('0' | [1-9][0-9]*) (^[0-9]? @exit);
307
- }%%
308
-
309
- static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
310
- {
311
- int cs = EVIL;
312
-
313
- %% write init;
314
- json->memo = p;
315
- %% write exec;
316
-
317
- if (cs >= JSON_integer_first_final) {
318
- long len = p - json->memo;
319
- fbuffer_clear(json->fbuffer);
320
- fbuffer_append(json->fbuffer, json->memo, len);
321
- fbuffer_append_char(json->fbuffer, '\0');
322
- *result = rb_cstr2inum(FBUFFER_PTR(json->fbuffer), 10);
323
- return p + 1;
324
- } else {
325
- return NULL;
326
- }
327
- }
328
-
329
- %%{
330
- machine JSON_float;
331
- include JSON_common;
332
-
333
- write data;
334
-
335
- action exit { fhold; fbreak; }
336
-
337
- main := '-'? (
338
- (('0' | [1-9][0-9]*) '.' [0-9]+ ([Ee] [+\-]?[0-9]+)?)
339
- | (('0' | [1-9][0-9]*) ([Ee] [+\-]?[0-9]+))
340
- ) (^[0-9Ee.\-]? @exit );
341
- }%%
342
-
343
- static int is_bigdecimal_class(VALUE obj)
344
- {
345
- if (cBigDecimal == Qundef) {
346
- if (rb_const_defined(rb_cObject, i_BigDecimal)) {
347
- cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal);
348
- }
349
- else {
350
- return 0;
351
- }
352
- }
353
- return obj == cBigDecimal;
354
- }
355
-
356
- static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
357
- {
358
- int cs = EVIL;
359
-
360
- %% write init;
361
- json->memo = p;
362
- %% write exec;
363
-
364
- if (cs >= JSON_float_first_final) {
365
- long len = p - json->memo;
366
- fbuffer_clear(json->fbuffer);
367
- fbuffer_append(json->fbuffer, json->memo, len);
368
- fbuffer_append_char(json->fbuffer, '\0');
369
- if (NIL_P(json->decimal_class)) {
370
- *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
371
- } else {
372
- VALUE text;
373
- text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
374
- if (is_bigdecimal_class(json->decimal_class)) {
375
- *result = rb_funcall(Qnil, i_BigDecimal, 1, text);
376
- } else {
377
- *result = rb_funcall(json->decimal_class, i_new, 1, text);
378
- }
379
- }
380
- return p + 1;
381
- } else {
382
- return NULL;
383
- }
384
- }
385
-
386
-
387
- %%{
388
- machine JSON_array;
389
- include JSON_common;
390
-
391
- write data;
392
-
393
- action parse_value {
394
- VALUE v = Qnil;
395
- char *np = JSON_parse_value(json, fpc, pe, &v, current_nesting);
396
- if (np == NULL) {
397
- fhold; fbreak;
398
- } else {
399
- if (NIL_P(json->array_class)) {
400
- rb_ary_push(*result, v);
401
- } else {
402
- rb_funcall(*result, i_leftshift, 1, v);
403
- }
404
- fexec np;
405
- }
406
- }
407
-
408
- action exit { fhold; fbreak; }
409
-
410
- next_element = value_separator ignore* begin_value >parse_value;
411
-
412
- main := begin_array ignore*
413
- ((begin_value >parse_value ignore*)
414
- (ignore* next_element ignore*)*)?
415
- end_array @exit;
416
- }%%
417
-
418
- static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
419
- {
420
- int cs = EVIL;
421
- VALUE array_class = json->array_class;
422
-
423
- if (json->max_nesting && current_nesting > json->max_nesting) {
424
- rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
425
- }
426
- *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
427
-
428
- %% write init;
429
- %% write exec;
430
-
431
- if(cs >= JSON_array_first_final) {
432
- return p + 1;
433
- } else {
434
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
435
- return NULL;
436
- }
437
- }
438
-
439
- static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
440
- {
441
- char *p = string, *pe = string, *unescape;
442
- int unescape_len;
443
- char buf[4];
444
-
445
- while (pe < stringEnd) {
446
- if (*pe == '\\') {
447
- unescape = (char *) "?";
448
- unescape_len = 1;
449
- if (pe > p) rb_str_buf_cat(result, p, pe - p);
450
- switch (*++pe) {
451
- case 'n':
452
- unescape = (char *) "\n";
453
- break;
454
- case 'r':
455
- unescape = (char *) "\r";
456
- break;
457
- case 't':
458
- unescape = (char *) "\t";
459
- break;
460
- case '"':
461
- unescape = (char *) "\"";
462
- break;
463
- case '\\':
464
- unescape = (char *) "\\";
465
- break;
466
- case 'b':
467
- unescape = (char *) "\b";
468
- break;
469
- case 'f':
470
- unescape = (char *) "\f";
471
- break;
472
- case 'u':
473
- if (pe > stringEnd - 4) {
474
- rb_enc_raise(
475
- EXC_ENCODING eParserError,
476
- "%u: incomplete unicode character escape sequence at '%s'", __LINE__, p
477
- );
478
- } else {
479
- UTF32 ch = unescape_unicode((unsigned char *) ++pe);
480
- pe += 3;
481
- if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
482
- pe++;
483
- if (pe > stringEnd - 6) {
484
- rb_enc_raise(
485
- EXC_ENCODING eParserError,
486
- "%u: incomplete surrogate pair at '%s'", __LINE__, p
487
- );
488
- }
489
- if (pe[0] == '\\' && pe[1] == 'u') {
490
- UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
491
- ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
492
- | (sur & 0x3FF));
493
- pe += 5;
494
- } else {
495
- unescape = (char *) "?";
496
- break;
497
- }
498
- }
499
- unescape_len = convert_UTF32_to_UTF8(buf, ch);
500
- unescape = buf;
501
- }
502
- break;
503
- default:
504
- p = pe;
505
- continue;
506
- }
507
- rb_str_buf_cat(result, unescape, unescape_len);
508
- p = ++pe;
509
- } else {
510
- pe++;
511
- }
512
- }
513
- rb_str_buf_cat(result, p, pe - p);
514
- return result;
515
- }
516
-
517
- %%{
518
- machine JSON_string;
519
- include JSON_common;
520
-
521
- write data;
522
-
523
- action parse_string {
524
- *result = json_string_unescape(*result, json->memo + 1, p);
525
- if (NIL_P(*result)) {
526
- fhold;
527
- fbreak;
528
- } else {
529
- FORCE_UTF8(*result);
530
- fexec p + 1;
531
- }
532
- }
533
-
534
- action exit { fhold; fbreak; }
535
-
536
- main := '"' ((^([\"\\] | 0..0x1f) | '\\'[\"\\/bfnrt] | '\\u'[0-9a-fA-F]{4} | '\\'^([\"\\/bfnrtu]|0..0x1f))* %parse_string) '"' @exit;
537
- }%%
538
-
539
- static int
540
- match_i(VALUE regexp, VALUE klass, VALUE memo)
541
- {
542
- if (regexp == Qundef) return ST_STOP;
543
- if (RTEST(rb_funcall(klass, i_json_creatable_p, 0)) &&
544
- RTEST(rb_funcall(regexp, i_match, 1, rb_ary_entry(memo, 0)))) {
545
- rb_ary_push(memo, klass);
546
- return ST_STOP;
547
- }
548
- return ST_CONTINUE;
549
- }
550
-
551
- static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
552
- {
553
- int cs = EVIL;
554
- VALUE match_string;
555
-
556
- *result = rb_str_buf_new(0);
557
- %% write init;
558
- json->memo = p;
559
- %% write exec;
560
-
561
- if (json->create_additions && RTEST(match_string = json->match_string)) {
562
- VALUE klass;
563
- VALUE memo = rb_ary_new2(2);
564
- rb_ary_push(memo, *result);
565
- rb_hash_foreach(match_string, match_i, memo);
566
- klass = rb_ary_entry(memo, 1);
567
- if (RTEST(klass)) {
568
- *result = rb_funcall(klass, i_json_create, 1, *result);
569
- }
570
- }
571
-
572
- if (json->symbolize_names && json->parsing_name) {
573
- *result = rb_str_intern(*result);
574
- } else if (RB_TYPE_P(*result, T_STRING)) {
575
- rb_str_resize(*result, RSTRING_LEN(*result));
576
- }
577
- if (cs >= JSON_string_first_final) {
578
- return p + 1;
579
- } else {
580
- return NULL;
581
- }
582
- }
583
-
584
- /*
585
- * Document-class: JSON::Ext::Parser
586
- *
587
- * This is the JSON parser implemented as a C extension. It can be configured
588
- * to be used by setting
589
- *
590
- * JSON.parser = JSON::Ext::Parser
591
- *
592
- * with the method parser= in JSON.
593
- *
594
- */
595
-
596
- static VALUE convert_encoding(VALUE source)
597
- {
598
- #ifdef HAVE_RUBY_ENCODING_H
599
- rb_encoding *enc = rb_enc_get(source);
600
- if (enc == rb_ascii8bit_encoding()) {
601
- if (OBJ_FROZEN(source)) {
602
- source = rb_str_dup(source);
603
- }
604
- FORCE_UTF8(source);
605
- } else {
606
- source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
607
- }
608
- #endif
609
- return source;
610
- }
611
-
612
- /*
613
- * call-seq: new(source, opts => {})
614
- *
615
- * Creates a new JSON::Ext::Parser instance for the string _source_.
616
- *
617
- * Creates a new JSON::Ext::Parser instance for the string _source_.
618
- *
619
- * It will be configured by the _opts_ hash. _opts_ can have the following
620
- * keys:
621
- *
622
- * _opts_ can have the following keys:
623
- * * *max_nesting*: The maximum depth of nesting allowed in the parsed data
624
- * structures. Disable depth checking with :max_nesting => false|nil|0, it
625
- * defaults to 100.
626
- * * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
627
- * defiance of RFC 4627 to be parsed by the Parser. This option defaults to
628
- * false.
629
- * * *symbolize_names*: If set to true, returns symbols for the names
630
- * (keys) in a JSON object. Otherwise strings are returned, which is
631
- * also the default. It's not possible to use this option in
632
- * conjunction with the *create_additions* option.
633
- * * *create_additions*: If set to false, the Parser doesn't create
634
- * additions even if a matching class and create_id was found. This option
635
- * defaults to false.
636
- * * *object_class*: Defaults to Hash
637
- * * *array_class*: Defaults to Array
638
- */
639
- static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
640
- {
641
- VALUE source, opts;
642
- GET_PARSER_INIT;
643
-
644
- if (json->Vsource) {
645
- rb_raise(rb_eTypeError, "already initialized instance");
646
- }
647
- #ifdef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
648
- rb_scan_args(argc, argv, "1:", &source, &opts);
649
- #else
650
- rb_scan_args(argc, argv, "11", &source, &opts);
651
- #endif
652
- if (!NIL_P(opts)) {
653
- #ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
654
- opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
655
- if (NIL_P(opts)) {
656
- rb_raise(rb_eArgError, "opts needs to be like a hash");
657
- } else {
658
- #endif
659
- VALUE tmp = ID2SYM(i_max_nesting);
660
- if (option_given_p(opts, tmp)) {
661
- VALUE max_nesting = rb_hash_aref(opts, tmp);
662
- if (RTEST(max_nesting)) {
663
- Check_Type(max_nesting, T_FIXNUM);
664
- json->max_nesting = FIX2INT(max_nesting);
665
- } else {
666
- json->max_nesting = 0;
667
- }
668
- } else {
669
- json->max_nesting = 100;
670
- }
671
- tmp = ID2SYM(i_allow_nan);
672
- if (option_given_p(opts, tmp)) {
673
- json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
674
- } else {
675
- json->allow_nan = 0;
676
- }
677
- tmp = ID2SYM(i_symbolize_names);
678
- if (option_given_p(opts, tmp)) {
679
- json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
680
- } else {
681
- json->symbolize_names = 0;
682
- }
683
- tmp = ID2SYM(i_create_additions);
684
- if (option_given_p(opts, tmp)) {
685
- json->create_additions = RTEST(rb_hash_aref(opts, tmp));
686
- } else {
687
- json->create_additions = 0;
688
- }
689
- if (json->symbolize_names && json->create_additions) {
690
- rb_raise(rb_eArgError,
691
- "options :symbolize_names and :create_additions cannot be "
692
- " used in conjunction");
693
- }
694
- tmp = ID2SYM(i_create_id);
695
- if (option_given_p(opts, tmp)) {
696
- json->create_id = rb_hash_aref(opts, tmp);
697
- } else {
698
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
699
- }
700
- tmp = ID2SYM(i_object_class);
701
- if (option_given_p(opts, tmp)) {
702
- json->object_class = rb_hash_aref(opts, tmp);
703
- } else {
704
- json->object_class = Qnil;
705
- }
706
- tmp = ID2SYM(i_array_class);
707
- if (option_given_p(opts, tmp)) {
708
- json->array_class = rb_hash_aref(opts, tmp);
709
- } else {
710
- json->array_class = Qnil;
711
- }
712
- tmp = ID2SYM(i_decimal_class);
713
- if (option_given_p(opts, tmp)) {
714
- json->decimal_class = rb_hash_aref(opts, tmp);
715
- } else {
716
- json->decimal_class = Qnil;
717
- }
718
- tmp = ID2SYM(i_match_string);
719
- if (option_given_p(opts, tmp)) {
720
- VALUE match_string = rb_hash_aref(opts, tmp);
721
- json->match_string = RTEST(match_string) ? match_string : Qnil;
722
- } else {
723
- json->match_string = Qnil;
724
- }
725
- #ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
726
- }
727
- #endif
728
- } else {
729
- json->max_nesting = 100;
730
- json->allow_nan = 0;
731
- json->create_additions = 0;
732
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
733
- json->object_class = Qnil;
734
- json->array_class = Qnil;
735
- json->decimal_class = Qnil;
736
- }
737
- source = convert_encoding(StringValue(source));
738
- StringValue(source);
739
- json->len = RSTRING_LEN(source);
740
- json->source = RSTRING_PTR(source);;
741
- json->Vsource = source;
742
- return self;
743
- }
744
-
745
- %%{
746
- machine JSON;
747
-
748
- write data;
749
-
750
- include JSON_common;
751
-
752
- action parse_value {
753
- char *np = JSON_parse_value(json, fpc, pe, &result, 0);
754
- if (np == NULL) { fhold; fbreak; } else fexec np;
755
- }
756
-
757
- main := ignore* (
758
- begin_value >parse_value
759
- ) ignore*;
760
- }%%
761
-
762
- /*
763
- * call-seq: parse()
764
- *
765
- * Parses the current JSON text _source_ and returns the complete data
766
- * structure as a result.
767
- */
768
- static VALUE cParser_parse(VALUE self)
769
- {
770
- char *p, *pe;
771
- int cs = EVIL;
772
- VALUE result = Qnil;
773
- GET_PARSER;
774
-
775
- %% write init;
776
- p = json->source;
777
- pe = p + json->len;
778
- %% write exec;
779
-
780
- if (cs >= JSON_first_final && p == pe) {
781
- return result;
782
- } else {
783
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
784
- return Qnil;
785
- }
786
- }
787
-
788
- static void JSON_mark(void *ptr)
789
- {
790
- JSON_Parser *json = ptr;
791
- rb_gc_mark_maybe(json->Vsource);
792
- rb_gc_mark_maybe(json->create_id);
793
- rb_gc_mark_maybe(json->object_class);
794
- rb_gc_mark_maybe(json->array_class);
795
- rb_gc_mark_maybe(json->decimal_class);
796
- rb_gc_mark_maybe(json->match_string);
797
- }
798
-
799
- static void JSON_free(void *ptr)
800
- {
801
- JSON_Parser *json = ptr;
802
- fbuffer_free(json->fbuffer);
803
- ruby_xfree(json);
804
- }
805
-
806
- static size_t JSON_memsize(const void *ptr)
807
- {
808
- const JSON_Parser *json = ptr;
809
- return sizeof(*json) + FBUFFER_CAPA(json->fbuffer);
810
- }
811
-
812
- #ifdef NEW_TYPEDDATA_WRAPPER
813
- static const rb_data_type_t JSON_Parser_type = {
814
- "JSON/Parser",
815
- {JSON_mark, JSON_free, JSON_memsize,},
816
- #ifdef RUBY_TYPED_FREE_IMMEDIATELY
817
- 0, 0,
818
- RUBY_TYPED_FREE_IMMEDIATELY,
819
- #endif
820
- };
821
- #endif
822
-
823
- static VALUE cJSON_parser_s_allocate(VALUE klass)
824
- {
825
- JSON_Parser *json;
826
- VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json);
827
- json->fbuffer = fbuffer_alloc(0);
828
- return obj;
829
- }
830
-
831
- /*
832
- * call-seq: source()
833
- *
834
- * Returns a copy of the current _source_ string, that was used to construct
835
- * this Parser.
836
- */
837
- static VALUE cParser_source(VALUE self)
838
- {
839
- GET_PARSER;
840
- return rb_str_dup(json->Vsource);
841
- }
842
-
843
- void Init_parser(void)
844
- {
845
- #undef rb_intern
846
- rb_require("json/common");
847
- mJSON = rb_define_module("JSON");
848
- mExt = rb_define_module_under(mJSON, "Ext");
849
- cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
850
- eParserError = rb_path2class("JSON::ParserError");
851
- eNestingError = rb_path2class("JSON::NestingError");
852
- rb_gc_register_mark_object(eParserError);
853
- rb_gc_register_mark_object(eNestingError);
854
- rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
855
- rb_define_method(cParser, "initialize", cParser_initialize, -1);
856
- rb_define_method(cParser, "parse", cParser_parse, 0);
857
- rb_define_method(cParser, "source", cParser_source, 0);
858
-
859
- CNaN = rb_const_get(mJSON, rb_intern("NaN"));
860
- rb_gc_register_mark_object(CNaN);
861
-
862
- CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
863
- rb_gc_register_mark_object(CInfinity);
864
-
865
- CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
866
- rb_gc_register_mark_object(CMinusInfinity);
867
-
868
- i_json_creatable_p = rb_intern("json_creatable?");
869
- i_json_create = rb_intern("json_create");
870
- i_create_id = rb_intern("create_id");
871
- i_create_additions = rb_intern("create_additions");
872
- i_chr = rb_intern("chr");
873
- i_max_nesting = rb_intern("max_nesting");
874
- i_allow_nan = rb_intern("allow_nan");
875
- i_symbolize_names = rb_intern("symbolize_names");
876
- i_object_class = rb_intern("object_class");
877
- i_array_class = rb_intern("array_class");
878
- i_decimal_class = rb_intern("decimal_class");
879
- i_match = rb_intern("match");
880
- i_match_string = rb_intern("match_string");
881
- i_key_p = rb_intern("key?");
882
- i_deep_const_get = rb_intern("deep_const_get");
883
- i_aset = rb_intern("[]=");
884
- i_aref = rb_intern("[]");
885
- i_leftshift = rb_intern("<<");
886
- i_new = rb_intern("new");
887
- i_BigDecimal = rb_intern("BigDecimal");
888
- }
889
-
890
- /*
891
- * Local variables:
892
- * mode: c
893
- * c-file-style: ruby
894
- * indent-tabs-mode: nil
895
- * End:
896
- */