json_pure 2.2.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +51 -0
  3. data/LICENSE +56 -0
  4. data/README.md +17 -1
  5. data/VERSION +1 -1
  6. data/json_pure.gemspec +49 -26
  7. data/lib/json.rb +549 -29
  8. data/lib/json/add/bigdecimal.rb +2 -2
  9. data/lib/json/add/complex.rb +2 -3
  10. data/lib/json/add/rational.rb +2 -3
  11. data/lib/json/add/regexp.rb +2 -2
  12. data/lib/json/common.rb +370 -125
  13. data/lib/json/pure/generator.rb +31 -10
  14. data/lib/json/pure/parser.rb +31 -5
  15. data/lib/json/version.rb +1 -1
  16. data/tests/fixtures/fail29.json +1 -0
  17. data/tests/fixtures/fail30.json +1 -0
  18. data/tests/fixtures/fail31.json +1 -0
  19. data/tests/fixtures/fail32.json +1 -0
  20. data/tests/json_addition_test.rb +0 -4
  21. data/tests/json_common_interface_test.rb +47 -4
  22. data/tests/json_fixtures_test.rb +9 -1
  23. data/tests/json_generator_test.rb +30 -8
  24. data/tests/json_parser_test.rb +39 -14
  25. data/tests/lib/core_assertions.rb +763 -0
  26. data/tests/lib/envutil.rb +365 -0
  27. data/tests/lib/find_executable.rb +22 -0
  28. data/tests/lib/helper.rb +4 -0
  29. data/tests/ractor_test.rb +30 -0
  30. data/tests/test_helper.rb +3 -3
  31. metadata +28 -48
  32. data/.gitignore +0 -17
  33. data/.travis.yml +0 -23
  34. data/README-json-jruby.md +0 -33
  35. data/Rakefile +0 -408
  36. data/diagrams/.keep +0 -0
  37. data/ext/json/ext/fbuffer/fbuffer.h +0 -187
  38. data/ext/json/ext/generator/depend +0 -1
  39. data/ext/json/ext/generator/extconf.rb +0 -4
  40. data/ext/json/ext/generator/generator.c +0 -1444
  41. data/ext/json/ext/generator/generator.h +0 -171
  42. data/ext/json/ext/parser/depend +0 -1
  43. data/ext/json/ext/parser/extconf.rb +0 -6
  44. data/ext/json/ext/parser/parser.c +0 -2131
  45. data/ext/json/ext/parser/parser.h +0 -91
  46. data/ext/json/ext/parser/parser.rl +0 -891
  47. data/ext/json/extconf.rb +0 -2
  48. data/install.rb +0 -23
  49. data/java/src/json/ext/ByteListTranscoder.java +0 -166
  50. data/java/src/json/ext/Generator.java +0 -443
  51. data/java/src/json/ext/GeneratorMethods.java +0 -231
  52. data/java/src/json/ext/GeneratorService.java +0 -42
  53. data/java/src/json/ext/GeneratorState.java +0 -490
  54. data/java/src/json/ext/OptionsReader.java +0 -113
  55. data/java/src/json/ext/Parser.java +0 -2362
  56. data/java/src/json/ext/Parser.rl +0 -893
  57. data/java/src/json/ext/ParserService.java +0 -34
  58. data/java/src/json/ext/RuntimeInfo.java +0 -116
  59. data/java/src/json/ext/StringDecoder.java +0 -166
  60. data/java/src/json/ext/StringEncoder.java +0 -111
  61. data/java/src/json/ext/Utils.java +0 -88
  62. data/json-java.gemspec +0 -38
  63. data/json.gemspec +0 -0
  64. data/references/rfc7159.txt +0 -899
  65. data/tools/diff.sh +0 -18
  66. data/tools/fuzz.rb +0 -131
  67. 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,891 +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 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
