json_pure 2.4.0 → 2.4.1

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