json 2.7.2 → 2.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/BSDL +22 -0
- data/CHANGES.md +73 -17
- data/LEGAL +60 -0
- data/README.md +15 -236
- data/ext/json/ext/fbuffer/fbuffer.h +76 -79
- data/ext/json/ext/generator/extconf.rb +8 -2
- data/ext/json/ext/generator/generator.c +776 -816
- data/ext/json/ext/parser/extconf.rb +7 -27
- data/ext/json/ext/parser/parser.c +1697 -670
- data/ext/json/ext/parser/parser.rl +832 -338
- data/json.gemspec +45 -49
- data/lib/json/add/bigdecimal.rb +2 -2
- data/lib/json/add/complex.rb +1 -1
- data/lib/json/add/core.rb +1 -1
- data/lib/json/add/date.rb +1 -1
- data/lib/json/add/date_time.rb +1 -1
- data/lib/json/add/exception.rb +1 -1
- data/lib/json/add/ostruct.rb +1 -1
- data/lib/json/add/range.rb +1 -1
- data/lib/json/add/rational.rb +1 -1
- data/lib/json/add/regexp.rb +1 -1
- data/lib/json/add/struct.rb +1 -1
- data/lib/json/add/symbol.rb +1 -2
- data/lib/json/add/time.rb +3 -10
- data/lib/json/common.rb +273 -95
- data/lib/json/ext/generator/state.rb +105 -0
- data/lib/json/ext.rb +13 -5
- data/lib/json/generic_object.rb +1 -1
- data/lib/json/{pure → truffle_ruby}/generator.rb +228 -120
- data/lib/json/version.rb +3 -7
- data/lib/json.rb +16 -21
- metadata +19 -21
- data/ext/json/ext/generator/depend +0 -1
- data/ext/json/ext/generator/generator.h +0 -177
- data/ext/json/ext/parser/depend +0 -1
- data/ext/json/ext/parser/parser.h +0 -96
- data/ext/json/extconf.rb +0 -3
- data/lib/json/pure/parser.rb +0 -337
- data/lib/json/pure.rb +0 -15
- /data/{LICENSE → COPYING} +0 -0
@@ -1,30 +1,322 @@
|
|
1
1
|
/* This file is automatically generated from parser.rl by using ragel */
|
2
2
|
#line 1 "parser.rl"
|
3
|
+
#include "ruby.h"
|
3
4
|
#include "../fbuffer/fbuffer.h"
|
4
|
-
#include "parser.h"
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
static
|
10
|
-
|
6
|
+
static VALUE mJSON, mExt, cParser, eNestingError, Encoding_UTF_8;
|
7
|
+
static VALUE CNaN, CInfinity, CMinusInfinity;
|
8
|
+
|
9
|
+
static ID i_json_creatable_p, i_json_create, i_create_id,
|
10
|
+
i_chr, i_deep_const_get, i_match, i_aset, i_aref,
|
11
|
+
i_leftshift, i_new, i_try_convert, i_uminus, i_encode;
|
12
|
+
|
13
|
+
static VALUE sym_max_nesting, sym_allow_nan, sym_allow_trailing_comma, sym_symbolize_names, sym_freeze,
|
14
|
+
sym_create_additions, sym_create_id, sym_object_class, sym_array_class,
|
15
|
+
sym_decimal_class, sym_match_string;
|
16
|
+
|
17
|
+
static int binary_encindex;
|
18
|
+
static int utf8_encindex;
|
19
|
+
|
20
|
+
#ifdef HAVE_RB_CATEGORY_WARN
|
21
|
+
# define json_deprecated(message) rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, message)
|
22
|
+
#else
|
23
|
+
# define json_deprecated(message) rb_warn(message)
|
24
|
+
#endif
|
25
|
+
|
26
|
+
static const char deprecated_create_additions_warning[] =
|
27
|
+
"JSON.load implicit support for `create_additions: true` is deprecated "
|
28
|
+
"and will be removed in 3.0, use JSON.unsafe_load or explicitly "
|
29
|
+
"pass `create_additions: true`";
|
30
|
+
|
31
|
+
#ifndef HAVE_RB_GC_MARK_LOCATIONS
|
32
|
+
// For TruffleRuby
|
33
|
+
void rb_gc_mark_locations(const VALUE *start, const VALUE *end)
|
11
34
|
{
|
12
|
-
|
13
|
-
VALUE mesg;
|
35
|
+
VALUE *value = start;
|
14
36
|
|
15
|
-
|
16
|
-
|
17
|
-
|
37
|
+
while (value < end) {
|
38
|
+
rb_gc_mark(*value);
|
39
|
+
value++;
|
40
|
+
}
|
41
|
+
}
|
42
|
+
#endif
|
18
43
|
|
19
|
-
|
44
|
+
#ifndef HAVE_RB_HASH_BULK_INSERT
|
45
|
+
// For TruffleRuby
|
46
|
+
void rb_hash_bulk_insert(long count, const VALUE *pairs, VALUE hash)
|
47
|
+
{
|
48
|
+
long index = 0;
|
49
|
+
while (index < count) {
|
50
|
+
VALUE name = pairs[index++];
|
51
|
+
VALUE value = pairs[index++];
|
52
|
+
rb_hash_aset(hash, name, value);
|
53
|
+
}
|
54
|
+
RB_GC_GUARD(hash);
|
20
55
|
}
|
21
|
-
# define rb_enc_raise enc_raise
|
22
|
-
# endif
|
23
|
-
#else
|
24
|
-
# define EXC_ENCODING /* nothing */
|
25
|
-
# define rb_enc_raise rb_raise
|
26
56
|
#endif
|
27
57
|
|
58
|
+
/* name cache */
|
59
|
+
|
60
|
+
#include <string.h>
|
61
|
+
#include <ctype.h>
|
62
|
+
|
63
|
+
// Object names are likely to be repeated, and are frozen.
|
64
|
+
// As such we can re-use them if we keep a cache of the ones we've seen so far,
|
65
|
+
// and save much more expensive lookups into the global fstring table.
|
66
|
+
// This cache implementation is deliberately simple, as we're optimizing for compactness,
|
67
|
+
// to be able to fit safely on the stack.
|
68
|
+
// As such, binary search into a sorted array gives a good tradeoff between compactness and
|
69
|
+
// performance.
|
70
|
+
#define JSON_RVALUE_CACHE_CAPA 63
|
71
|
+
typedef struct rvalue_cache_struct {
|
72
|
+
int length;
|
73
|
+
VALUE entries[JSON_RVALUE_CACHE_CAPA];
|
74
|
+
} rvalue_cache;
|
75
|
+
|
76
|
+
static rb_encoding *enc_utf8;
|
77
|
+
|
78
|
+
#define JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH 55
|
79
|
+
|
80
|
+
static inline VALUE build_interned_string(const char *str, const long length)
|
81
|
+
{
|
82
|
+
# ifdef HAVE_RB_ENC_INTERNED_STR
|
83
|
+
return rb_enc_interned_str(str, length, enc_utf8);
|
84
|
+
# else
|
85
|
+
VALUE rstring = rb_utf8_str_new(str, length);
|
86
|
+
return rb_funcall(rb_str_freeze(rstring), i_uminus, 0);
|
87
|
+
# endif
|
88
|
+
}
|
89
|
+
|
90
|
+
static inline VALUE build_symbol(const char *str, const long length)
|
91
|
+
{
|
92
|
+
return rb_str_intern(build_interned_string(str, length));
|
93
|
+
}
|
94
|
+
|
95
|
+
static void rvalue_cache_insert_at(rvalue_cache *cache, int index, VALUE rstring)
|
96
|
+
{
|
97
|
+
MEMMOVE(&cache->entries[index + 1], &cache->entries[index], VALUE, cache->length - index);
|
98
|
+
cache->length++;
|
99
|
+
cache->entries[index] = rstring;
|
100
|
+
}
|
101
|
+
|
102
|
+
static inline int rstring_cache_cmp(const char *str, const long length, VALUE rstring)
|
103
|
+
{
|
104
|
+
long rstring_length = RSTRING_LEN(rstring);
|
105
|
+
if (length == rstring_length) {
|
106
|
+
return memcmp(str, RSTRING_PTR(rstring), length);
|
107
|
+
} else {
|
108
|
+
return (int)(length - rstring_length);
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
static VALUE rstring_cache_fetch(rvalue_cache *cache, const char *str, const long length)
|
113
|
+
{
|
114
|
+
if (RB_UNLIKELY(length > JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH)) {
|
115
|
+
// Common names aren't likely to be very long. So we just don't
|
116
|
+
// cache names above an arbitrary threshold.
|
117
|
+
return Qfalse;
|
118
|
+
}
|
119
|
+
|
120
|
+
if (RB_UNLIKELY(!isalpha(str[0]))) {
|
121
|
+
// Simple heuristic, if the first character isn't a letter,
|
122
|
+
// we're much less likely to see this string again.
|
123
|
+
// We mostly want to cache strings that are likely to be repeated.
|
124
|
+
return Qfalse;
|
125
|
+
}
|
126
|
+
|
127
|
+
int low = 0;
|
128
|
+
int high = cache->length - 1;
|
129
|
+
int mid = 0;
|
130
|
+
int last_cmp = 0;
|
131
|
+
|
132
|
+
while (low <= high) {
|
133
|
+
mid = (high + low) >> 1;
|
134
|
+
VALUE entry = cache->entries[mid];
|
135
|
+
last_cmp = rstring_cache_cmp(str, length, entry);
|
136
|
+
|
137
|
+
if (last_cmp == 0) {
|
138
|
+
return entry;
|
139
|
+
} else if (last_cmp > 0) {
|
140
|
+
low = mid + 1;
|
141
|
+
} else {
|
142
|
+
high = mid - 1;
|
143
|
+
}
|
144
|
+
}
|
145
|
+
|
146
|
+
if (RB_UNLIKELY(memchr(str, '\\', length))) {
|
147
|
+
// We assume the overwhelming majority of names don't need to be escaped.
|
148
|
+
// But if they do, we have to fallback to the slow path.
|
149
|
+
return Qfalse;
|
150
|
+
}
|
151
|
+
|
152
|
+
VALUE rstring = build_interned_string(str, length);
|
153
|
+
|
154
|
+
if (cache->length < JSON_RVALUE_CACHE_CAPA) {
|
155
|
+
if (last_cmp > 0) {
|
156
|
+
mid += 1;
|
157
|
+
}
|
158
|
+
|
159
|
+
rvalue_cache_insert_at(cache, mid, rstring);
|
160
|
+
}
|
161
|
+
return rstring;
|
162
|
+
}
|
163
|
+
|
164
|
+
static VALUE rsymbol_cache_fetch(rvalue_cache *cache, const char *str, const long length)
|
165
|
+
{
|
166
|
+
if (RB_UNLIKELY(length > JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH)) {
|
167
|
+
// Common names aren't likely to be very long. So we just don't
|
168
|
+
// cache names above an arbitrary threshold.
|
169
|
+
return Qfalse;
|
170
|
+
}
|
171
|
+
|
172
|
+
if (RB_UNLIKELY(!isalpha(str[0]))) {
|
173
|
+
// Simple heuristic, if the first character isn't a letter,
|
174
|
+
// we're much less likely to see this string again.
|
175
|
+
// We mostly want to cache strings that are likely to be repeated.
|
176
|
+
return Qfalse;
|
177
|
+
}
|
178
|
+
|
179
|
+
int low = 0;
|
180
|
+
int high = cache->length - 1;
|
181
|
+
int mid = 0;
|
182
|
+
int last_cmp = 0;
|
183
|
+
|
184
|
+
while (low <= high) {
|
185
|
+
mid = (high + low) >> 1;
|
186
|
+
VALUE entry = cache->entries[mid];
|
187
|
+
last_cmp = rstring_cache_cmp(str, length, rb_sym2str(entry));
|
188
|
+
|
189
|
+
if (last_cmp == 0) {
|
190
|
+
return entry;
|
191
|
+
} else if (last_cmp > 0) {
|
192
|
+
low = mid + 1;
|
193
|
+
} else {
|
194
|
+
high = mid - 1;
|
195
|
+
}
|
196
|
+
}
|
197
|
+
|
198
|
+
if (RB_UNLIKELY(memchr(str, '\\', length))) {
|
199
|
+
// We assume the overwhelming majority of names don't need to be escaped.
|
200
|
+
// But if they do, we have to fallback to the slow path.
|
201
|
+
return Qfalse;
|
202
|
+
}
|
203
|
+
|
204
|
+
VALUE rsymbol = build_symbol(str, length);
|
205
|
+
|
206
|
+
if (cache->length < JSON_RVALUE_CACHE_CAPA) {
|
207
|
+
if (last_cmp > 0) {
|
208
|
+
mid += 1;
|
209
|
+
}
|
210
|
+
|
211
|
+
rvalue_cache_insert_at(cache, mid, rsymbol);
|
212
|
+
}
|
213
|
+
return rsymbol;
|
214
|
+
}
|
215
|
+
|
216
|
+
/* rvalue stack */
|
217
|
+
|
218
|
+
#define RVALUE_STACK_INITIAL_CAPA 128
|
219
|
+
|
220
|
+
enum rvalue_stack_type {
|
221
|
+
RVALUE_STACK_HEAP_ALLOCATED = 0,
|
222
|
+
RVALUE_STACK_STACK_ALLOCATED = 1,
|
223
|
+
};
|
224
|
+
|
225
|
+
typedef struct rvalue_stack_struct {
|
226
|
+
enum rvalue_stack_type type;
|
227
|
+
long capa;
|
228
|
+
long head;
|
229
|
+
VALUE *ptr;
|
230
|
+
} rvalue_stack;
|
231
|
+
|
232
|
+
static rvalue_stack *rvalue_stack_spill(rvalue_stack *old_stack, VALUE *handle, rvalue_stack **stack_ref);
|
233
|
+
|
234
|
+
static rvalue_stack *rvalue_stack_grow(rvalue_stack *stack, VALUE *handle, rvalue_stack **stack_ref)
|
235
|
+
{
|
236
|
+
long required = stack->capa * 2;
|
237
|
+
|
238
|
+
if (stack->type == RVALUE_STACK_STACK_ALLOCATED) {
|
239
|
+
stack = rvalue_stack_spill(stack, handle, stack_ref);
|
240
|
+
} else {
|
241
|
+
REALLOC_N(stack->ptr, VALUE, required);
|
242
|
+
stack->capa = required;
|
243
|
+
}
|
244
|
+
return stack;
|
245
|
+
}
|
246
|
+
|
247
|
+
static void rvalue_stack_push(rvalue_stack *stack, VALUE value, VALUE *handle, rvalue_stack **stack_ref)
|
248
|
+
{
|
249
|
+
if (RB_UNLIKELY(stack->head >= stack->capa)) {
|
250
|
+
stack = rvalue_stack_grow(stack, handle, stack_ref);
|
251
|
+
}
|
252
|
+
stack->ptr[stack->head] = value;
|
253
|
+
stack->head++;
|
254
|
+
}
|
255
|
+
|
256
|
+
static inline VALUE *rvalue_stack_peek(rvalue_stack *stack, long count)
|
257
|
+
{
|
258
|
+
return stack->ptr + (stack->head - count);
|
259
|
+
}
|
260
|
+
|
261
|
+
static inline void rvalue_stack_pop(rvalue_stack *stack, long count)
|
262
|
+
{
|
263
|
+
stack->head -= count;
|
264
|
+
}
|
265
|
+
|
266
|
+
static void rvalue_stack_mark(void *ptr)
|
267
|
+
{
|
268
|
+
rvalue_stack *stack = (rvalue_stack *)ptr;
|
269
|
+
rb_gc_mark_locations(stack->ptr, stack->ptr + stack->head);
|
270
|
+
}
|
271
|
+
|
272
|
+
static void rvalue_stack_free(void *ptr)
|
273
|
+
{
|
274
|
+
rvalue_stack *stack = (rvalue_stack *)ptr;
|
275
|
+
if (stack) {
|
276
|
+
ruby_xfree(stack->ptr);
|
277
|
+
ruby_xfree(stack);
|
278
|
+
}
|
279
|
+
}
|
280
|
+
|
281
|
+
static size_t rvalue_stack_memsize(const void *ptr)
|
282
|
+
{
|
283
|
+
const rvalue_stack *stack = (const rvalue_stack *)ptr;
|
284
|
+
return sizeof(rvalue_stack) + sizeof(VALUE) * stack->capa;
|
285
|
+
}
|
286
|
+
|
287
|
+
static const rb_data_type_t JSON_Parser_rvalue_stack_type = {
|
288
|
+
"JSON::Ext::Parser/rvalue_stack",
|
289
|
+
{
|
290
|
+
.dmark = rvalue_stack_mark,
|
291
|
+
.dfree = rvalue_stack_free,
|
292
|
+
.dsize = rvalue_stack_memsize,
|
293
|
+
},
|
294
|
+
0, 0,
|
295
|
+
RUBY_TYPED_FREE_IMMEDIATELY,
|
296
|
+
};
|
297
|
+
|
298
|
+
static rvalue_stack *rvalue_stack_spill(rvalue_stack *old_stack, VALUE *handle, rvalue_stack **stack_ref)
|
299
|
+
{
|
300
|
+
rvalue_stack *stack;
|
301
|
+
*handle = TypedData_Make_Struct(0, rvalue_stack, &JSON_Parser_rvalue_stack_type, stack);
|
302
|
+
*stack_ref = stack;
|
303
|
+
MEMCPY(stack, old_stack, rvalue_stack, 1);
|
304
|
+
|
305
|
+
stack->capa = old_stack->capa << 1;
|
306
|
+
stack->ptr = ALLOC_N(VALUE, stack->capa);
|
307
|
+
stack->type = RVALUE_STACK_HEAP_ALLOCATED;
|
308
|
+
MEMCPY(stack->ptr, old_stack->ptr, VALUE, old_stack->head);
|
309
|
+
return stack;
|
310
|
+
}
|
311
|
+
|
312
|
+
static void rvalue_stack_eagerly_release(VALUE handle)
|
313
|
+
{
|
314
|
+
rvalue_stack *stack;
|
315
|
+
TypedData_Get_Struct(handle, rvalue_stack, &JSON_Parser_rvalue_stack_type, stack);
|
316
|
+
RTYPEDDATA_DATA(handle) = NULL;
|
317
|
+
rvalue_stack_free(stack);
|
318
|
+
}
|
319
|
+
|
28
320
|
/* unicode */
|
29
321
|
|
30
322
|
static const signed char digit_values[256] = {
|
@@ -44,26 +336,28 @@ static const signed char digit_values[256] = {
|
|
44
336
|
-1, -1, -1, -1, -1, -1, -1
|
45
337
|
};
|
46
338
|
|
47
|
-
static
|
339
|
+
static uint32_t unescape_unicode(const unsigned char *p)
|
48
340
|
{
|
341
|
+
const uint32_t replacement_char = 0xFFFD;
|
342
|
+
|
49
343
|
signed char b;
|
50
|
-
|
344
|
+
uint32_t result = 0;
|
51
345
|
b = digit_values[p[0]];
|
52
|
-
if (b < 0) return
|
346
|
+
if (b < 0) return replacement_char;
|
53
347
|
result = (result << 4) | (unsigned char)b;
|
54
348
|
b = digit_values[p[1]];
|
55
|
-
if (b < 0) return
|
349
|
+
if (b < 0) return replacement_char;
|
56
350
|
result = (result << 4) | (unsigned char)b;
|
57
351
|
b = digit_values[p[2]];
|
58
|
-
if (b < 0) return
|
352
|
+
if (b < 0) return replacement_char;
|
59
353
|
result = (result << 4) | (unsigned char)b;
|
60
354
|
b = digit_values[p[3]];
|
61
|
-
if (b < 0) return
|
355
|
+
if (b < 0) return replacement_char;
|
62
356
|
result = (result << 4) | (unsigned char)b;
|
63
357
|
return result;
|
64
358
|
}
|
65
359
|
|
66
|
-
static int convert_UTF32_to_UTF8(char *buf,
|
360
|
+
static int convert_UTF32_to_UTF8(char *buf, uint32_t ch)
|
67
361
|
{
|
68
362
|
int len = 1;
|
69
363
|
if (ch <= 0x7F) {
|
@@ -89,53 +383,110 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
|
|
89
383
|
return len;
|
90
384
|
}
|
91
385
|
|
92
|
-
|
93
|
-
|
386
|
+
typedef struct JSON_ParserStruct {
|
387
|
+
VALUE Vsource;
|
388
|
+
char *source;
|
389
|
+
long len;
|
390
|
+
char *memo;
|
391
|
+
VALUE create_id;
|
392
|
+
VALUE object_class;
|
393
|
+
VALUE array_class;
|
394
|
+
VALUE decimal_class;
|
395
|
+
VALUE match_string;
|
396
|
+
FBuffer fbuffer;
|
397
|
+
int in_array;
|
398
|
+
int max_nesting;
|
399
|
+
bool allow_nan;
|
400
|
+
bool allow_trailing_comma;
|
401
|
+
bool parsing_name;
|
402
|
+
bool symbolize_names;
|
403
|
+
bool freeze;
|
404
|
+
bool create_additions;
|
405
|
+
bool deprecated_create_additions;
|
406
|
+
rvalue_cache name_cache;
|
407
|
+
rvalue_stack *stack;
|
408
|
+
VALUE stack_handle;
|
409
|
+
} JSON_Parser;
|
410
|
+
|
411
|
+
#define GET_PARSER \
|
412
|
+
GET_PARSER_INIT; \
|
413
|
+
if (!json->Vsource) rb_raise(rb_eTypeError, "uninitialized instance")
|
414
|
+
|
415
|
+
#define GET_PARSER_INIT \
|
416
|
+
JSON_Parser *json; \
|
417
|
+
TypedData_Get_Struct(self, JSON_Parser, &JSON_Parser_type, json)
|
418
|
+
|
419
|
+
#define MinusInfinity "-Infinity"
|
420
|
+
#define EVIL 0x666
|
421
|
+
|
422
|
+
static const rb_data_type_t JSON_Parser_type;
|
423
|
+
static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
424
|
+
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
|
425
|
+
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
|
426
|
+
static char *JSON_parse_number(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
427
|
+
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
|
428
|
+
|
429
|
+
|
430
|
+
#define PARSE_ERROR_FRAGMENT_LEN 32
|
431
|
+
#ifdef RBIMPL_ATTR_NORETURN
|
432
|
+
RBIMPL_ATTR_NORETURN()
|
433
|
+
#endif
|
434
|
+
static void raise_parse_error(const char *format, const char *start)
|
435
|
+
{
|
436
|
+
char buffer[PARSE_ERROR_FRAGMENT_LEN + 1];
|
437
|
+
|
438
|
+
size_t len = strnlen(start, PARSE_ERROR_FRAGMENT_LEN);
|
439
|
+
const char *ptr = start;
|
94
440
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
441
|
+
if (len == PARSE_ERROR_FRAGMENT_LEN) {
|
442
|
+
MEMCPY(buffer, start, char, PARSE_ERROR_FRAGMENT_LEN);
|
443
|
+
buffer[PARSE_ERROR_FRAGMENT_LEN] = '\0';
|
444
|
+
ptr = buffer;
|
445
|
+
}
|
446
|
+
|
447
|
+
rb_enc_raise(enc_utf8, rb_path2class("JSON::ParserError"), format, ptr);
|
448
|
+
}
|
100
449
|
|
101
450
|
|
102
|
-
#line 125 "parser.rl"
|
103
451
|
|
452
|
+
#line 475 "parser.rl"
|
104
453
|
|
105
454
|
|
106
|
-
|
455
|
+
|
456
|
+
#line 457 "parser.c"
|
107
457
|
enum {JSON_object_start = 1};
|
108
|
-
enum {JSON_object_first_final =
|
458
|
+
enum {JSON_object_first_final = 32};
|
109
459
|
enum {JSON_object_error = 0};
|
110
460
|
|
111
461
|
enum {JSON_object_en_main = 1};
|
112
462
|
|
113
463
|
|
114
|
-
#line
|
464
|
+
#line 515 "parser.rl"
|
465
|
+
|
115
466
|
|
467
|
+
#define PUSH(result) rvalue_stack_push(json->stack, result, &json->stack_handle, &json->stack)
|
116
468
|
|
117
469
|
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
118
470
|
{
|
119
471
|
int cs = EVIL;
|
120
|
-
VALUE last_name = Qnil;
|
121
|
-
VALUE object_class = json->object_class;
|
122
472
|
|
123
473
|
if (json->max_nesting && current_nesting > json->max_nesting) {
|
124
474
|
rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
|
125
475
|
}
|
126
476
|
|
127
|
-
|
477
|
+
long stack_head = json->stack->head;
|
128
478
|
|
129
479
|
|
130
|
-
#line
|
480
|
+
#line 481 "parser.c"
|
131
481
|
{
|
132
482
|
cs = JSON_object_start;
|
133
483
|
}
|
134
484
|
|
135
|
-
#line
|
485
|
+
#line 530 "parser.rl"
|
136
486
|
|
137
|
-
#line
|
487
|
+
#line 488 "parser.c"
|
138
488
|
{
|
489
|
+
short _widec;
|
139
490
|
if ( p == pe )
|
140
491
|
goto _test_eof;
|
141
492
|
switch ( cs )
|
@@ -155,27 +506,30 @@ case 2:
|
|
155
506
|
case 13: goto st2;
|
156
507
|
case 32: goto st2;
|
157
508
|
case 34: goto tr2;
|
158
|
-
case 47: goto
|
509
|
+
case 47: goto st28;
|
159
510
|
case 125: goto tr4;
|
160
511
|
}
|
161
512
|
if ( 9 <= (*p) && (*p) <= 10 )
|
162
513
|
goto st2;
|
163
514
|
goto st0;
|
164
515
|
tr2:
|
165
|
-
#line
|
516
|
+
#line 494 "parser.rl"
|
166
517
|
{
|
167
518
|
char *np;
|
168
|
-
json->parsing_name =
|
169
|
-
np = JSON_parse_string(json, p, pe,
|
170
|
-
json->parsing_name =
|
171
|
-
if (np == NULL) { p--; {p++; cs = 3; goto _out;} } else {
|
519
|
+
json->parsing_name = true;
|
520
|
+
np = JSON_parse_string(json, p, pe, result);
|
521
|
+
json->parsing_name = false;
|
522
|
+
if (np == NULL) { p--; {p++; cs = 3; goto _out;} } else {
|
523
|
+
PUSH(*result);
|
524
|
+
{p = (( np))-1;}
|
525
|
+
}
|
172
526
|
}
|
173
527
|
goto st3;
|
174
528
|
st3:
|
175
529
|
if ( ++p == pe )
|
176
530
|
goto _test_eof3;
|
177
531
|
case 3:
|
178
|
-
#line
|
532
|
+
#line 533 "parser.c"
|
179
533
|
switch( (*p) ) {
|
180
534
|
case 13: goto st3;
|
181
535
|
case 32: goto st3;
|
@@ -226,7 +580,7 @@ case 8:
|
|
226
580
|
case 32: goto st8;
|
227
581
|
case 34: goto tr11;
|
228
582
|
case 45: goto tr11;
|
229
|
-
case 47: goto
|
583
|
+
case 47: goto st24;
|
230
584
|
case 73: goto tr11;
|
231
585
|
case 78: goto tr11;
|
232
586
|
case 91: goto tr11;
|
@@ -242,19 +596,12 @@ case 8:
|
|
242
596
|
goto st8;
|
243
597
|
goto st0;
|
244
598
|
tr11:
|
245
|
-
#line
|
599
|
+
#line 483 "parser.rl"
|
246
600
|
{
|
247
|
-
|
248
|
-
char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
|
601
|
+
char *np = JSON_parse_value(json, p, pe, result, current_nesting);
|
249
602
|
if (np == NULL) {
|
250
603
|
p--; {p++; cs = 9; goto _out;}
|
251
604
|
} else {
|
252
|
-
if (NIL_P(json->object_class)) {
|
253
|
-
OBJ_FREEZE(last_name);
|
254
|
-
rb_hash_aset(*result, last_name, v);
|
255
|
-
} else {
|
256
|
-
rb_funcall(*result, i_aset, 2, last_name, v);
|
257
|
-
}
|
258
605
|
{p = (( np))-1;}
|
259
606
|
}
|
260
607
|
}
|
@@ -263,16 +610,75 @@ st9:
|
|
263
610
|
if ( ++p == pe )
|
264
611
|
goto _test_eof9;
|
265
612
|
case 9:
|
266
|
-
#line
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
613
|
+
#line 614 "parser.c"
|
614
|
+
_widec = (*p);
|
615
|
+
if ( (*p) < 13 ) {
|
616
|
+
if ( (*p) > 9 ) {
|
617
|
+
if ( 10 <= (*p) && (*p) <= 10 ) {
|
618
|
+
_widec = (short)(128 + ((*p) - -128));
|
619
|
+
if (
|
620
|
+
#line 492 "parser.rl"
|
621
|
+
json->allow_trailing_comma ) _widec += 256;
|
622
|
+
}
|
623
|
+
} else if ( (*p) >= 9 ) {
|
624
|
+
_widec = (short)(128 + ((*p) - -128));
|
625
|
+
if (
|
626
|
+
#line 492 "parser.rl"
|
627
|
+
json->allow_trailing_comma ) _widec += 256;
|
628
|
+
}
|
629
|
+
} else if ( (*p) > 13 ) {
|
630
|
+
if ( (*p) < 44 ) {
|
631
|
+
if ( 32 <= (*p) && (*p) <= 32 ) {
|
632
|
+
_widec = (short)(128 + ((*p) - -128));
|
633
|
+
if (
|
634
|
+
#line 492 "parser.rl"
|
635
|
+
json->allow_trailing_comma ) _widec += 256;
|
636
|
+
}
|
637
|
+
} else if ( (*p) > 44 ) {
|
638
|
+
if ( 47 <= (*p) && (*p) <= 47 ) {
|
639
|
+
_widec = (short)(128 + ((*p) - -128));
|
640
|
+
if (
|
641
|
+
#line 492 "parser.rl"
|
642
|
+
json->allow_trailing_comma ) _widec += 256;
|
643
|
+
}
|
644
|
+
} else {
|
645
|
+
_widec = (short)(128 + ((*p) - -128));
|
646
|
+
if (
|
647
|
+
#line 492 "parser.rl"
|
648
|
+
json->allow_trailing_comma ) _widec += 256;
|
649
|
+
}
|
650
|
+
} else {
|
651
|
+
_widec = (short)(128 + ((*p) - -128));
|
652
|
+
if (
|
653
|
+
#line 492 "parser.rl"
|
654
|
+
json->allow_trailing_comma ) _widec += 256;
|
273
655
|
}
|
274
|
-
|
275
|
-
goto
|
656
|
+
switch( _widec ) {
|
657
|
+
case 125: goto tr4;
|
658
|
+
case 269: goto st10;
|
659
|
+
case 288: goto st10;
|
660
|
+
case 300: goto st11;
|
661
|
+
case 303: goto st16;
|
662
|
+
case 525: goto st9;
|
663
|
+
case 544: goto st9;
|
664
|
+
case 556: goto st2;
|
665
|
+
case 559: goto st20;
|
666
|
+
}
|
667
|
+
if ( _widec > 266 ) {
|
668
|
+
if ( 521 <= _widec && _widec <= 522 )
|
669
|
+
goto st9;
|
670
|
+
} else if ( _widec >= 265 )
|
671
|
+
goto st10;
|
672
|
+
goto st0;
|
673
|
+
tr4:
|
674
|
+
#line 505 "parser.rl"
|
675
|
+
{ p--; {p++; cs = 32; goto _out;} }
|
676
|
+
goto st32;
|
677
|
+
st32:
|
678
|
+
if ( ++p == pe )
|
679
|
+
goto _test_eof32;
|
680
|
+
case 32:
|
681
|
+
#line 682 "parser.c"
|
276
682
|
goto st0;
|
277
683
|
st10:
|
278
684
|
if ( ++p == pe )
|
@@ -281,8 +687,9 @@ case 10:
|
|
281
687
|
switch( (*p) ) {
|
282
688
|
case 13: goto st10;
|
283
689
|
case 32: goto st10;
|
284
|
-
case
|
285
|
-
case 47: goto
|
690
|
+
case 44: goto st11;
|
691
|
+
case 47: goto st16;
|
692
|
+
case 125: goto tr4;
|
286
693
|
}
|
287
694
|
if ( 9 <= (*p) && (*p) <= 10 )
|
288
695
|
goto st10;
|
@@ -292,139 +699,288 @@ st11:
|
|
292
699
|
goto _test_eof11;
|
293
700
|
case 11:
|
294
701
|
switch( (*p) ) {
|
295
|
-
case
|
296
|
-
case
|
702
|
+
case 13: goto st11;
|
703
|
+
case 32: goto st11;
|
704
|
+
case 34: goto tr2;
|
705
|
+
case 47: goto st12;
|
297
706
|
}
|
707
|
+
if ( 9 <= (*p) && (*p) <= 10 )
|
708
|
+
goto st11;
|
298
709
|
goto st0;
|
299
710
|
st12:
|
300
711
|
if ( ++p == pe )
|
301
712
|
goto _test_eof12;
|
302
713
|
case 12:
|
303
|
-
|
304
|
-
goto st13;
|
305
|
-
|
714
|
+
switch( (*p) ) {
|
715
|
+
case 42: goto st13;
|
716
|
+
case 47: goto st15;
|
717
|
+
}
|
718
|
+
goto st0;
|
306
719
|
st13:
|
307
720
|
if ( ++p == pe )
|
308
721
|
goto _test_eof13;
|
309
722
|
case 13:
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
}
|
314
|
-
goto st12;
|
723
|
+
if ( (*p) == 42 )
|
724
|
+
goto st14;
|
725
|
+
goto st13;
|
315
726
|
st14:
|
316
727
|
if ( ++p == pe )
|
317
728
|
goto _test_eof14;
|
318
729
|
case 14:
|
319
|
-
|
320
|
-
goto
|
321
|
-
|
730
|
+
switch( (*p) ) {
|
731
|
+
case 42: goto st14;
|
732
|
+
case 47: goto st11;
|
733
|
+
}
|
734
|
+
goto st13;
|
322
735
|
st15:
|
323
736
|
if ( ++p == pe )
|
324
737
|
goto _test_eof15;
|
325
738
|
case 15:
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
}
|
330
|
-
goto st0;
|
739
|
+
if ( (*p) == 10 )
|
740
|
+
goto st11;
|
741
|
+
goto st15;
|
331
742
|
st16:
|
332
743
|
if ( ++p == pe )
|
333
744
|
goto _test_eof16;
|
334
745
|
case 16:
|
335
|
-
|
336
|
-
goto st17;
|
337
|
-
|
746
|
+
switch( (*p) ) {
|
747
|
+
case 42: goto st17;
|
748
|
+
case 47: goto st19;
|
749
|
+
}
|
750
|
+
goto st0;
|
338
751
|
st17:
|
339
752
|
if ( ++p == pe )
|
340
753
|
goto _test_eof17;
|
341
754
|
case 17:
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
}
|
346
|
-
goto st16;
|
755
|
+
if ( (*p) == 42 )
|
756
|
+
goto st18;
|
757
|
+
goto st17;
|
347
758
|
st18:
|
348
759
|
if ( ++p == pe )
|
349
760
|
goto _test_eof18;
|
350
761
|
case 18:
|
351
|
-
|
352
|
-
goto
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
{ p--; {p++; cs = 27; goto _out;} }
|
357
|
-
goto st27;
|
358
|
-
st27:
|
359
|
-
if ( ++p == pe )
|
360
|
-
goto _test_eof27;
|
361
|
-
case 27:
|
362
|
-
#line 363 "parser.c"
|
363
|
-
goto st0;
|
762
|
+
switch( (*p) ) {
|
763
|
+
case 42: goto st18;
|
764
|
+
case 47: goto st10;
|
765
|
+
}
|
766
|
+
goto st17;
|
364
767
|
st19:
|
365
768
|
if ( ++p == pe )
|
366
769
|
goto _test_eof19;
|
367
770
|
case 19:
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
}
|
372
|
-
goto st0;
|
771
|
+
if ( (*p) == 10 )
|
772
|
+
goto st10;
|
773
|
+
goto st19;
|
373
774
|
st20:
|
374
775
|
if ( ++p == pe )
|
375
776
|
goto _test_eof20;
|
376
777
|
case 20:
|
377
|
-
|
378
|
-
|
379
|
-
|
778
|
+
_widec = (*p);
|
779
|
+
if ( (*p) > 42 ) {
|
780
|
+
if ( 47 <= (*p) && (*p) <= 47 ) {
|
781
|
+
_widec = (short)(128 + ((*p) - -128));
|
782
|
+
if (
|
783
|
+
#line 492 "parser.rl"
|
784
|
+
json->allow_trailing_comma ) _widec += 256;
|
785
|
+
}
|
786
|
+
} else if ( (*p) >= 42 ) {
|
787
|
+
_widec = (short)(128 + ((*p) - -128));
|
788
|
+
if (
|
789
|
+
#line 492 "parser.rl"
|
790
|
+
json->allow_trailing_comma ) _widec += 256;
|
791
|
+
}
|
792
|
+
switch( _widec ) {
|
793
|
+
case 298: goto st17;
|
794
|
+
case 303: goto st19;
|
795
|
+
case 554: goto st21;
|
796
|
+
case 559: goto st23;
|
797
|
+
}
|
798
|
+
goto st0;
|
380
799
|
st21:
|
381
800
|
if ( ++p == pe )
|
382
801
|
goto _test_eof21;
|
383
802
|
case 21:
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
803
|
+
_widec = (*p);
|
804
|
+
if ( (*p) < 42 ) {
|
805
|
+
if ( (*p) <= 41 ) {
|
806
|
+
_widec = (short)(128 + ((*p) - -128));
|
807
|
+
if (
|
808
|
+
#line 492 "parser.rl"
|
809
|
+
json->allow_trailing_comma ) _widec += 256;
|
810
|
+
}
|
811
|
+
} else if ( (*p) > 42 ) {
|
812
|
+
if ( 43 <= (*p) )
|
813
|
+
{ _widec = (short)(128 + ((*p) - -128));
|
814
|
+
if (
|
815
|
+
#line 492 "parser.rl"
|
816
|
+
json->allow_trailing_comma ) _widec += 256;
|
817
|
+
}
|
818
|
+
} else {
|
819
|
+
_widec = (short)(128 + ((*p) - -128));
|
820
|
+
if (
|
821
|
+
#line 492 "parser.rl"
|
822
|
+
json->allow_trailing_comma ) _widec += 256;
|
823
|
+
}
|
824
|
+
switch( _widec ) {
|
825
|
+
case 298: goto st18;
|
826
|
+
case 554: goto st22;
|
827
|
+
}
|
828
|
+
if ( _widec > 383 ) {
|
829
|
+
if ( 384 <= _widec && _widec <= 639 )
|
830
|
+
goto st21;
|
831
|
+
} else if ( _widec >= 128 )
|
832
|
+
goto st17;
|
833
|
+
goto st0;
|
389
834
|
st22:
|
390
835
|
if ( ++p == pe )
|
391
836
|
goto _test_eof22;
|
392
837
|
case 22:
|
393
|
-
|
394
|
-
|
395
|
-
|
838
|
+
_widec = (*p);
|
839
|
+
if ( (*p) < 43 ) {
|
840
|
+
if ( (*p) > 41 ) {
|
841
|
+
if ( 42 <= (*p) && (*p) <= 42 ) {
|
842
|
+
_widec = (short)(128 + ((*p) - -128));
|
843
|
+
if (
|
844
|
+
#line 492 "parser.rl"
|
845
|
+
json->allow_trailing_comma ) _widec += 256;
|
846
|
+
}
|
847
|
+
} else {
|
848
|
+
_widec = (short)(128 + ((*p) - -128));
|
849
|
+
if (
|
850
|
+
#line 492 "parser.rl"
|
851
|
+
json->allow_trailing_comma ) _widec += 256;
|
852
|
+
}
|
853
|
+
} else if ( (*p) > 46 ) {
|
854
|
+
if ( (*p) > 47 ) {
|
855
|
+
if ( 48 <= (*p) )
|
856
|
+
{ _widec = (short)(128 + ((*p) - -128));
|
857
|
+
if (
|
858
|
+
#line 492 "parser.rl"
|
859
|
+
json->allow_trailing_comma ) _widec += 256;
|
860
|
+
}
|
861
|
+
} else if ( (*p) >= 47 ) {
|
862
|
+
_widec = (short)(128 + ((*p) - -128));
|
863
|
+
if (
|
864
|
+
#line 492 "parser.rl"
|
865
|
+
json->allow_trailing_comma ) _widec += 256;
|
866
|
+
}
|
867
|
+
} else {
|
868
|
+
_widec = (short)(128 + ((*p) - -128));
|
869
|
+
if (
|
870
|
+
#line 492 "parser.rl"
|
871
|
+
json->allow_trailing_comma ) _widec += 256;
|
872
|
+
}
|
873
|
+
switch( _widec ) {
|
874
|
+
case 298: goto st18;
|
875
|
+
case 303: goto st10;
|
876
|
+
case 554: goto st22;
|
877
|
+
case 559: goto st9;
|
878
|
+
}
|
879
|
+
if ( _widec > 383 ) {
|
880
|
+
if ( 384 <= _widec && _widec <= 639 )
|
881
|
+
goto st21;
|
882
|
+
} else if ( _widec >= 128 )
|
883
|
+
goto st17;
|
884
|
+
goto st0;
|
396
885
|
st23:
|
397
886
|
if ( ++p == pe )
|
398
887
|
goto _test_eof23;
|
399
888
|
case 23:
|
400
|
-
|
401
|
-
|
402
|
-
|
889
|
+
_widec = (*p);
|
890
|
+
if ( (*p) < 10 ) {
|
891
|
+
if ( (*p) <= 9 ) {
|
892
|
+
_widec = (short)(128 + ((*p) - -128));
|
893
|
+
if (
|
894
|
+
#line 492 "parser.rl"
|
895
|
+
json->allow_trailing_comma ) _widec += 256;
|
896
|
+
}
|
897
|
+
} else if ( (*p) > 10 ) {
|
898
|
+
if ( 11 <= (*p) )
|
899
|
+
{ _widec = (short)(128 + ((*p) - -128));
|
900
|
+
if (
|
901
|
+
#line 492 "parser.rl"
|
902
|
+
json->allow_trailing_comma ) _widec += 256;
|
903
|
+
}
|
904
|
+
} else {
|
905
|
+
_widec = (short)(128 + ((*p) - -128));
|
906
|
+
if (
|
907
|
+
#line 492 "parser.rl"
|
908
|
+
json->allow_trailing_comma ) _widec += 256;
|
909
|
+
}
|
910
|
+
switch( _widec ) {
|
911
|
+
case 266: goto st10;
|
912
|
+
case 522: goto st9;
|
403
913
|
}
|
914
|
+
if ( _widec > 383 ) {
|
915
|
+
if ( 384 <= _widec && _widec <= 639 )
|
916
|
+
goto st23;
|
917
|
+
} else if ( _widec >= 128 )
|
918
|
+
goto st19;
|
404
919
|
goto st0;
|
405
920
|
st24:
|
406
921
|
if ( ++p == pe )
|
407
922
|
goto _test_eof24;
|
408
923
|
case 24:
|
409
|
-
|
410
|
-
goto st25;
|
411
|
-
|
924
|
+
switch( (*p) ) {
|
925
|
+
case 42: goto st25;
|
926
|
+
case 47: goto st27;
|
927
|
+
}
|
928
|
+
goto st0;
|
412
929
|
st25:
|
413
930
|
if ( ++p == pe )
|
414
931
|
goto _test_eof25;
|
415
932
|
case 25:
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
}
|
420
|
-
goto st24;
|
933
|
+
if ( (*p) == 42 )
|
934
|
+
goto st26;
|
935
|
+
goto st25;
|
421
936
|
st26:
|
422
937
|
if ( ++p == pe )
|
423
938
|
goto _test_eof26;
|
424
939
|
case 26:
|
940
|
+
switch( (*p) ) {
|
941
|
+
case 42: goto st26;
|
942
|
+
case 47: goto st8;
|
943
|
+
}
|
944
|
+
goto st25;
|
945
|
+
st27:
|
946
|
+
if ( ++p == pe )
|
947
|
+
goto _test_eof27;
|
948
|
+
case 27:
|
949
|
+
if ( (*p) == 10 )
|
950
|
+
goto st8;
|
951
|
+
goto st27;
|
952
|
+
st28:
|
953
|
+
if ( ++p == pe )
|
954
|
+
goto _test_eof28;
|
955
|
+
case 28:
|
956
|
+
switch( (*p) ) {
|
957
|
+
case 42: goto st29;
|
958
|
+
case 47: goto st31;
|
959
|
+
}
|
960
|
+
goto st0;
|
961
|
+
st29:
|
962
|
+
if ( ++p == pe )
|
963
|
+
goto _test_eof29;
|
964
|
+
case 29:
|
965
|
+
if ( (*p) == 42 )
|
966
|
+
goto st30;
|
967
|
+
goto st29;
|
968
|
+
st30:
|
969
|
+
if ( ++p == pe )
|
970
|
+
goto _test_eof30;
|
971
|
+
case 30:
|
972
|
+
switch( (*p) ) {
|
973
|
+
case 42: goto st30;
|
974
|
+
case 47: goto st2;
|
975
|
+
}
|
976
|
+
goto st29;
|
977
|
+
st31:
|
978
|
+
if ( ++p == pe )
|
979
|
+
goto _test_eof31;
|
980
|
+
case 31:
|
425
981
|
if ( (*p) == 10 )
|
426
982
|
goto st2;
|
427
|
-
goto
|
983
|
+
goto st31;
|
428
984
|
}
|
429
985
|
_test_eof2: cs = 2; goto _test_eof;
|
430
986
|
_test_eof3: cs = 3; goto _test_eof;
|
@@ -434,6 +990,7 @@ case 26:
|
|
434
990
|
_test_eof7: cs = 7; goto _test_eof;
|
435
991
|
_test_eof8: cs = 8; goto _test_eof;
|
436
992
|
_test_eof9: cs = 9; goto _test_eof;
|
993
|
+
_test_eof32: cs = 32; goto _test_eof;
|
437
994
|
_test_eof10: cs = 10; goto _test_eof;
|
438
995
|
_test_eof11: cs = 11; goto _test_eof;
|
439
996
|
_test_eof12: cs = 12; goto _test_eof;
|
@@ -443,7 +1000,6 @@ case 26:
|
|
443
1000
|
_test_eof16: cs = 16; goto _test_eof;
|
444
1001
|
_test_eof17: cs = 17; goto _test_eof;
|
445
1002
|
_test_eof18: cs = 18; goto _test_eof;
|
446
|
-
_test_eof27: cs = 27; goto _test_eof;
|
447
1003
|
_test_eof19: cs = 19; goto _test_eof;
|
448
1004
|
_test_eof20: cs = 20; goto _test_eof;
|
449
1005
|
_test_eof21: cs = 21; goto _test_eof;
|
@@ -452,24 +1008,56 @@ case 26:
|
|
452
1008
|
_test_eof24: cs = 24; goto _test_eof;
|
453
1009
|
_test_eof25: cs = 25; goto _test_eof;
|
454
1010
|
_test_eof26: cs = 26; goto _test_eof;
|
1011
|
+
_test_eof27: cs = 27; goto _test_eof;
|
1012
|
+
_test_eof28: cs = 28; goto _test_eof;
|
1013
|
+
_test_eof29: cs = 29; goto _test_eof;
|
1014
|
+
_test_eof30: cs = 30; goto _test_eof;
|
1015
|
+
_test_eof31: cs = 31; goto _test_eof;
|
455
1016
|
|
456
1017
|
_test_eof: {}
|
457
1018
|
_out: {}
|
458
1019
|
}
|
459
1020
|
|
460
|
-
#line
|
1021
|
+
#line 531 "parser.rl"
|
461
1022
|
|
462
1023
|
if (cs >= JSON_object_first_final) {
|
463
|
-
|
1024
|
+
long count = json->stack->head - stack_head;
|
1025
|
+
|
1026
|
+
if (RB_UNLIKELY(json->object_class)) {
|
1027
|
+
VALUE object = rb_class_new_instance(0, 0, json->object_class);
|
1028
|
+
long index = 0;
|
1029
|
+
VALUE *items = rvalue_stack_peek(json->stack, count);
|
1030
|
+
while (index < count) {
|
1031
|
+
VALUE name = items[index++];
|
1032
|
+
VALUE value = items[index++];
|
1033
|
+
rb_funcall(object, i_aset, 2, name, value);
|
1034
|
+
}
|
1035
|
+
*result = object;
|
1036
|
+
} else {
|
1037
|
+
VALUE hash;
|
1038
|
+
#ifdef HAVE_RB_HASH_NEW_CAPA
|
1039
|
+
hash = rb_hash_new_capa(count >> 1);
|
1040
|
+
#else
|
1041
|
+
hash = rb_hash_new();
|
1042
|
+
#endif
|
1043
|
+
rb_hash_bulk_insert(count, rvalue_stack_peek(json->stack, count), hash);
|
1044
|
+
*result = hash;
|
1045
|
+
}
|
1046
|
+
rvalue_stack_pop(json->stack, count);
|
1047
|
+
|
1048
|
+
if (RB_UNLIKELY(json->create_additions)) {
|
464
1049
|
VALUE klassname;
|
465
|
-
if (
|
466
|
-
|
1050
|
+
if (json->object_class) {
|
1051
|
+
klassname = rb_funcall(*result, i_aref, 1, json->create_id);
|
467
1052
|
} else {
|
468
|
-
|
1053
|
+
klassname = rb_hash_aref(*result, json->create_id);
|
469
1054
|
}
|
470
1055
|
if (!NIL_P(klassname)) {
|
471
1056
|
VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname);
|
472
1057
|
if (RTEST(rb_funcall(klass, i_json_creatable_p, 0))) {
|
1058
|
+
if (json->deprecated_create_additions) {
|
1059
|
+
json_deprecated(deprecated_create_additions_warning);
|
1060
|
+
}
|
473
1061
|
*result = rb_funcall(klass, i_json_create, 1, *result);
|
474
1062
|
}
|
475
1063
|
}
|
@@ -481,8 +1069,7 @@ case 26:
|
|
481
1069
|
}
|
482
1070
|
|
483
1071
|
|
484
|
-
|
485
|
-
#line 486 "parser.c"
|
1072
|
+
#line 1073 "parser.c"
|
486
1073
|
enum {JSON_value_start = 1};
|
487
1074
|
enum {JSON_value_first_final = 29};
|
488
1075
|
enum {JSON_value_error = 0};
|
@@ -490,7 +1077,7 @@ enum {JSON_value_error = 0};
|
|
490
1077
|
enum {JSON_value_en_main = 1};
|
491
1078
|
|
492
1079
|
|
493
|
-
#line
|
1080
|
+
#line 664 "parser.rl"
|
494
1081
|
|
495
1082
|
|
496
1083
|
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
@@ -498,14 +1085,14 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
498
1085
|
int cs = EVIL;
|
499
1086
|
|
500
1087
|
|
501
|
-
#line
|
1088
|
+
#line 1089 "parser.c"
|
502
1089
|
{
|
503
1090
|
cs = JSON_value_start;
|
504
1091
|
}
|
505
1092
|
|
506
|
-
#line
|
1093
|
+
#line 671 "parser.rl"
|
507
1094
|
|
508
|
-
#line
|
1095
|
+
#line 1096 "parser.c"
|
509
1096
|
{
|
510
1097
|
if ( p == pe )
|
511
1098
|
goto _test_eof;
|
@@ -539,14 +1126,19 @@ st0:
|
|
539
1126
|
cs = 0;
|
540
1127
|
goto _out;
|
541
1128
|
tr2:
|
542
|
-
#line
|
1129
|
+
#line 609 "parser.rl"
|
543
1130
|
{
|
544
1131
|
char *np = JSON_parse_string(json, p, pe, result);
|
545
|
-
if (np == NULL) {
|
1132
|
+
if (np == NULL) {
|
1133
|
+
p--;
|
1134
|
+
{p++; cs = 29; goto _out;}
|
1135
|
+
} else {
|
1136
|
+
{p = (( np))-1;}
|
1137
|
+
}
|
546
1138
|
}
|
547
1139
|
goto st29;
|
548
1140
|
tr3:
|
549
|
-
#line
|
1141
|
+
#line 619 "parser.rl"
|
550
1142
|
{
|
551
1143
|
char *np;
|
552
1144
|
if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) {
|
@@ -555,26 +1147,28 @@ tr3:
|
|
555
1147
|
{p = (( p + 10))-1;}
|
556
1148
|
p--; {p++; cs = 29; goto _out;}
|
557
1149
|
} else {
|
558
|
-
|
1150
|
+
raise_parse_error("unexpected token at '%s'", p);
|
559
1151
|
}
|
560
1152
|
}
|
561
|
-
np =
|
562
|
-
if (np != NULL) {
|
563
|
-
|
564
|
-
|
1153
|
+
np = JSON_parse_number(json, p, pe, result);
|
1154
|
+
if (np != NULL) {
|
1155
|
+
{p = (( np))-1;}
|
1156
|
+
}
|
565
1157
|
p--; {p++; cs = 29; goto _out;}
|
566
1158
|
}
|
567
1159
|
goto st29;
|
568
1160
|
tr7:
|
569
|
-
#line
|
1161
|
+
#line 637 "parser.rl"
|
570
1162
|
{
|
571
1163
|
char *np;
|
1164
|
+
json->in_array++;
|
572
1165
|
np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
|
1166
|
+
json->in_array--;
|
573
1167
|
if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
|
574
1168
|
}
|
575
1169
|
goto st29;
|
576
1170
|
tr11:
|
577
|
-
#line
|
1171
|
+
#line 645 "parser.rl"
|
578
1172
|
{
|
579
1173
|
char *np;
|
580
1174
|
np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
|
@@ -582,39 +1176,39 @@ tr11:
|
|
582
1176
|
}
|
583
1177
|
goto st29;
|
584
1178
|
tr25:
|
585
|
-
#line
|
1179
|
+
#line 602 "parser.rl"
|
586
1180
|
{
|
587
1181
|
if (json->allow_nan) {
|
588
1182
|
*result = CInfinity;
|
589
1183
|
} else {
|
590
|
-
|
1184
|
+
raise_parse_error("unexpected token at '%s'", p - 7);
|
591
1185
|
}
|
592
1186
|
}
|
593
1187
|
goto st29;
|
594
1188
|
tr27:
|
595
|
-
#line
|
1189
|
+
#line 595 "parser.rl"
|
596
1190
|
{
|
597
1191
|
if (json->allow_nan) {
|
598
1192
|
*result = CNaN;
|
599
1193
|
} else {
|
600
|
-
|
1194
|
+
raise_parse_error("unexpected token at '%s'", p - 2);
|
601
1195
|
}
|
602
1196
|
}
|
603
1197
|
goto st29;
|
604
1198
|
tr31:
|
605
|
-
#line
|
1199
|
+
#line 589 "parser.rl"
|
606
1200
|
{
|
607
1201
|
*result = Qfalse;
|
608
1202
|
}
|
609
1203
|
goto st29;
|
610
1204
|
tr34:
|
611
|
-
#line
|
1205
|
+
#line 586 "parser.rl"
|
612
1206
|
{
|
613
1207
|
*result = Qnil;
|
614
1208
|
}
|
615
1209
|
goto st29;
|
616
1210
|
tr37:
|
617
|
-
#line
|
1211
|
+
#line 592 "parser.rl"
|
618
1212
|
{
|
619
1213
|
*result = Qtrue;
|
620
1214
|
}
|
@@ -623,9 +1217,9 @@ st29:
|
|
623
1217
|
if ( ++p == pe )
|
624
1218
|
goto _test_eof29;
|
625
1219
|
case 29:
|
626
|
-
#line
|
1220
|
+
#line 651 "parser.rl"
|
627
1221
|
{ p--; {p++; cs = 29; goto _out;} }
|
628
|
-
#line
|
1222
|
+
#line 1223 "parser.c"
|
629
1223
|
switch( (*p) ) {
|
630
1224
|
case 13: goto st29;
|
631
1225
|
case 32: goto st29;
|
@@ -866,13 +1460,14 @@ case 28:
|
|
866
1460
|
_out: {}
|
867
1461
|
}
|
868
1462
|
|
869
|
-
#line
|
1463
|
+
#line 672 "parser.rl"
|
870
1464
|
|
871
1465
|
if (json->freeze) {
|
872
1466
|
OBJ_FREEZE(*result);
|
873
1467
|
}
|
874
1468
|
|
875
1469
|
if (cs >= JSON_value_first_final) {
|
1470
|
+
PUSH(*result);
|
876
1471
|
return p;
|
877
1472
|
} else {
|
878
1473
|
return NULL;
|
@@ -880,7 +1475,7 @@ case 28:
|
|
880
1475
|
}
|
881
1476
|
|
882
1477
|
|
883
|
-
#line
|
1478
|
+
#line 1479 "parser.c"
|
884
1479
|
enum {JSON_integer_start = 1};
|
885
1480
|
enum {JSON_integer_first_final = 3};
|
886
1481
|
enum {JSON_integer_error = 0};
|
@@ -888,122 +1483,72 @@ enum {JSON_integer_error = 0};
|
|
888
1483
|
enum {JSON_integer_en_main = 1};
|
889
1484
|
|
890
1485
|
|
891
|
-
#line
|
1486
|
+
#line 693 "parser.rl"
|
892
1487
|
|
893
1488
|
|
894
|
-
|
1489
|
+
#define MAX_FAST_INTEGER_SIZE 18
|
1490
|
+
static inline VALUE fast_parse_integer(char *p, char *pe)
|
895
1491
|
{
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
cs = JSON_integer_start;
|
902
|
-
}
|
903
|
-
|
904
|
-
#line 318 "parser.rl"
|
905
|
-
json->memo = p;
|
906
|
-
|
907
|
-
#line 908 "parser.c"
|
908
|
-
{
|
909
|
-
if ( p == pe )
|
910
|
-
goto _test_eof;
|
911
|
-
switch ( cs )
|
912
|
-
{
|
913
|
-
case 1:
|
914
|
-
switch( (*p) ) {
|
915
|
-
case 45: goto st2;
|
916
|
-
case 48: goto st3;
|
917
|
-
}
|
918
|
-
if ( 49 <= (*p) && (*p) <= 57 )
|
919
|
-
goto st5;
|
920
|
-
goto st0;
|
921
|
-
st0:
|
922
|
-
cs = 0;
|
923
|
-
goto _out;
|
924
|
-
st2:
|
925
|
-
if ( ++p == pe )
|
926
|
-
goto _test_eof2;
|
927
|
-
case 2:
|
928
|
-
if ( (*p) == 48 )
|
929
|
-
goto st3;
|
930
|
-
if ( 49 <= (*p) && (*p) <= 57 )
|
931
|
-
goto st5;
|
932
|
-
goto st0;
|
933
|
-
st3:
|
934
|
-
if ( ++p == pe )
|
935
|
-
goto _test_eof3;
|
936
|
-
case 3:
|
937
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
938
|
-
goto st0;
|
939
|
-
goto tr4;
|
940
|
-
tr4:
|
941
|
-
#line 308 "parser.rl"
|
942
|
-
{ p--; {p++; cs = 4; goto _out;} }
|
943
|
-
goto st4;
|
944
|
-
st4:
|
945
|
-
if ( ++p == pe )
|
946
|
-
goto _test_eof4;
|
947
|
-
case 4:
|
948
|
-
#line 949 "parser.c"
|
949
|
-
goto st0;
|
950
|
-
st5:
|
951
|
-
if ( ++p == pe )
|
952
|
-
goto _test_eof5;
|
953
|
-
case 5:
|
954
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
955
|
-
goto st5;
|
956
|
-
goto tr4;
|
957
|
-
}
|
958
|
-
_test_eof2: cs = 2; goto _test_eof;
|
959
|
-
_test_eof3: cs = 3; goto _test_eof;
|
960
|
-
_test_eof4: cs = 4; goto _test_eof;
|
961
|
-
_test_eof5: cs = 5; goto _test_eof;
|
1492
|
+
bool negative = false;
|
1493
|
+
if (*p == '-') {
|
1494
|
+
negative = true;
|
1495
|
+
p++;
|
1496
|
+
}
|
962
1497
|
|
963
|
-
|
964
|
-
|
965
|
-
|
1498
|
+
long long memo = 0;
|
1499
|
+
while (p < pe) {
|
1500
|
+
memo *= 10;
|
1501
|
+
memo += *p - '0';
|
1502
|
+
p++;
|
1503
|
+
}
|
966
1504
|
|
967
|
-
|
1505
|
+
if (negative) {
|
1506
|
+
memo = -memo;
|
1507
|
+
}
|
1508
|
+
return LL2NUM(memo);
|
1509
|
+
}
|
968
1510
|
|
969
|
-
|
1511
|
+
static char *JSON_decode_integer(JSON_Parser *json, char *p, VALUE *result)
|
1512
|
+
{
|
970
1513
|
long len = p - json->memo;
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
1514
|
+
if (RB_LIKELY(len < MAX_FAST_INTEGER_SIZE)) {
|
1515
|
+
*result = fast_parse_integer(json->memo, p);
|
1516
|
+
} else {
|
1517
|
+
fbuffer_clear(&json->fbuffer);
|
1518
|
+
fbuffer_append(&json->fbuffer, json->memo, len);
|
1519
|
+
fbuffer_append_char(&json->fbuffer, '\0');
|
1520
|
+
*result = rb_cstr2inum(FBUFFER_PTR(&json->fbuffer), 10);
|
1521
|
+
}
|
975
1522
|
return p + 1;
|
976
|
-
} else {
|
977
|
-
return NULL;
|
978
|
-
}
|
979
1523
|
}
|
980
1524
|
|
981
1525
|
|
982
|
-
#line
|
1526
|
+
#line 1527 "parser.c"
|
983
1527
|
enum {JSON_float_start = 1};
|
984
|
-
enum {JSON_float_first_final =
|
1528
|
+
enum {JSON_float_first_final = 6};
|
985
1529
|
enum {JSON_float_error = 0};
|
986
1530
|
|
987
1531
|
enum {JSON_float_en_main = 1};
|
988
1532
|
|
989
1533
|
|
990
|
-
#line
|
1534
|
+
#line 745 "parser.rl"
|
991
1535
|
|
992
1536
|
|
993
|
-
static char *
|
1537
|
+
static char *JSON_parse_number(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
994
1538
|
{
|
995
1539
|
int cs = EVIL;
|
1540
|
+
bool is_float = false;
|
996
1541
|
|
997
1542
|
|
998
|
-
#line
|
1543
|
+
#line 1544 "parser.c"
|
999
1544
|
{
|
1000
1545
|
cs = JSON_float_start;
|
1001
1546
|
}
|
1002
1547
|
|
1003
|
-
#line
|
1548
|
+
#line 753 "parser.rl"
|
1004
1549
|
json->memo = p;
|
1005
1550
|
|
1006
|
-
#line
|
1551
|
+
#line 1552 "parser.c"
|
1007
1552
|
{
|
1008
1553
|
if ( p == pe )
|
1009
1554
|
goto _test_eof;
|
@@ -1012,10 +1557,10 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
1012
1557
|
case 1:
|
1013
1558
|
switch( (*p) ) {
|
1014
1559
|
case 45: goto st2;
|
1015
|
-
case 48: goto
|
1560
|
+
case 48: goto st6;
|
1016
1561
|
}
|
1017
1562
|
if ( 49 <= (*p) && (*p) <= 57 )
|
1018
|
-
goto
|
1563
|
+
goto st10;
|
1019
1564
|
goto st0;
|
1020
1565
|
st0:
|
1021
1566
|
cs = 0;
|
@@ -1025,24 +1570,42 @@ st2:
|
|
1025
1570
|
goto _test_eof2;
|
1026
1571
|
case 2:
|
1027
1572
|
if ( (*p) == 48 )
|
1028
|
-
goto
|
1573
|
+
goto st6;
|
1029
1574
|
if ( 49 <= (*p) && (*p) <= 57 )
|
1030
|
-
goto
|
1575
|
+
goto st10;
|
1031
1576
|
goto st0;
|
1032
|
-
|
1577
|
+
st6:
|
1033
1578
|
if ( ++p == pe )
|
1034
|
-
goto
|
1035
|
-
case
|
1579
|
+
goto _test_eof6;
|
1580
|
+
case 6:
|
1036
1581
|
switch( (*p) ) {
|
1037
|
-
case
|
1038
|
-
case
|
1039
|
-
case
|
1582
|
+
case 45: goto st0;
|
1583
|
+
case 46: goto tr8;
|
1584
|
+
case 69: goto tr9;
|
1585
|
+
case 101: goto tr9;
|
1040
1586
|
}
|
1587
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
1588
|
+
goto st0;
|
1589
|
+
goto tr7;
|
1590
|
+
tr7:
|
1591
|
+
#line 737 "parser.rl"
|
1592
|
+
{ p--; {p++; cs = 7; goto _out;} }
|
1593
|
+
goto st7;
|
1594
|
+
st7:
|
1595
|
+
if ( ++p == pe )
|
1596
|
+
goto _test_eof7;
|
1597
|
+
case 7:
|
1598
|
+
#line 1599 "parser.c"
|
1041
1599
|
goto st0;
|
1042
|
-
|
1600
|
+
tr8:
|
1601
|
+
#line 738 "parser.rl"
|
1602
|
+
{ is_float = true; }
|
1603
|
+
goto st3;
|
1604
|
+
st3:
|
1043
1605
|
if ( ++p == pe )
|
1044
|
-
goto
|
1045
|
-
case
|
1606
|
+
goto _test_eof3;
|
1607
|
+
case 3:
|
1608
|
+
#line 1609 "parser.c"
|
1046
1609
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1047
1610
|
goto st8;
|
1048
1611
|
goto st0;
|
@@ -1051,125 +1614,126 @@ st8:
|
|
1051
1614
|
goto _test_eof8;
|
1052
1615
|
case 8:
|
1053
1616
|
switch( (*p) ) {
|
1054
|
-
case 69: goto
|
1055
|
-
case 101: goto
|
1617
|
+
case 69: goto st4;
|
1618
|
+
case 101: goto st4;
|
1056
1619
|
}
|
1057
1620
|
if ( (*p) > 46 ) {
|
1058
1621
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1059
1622
|
goto st8;
|
1060
1623
|
} else if ( (*p) >= 45 )
|
1061
1624
|
goto st0;
|
1062
|
-
goto
|
1625
|
+
goto tr7;
|
1063
1626
|
tr9:
|
1064
|
-
#line
|
1065
|
-
{
|
1066
|
-
goto
|
1067
|
-
|
1068
|
-
if ( ++p == pe )
|
1069
|
-
goto _test_eof9;
|
1070
|
-
case 9:
|
1071
|
-
#line 1072 "parser.c"
|
1072
|
-
goto st0;
|
1073
|
-
st5:
|
1627
|
+
#line 738 "parser.rl"
|
1628
|
+
{ is_float = true; }
|
1629
|
+
goto st4;
|
1630
|
+
st4:
|
1074
1631
|
if ( ++p == pe )
|
1075
|
-
goto
|
1076
|
-
case
|
1632
|
+
goto _test_eof4;
|
1633
|
+
case 4:
|
1634
|
+
#line 1635 "parser.c"
|
1077
1635
|
switch( (*p) ) {
|
1078
|
-
case 43: goto
|
1079
|
-
case 45: goto
|
1636
|
+
case 43: goto st5;
|
1637
|
+
case 45: goto st5;
|
1080
1638
|
}
|
1081
1639
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1082
|
-
goto
|
1640
|
+
goto st9;
|
1083
1641
|
goto st0;
|
1084
|
-
|
1642
|
+
st5:
|
1085
1643
|
if ( ++p == pe )
|
1086
|
-
goto
|
1087
|
-
case
|
1644
|
+
goto _test_eof5;
|
1645
|
+
case 5:
|
1088
1646
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1089
|
-
goto
|
1647
|
+
goto st9;
|
1090
1648
|
goto st0;
|
1091
|
-
|
1649
|
+
st9:
|
1092
1650
|
if ( ++p == pe )
|
1093
|
-
goto
|
1094
|
-
case
|
1651
|
+
goto _test_eof9;
|
1652
|
+
case 9:
|
1095
1653
|
switch( (*p) ) {
|
1096
1654
|
case 69: goto st0;
|
1097
1655
|
case 101: goto st0;
|
1098
1656
|
}
|
1099
1657
|
if ( (*p) > 46 ) {
|
1100
1658
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1101
|
-
goto
|
1659
|
+
goto st9;
|
1102
1660
|
} else if ( (*p) >= 45 )
|
1103
1661
|
goto st0;
|
1104
|
-
goto
|
1105
|
-
|
1662
|
+
goto tr7;
|
1663
|
+
st10:
|
1106
1664
|
if ( ++p == pe )
|
1107
|
-
goto
|
1108
|
-
case
|
1665
|
+
goto _test_eof10;
|
1666
|
+
case 10:
|
1109
1667
|
switch( (*p) ) {
|
1110
|
-
case
|
1111
|
-
case
|
1112
|
-
case
|
1668
|
+
case 45: goto st0;
|
1669
|
+
case 46: goto tr8;
|
1670
|
+
case 69: goto tr9;
|
1671
|
+
case 101: goto tr9;
|
1113
1672
|
}
|
1114
1673
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1115
|
-
goto
|
1116
|
-
goto
|
1674
|
+
goto st10;
|
1675
|
+
goto tr7;
|
1117
1676
|
}
|
1118
1677
|
_test_eof2: cs = 2; goto _test_eof;
|
1678
|
+
_test_eof6: cs = 6; goto _test_eof;
|
1679
|
+
_test_eof7: cs = 7; goto _test_eof;
|
1119
1680
|
_test_eof3: cs = 3; goto _test_eof;
|
1120
|
-
_test_eof4: cs = 4; goto _test_eof;
|
1121
1681
|
_test_eof8: cs = 8; goto _test_eof;
|
1122
|
-
|
1682
|
+
_test_eof4: cs = 4; goto _test_eof;
|
1123
1683
|
_test_eof5: cs = 5; goto _test_eof;
|
1124
|
-
|
1684
|
+
_test_eof9: cs = 9; goto _test_eof;
|
1125
1685
|
_test_eof10: cs = 10; goto _test_eof;
|
1126
|
-
_test_eof7: cs = 7; goto _test_eof;
|
1127
1686
|
|
1128
1687
|
_test_eof: {}
|
1129
1688
|
_out: {}
|
1130
1689
|
}
|
1131
1690
|
|
1132
|
-
#line
|
1691
|
+
#line 755 "parser.rl"
|
1133
1692
|
|
1134
1693
|
if (cs >= JSON_float_first_final) {
|
1694
|
+
if (!is_float) {
|
1695
|
+
return JSON_decode_integer(json, p, result);
|
1696
|
+
}
|
1135
1697
|
VALUE mod = Qnil;
|
1136
1698
|
ID method_id = 0;
|
1137
|
-
if (
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
1150
|
-
|
1151
|
-
|
1152
|
-
|
1153
|
-
|
1154
|
-
|
1155
|
-
|
1156
|
-
|
1157
|
-
|
1158
|
-
|
1159
|
-
|
1699
|
+
if (json->decimal_class) {
|
1700
|
+
if (rb_respond_to(json->decimal_class, i_try_convert)) {
|
1701
|
+
mod = json->decimal_class;
|
1702
|
+
method_id = i_try_convert;
|
1703
|
+
} else if (rb_respond_to(json->decimal_class, i_new)) {
|
1704
|
+
mod = json->decimal_class;
|
1705
|
+
method_id = i_new;
|
1706
|
+
} else if (RB_TYPE_P(json->decimal_class, T_CLASS)) {
|
1707
|
+
VALUE name = rb_class_name(json->decimal_class);
|
1708
|
+
const char *name_cstr = RSTRING_PTR(name);
|
1709
|
+
const char *last_colon = strrchr(name_cstr, ':');
|
1710
|
+
if (last_colon) {
|
1711
|
+
const char *mod_path_end = last_colon - 1;
|
1712
|
+
VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr);
|
1713
|
+
mod = rb_path_to_class(mod_path);
|
1714
|
+
|
1715
|
+
const char *method_name_beg = last_colon + 1;
|
1716
|
+
long before_len = method_name_beg - name_cstr;
|
1717
|
+
long len = RSTRING_LEN(name) - before_len;
|
1718
|
+
VALUE method_name = rb_str_substr(name, before_len, len);
|
1719
|
+
method_id = SYM2ID(rb_str_intern(method_name));
|
1720
|
+
} else {
|
1721
|
+
mod = rb_mKernel;
|
1722
|
+
method_id = SYM2ID(rb_str_intern(name));
|
1723
|
+
}
|
1160
1724
|
}
|
1161
1725
|
}
|
1162
1726
|
|
1163
1727
|
long len = p - json->memo;
|
1164
|
-
fbuffer_clear(json->fbuffer);
|
1165
|
-
fbuffer_append(json->fbuffer, json->memo, len);
|
1166
|
-
fbuffer_append_char(json->fbuffer, '\0');
|
1728
|
+
fbuffer_clear(&json->fbuffer);
|
1729
|
+
fbuffer_append(&json->fbuffer, json->memo, len);
|
1730
|
+
fbuffer_append_char(&json->fbuffer, '\0');
|
1167
1731
|
|
1168
1732
|
if (method_id) {
|
1169
|
-
VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
|
1733
|
+
VALUE text = rb_str_new2(FBUFFER_PTR(&json->fbuffer));
|
1170
1734
|
*result = rb_funcallv(mod, method_id, 1, &text);
|
1171
1735
|
} else {
|
1172
|
-
*result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
|
1736
|
+
*result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(&json->fbuffer), 1));
|
1173
1737
|
}
|
1174
1738
|
|
1175
1739
|
return p + 1;
|
@@ -1180,37 +1744,37 @@ case 7:
|
|
1180
1744
|
|
1181
1745
|
|
1182
1746
|
|
1183
|
-
#line
|
1747
|
+
#line 1748 "parser.c"
|
1184
1748
|
enum {JSON_array_start = 1};
|
1185
|
-
enum {JSON_array_first_final =
|
1749
|
+
enum {JSON_array_first_final = 22};
|
1186
1750
|
enum {JSON_array_error = 0};
|
1187
1751
|
|
1188
1752
|
enum {JSON_array_en_main = 1};
|
1189
1753
|
|
1190
1754
|
|
1191
|
-
#line
|
1755
|
+
#line 835 "parser.rl"
|
1192
1756
|
|
1193
1757
|
|
1194
1758
|
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
1195
1759
|
{
|
1196
1760
|
int cs = EVIL;
|
1197
|
-
VALUE array_class = json->array_class;
|
1198
1761
|
|
1199
1762
|
if (json->max_nesting && current_nesting > json->max_nesting) {
|
1200
1763
|
rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
|
1201
1764
|
}
|
1202
|
-
|
1765
|
+
long stack_head = json->stack->head;
|
1203
1766
|
|
1204
1767
|
|
1205
|
-
#line
|
1768
|
+
#line 1769 "parser.c"
|
1206
1769
|
{
|
1207
1770
|
cs = JSON_array_start;
|
1208
1771
|
}
|
1209
1772
|
|
1210
|
-
#line
|
1773
|
+
#line 847 "parser.rl"
|
1211
1774
|
|
1212
|
-
#line
|
1775
|
+
#line 1776 "parser.c"
|
1213
1776
|
{
|
1777
|
+
short _widec;
|
1214
1778
|
if ( p == pe )
|
1215
1779
|
goto _test_eof;
|
1216
1780
|
switch ( cs )
|
@@ -1231,7 +1795,7 @@ case 2:
|
|
1231
1795
|
case 32: goto st2;
|
1232
1796
|
case 34: goto tr2;
|
1233
1797
|
case 45: goto tr2;
|
1234
|
-
case 47: goto
|
1798
|
+
case 47: goto st18;
|
1235
1799
|
case 73: goto tr2;
|
1236
1800
|
case 78: goto tr2;
|
1237
1801
|
case 91: goto tr2;
|
@@ -1248,18 +1812,13 @@ case 2:
|
|
1248
1812
|
goto st2;
|
1249
1813
|
goto st0;
|
1250
1814
|
tr2:
|
1251
|
-
#line
|
1815
|
+
#line 815 "parser.rl"
|
1252
1816
|
{
|
1253
1817
|
VALUE v = Qnil;
|
1254
1818
|
char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
|
1255
1819
|
if (np == NULL) {
|
1256
1820
|
p--; {p++; cs = 3; goto _out;}
|
1257
1821
|
} else {
|
1258
|
-
if (NIL_P(json->array_class)) {
|
1259
|
-
rb_ary_push(*result, v);
|
1260
|
-
} else {
|
1261
|
-
rb_funcall(*result, i_leftshift, 1, v);
|
1262
|
-
}
|
1263
1822
|
{p = (( np))-1;}
|
1264
1823
|
}
|
1265
1824
|
}
|
@@ -1268,15 +1827,23 @@ st3:
|
|
1268
1827
|
if ( ++p == pe )
|
1269
1828
|
goto _test_eof3;
|
1270
1829
|
case 3:
|
1271
|
-
#line
|
1272
|
-
|
1830
|
+
#line 1831 "parser.c"
|
1831
|
+
_widec = (*p);
|
1832
|
+
if ( 44 <= (*p) && (*p) <= 44 ) {
|
1833
|
+
_widec = (short)(128 + ((*p) - -128));
|
1834
|
+
if (
|
1835
|
+
#line 825 "parser.rl"
|
1836
|
+
json->allow_trailing_comma ) _widec += 256;
|
1837
|
+
}
|
1838
|
+
switch( _widec ) {
|
1273
1839
|
case 13: goto st3;
|
1274
1840
|
case 32: goto st3;
|
1275
|
-
case
|
1276
|
-
case 47: goto st9;
|
1841
|
+
case 47: goto st4;
|
1277
1842
|
case 93: goto tr4;
|
1843
|
+
case 300: goto st8;
|
1844
|
+
case 556: goto st13;
|
1278
1845
|
}
|
1279
|
-
if ( 9 <=
|
1846
|
+
if ( 9 <= _widec && _widec <= 10 )
|
1280
1847
|
goto st3;
|
1281
1848
|
goto st0;
|
1282
1849
|
st4:
|
@@ -1284,57 +1851,67 @@ st4:
|
|
1284
1851
|
goto _test_eof4;
|
1285
1852
|
case 4:
|
1286
1853
|
switch( (*p) ) {
|
1287
|
-
case
|
1288
|
-
case
|
1289
|
-
case 34: goto tr2;
|
1290
|
-
case 45: goto tr2;
|
1291
|
-
case 47: goto st5;
|
1292
|
-
case 73: goto tr2;
|
1293
|
-
case 78: goto tr2;
|
1294
|
-
case 91: goto tr2;
|
1295
|
-
case 102: goto tr2;
|
1296
|
-
case 110: goto tr2;
|
1297
|
-
case 116: goto tr2;
|
1298
|
-
case 123: goto tr2;
|
1854
|
+
case 42: goto st5;
|
1855
|
+
case 47: goto st7;
|
1299
1856
|
}
|
1300
|
-
if ( (*p) > 10 ) {
|
1301
|
-
if ( 48 <= (*p) && (*p) <= 57 )
|
1302
|
-
goto tr2;
|
1303
|
-
} else if ( (*p) >= 9 )
|
1304
|
-
goto st4;
|
1305
1857
|
goto st0;
|
1306
1858
|
st5:
|
1307
1859
|
if ( ++p == pe )
|
1308
1860
|
goto _test_eof5;
|
1309
1861
|
case 5:
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1313
|
-
}
|
1314
|
-
goto st0;
|
1862
|
+
if ( (*p) == 42 )
|
1863
|
+
goto st6;
|
1864
|
+
goto st5;
|
1315
1865
|
st6:
|
1316
1866
|
if ( ++p == pe )
|
1317
1867
|
goto _test_eof6;
|
1318
1868
|
case 6:
|
1319
|
-
|
1320
|
-
goto
|
1321
|
-
|
1869
|
+
switch( (*p) ) {
|
1870
|
+
case 42: goto st6;
|
1871
|
+
case 47: goto st3;
|
1872
|
+
}
|
1873
|
+
goto st5;
|
1322
1874
|
st7:
|
1323
1875
|
if ( ++p == pe )
|
1324
1876
|
goto _test_eof7;
|
1325
1877
|
case 7:
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
1329
|
-
|
1330
|
-
|
1878
|
+
if ( (*p) == 10 )
|
1879
|
+
goto st3;
|
1880
|
+
goto st7;
|
1881
|
+
tr4:
|
1882
|
+
#line 827 "parser.rl"
|
1883
|
+
{ p--; {p++; cs = 22; goto _out;} }
|
1884
|
+
goto st22;
|
1885
|
+
st22:
|
1886
|
+
if ( ++p == pe )
|
1887
|
+
goto _test_eof22;
|
1888
|
+
case 22:
|
1889
|
+
#line 1890 "parser.c"
|
1890
|
+
goto st0;
|
1331
1891
|
st8:
|
1332
1892
|
if ( ++p == pe )
|
1333
1893
|
goto _test_eof8;
|
1334
1894
|
case 8:
|
1335
|
-
|
1336
|
-
goto
|
1337
|
-
|
1895
|
+
switch( (*p) ) {
|
1896
|
+
case 13: goto st8;
|
1897
|
+
case 32: goto st8;
|
1898
|
+
case 34: goto tr2;
|
1899
|
+
case 45: goto tr2;
|
1900
|
+
case 47: goto st9;
|
1901
|
+
case 73: goto tr2;
|
1902
|
+
case 78: goto tr2;
|
1903
|
+
case 91: goto tr2;
|
1904
|
+
case 102: goto tr2;
|
1905
|
+
case 110: goto tr2;
|
1906
|
+
case 116: goto tr2;
|
1907
|
+
case 123: goto tr2;
|
1908
|
+
}
|
1909
|
+
if ( (*p) > 10 ) {
|
1910
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
1911
|
+
goto tr2;
|
1912
|
+
} else if ( (*p) >= 9 )
|
1913
|
+
goto st8;
|
1914
|
+
goto st0;
|
1338
1915
|
st9:
|
1339
1916
|
if ( ++p == pe )
|
1340
1917
|
goto _test_eof9;
|
@@ -1357,7 +1934,7 @@ st11:
|
|
1357
1934
|
case 11:
|
1358
1935
|
switch( (*p) ) {
|
1359
1936
|
case 42: goto st11;
|
1360
|
-
case 47: goto
|
1937
|
+
case 47: goto st8;
|
1361
1938
|
}
|
1362
1939
|
goto st10;
|
1363
1940
|
st12:
|
@@ -1365,50 +1942,252 @@ st12:
|
|
1365
1942
|
goto _test_eof12;
|
1366
1943
|
case 12:
|
1367
1944
|
if ( (*p) == 10 )
|
1368
|
-
goto
|
1945
|
+
goto st8;
|
1369
1946
|
goto st12;
|
1370
|
-
tr4:
|
1371
|
-
#line 424 "parser.rl"
|
1372
|
-
{ p--; {p++; cs = 17; goto _out;} }
|
1373
|
-
goto st17;
|
1374
|
-
st17:
|
1375
|
-
if ( ++p == pe )
|
1376
|
-
goto _test_eof17;
|
1377
|
-
case 17:
|
1378
|
-
#line 1379 "parser.c"
|
1379
|
-
goto st0;
|
1380
1947
|
st13:
|
1381
1948
|
if ( ++p == pe )
|
1382
1949
|
goto _test_eof13;
|
1383
1950
|
case 13:
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1951
|
+
_widec = (*p);
|
1952
|
+
if ( (*p) < 13 ) {
|
1953
|
+
if ( (*p) > 9 ) {
|
1954
|
+
if ( 10 <= (*p) && (*p) <= 10 ) {
|
1955
|
+
_widec = (short)(128 + ((*p) - -128));
|
1956
|
+
if (
|
1957
|
+
#line 825 "parser.rl"
|
1958
|
+
json->allow_trailing_comma ) _widec += 256;
|
1959
|
+
}
|
1960
|
+
} else if ( (*p) >= 9 ) {
|
1961
|
+
_widec = (short)(128 + ((*p) - -128));
|
1962
|
+
if (
|
1963
|
+
#line 825 "parser.rl"
|
1964
|
+
json->allow_trailing_comma ) _widec += 256;
|
1965
|
+
}
|
1966
|
+
} else if ( (*p) > 13 ) {
|
1967
|
+
if ( (*p) > 32 ) {
|
1968
|
+
if ( 47 <= (*p) && (*p) <= 47 ) {
|
1969
|
+
_widec = (short)(128 + ((*p) - -128));
|
1970
|
+
if (
|
1971
|
+
#line 825 "parser.rl"
|
1972
|
+
json->allow_trailing_comma ) _widec += 256;
|
1973
|
+
}
|
1974
|
+
} else if ( (*p) >= 32 ) {
|
1975
|
+
_widec = (short)(128 + ((*p) - -128));
|
1976
|
+
if (
|
1977
|
+
#line 825 "parser.rl"
|
1978
|
+
json->allow_trailing_comma ) _widec += 256;
|
1979
|
+
}
|
1980
|
+
} else {
|
1981
|
+
_widec = (short)(128 + ((*p) - -128));
|
1982
|
+
if (
|
1983
|
+
#line 825 "parser.rl"
|
1984
|
+
json->allow_trailing_comma ) _widec += 256;
|
1387
1985
|
}
|
1986
|
+
switch( _widec ) {
|
1987
|
+
case 34: goto tr2;
|
1988
|
+
case 45: goto tr2;
|
1989
|
+
case 73: goto tr2;
|
1990
|
+
case 78: goto tr2;
|
1991
|
+
case 91: goto tr2;
|
1992
|
+
case 93: goto tr4;
|
1993
|
+
case 102: goto tr2;
|
1994
|
+
case 110: goto tr2;
|
1995
|
+
case 116: goto tr2;
|
1996
|
+
case 123: goto tr2;
|
1997
|
+
case 269: goto st8;
|
1998
|
+
case 288: goto st8;
|
1999
|
+
case 303: goto st9;
|
2000
|
+
case 525: goto st13;
|
2001
|
+
case 544: goto st13;
|
2002
|
+
case 559: goto st14;
|
2003
|
+
}
|
2004
|
+
if ( _widec < 265 ) {
|
2005
|
+
if ( 48 <= _widec && _widec <= 57 )
|
2006
|
+
goto tr2;
|
2007
|
+
} else if ( _widec > 266 ) {
|
2008
|
+
if ( 521 <= _widec && _widec <= 522 )
|
2009
|
+
goto st13;
|
2010
|
+
} else
|
2011
|
+
goto st8;
|
1388
2012
|
goto st0;
|
1389
2013
|
st14:
|
1390
2014
|
if ( ++p == pe )
|
1391
2015
|
goto _test_eof14;
|
1392
2016
|
case 14:
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
2017
|
+
_widec = (*p);
|
2018
|
+
if ( (*p) > 42 ) {
|
2019
|
+
if ( 47 <= (*p) && (*p) <= 47 ) {
|
2020
|
+
_widec = (short)(128 + ((*p) - -128));
|
2021
|
+
if (
|
2022
|
+
#line 825 "parser.rl"
|
2023
|
+
json->allow_trailing_comma ) _widec += 256;
|
2024
|
+
}
|
2025
|
+
} else if ( (*p) >= 42 ) {
|
2026
|
+
_widec = (short)(128 + ((*p) - -128));
|
2027
|
+
if (
|
2028
|
+
#line 825 "parser.rl"
|
2029
|
+
json->allow_trailing_comma ) _widec += 256;
|
2030
|
+
}
|
2031
|
+
switch( _widec ) {
|
2032
|
+
case 298: goto st10;
|
2033
|
+
case 303: goto st12;
|
2034
|
+
case 554: goto st15;
|
2035
|
+
case 559: goto st17;
|
2036
|
+
}
|
2037
|
+
goto st0;
|
1396
2038
|
st15:
|
1397
2039
|
if ( ++p == pe )
|
1398
2040
|
goto _test_eof15;
|
1399
2041
|
case 15:
|
1400
|
-
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
2042
|
+
_widec = (*p);
|
2043
|
+
if ( (*p) < 42 ) {
|
2044
|
+
if ( (*p) <= 41 ) {
|
2045
|
+
_widec = (short)(128 + ((*p) - -128));
|
2046
|
+
if (
|
2047
|
+
#line 825 "parser.rl"
|
2048
|
+
json->allow_trailing_comma ) _widec += 256;
|
2049
|
+
}
|
2050
|
+
} else if ( (*p) > 42 ) {
|
2051
|
+
if ( 43 <= (*p) )
|
2052
|
+
{ _widec = (short)(128 + ((*p) - -128));
|
2053
|
+
if (
|
2054
|
+
#line 825 "parser.rl"
|
2055
|
+
json->allow_trailing_comma ) _widec += 256;
|
2056
|
+
}
|
2057
|
+
} else {
|
2058
|
+
_widec = (short)(128 + ((*p) - -128));
|
2059
|
+
if (
|
2060
|
+
#line 825 "parser.rl"
|
2061
|
+
json->allow_trailing_comma ) _widec += 256;
|
2062
|
+
}
|
2063
|
+
switch( _widec ) {
|
2064
|
+
case 298: goto st11;
|
2065
|
+
case 554: goto st16;
|
2066
|
+
}
|
2067
|
+
if ( _widec > 383 ) {
|
2068
|
+
if ( 384 <= _widec && _widec <= 639 )
|
2069
|
+
goto st15;
|
2070
|
+
} else if ( _widec >= 128 )
|
2071
|
+
goto st10;
|
2072
|
+
goto st0;
|
1405
2073
|
st16:
|
1406
2074
|
if ( ++p == pe )
|
1407
2075
|
goto _test_eof16;
|
1408
2076
|
case 16:
|
2077
|
+
_widec = (*p);
|
2078
|
+
if ( (*p) < 43 ) {
|
2079
|
+
if ( (*p) > 41 ) {
|
2080
|
+
if ( 42 <= (*p) && (*p) <= 42 ) {
|
2081
|
+
_widec = (short)(128 + ((*p) - -128));
|
2082
|
+
if (
|
2083
|
+
#line 825 "parser.rl"
|
2084
|
+
json->allow_trailing_comma ) _widec += 256;
|
2085
|
+
}
|
2086
|
+
} else {
|
2087
|
+
_widec = (short)(128 + ((*p) - -128));
|
2088
|
+
if (
|
2089
|
+
#line 825 "parser.rl"
|
2090
|
+
json->allow_trailing_comma ) _widec += 256;
|
2091
|
+
}
|
2092
|
+
} else if ( (*p) > 46 ) {
|
2093
|
+
if ( (*p) > 47 ) {
|
2094
|
+
if ( 48 <= (*p) )
|
2095
|
+
{ _widec = (short)(128 + ((*p) - -128));
|
2096
|
+
if (
|
2097
|
+
#line 825 "parser.rl"
|
2098
|
+
json->allow_trailing_comma ) _widec += 256;
|
2099
|
+
}
|
2100
|
+
} else if ( (*p) >= 47 ) {
|
2101
|
+
_widec = (short)(128 + ((*p) - -128));
|
2102
|
+
if (
|
2103
|
+
#line 825 "parser.rl"
|
2104
|
+
json->allow_trailing_comma ) _widec += 256;
|
2105
|
+
}
|
2106
|
+
} else {
|
2107
|
+
_widec = (short)(128 + ((*p) - -128));
|
2108
|
+
if (
|
2109
|
+
#line 825 "parser.rl"
|
2110
|
+
json->allow_trailing_comma ) _widec += 256;
|
2111
|
+
}
|
2112
|
+
switch( _widec ) {
|
2113
|
+
case 298: goto st11;
|
2114
|
+
case 303: goto st8;
|
2115
|
+
case 554: goto st16;
|
2116
|
+
case 559: goto st13;
|
2117
|
+
}
|
2118
|
+
if ( _widec > 383 ) {
|
2119
|
+
if ( 384 <= _widec && _widec <= 639 )
|
2120
|
+
goto st15;
|
2121
|
+
} else if ( _widec >= 128 )
|
2122
|
+
goto st10;
|
2123
|
+
goto st0;
|
2124
|
+
st17:
|
2125
|
+
if ( ++p == pe )
|
2126
|
+
goto _test_eof17;
|
2127
|
+
case 17:
|
2128
|
+
_widec = (*p);
|
2129
|
+
if ( (*p) < 10 ) {
|
2130
|
+
if ( (*p) <= 9 ) {
|
2131
|
+
_widec = (short)(128 + ((*p) - -128));
|
2132
|
+
if (
|
2133
|
+
#line 825 "parser.rl"
|
2134
|
+
json->allow_trailing_comma ) _widec += 256;
|
2135
|
+
}
|
2136
|
+
} else if ( (*p) > 10 ) {
|
2137
|
+
if ( 11 <= (*p) )
|
2138
|
+
{ _widec = (short)(128 + ((*p) - -128));
|
2139
|
+
if (
|
2140
|
+
#line 825 "parser.rl"
|
2141
|
+
json->allow_trailing_comma ) _widec += 256;
|
2142
|
+
}
|
2143
|
+
} else {
|
2144
|
+
_widec = (short)(128 + ((*p) - -128));
|
2145
|
+
if (
|
2146
|
+
#line 825 "parser.rl"
|
2147
|
+
json->allow_trailing_comma ) _widec += 256;
|
2148
|
+
}
|
2149
|
+
switch( _widec ) {
|
2150
|
+
case 266: goto st8;
|
2151
|
+
case 522: goto st13;
|
2152
|
+
}
|
2153
|
+
if ( _widec > 383 ) {
|
2154
|
+
if ( 384 <= _widec && _widec <= 639 )
|
2155
|
+
goto st17;
|
2156
|
+
} else if ( _widec >= 128 )
|
2157
|
+
goto st12;
|
2158
|
+
goto st0;
|
2159
|
+
st18:
|
2160
|
+
if ( ++p == pe )
|
2161
|
+
goto _test_eof18;
|
2162
|
+
case 18:
|
2163
|
+
switch( (*p) ) {
|
2164
|
+
case 42: goto st19;
|
2165
|
+
case 47: goto st21;
|
2166
|
+
}
|
2167
|
+
goto st0;
|
2168
|
+
st19:
|
2169
|
+
if ( ++p == pe )
|
2170
|
+
goto _test_eof19;
|
2171
|
+
case 19:
|
2172
|
+
if ( (*p) == 42 )
|
2173
|
+
goto st20;
|
2174
|
+
goto st19;
|
2175
|
+
st20:
|
2176
|
+
if ( ++p == pe )
|
2177
|
+
goto _test_eof20;
|
2178
|
+
case 20:
|
2179
|
+
switch( (*p) ) {
|
2180
|
+
case 42: goto st20;
|
2181
|
+
case 47: goto st2;
|
2182
|
+
}
|
2183
|
+
goto st19;
|
2184
|
+
st21:
|
2185
|
+
if ( ++p == pe )
|
2186
|
+
goto _test_eof21;
|
2187
|
+
case 21:
|
1409
2188
|
if ( (*p) == 10 )
|
1410
2189
|
goto st2;
|
1411
|
-
goto
|
2190
|
+
goto st21;
|
1412
2191
|
}
|
1413
2192
|
_test_eof2: cs = 2; goto _test_eof;
|
1414
2193
|
_test_eof3: cs = 3; goto _test_eof;
|
@@ -1416,54 +2195,127 @@ case 16:
|
|
1416
2195
|
_test_eof5: cs = 5; goto _test_eof;
|
1417
2196
|
_test_eof6: cs = 6; goto _test_eof;
|
1418
2197
|
_test_eof7: cs = 7; goto _test_eof;
|
2198
|
+
_test_eof22: cs = 22; goto _test_eof;
|
1419
2199
|
_test_eof8: cs = 8; goto _test_eof;
|
1420
2200
|
_test_eof9: cs = 9; goto _test_eof;
|
1421
2201
|
_test_eof10: cs = 10; goto _test_eof;
|
1422
2202
|
_test_eof11: cs = 11; goto _test_eof;
|
1423
2203
|
_test_eof12: cs = 12; goto _test_eof;
|
1424
|
-
_test_eof17: cs = 17; goto _test_eof;
|
1425
2204
|
_test_eof13: cs = 13; goto _test_eof;
|
1426
2205
|
_test_eof14: cs = 14; goto _test_eof;
|
1427
2206
|
_test_eof15: cs = 15; goto _test_eof;
|
1428
2207
|
_test_eof16: cs = 16; goto _test_eof;
|
2208
|
+
_test_eof17: cs = 17; goto _test_eof;
|
2209
|
+
_test_eof18: cs = 18; goto _test_eof;
|
2210
|
+
_test_eof19: cs = 19; goto _test_eof;
|
2211
|
+
_test_eof20: cs = 20; goto _test_eof;
|
2212
|
+
_test_eof21: cs = 21; goto _test_eof;
|
1429
2213
|
|
1430
2214
|
_test_eof: {}
|
1431
2215
|
_out: {}
|
1432
2216
|
}
|
1433
2217
|
|
1434
|
-
#line
|
2218
|
+
#line 848 "parser.rl"
|
1435
2219
|
|
1436
2220
|
if(cs >= JSON_array_first_final) {
|
2221
|
+
long count = json->stack->head - stack_head;
|
2222
|
+
|
2223
|
+
if (RB_UNLIKELY(json->array_class)) {
|
2224
|
+
VALUE array = rb_class_new_instance(0, 0, json->array_class);
|
2225
|
+
VALUE *items = rvalue_stack_peek(json->stack, count);
|
2226
|
+
long index;
|
2227
|
+
for (index = 0; index < count; index++) {
|
2228
|
+
rb_funcall(array, i_leftshift, 1, items[index]);
|
2229
|
+
}
|
2230
|
+
*result = array;
|
2231
|
+
} else {
|
2232
|
+
VALUE array = rb_ary_new_from_values(count, rvalue_stack_peek(json->stack, count));
|
2233
|
+
*result = array;
|
2234
|
+
}
|
2235
|
+
rvalue_stack_pop(json->stack, count);
|
2236
|
+
|
1437
2237
|
return p + 1;
|
1438
2238
|
} else {
|
1439
|
-
|
2239
|
+
raise_parse_error("unexpected token at '%s'", p);
|
1440
2240
|
return NULL;
|
1441
2241
|
}
|
1442
2242
|
}
|
1443
2243
|
|
1444
|
-
static const
|
1445
|
-
|
2244
|
+
static inline VALUE build_string(const char *start, const char *end, bool intern, bool symbolize)
|
2245
|
+
{
|
2246
|
+
if (symbolize) {
|
2247
|
+
intern = true;
|
2248
|
+
}
|
2249
|
+
VALUE result;
|
2250
|
+
# ifdef HAVE_RB_ENC_INTERNED_STR
|
2251
|
+
if (intern) {
|
2252
|
+
result = rb_enc_interned_str(start, (long)(end - start), enc_utf8);
|
2253
|
+
} else {
|
2254
|
+
result = rb_utf8_str_new(start, (long)(end - start));
|
2255
|
+
}
|
2256
|
+
# else
|
2257
|
+
result = rb_utf8_str_new(start, (long)(end - start));
|
2258
|
+
if (intern) {
|
2259
|
+
result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
|
2260
|
+
}
|
2261
|
+
# endif
|
2262
|
+
|
2263
|
+
if (symbolize) {
|
2264
|
+
result = rb_str_intern(result);
|
2265
|
+
}
|
2266
|
+
|
2267
|
+
return result;
|
2268
|
+
}
|
2269
|
+
|
2270
|
+
static VALUE json_string_fastpath(JSON_Parser *json, char *string, char *stringEnd, bool is_name, bool intern, bool symbolize)
|
2271
|
+
{
|
2272
|
+
size_t bufferSize = stringEnd - string;
|
2273
|
+
|
2274
|
+
if (is_name && json->in_array) {
|
2275
|
+
VALUE cached_key;
|
2276
|
+
if (RB_UNLIKELY(symbolize)) {
|
2277
|
+
cached_key = rsymbol_cache_fetch(&json->name_cache, string, bufferSize);
|
2278
|
+
} else {
|
2279
|
+
cached_key = rstring_cache_fetch(&json->name_cache, string, bufferSize);
|
2280
|
+
}
|
2281
|
+
|
2282
|
+
if (RB_LIKELY(cached_key)) {
|
2283
|
+
return cached_key;
|
2284
|
+
}
|
2285
|
+
}
|
2286
|
+
|
2287
|
+
return build_string(string, stringEnd, intern, symbolize);
|
2288
|
+
}
|
2289
|
+
|
2290
|
+
static VALUE json_string_unescape(JSON_Parser *json, char *string, char *stringEnd, bool is_name, bool intern, bool symbolize)
|
1446
2291
|
{
|
1447
|
-
VALUE result = Qnil;
|
1448
2292
|
size_t bufferSize = stringEnd - string;
|
1449
2293
|
char *p = string, *pe = string, *unescape, *bufferStart, *buffer;
|
1450
2294
|
int unescape_len;
|
1451
2295
|
char buf[4];
|
1452
2296
|
|
1453
|
-
if (
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
2297
|
+
if (is_name && json->in_array) {
|
2298
|
+
VALUE cached_key;
|
2299
|
+
if (RB_UNLIKELY(symbolize)) {
|
2300
|
+
cached_key = rsymbol_cache_fetch(&json->name_cache, string, bufferSize);
|
2301
|
+
} else {
|
2302
|
+
cached_key = rstring_cache_fetch(&json->name_cache, string, bufferSize);
|
2303
|
+
}
|
2304
|
+
|
2305
|
+
if (RB_LIKELY(cached_key)) {
|
2306
|
+
return cached_key;
|
2307
|
+
}
|
2308
|
+
}
|
2309
|
+
|
2310
|
+
pe = memchr(p, '\\', bufferSize);
|
2311
|
+
if (RB_UNLIKELY(pe == NULL)) {
|
2312
|
+
return build_string(string, stringEnd, intern, symbolize);
|
1465
2313
|
}
|
1466
2314
|
|
2315
|
+
VALUE result = rb_str_buf_new(bufferSize);
|
2316
|
+
rb_enc_associate_index(result, utf8_encindex);
|
2317
|
+
buffer = bufferStart = RSTRING_PTR(result);
|
2318
|
+
|
1467
2319
|
while (pe < stringEnd) {
|
1468
2320
|
if (*pe == '\\') {
|
1469
2321
|
unescape = (char *) "?";
|
@@ -1496,29 +2348,27 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
|
|
1496
2348
|
break;
|
1497
2349
|
case 'u':
|
1498
2350
|
if (pe > stringEnd - 4) {
|
1499
|
-
|
1500
|
-
ruby_xfree(bufferStart);
|
1501
|
-
}
|
1502
|
-
rb_enc_raise(
|
1503
|
-
EXC_ENCODING eParserError,
|
1504
|
-
"incomplete unicode character escape sequence at '%s'", p
|
1505
|
-
);
|
2351
|
+
raise_parse_error("incomplete unicode character escape sequence at '%s'", p);
|
1506
2352
|
} else {
|
1507
|
-
|
2353
|
+
uint32_t ch = unescape_unicode((unsigned char *) ++pe);
|
1508
2354
|
pe += 3;
|
1509
|
-
|
2355
|
+
/* To handle values above U+FFFF, we take a sequence of
|
2356
|
+
* \uXXXX escapes in the U+D800..U+DBFF then
|
2357
|
+
* U+DC00..U+DFFF ranges, take the low 10 bits from each
|
2358
|
+
* to make a 20-bit number, then add 0x10000 to get the
|
2359
|
+
* final codepoint.
|
2360
|
+
*
|
2361
|
+
* See Unicode 15: 3.8 "Surrogates", 5.3 "Handling
|
2362
|
+
* Surrogate Pairs in UTF-16", and 23.6 "Surrogates
|
2363
|
+
* Area".
|
2364
|
+
*/
|
2365
|
+
if ((ch & 0xFC00) == 0xD800) {
|
1510
2366
|
pe++;
|
1511
2367
|
if (pe > stringEnd - 6) {
|
1512
|
-
|
1513
|
-
ruby_xfree(bufferStart);
|
1514
|
-
}
|
1515
|
-
rb_enc_raise(
|
1516
|
-
EXC_ENCODING eParserError,
|
1517
|
-
"incomplete surrogate pair at '%s'", p
|
1518
|
-
);
|
2368
|
+
raise_parse_error("incomplete surrogate pair at '%s'", p);
|
1519
2369
|
}
|
1520
2370
|
if (pe[0] == '\\' && pe[1] == 'u') {
|
1521
|
-
|
2371
|
+
uint32_t sur = unescape_unicode((unsigned char *) pe + 2);
|
1522
2372
|
ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
|
1523
2373
|
| (sur & 0x3FF));
|
1524
2374
|
pe += 5;
|
@@ -1547,56 +2397,27 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
|
|
1547
2397
|
MEMCPY(buffer, p, char, pe - p);
|
1548
2398
|
buffer += pe - p;
|
1549
2399
|
}
|
1550
|
-
|
1551
|
-
# ifdef HAVE_RB_ENC_INTERNED_STR
|
1552
|
-
if (intern) {
|
1553
|
-
result = rb_enc_interned_str(bufferStart, (long)(buffer - bufferStart), rb_utf8_encoding());
|
1554
|
-
} else {
|
1555
|
-
result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
|
1556
|
-
}
|
1557
|
-
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
|
1558
|
-
ruby_xfree(bufferStart);
|
1559
|
-
}
|
1560
|
-
# else
|
1561
|
-
result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
|
1562
|
-
|
1563
|
-
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
|
1564
|
-
ruby_xfree(bufferStart);
|
1565
|
-
}
|
1566
|
-
|
1567
|
-
if (intern) {
|
1568
|
-
# if STR_UMINUS_DEDUPE_FROZEN
|
1569
|
-
// Starting from MRI 2.8 it is preferable to freeze the string
|
1570
|
-
// before deduplication so that it can be interned directly
|
1571
|
-
// otherwise it would be duplicated first which is wasteful.
|
1572
|
-
result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
|
1573
|
-
# elif STR_UMINUS_DEDUPE
|
1574
|
-
// MRI 2.5 and older do not deduplicate strings that are already
|
1575
|
-
// frozen.
|
1576
|
-
result = rb_funcall(result, i_uminus, 0);
|
1577
|
-
# else
|
1578
|
-
result = rb_str_freeze(result);
|
1579
|
-
# endif
|
1580
|
-
}
|
1581
|
-
# endif
|
2400
|
+
rb_str_set_len(result, buffer - bufferStart);
|
1582
2401
|
|
1583
2402
|
if (symbolize) {
|
1584
|
-
|
2403
|
+
result = rb_str_intern(result);
|
2404
|
+
} else if (intern) {
|
2405
|
+
result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
|
1585
2406
|
}
|
1586
2407
|
|
1587
2408
|
return result;
|
1588
2409
|
}
|
1589
2410
|
|
1590
2411
|
|
1591
|
-
#line
|
2412
|
+
#line 2413 "parser.c"
|
1592
2413
|
enum {JSON_string_start = 1};
|
1593
|
-
enum {JSON_string_first_final =
|
2414
|
+
enum {JSON_string_first_final = 9};
|
1594
2415
|
enum {JSON_string_error = 0};
|
1595
2416
|
|
1596
2417
|
enum {JSON_string_en_main = 1};
|
1597
2418
|
|
1598
2419
|
|
1599
|
-
#line
|
2420
|
+
#line 1071 "parser.rl"
|
1600
2421
|
|
1601
2422
|
|
1602
2423
|
static int
|
@@ -1617,15 +2438,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
1617
2438
|
VALUE match_string;
|
1618
2439
|
|
1619
2440
|
|
1620
|
-
#line
|
2441
|
+
#line 2442 "parser.c"
|
1621
2442
|
{
|
1622
2443
|
cs = JSON_string_start;
|
1623
2444
|
}
|
1624
2445
|
|
1625
|
-
#line
|
2446
|
+
#line 1091 "parser.rl"
|
1626
2447
|
json->memo = p;
|
1627
2448
|
|
1628
|
-
#line
|
2449
|
+
#line 2450 "parser.c"
|
1629
2450
|
{
|
1630
2451
|
if ( p == pe )
|
1631
2452
|
goto _test_eof;
|
@@ -1650,47 +2471,56 @@ case 2:
|
|
1650
2471
|
goto st0;
|
1651
2472
|
goto st2;
|
1652
2473
|
tr2:
|
1653
|
-
#line
|
2474
|
+
#line 1053 "parser.rl"
|
1654
2475
|
{
|
1655
|
-
*result =
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
} else {
|
1660
|
-
{p = (( p + 1))-1;}
|
1661
|
-
}
|
2476
|
+
*result = json_string_fastpath(json, json->memo + 1, p, json->parsing_name, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
|
2477
|
+
{p = (( p + 1))-1;}
|
2478
|
+
p--;
|
2479
|
+
{p++; cs = 9; goto _out;}
|
1662
2480
|
}
|
1663
|
-
#line
|
1664
|
-
{
|
1665
|
-
|
1666
|
-
|
2481
|
+
#line 1046 "parser.rl"
|
2482
|
+
{
|
2483
|
+
*result = json_string_unescape(json, json->memo + 1, p, json->parsing_name, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
|
2484
|
+
{p = (( p + 1))-1;}
|
2485
|
+
p--;
|
2486
|
+
{p++; cs = 9; goto _out;}
|
2487
|
+
}
|
2488
|
+
goto st9;
|
2489
|
+
tr6:
|
2490
|
+
#line 1046 "parser.rl"
|
2491
|
+
{
|
2492
|
+
*result = json_string_unescape(json, json->memo + 1, p, json->parsing_name, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
|
2493
|
+
{p = (( p + 1))-1;}
|
2494
|
+
p--;
|
2495
|
+
{p++; cs = 9; goto _out;}
|
2496
|
+
}
|
2497
|
+
goto st9;
|
2498
|
+
st9:
|
1667
2499
|
if ( ++p == pe )
|
1668
|
-
goto
|
1669
|
-
case
|
1670
|
-
#line
|
2500
|
+
goto _test_eof9;
|
2501
|
+
case 9:
|
2502
|
+
#line 2503 "parser.c"
|
1671
2503
|
goto st0;
|
1672
2504
|
st3:
|
1673
2505
|
if ( ++p == pe )
|
1674
2506
|
goto _test_eof3;
|
1675
2507
|
case 3:
|
1676
2508
|
if ( (*p) == 117 )
|
1677
|
-
goto
|
2509
|
+
goto st5;
|
1678
2510
|
if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 )
|
1679
2511
|
goto st0;
|
1680
|
-
goto
|
2512
|
+
goto st4;
|
1681
2513
|
st4:
|
1682
2514
|
if ( ++p == pe )
|
1683
2515
|
goto _test_eof4;
|
1684
2516
|
case 4:
|
1685
|
-
|
1686
|
-
|
1687
|
-
|
1688
|
-
}
|
1689
|
-
|
1690
|
-
|
1691
|
-
|
1692
|
-
goto st5;
|
1693
|
-
goto st0;
|
2517
|
+
switch( (*p) ) {
|
2518
|
+
case 34: goto tr6;
|
2519
|
+
case 92: goto st3;
|
2520
|
+
}
|
2521
|
+
if ( 0 <= (signed char)(*(p)) && (*(p)) <= 31 )
|
2522
|
+
goto st0;
|
2523
|
+
goto st4;
|
1694
2524
|
st5:
|
1695
2525
|
if ( ++p == pe )
|
1696
2526
|
goto _test_eof5;
|
@@ -1723,27 +2553,41 @@ st7:
|
|
1723
2553
|
case 7:
|
1724
2554
|
if ( (*p) < 65 ) {
|
1725
2555
|
if ( 48 <= (*p) && (*p) <= 57 )
|
1726
|
-
goto
|
2556
|
+
goto st8;
|
1727
2557
|
} else if ( (*p) > 70 ) {
|
1728
2558
|
if ( 97 <= (*p) && (*p) <= 102 )
|
1729
|
-
goto
|
2559
|
+
goto st8;
|
1730
2560
|
} else
|
1731
|
-
goto
|
2561
|
+
goto st8;
|
2562
|
+
goto st0;
|
2563
|
+
st8:
|
2564
|
+
if ( ++p == pe )
|
2565
|
+
goto _test_eof8;
|
2566
|
+
case 8:
|
2567
|
+
if ( (*p) < 65 ) {
|
2568
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
2569
|
+
goto st4;
|
2570
|
+
} else if ( (*p) > 70 ) {
|
2571
|
+
if ( 97 <= (*p) && (*p) <= 102 )
|
2572
|
+
goto st4;
|
2573
|
+
} else
|
2574
|
+
goto st4;
|
1732
2575
|
goto st0;
|
1733
2576
|
}
|
1734
2577
|
_test_eof2: cs = 2; goto _test_eof;
|
1735
|
-
|
2578
|
+
_test_eof9: cs = 9; goto _test_eof;
|
1736
2579
|
_test_eof3: cs = 3; goto _test_eof;
|
1737
2580
|
_test_eof4: cs = 4; goto _test_eof;
|
1738
2581
|
_test_eof5: cs = 5; goto _test_eof;
|
1739
2582
|
_test_eof6: cs = 6; goto _test_eof;
|
1740
2583
|
_test_eof7: cs = 7; goto _test_eof;
|
2584
|
+
_test_eof8: cs = 8; goto _test_eof;
|
1741
2585
|
|
1742
2586
|
_test_eof: {}
|
1743
2587
|
_out: {}
|
1744
2588
|
}
|
1745
2589
|
|
1746
|
-
#line
|
2590
|
+
#line 1093 "parser.rl"
|
1747
2591
|
|
1748
2592
|
if (json->create_additions && RTEST(match_string = json->match_string)) {
|
1749
2593
|
VALUE klass;
|
@@ -1777,18 +2621,80 @@ case 7:
|
|
1777
2621
|
|
1778
2622
|
static VALUE convert_encoding(VALUE source)
|
1779
2623
|
{
|
1780
|
-
|
1781
|
-
|
1782
|
-
if (
|
1783
|
-
if (OBJ_FROZEN(source)) {
|
1784
|
-
source = rb_str_dup(source);
|
1785
|
-
}
|
1786
|
-
FORCE_UTF8(source);
|
1787
|
-
} else {
|
1788
|
-
source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
|
1789
|
-
}
|
1790
|
-
#endif
|
2624
|
+
int encindex = RB_ENCODING_GET(source);
|
2625
|
+
|
2626
|
+
if (RB_LIKELY(encindex == utf8_encindex)) {
|
1791
2627
|
return source;
|
2628
|
+
}
|
2629
|
+
|
2630
|
+
if (encindex == binary_encindex) {
|
2631
|
+
// For historical reason, we silently reinterpret binary strings as UTF-8
|
2632
|
+
return rb_enc_associate_index(rb_str_dup(source), utf8_encindex);
|
2633
|
+
}
|
2634
|
+
|
2635
|
+
return rb_funcall(source, i_encode, 1, Encoding_UTF_8);
|
2636
|
+
}
|
2637
|
+
|
2638
|
+
static int configure_parser_i(VALUE key, VALUE val, VALUE data)
|
2639
|
+
{
|
2640
|
+
JSON_Parser *json = (JSON_Parser *)data;
|
2641
|
+
|
2642
|
+
if (key == sym_max_nesting) { json->max_nesting = RTEST(val) ? FIX2INT(val) : 0; }
|
2643
|
+
else if (key == sym_allow_nan) { json->allow_nan = RTEST(val); }
|
2644
|
+
else if (key == sym_allow_trailing_comma) { json->allow_trailing_comma = RTEST(val); }
|
2645
|
+
else if (key == sym_symbolize_names) { json->symbolize_names = RTEST(val); }
|
2646
|
+
else if (key == sym_freeze) { json->freeze = RTEST(val); }
|
2647
|
+
else if (key == sym_create_id) { json->create_id = RTEST(val) ? val : Qfalse; }
|
2648
|
+
else if (key == sym_object_class) { json->object_class = RTEST(val) ? val : Qfalse; }
|
2649
|
+
else if (key == sym_array_class) { json->array_class = RTEST(val) ? val : Qfalse; }
|
2650
|
+
else if (key == sym_decimal_class) { json->decimal_class = RTEST(val) ? val : Qfalse; }
|
2651
|
+
else if (key == sym_match_string) { json->match_string = RTEST(val) ? val : Qfalse; }
|
2652
|
+
else if (key == sym_create_additions) {
|
2653
|
+
if (NIL_P(val)) {
|
2654
|
+
json->create_additions = true;
|
2655
|
+
json->deprecated_create_additions = true;
|
2656
|
+
} else {
|
2657
|
+
json->create_additions = RTEST(val);
|
2658
|
+
json->deprecated_create_additions = false;
|
2659
|
+
}
|
2660
|
+
}
|
2661
|
+
|
2662
|
+
return ST_CONTINUE;
|
2663
|
+
}
|
2664
|
+
|
2665
|
+
static void parser_init(JSON_Parser *json, VALUE source, VALUE opts)
|
2666
|
+
{
|
2667
|
+
if (json->Vsource) {
|
2668
|
+
rb_raise(rb_eTypeError, "already initialized instance");
|
2669
|
+
}
|
2670
|
+
|
2671
|
+
json->fbuffer.initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT;
|
2672
|
+
json->max_nesting = 100;
|
2673
|
+
|
2674
|
+
if (!NIL_P(opts)) {
|
2675
|
+
Check_Type(opts, T_HASH);
|
2676
|
+
if (RHASH_SIZE(opts) > 0) {
|
2677
|
+
// We assume in most cases few keys are set so it's faster to go over
|
2678
|
+
// the provided keys than to check all possible keys.
|
2679
|
+
rb_hash_foreach(opts, configure_parser_i, (VALUE)json);
|
2680
|
+
|
2681
|
+
if (json->symbolize_names && json->create_additions) {
|
2682
|
+
rb_raise(rb_eArgError,
|
2683
|
+
"options :symbolize_names and :create_additions cannot be "
|
2684
|
+
" used in conjunction");
|
2685
|
+
}
|
2686
|
+
|
2687
|
+
if (json->create_additions && !json->create_id) {
|
2688
|
+
json->create_id = rb_funcall(mJSON, i_create_id, 0);
|
2689
|
+
}
|
2690
|
+
}
|
2691
|
+
|
2692
|
+
}
|
2693
|
+
source = convert_encoding(StringValue(source));
|
2694
|
+
StringValue(source);
|
2695
|
+
json->len = RSTRING_LEN(source);
|
2696
|
+
json->source = RSTRING_PTR(source);
|
2697
|
+
json->Vsource = source;
|
1792
2698
|
}
|
1793
2699
|
|
1794
2700
|
/*
|
@@ -1813,110 +2719,28 @@ static VALUE convert_encoding(VALUE source)
|
|
1813
2719
|
* * *create_additions*: If set to false, the Parser doesn't create
|
1814
2720
|
* additions even if a matching class and create_id was found. This option
|
1815
2721
|
* defaults to false.
|
1816
|
-
* * *object_class*: Defaults to Hash
|
1817
|
-
*
|
2722
|
+
* * *object_class*: Defaults to Hash. If another type is provided, it will be used
|
2723
|
+
* instead of Hash to represent JSON objects. The type must respond to
|
2724
|
+
* +new+ without arguments, and return an object that respond to +[]=+.
|
2725
|
+
* * *array_class*: Defaults to Array If another type is provided, it will be used
|
2726
|
+
* instead of Hash to represent JSON arrays. The type must respond to
|
2727
|
+
* +new+ without arguments, and return an object that respond to +<<+.
|
2728
|
+
* * *decimal_class*: Specifies which class to use instead of the default
|
2729
|
+
* (Float) when parsing decimal numbers. This class must accept a single
|
2730
|
+
* string argument in its constructor.
|
1818
2731
|
*/
|
1819
2732
|
static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
1820
2733
|
{
|
1821
|
-
VALUE source, opts;
|
1822
2734
|
GET_PARSER_INIT;
|
1823
2735
|
|
1824
|
-
|
1825
|
-
|
1826
|
-
|
1827
|
-
rb_scan_args(argc, argv, "1:", &source, &opts);
|
1828
|
-
if (!NIL_P(opts)) {
|
1829
|
-
VALUE tmp = ID2SYM(i_max_nesting);
|
1830
|
-
if (option_given_p(opts, tmp)) {
|
1831
|
-
VALUE max_nesting = rb_hash_aref(opts, tmp);
|
1832
|
-
if (RTEST(max_nesting)) {
|
1833
|
-
Check_Type(max_nesting, T_FIXNUM);
|
1834
|
-
json->max_nesting = FIX2INT(max_nesting);
|
1835
|
-
} else {
|
1836
|
-
json->max_nesting = 0;
|
1837
|
-
}
|
1838
|
-
} else {
|
1839
|
-
json->max_nesting = 100;
|
1840
|
-
}
|
1841
|
-
tmp = ID2SYM(i_allow_nan);
|
1842
|
-
if (option_given_p(opts, tmp)) {
|
1843
|
-
json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
|
1844
|
-
} else {
|
1845
|
-
json->allow_nan = 0;
|
1846
|
-
}
|
1847
|
-
tmp = ID2SYM(i_symbolize_names);
|
1848
|
-
if (option_given_p(opts, tmp)) {
|
1849
|
-
json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
|
1850
|
-
} else {
|
1851
|
-
json->symbolize_names = 0;
|
1852
|
-
}
|
1853
|
-
tmp = ID2SYM(i_freeze);
|
1854
|
-
if (option_given_p(opts, tmp)) {
|
1855
|
-
json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
|
1856
|
-
} else {
|
1857
|
-
json->freeze = 0;
|
1858
|
-
}
|
1859
|
-
tmp = ID2SYM(i_create_additions);
|
1860
|
-
if (option_given_p(opts, tmp)) {
|
1861
|
-
json->create_additions = RTEST(rb_hash_aref(opts, tmp));
|
1862
|
-
} else {
|
1863
|
-
json->create_additions = 0;
|
1864
|
-
}
|
1865
|
-
if (json->symbolize_names && json->create_additions) {
|
1866
|
-
rb_raise(rb_eArgError,
|
1867
|
-
"options :symbolize_names and :create_additions cannot be "
|
1868
|
-
" used in conjunction");
|
1869
|
-
}
|
1870
|
-
tmp = ID2SYM(i_create_id);
|
1871
|
-
if (option_given_p(opts, tmp)) {
|
1872
|
-
json->create_id = rb_hash_aref(opts, tmp);
|
1873
|
-
} else {
|
1874
|
-
json->create_id = rb_funcall(mJSON, i_create_id, 0);
|
1875
|
-
}
|
1876
|
-
tmp = ID2SYM(i_object_class);
|
1877
|
-
if (option_given_p(opts, tmp)) {
|
1878
|
-
json->object_class = rb_hash_aref(opts, tmp);
|
1879
|
-
} else {
|
1880
|
-
json->object_class = Qnil;
|
1881
|
-
}
|
1882
|
-
tmp = ID2SYM(i_array_class);
|
1883
|
-
if (option_given_p(opts, tmp)) {
|
1884
|
-
json->array_class = rb_hash_aref(opts, tmp);
|
1885
|
-
} else {
|
1886
|
-
json->array_class = Qnil;
|
1887
|
-
}
|
1888
|
-
tmp = ID2SYM(i_decimal_class);
|
1889
|
-
if (option_given_p(opts, tmp)) {
|
1890
|
-
json->decimal_class = rb_hash_aref(opts, tmp);
|
1891
|
-
} else {
|
1892
|
-
json->decimal_class = Qnil;
|
1893
|
-
}
|
1894
|
-
tmp = ID2SYM(i_match_string);
|
1895
|
-
if (option_given_p(opts, tmp)) {
|
1896
|
-
VALUE match_string = rb_hash_aref(opts, tmp);
|
1897
|
-
json->match_string = RTEST(match_string) ? match_string : Qnil;
|
1898
|
-
} else {
|
1899
|
-
json->match_string = Qnil;
|
1900
|
-
}
|
1901
|
-
} else {
|
1902
|
-
json->max_nesting = 100;
|
1903
|
-
json->allow_nan = 0;
|
1904
|
-
json->create_additions = 0;
|
1905
|
-
json->create_id = Qnil;
|
1906
|
-
json->object_class = Qnil;
|
1907
|
-
json->array_class = Qnil;
|
1908
|
-
json->decimal_class = Qnil;
|
1909
|
-
}
|
1910
|
-
source = convert_encoding(StringValue(source));
|
1911
|
-
StringValue(source);
|
1912
|
-
json->len = RSTRING_LEN(source);
|
1913
|
-
json->source = RSTRING_PTR(source);;
|
1914
|
-
json->Vsource = source;
|
2736
|
+
rb_check_arity(argc, 1, 2);
|
2737
|
+
|
2738
|
+
parser_init(json, argv[0], argc == 2 ? argv[1] : Qnil);
|
1915
2739
|
return self;
|
1916
2740
|
}
|
1917
2741
|
|
1918
2742
|
|
1919
|
-
#line
|
2743
|
+
#line 2744 "parser.c"
|
1920
2744
|
enum {JSON_start = 1};
|
1921
2745
|
enum {JSON_first_final = 10};
|
1922
2746
|
enum {JSON_error = 0};
|
@@ -1924,7 +2748,7 @@ enum {JSON_error = 0};
|
|
1924
2748
|
enum {JSON_en_main = 1};
|
1925
2749
|
|
1926
2750
|
|
1927
|
-
#line
|
2751
|
+
#line 1259 "parser.rl"
|
1928
2752
|
|
1929
2753
|
|
1930
2754
|
/*
|
@@ -1936,22 +2760,33 @@ enum {JSON_en_main = 1};
|
|
1936
2760
|
*/
|
1937
2761
|
static VALUE cParser_parse(VALUE self)
|
1938
2762
|
{
|
1939
|
-
|
1940
|
-
|
1941
|
-
|
1942
|
-
|
2763
|
+
char *p, *pe;
|
2764
|
+
int cs = EVIL;
|
2765
|
+
VALUE result = Qnil;
|
2766
|
+
GET_PARSER;
|
2767
|
+
|
2768
|
+
char stack_buffer[FBUFFER_STACK_SIZE];
|
2769
|
+
fbuffer_stack_init(&json->fbuffer, FBUFFER_INITIAL_LENGTH_DEFAULT, stack_buffer, FBUFFER_STACK_SIZE);
|
2770
|
+
|
2771
|
+
VALUE rvalue_stack_buffer[RVALUE_STACK_INITIAL_CAPA];
|
2772
|
+
rvalue_stack stack = {
|
2773
|
+
.type = RVALUE_STACK_STACK_ALLOCATED,
|
2774
|
+
.ptr = rvalue_stack_buffer,
|
2775
|
+
.capa = RVALUE_STACK_INITIAL_CAPA,
|
2776
|
+
};
|
2777
|
+
json->stack = &stack;
|
1943
2778
|
|
1944
2779
|
|
1945
|
-
#line
|
2780
|
+
#line 2781 "parser.c"
|
1946
2781
|
{
|
1947
2782
|
cs = JSON_start;
|
1948
2783
|
}
|
1949
2784
|
|
1950
|
-
#line
|
1951
|
-
|
1952
|
-
|
2785
|
+
#line 1287 "parser.rl"
|
2786
|
+
p = json->source;
|
2787
|
+
pe = p + json->len;
|
1953
2788
|
|
1954
|
-
#line
|
2789
|
+
#line 2790 "parser.c"
|
1955
2790
|
{
|
1956
2791
|
if ( p == pe )
|
1957
2792
|
goto _test_eof;
|
@@ -1985,7 +2820,7 @@ st0:
|
|
1985
2820
|
cs = 0;
|
1986
2821
|
goto _out;
|
1987
2822
|
tr2:
|
1988
|
-
#line
|
2823
|
+
#line 1251 "parser.rl"
|
1989
2824
|
{
|
1990
2825
|
char *np = JSON_parse_value(json, p, pe, &result, 0);
|
1991
2826
|
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
|
@@ -1995,7 +2830,7 @@ st10:
|
|
1995
2830
|
if ( ++p == pe )
|
1996
2831
|
goto _test_eof10;
|
1997
2832
|
case 10:
|
1998
|
-
#line
|
2833
|
+
#line 2834 "parser.c"
|
1999
2834
|
switch( (*p) ) {
|
2000
2835
|
case 13: goto st10;
|
2001
2836
|
case 32: goto st10;
|
@@ -2084,56 +2919,238 @@ case 9:
|
|
2084
2919
|
_out: {}
|
2085
2920
|
}
|
2086
2921
|
|
2087
|
-
#line
|
2922
|
+
#line 1290 "parser.rl"
|
2088
2923
|
|
2089
|
-
|
2090
|
-
|
2091
|
-
|
2092
|
-
|
2093
|
-
|
2094
|
-
|
2924
|
+
if (json->stack_handle) {
|
2925
|
+
rvalue_stack_eagerly_release(json->stack_handle);
|
2926
|
+
}
|
2927
|
+
|
2928
|
+
if (cs >= JSON_first_final && p == pe) {
|
2929
|
+
return result;
|
2930
|
+
} else {
|
2931
|
+
raise_parse_error("unexpected token at '%s'", p);
|
2932
|
+
return Qnil;
|
2933
|
+
}
|
2934
|
+
}
|
2935
|
+
|
2936
|
+
static VALUE cParser_m_parse(VALUE klass, VALUE source, VALUE opts)
|
2937
|
+
{
|
2938
|
+
char *p, *pe;
|
2939
|
+
int cs = EVIL;
|
2940
|
+
VALUE result = Qnil;
|
2941
|
+
|
2942
|
+
JSON_Parser _parser = {0};
|
2943
|
+
JSON_Parser *json = &_parser;
|
2944
|
+
parser_init(json, source, opts);
|
2945
|
+
|
2946
|
+
char stack_buffer[FBUFFER_STACK_SIZE];
|
2947
|
+
fbuffer_stack_init(&json->fbuffer, FBUFFER_INITIAL_LENGTH_DEFAULT, stack_buffer, FBUFFER_STACK_SIZE);
|
2948
|
+
|
2949
|
+
VALUE rvalue_stack_buffer[RVALUE_STACK_INITIAL_CAPA];
|
2950
|
+
rvalue_stack stack = {
|
2951
|
+
.type = RVALUE_STACK_STACK_ALLOCATED,
|
2952
|
+
.ptr = rvalue_stack_buffer,
|
2953
|
+
.capa = RVALUE_STACK_INITIAL_CAPA,
|
2954
|
+
};
|
2955
|
+
json->stack = &stack;
|
2956
|
+
|
2957
|
+
|
2958
|
+
#line 2959 "parser.c"
|
2959
|
+
{
|
2960
|
+
cs = JSON_start;
|
2961
|
+
}
|
2962
|
+
|
2963
|
+
#line 1325 "parser.rl"
|
2964
|
+
p = json->source;
|
2965
|
+
pe = p + json->len;
|
2966
|
+
|
2967
|
+
#line 2968 "parser.c"
|
2968
|
+
{
|
2969
|
+
if ( p == pe )
|
2970
|
+
goto _test_eof;
|
2971
|
+
switch ( cs )
|
2972
|
+
{
|
2973
|
+
st1:
|
2974
|
+
if ( ++p == pe )
|
2975
|
+
goto _test_eof1;
|
2976
|
+
case 1:
|
2977
|
+
switch( (*p) ) {
|
2978
|
+
case 13: goto st1;
|
2979
|
+
case 32: goto st1;
|
2980
|
+
case 34: goto tr2;
|
2981
|
+
case 45: goto tr2;
|
2982
|
+
case 47: goto st6;
|
2983
|
+
case 73: goto tr2;
|
2984
|
+
case 78: goto tr2;
|
2985
|
+
case 91: goto tr2;
|
2986
|
+
case 102: goto tr2;
|
2987
|
+
case 110: goto tr2;
|
2988
|
+
case 116: goto tr2;
|
2989
|
+
case 123: goto tr2;
|
2990
|
+
}
|
2991
|
+
if ( (*p) > 10 ) {
|
2992
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
2993
|
+
goto tr2;
|
2994
|
+
} else if ( (*p) >= 9 )
|
2995
|
+
goto st1;
|
2996
|
+
goto st0;
|
2997
|
+
st0:
|
2998
|
+
cs = 0;
|
2999
|
+
goto _out;
|
3000
|
+
tr2:
|
3001
|
+
#line 1251 "parser.rl"
|
3002
|
+
{
|
3003
|
+
char *np = JSON_parse_value(json, p, pe, &result, 0);
|
3004
|
+
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
|
3005
|
+
}
|
3006
|
+
goto st10;
|
3007
|
+
st10:
|
3008
|
+
if ( ++p == pe )
|
3009
|
+
goto _test_eof10;
|
3010
|
+
case 10:
|
3011
|
+
#line 3012 "parser.c"
|
3012
|
+
switch( (*p) ) {
|
3013
|
+
case 13: goto st10;
|
3014
|
+
case 32: goto st10;
|
3015
|
+
case 47: goto st2;
|
3016
|
+
}
|
3017
|
+
if ( 9 <= (*p) && (*p) <= 10 )
|
3018
|
+
goto st10;
|
3019
|
+
goto st0;
|
3020
|
+
st2:
|
3021
|
+
if ( ++p == pe )
|
3022
|
+
goto _test_eof2;
|
3023
|
+
case 2:
|
3024
|
+
switch( (*p) ) {
|
3025
|
+
case 42: goto st3;
|
3026
|
+
case 47: goto st5;
|
3027
|
+
}
|
3028
|
+
goto st0;
|
3029
|
+
st3:
|
3030
|
+
if ( ++p == pe )
|
3031
|
+
goto _test_eof3;
|
3032
|
+
case 3:
|
3033
|
+
if ( (*p) == 42 )
|
3034
|
+
goto st4;
|
3035
|
+
goto st3;
|
3036
|
+
st4:
|
3037
|
+
if ( ++p == pe )
|
3038
|
+
goto _test_eof4;
|
3039
|
+
case 4:
|
3040
|
+
switch( (*p) ) {
|
3041
|
+
case 42: goto st4;
|
3042
|
+
case 47: goto st10;
|
3043
|
+
}
|
3044
|
+
goto st3;
|
3045
|
+
st5:
|
3046
|
+
if ( ++p == pe )
|
3047
|
+
goto _test_eof5;
|
3048
|
+
case 5:
|
3049
|
+
if ( (*p) == 10 )
|
3050
|
+
goto st10;
|
3051
|
+
goto st5;
|
3052
|
+
st6:
|
3053
|
+
if ( ++p == pe )
|
3054
|
+
goto _test_eof6;
|
3055
|
+
case 6:
|
3056
|
+
switch( (*p) ) {
|
3057
|
+
case 42: goto st7;
|
3058
|
+
case 47: goto st9;
|
3059
|
+
}
|
3060
|
+
goto st0;
|
3061
|
+
st7:
|
3062
|
+
if ( ++p == pe )
|
3063
|
+
goto _test_eof7;
|
3064
|
+
case 7:
|
3065
|
+
if ( (*p) == 42 )
|
3066
|
+
goto st8;
|
3067
|
+
goto st7;
|
3068
|
+
st8:
|
3069
|
+
if ( ++p == pe )
|
3070
|
+
goto _test_eof8;
|
3071
|
+
case 8:
|
3072
|
+
switch( (*p) ) {
|
3073
|
+
case 42: goto st8;
|
3074
|
+
case 47: goto st1;
|
3075
|
+
}
|
3076
|
+
goto st7;
|
3077
|
+
st9:
|
3078
|
+
if ( ++p == pe )
|
3079
|
+
goto _test_eof9;
|
3080
|
+
case 9:
|
3081
|
+
if ( (*p) == 10 )
|
3082
|
+
goto st1;
|
3083
|
+
goto st9;
|
3084
|
+
}
|
3085
|
+
_test_eof1: cs = 1; goto _test_eof;
|
3086
|
+
_test_eof10: cs = 10; goto _test_eof;
|
3087
|
+
_test_eof2: cs = 2; goto _test_eof;
|
3088
|
+
_test_eof3: cs = 3; goto _test_eof;
|
3089
|
+
_test_eof4: cs = 4; goto _test_eof;
|
3090
|
+
_test_eof5: cs = 5; goto _test_eof;
|
3091
|
+
_test_eof6: cs = 6; goto _test_eof;
|
3092
|
+
_test_eof7: cs = 7; goto _test_eof;
|
3093
|
+
_test_eof8: cs = 8; goto _test_eof;
|
3094
|
+
_test_eof9: cs = 9; goto _test_eof;
|
3095
|
+
|
3096
|
+
_test_eof: {}
|
3097
|
+
_out: {}
|
3098
|
+
}
|
3099
|
+
|
3100
|
+
#line 1328 "parser.rl"
|
3101
|
+
|
3102
|
+
if (json->stack_handle) {
|
3103
|
+
rvalue_stack_eagerly_release(json->stack_handle);
|
3104
|
+
}
|
3105
|
+
|
3106
|
+
if (cs >= JSON_first_final && p == pe) {
|
3107
|
+
return result;
|
3108
|
+
} else {
|
3109
|
+
raise_parse_error("unexpected token at '%s'", p);
|
3110
|
+
return Qnil;
|
3111
|
+
}
|
2095
3112
|
}
|
2096
3113
|
|
2097
3114
|
static void JSON_mark(void *ptr)
|
2098
3115
|
{
|
2099
3116
|
JSON_Parser *json = ptr;
|
2100
|
-
|
2101
|
-
|
2102
|
-
|
2103
|
-
|
2104
|
-
|
2105
|
-
|
3117
|
+
rb_gc_mark(json->Vsource);
|
3118
|
+
rb_gc_mark(json->create_id);
|
3119
|
+
rb_gc_mark(json->object_class);
|
3120
|
+
rb_gc_mark(json->array_class);
|
3121
|
+
rb_gc_mark(json->decimal_class);
|
3122
|
+
rb_gc_mark(json->match_string);
|
3123
|
+
rb_gc_mark(json->stack_handle);
|
3124
|
+
|
3125
|
+
const VALUE *name_cache_entries = &json->name_cache.entries[0];
|
3126
|
+
rb_gc_mark_locations(name_cache_entries, name_cache_entries + json->name_cache.length);
|
2106
3127
|
}
|
2107
3128
|
|
2108
3129
|
static void JSON_free(void *ptr)
|
2109
3130
|
{
|
2110
3131
|
JSON_Parser *json = ptr;
|
2111
|
-
fbuffer_free(json->fbuffer);
|
3132
|
+
fbuffer_free(&json->fbuffer);
|
2112
3133
|
ruby_xfree(json);
|
2113
3134
|
}
|
2114
3135
|
|
2115
3136
|
static size_t JSON_memsize(const void *ptr)
|
2116
3137
|
{
|
2117
3138
|
const JSON_Parser *json = ptr;
|
2118
|
-
return sizeof(*json) + FBUFFER_CAPA(json->fbuffer);
|
3139
|
+
return sizeof(*json) + FBUFFER_CAPA(&json->fbuffer);
|
2119
3140
|
}
|
2120
3141
|
|
2121
|
-
#ifdef NEW_TYPEDDATA_WRAPPER
|
2122
3142
|
static const rb_data_type_t JSON_Parser_type = {
|
2123
3143
|
"JSON/Parser",
|
2124
3144
|
{JSON_mark, JSON_free, JSON_memsize,},
|
2125
|
-
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
|
2126
3145
|
0, 0,
|
2127
3146
|
RUBY_TYPED_FREE_IMMEDIATELY,
|
2128
|
-
#endif
|
2129
3147
|
};
|
2130
|
-
#endif
|
2131
3148
|
|
2132
3149
|
static VALUE cJSON_parser_s_allocate(VALUE klass)
|
2133
3150
|
{
|
2134
3151
|
JSON_Parser *json;
|
2135
3152
|
VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json);
|
2136
|
-
json->fbuffer
|
3153
|
+
fbuffer_stack_init(&json->fbuffer, 0, NULL, 0);
|
2137
3154
|
return obj;
|
2138
3155
|
}
|
2139
3156
|
|
@@ -2160,15 +3177,15 @@ void Init_parser(void)
|
|
2160
3177
|
mJSON = rb_define_module("JSON");
|
2161
3178
|
mExt = rb_define_module_under(mJSON, "Ext");
|
2162
3179
|
cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
|
2163
|
-
eParserError = rb_path2class("JSON::ParserError");
|
2164
3180
|
eNestingError = rb_path2class("JSON::NestingError");
|
2165
|
-
rb_gc_register_mark_object(eParserError);
|
2166
3181
|
rb_gc_register_mark_object(eNestingError);
|
2167
3182
|
rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
|
2168
3183
|
rb_define_method(cParser, "initialize", cParser_initialize, -1);
|
2169
3184
|
rb_define_method(cParser, "parse", cParser_parse, 0);
|
2170
3185
|
rb_define_method(cParser, "source", cParser_source, 0);
|
2171
3186
|
|
3187
|
+
rb_define_singleton_method(cParser, "parse", cParser_m_parse, 2);
|
3188
|
+
|
2172
3189
|
CNaN = rb_const_get(mJSON, rb_intern("NaN"));
|
2173
3190
|
rb_gc_register_mark_object(CNaN);
|
2174
3191
|
|
@@ -2178,28 +3195,38 @@ void Init_parser(void)
|
|
2178
3195
|
CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
|
2179
3196
|
rb_gc_register_mark_object(CMinusInfinity);
|
2180
3197
|
|
3198
|
+
rb_global_variable(&Encoding_UTF_8);
|
3199
|
+
Encoding_UTF_8 = rb_const_get(rb_path2class("Encoding"), rb_intern("UTF_8"));
|
3200
|
+
|
3201
|
+
sym_max_nesting = ID2SYM(rb_intern("max_nesting"));
|
3202
|
+
sym_allow_nan = ID2SYM(rb_intern("allow_nan"));
|
3203
|
+
sym_allow_trailing_comma = ID2SYM(rb_intern("allow_trailing_comma"));
|
3204
|
+
sym_symbolize_names = ID2SYM(rb_intern("symbolize_names"));
|
3205
|
+
sym_freeze = ID2SYM(rb_intern("freeze"));
|
3206
|
+
sym_create_additions = ID2SYM(rb_intern("create_additions"));
|
3207
|
+
sym_create_id = ID2SYM(rb_intern("create_id"));
|
3208
|
+
sym_object_class = ID2SYM(rb_intern("object_class"));
|
3209
|
+
sym_array_class = ID2SYM(rb_intern("array_class"));
|
3210
|
+
sym_decimal_class = ID2SYM(rb_intern("decimal_class"));
|
3211
|
+
sym_match_string = ID2SYM(rb_intern("match_string"));
|
3212
|
+
|
3213
|
+
i_create_id = rb_intern("create_id");
|
2181
3214
|
i_json_creatable_p = rb_intern("json_creatable?");
|
2182
3215
|
i_json_create = rb_intern("json_create");
|
2183
|
-
i_create_id = rb_intern("create_id");
|
2184
|
-
i_create_additions = rb_intern("create_additions");
|
2185
3216
|
i_chr = rb_intern("chr");
|
2186
|
-
i_max_nesting = rb_intern("max_nesting");
|
2187
|
-
i_allow_nan = rb_intern("allow_nan");
|
2188
|
-
i_symbolize_names = rb_intern("symbolize_names");
|
2189
|
-
i_object_class = rb_intern("object_class");
|
2190
|
-
i_array_class = rb_intern("array_class");
|
2191
|
-
i_decimal_class = rb_intern("decimal_class");
|
2192
3217
|
i_match = rb_intern("match");
|
2193
|
-
i_match_string = rb_intern("match_string");
|
2194
|
-
i_key_p = rb_intern("key?");
|
2195
3218
|
i_deep_const_get = rb_intern("deep_const_get");
|
2196
3219
|
i_aset = rb_intern("[]=");
|
2197
3220
|
i_aref = rb_intern("[]");
|
2198
3221
|
i_leftshift = rb_intern("<<");
|
2199
3222
|
i_new = rb_intern("new");
|
2200
3223
|
i_try_convert = rb_intern("try_convert");
|
2201
|
-
i_freeze = rb_intern("freeze");
|
2202
3224
|
i_uminus = rb_intern("-@");
|
3225
|
+
i_encode = rb_intern("encode");
|
3226
|
+
|
3227
|
+
binary_encindex = rb_ascii8bit_encindex();
|
3228
|
+
utf8_encindex = rb_utf8_encindex();
|
3229
|
+
enc_utf8 = rb_utf8_encoding();
|
2203
3230
|
}
|
2204
3231
|
|
2205
3232
|
/*
|