- 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 {
575
- if (RB_TYPE_P(*result, T_STRING)) {
576
- rb_str_resize(*result, RSTRING_LEN(*result));
577
- }
578
- }
579
- if (cs >= JSON_string_first_final) {
580
- return p + 1;
581
- } else {
582
- return NULL;
583
- }
584
- }
585
-
586
- /*
587
- * Document-class: JSON::Ext::Parser
588
- *
589
- * This is the JSON parser implemented as a C extension. It can be configured
590
- * to be used by setting
591
- *
592
- * JSON.parser = JSON::Ext::Parser
593
- *
594
- * with the method parser= in JSON.
595
- *
596
- */
597
-
598
- static VALUE convert_encoding(VALUE source)
599
- {
600
- #ifdef HAVE_RUBY_ENCODING_H
601
- rb_encoding *enc = rb_enc_get(source);
602
- if (enc == rb_ascii8bit_encoding()) {
603
- if (OBJ_FROZEN(source)) {
604
- source = rb_str_dup(source);
605
- }
606
- FORCE_UTF8(source);
607
- } else {
608
- source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
609
- }
610
- #endif
611
- return source;
612
- }
613
-
614
- /*
615
- * call-seq: new(source, opts => {})
616
- *
617
- * Creates a new JSON::Ext::Parser instance for the string _source_.
618
- *
619
- * Creates a new JSON::Ext::Parser instance for the string _source_.
620
- *
621
- * It will be configured by the _opts_ hash. _opts_ can have the following
622
- * keys:
623
- *
624
- * _opts_ can have the following keys:
625
- * * *max_nesting*: The maximum depth of nesting allowed in the parsed data
626
- * structures. Disable depth checking with :max_nesting => false|nil|0, it
627
- * defaults to 100.
628
- * * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
629
- * defiance of RFC 4627 to be parsed by the Parser. This option defaults to
630
- * false.
631
- * * *symbolize_names*: If set to true, returns symbols for the names
632
- * (keys) in a JSON object. Otherwise strings are returned, which is
633
- * also the default. It's not possible to use this option in
634
- * conjunction with the *create_additions* option.
635
- * * *create_additions*: If set to false, the Parser doesn't create
636
- * additions even if a matching class and create_id was found. This option
637
- * defaults to false.
638
- * * *object_class*: Defaults to Hash
639
- * * *array_class*: Defaults to Array
640
- */
641
- static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
642
- {
643
- VALUE source, opts;
644
- GET_PARSER_INIT;
645
-
646
- if (json->Vsource) {
647
- rb_raise(rb_eTypeError, "already initialized instance");
648
- }
649
- #ifdef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
650
- rb_scan_args(argc, argv, "1:", &source, &opts);
651
- #else
652
- rb_scan_args(argc, argv, "11", &source, &opts);
653
- #endif
654
- if (!NIL_P(opts)) {
655
- #ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
656
- opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
657
- if (NIL_P(opts)) {
658
- rb_raise(rb_eArgError, "opts needs to be like a hash");
659
- } else {
660
- #endif
661
- VALUE tmp = ID2SYM(i_max_nesting);
662
- if (option_given_p(opts, tmp)) {
663
- VALUE max_nesting = rb_hash_aref(opts, tmp);
664
- if (RTEST(max_nesting)) {
665
- Check_Type(max_nesting, T_FIXNUM);
666
- json->max_nesting = FIX2INT(max_nesting);
667
- } else {
668
- json->max_nesting = 0;
669
- }
670
- } else {
671
- json->max_nesting = 100;
672
- }
673
- tmp = ID2SYM(i_allow_nan);
674
- if (option_given_p(opts, tmp)) {
675
- json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
676
- } else {
677
- json->allow_nan = 0;
678
- }
679
- tmp = ID2SYM(i_symbolize_names);
680
- if (option_given_p(opts, tmp)) {
681
- json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
682
- } else {
683
- json->symbolize_names = 0;
684
- }
685
- tmp = ID2SYM(i_create_additions);
686
- if (option_given_p(opts, tmp)) {
687
- json->create_additions = RTEST(rb_hash_aref(opts, tmp));
688
- } else {
689
- json->create_additions = 0;
690
- }
691
- if (json->symbolize_names && json->create_additions) {
692
- rb_raise(rb_eArgError,
693
- "options :symbolize_names and :create_additions cannot be "
694
- " used in conjunction");
695
- }
696
- tmp = ID2SYM(i_create_id);
697
- if (option_given_p(opts, tmp)) {
698
- json->create_id = rb_hash_aref(opts, tmp);
699
- } else {
700
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
701
- }
702
- tmp = ID2SYM(i_object_class);
703
- if (option_given_p(opts, tmp)) {
704
- json->object_class = rb_hash_aref(opts, tmp);
705
- } else {
706
- json->object_class = Qnil;
707
- }
708
- tmp = ID2SYM(i_array_class);
709
- if (option_given_p(opts, tmp)) {
710
- json->array_class = rb_hash_aref(opts, tmp);
711
- } else {
712
- json->array_class = Qnil;
713
- }
714
- tmp = ID2SYM(i_decimal_class);
715
- if (option_given_p(opts, tmp)) {
716
- json->decimal_class = rb_hash_aref(opts, tmp);
717
- } else {
718
- json->decimal_class = Qnil;
719
- }
720
- tmp = ID2SYM(i_match_string);
721
- if (option_given_p(opts, tmp)) {
722
- VALUE match_string = rb_hash_aref(opts, tmp);
723
- json->match_string = RTEST(match_string) ? match_string : Qnil;
724
- } else {
725
- json->match_string = Qnil;
726
- }
727
- #ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
728
- }
729
- #endif
730
- } else {
731
- json->max_nesting = 100;
732
- json->allow_nan = 0;
733
- json->create_additions = 1;
734
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
735
- json->object_class = Qnil;
736
- json->array_class = Qnil;
737
- json->decimal_class = Qnil;
738
- }
739
- source = convert_encoding(StringValue(source));
740
- StringValue(source);
741
- json->len = RSTRING_LEN(source);
742
- json->source = RSTRING_PTR(source);;
743
- json->Vsource = source;
744
- return self;
745
- }
746
-
747
- %%{
748
- machine JSON;
749
-
750
- write data;
751
-
752
- include JSON_common;
753
-
754
- action parse_value {
755
- char *np = JSON_parse_value(json, fpc, pe, &result, 0);
756
- if (np == NULL) { fhold; fbreak; } else fexec np;
757
- }
758
-
759
- main := ignore* (
760
- begin_value >parse_value
761
- ) ignore*;
762
- }%%
763
-
764
- /*
765
- * call-seq: parse()
766
- *
767
- * Parses the current JSON text _source_ and returns the complete data
768
- * structure as a result.
769
- */
770
- static VALUE cParser_parse(VALUE self)
771
- {
772
- char *p, *pe;
773
- int cs = EVIL;
774
- VALUE result = Qnil;
775
- GET_PARSER;
776
-
777
- %% write init;
778
- p = json->source;
779
- pe = p + json->len;
780
- %% write exec;
781
-
782
- if (cs >= JSON_first_final && p == pe) {
783
- return result;
784
- } else {
785
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
786
- return Qnil;
787
- }
788
- }
789
-
790
- static void JSON_mark(void *ptr)
791
- {
792
- JSON_Parser *json = ptr;
793
- rb_gc_mark_maybe(json->Vsource);
794
- rb_gc_mark_maybe(json->create_id);
795
- rb_gc_mark_maybe(json->object_class);
796
- rb_gc_mark_maybe(json->array_class);
797
- rb_gc_mark_maybe(json->decimal_class);
798
- rb_gc_mark_maybe(json->match_string);
799
- }
800
-
801
- static void JSON_free(void *ptr)
802
- {
803
- JSON_Parser *json = ptr;
804
- fbuffer_free(json->fbuffer);
805
- ruby_xfree(json);
806
- }
807
-
808
- static size_t JSON_memsize(const void *ptr)
809
- {
810
- const JSON_Parser *json = ptr;
811
- return sizeof(*json) + FBUFFER_CAPA(json->fbuffer);
812
- }
813
-
814
- #ifdef NEW_TYPEDDATA_WRAPPER
815
- static const rb_data_type_t JSON_Parser_type = {
816
- "JSON/Parser",
817
- {JSON_mark, JSON_free, JSON_memsize,},
818
- #ifdef RUBY_TYPED_FREE_IMMEDIATELY
819
- 0, 0,
820
- RUBY_TYPED_FREE_IMMEDIATELY,
821
- #endif
822
- };
823
- #endif
824
-
825
- static VALUE cJSON_parser_s_allocate(VALUE klass)
826
- {
827
- JSON_Parser *json;
828
- VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json);
829
- json->fbuffer = fbuffer_alloc(0);
830
- return obj;
831
- }
832
-
833
- /*
834
- * call-seq: source()
835
- *
836
- * Returns a copy of the current _source_ string, that was used to construct
837
- * this Parser.
838
- */
839
- static VALUE cParser_source(VALUE self)
840
- {
841
- GET_PARSER;
842
- return rb_str_dup(json->Vsource);
843
- }
844
-
845
- void Init_parser(void)
846
- {
847
- #undef rb_intern
848
- rb_require("json/common");
849
- mJSON = rb_define_module("JSON");
850
- mExt = rb_define_module_under(mJSON, "Ext");
851
- cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
852
- eParserError = rb_path2class("JSON::ParserError");
853
- eNestingError = rb_path2class("JSON::NestingError");
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
- CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
861
- CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
862
-
863
- i_json_creatable_p = rb_intern("json_creatable?");
864
- i_json_create = rb_intern("json_create");
865
- i_create_id = rb_intern("create_id");
866
- i_create_additions = rb_intern("create_additions");
867
- i_chr = rb_intern("chr");
868
- i_max_nesting = rb_intern("max_nesting");
869
- i_allow_nan = rb_intern("allow_nan");
870
- i_symbolize_names = rb_intern("symbolize_names");
871
- i_object_class = rb_intern("object_class");
872
- i_array_class = rb_intern("array_class");
873
- i_decimal_class = rb_intern("decimal_class");
874
- i_match = rb_intern("match");
875
- i_match_string = rb_intern("match_string");
876
- i_key_p = rb_intern("key?");
877
- i_deep_const_get = rb_intern("deep_const_get");
878
- i_aset = rb_intern("[]=");
879
- i_aref = rb_intern("[]");
880
- i_leftshift = rb_intern("<<");
881
- i_new = rb_intern("new");
882
- i_BigDecimal = rb_intern("BigDecimal");
883
- }
884
-
885
- /*
886
- * Local variables:
887
- * mode: c
888
- * c-file-style: ruby
889
- * indent-tabs-mode: nil
890
- * End:
891
- */