json_pure 2.1.0 → 2.4.1

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