oj 3.13.14 → 3.13.22
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +32 -0
- data/README.md +2 -0
- data/ext/oj/buf.h +4 -0
- data/ext/oj/compat.c +10 -10
- data/ext/oj/custom.c +34 -53
- data/ext/oj/dump.c +24 -13
- data/ext/oj/dump_compat.c +5 -10
- data/ext/oj/dump_object.c +5 -60
- data/ext/oj/dump_strict.c +5 -5
- data/ext/oj/extconf.rb +5 -4
- data/ext/oj/fast.c +15 -13
- data/ext/oj/intern.c +6 -9
- data/ext/oj/introspect.c +96 -0
- data/ext/oj/mimic_json.c +18 -8
- data/ext/oj/object.c +42 -41
- data/ext/oj/oj.c +27 -4
- data/ext/oj/oj.h +4 -1
- data/ext/oj/parse.c +111 -76
- data/ext/oj/parse.h +2 -0
- data/ext/oj/parser.c +61 -4
- data/ext/oj/parser.h +12 -0
- data/ext/oj/rails.c +5 -10
- data/ext/oj/saj2.c +333 -85
- data/ext/oj/saj2.h +23 -0
- data/ext/oj/sparse.c +4 -0
- data/ext/oj/strict.c +13 -13
- data/ext/oj/usual.c +82 -129
- data/ext/oj/usual.h +68 -0
- data/ext/oj/val_stack.c +1 -1
- data/ext/oj/validate.c +21 -26
- data/ext/oj/wab.c +15 -20
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/state.rb +1 -1
- data/lib/oj/version.rb +1 -1
- data/pages/Compatibility.md +1 -1
- data/test/bar.rb +3 -1
- data/test/helper.rb +8 -2
- data/test/json_gem/json_generator_test.rb +3 -4
- data/test/json_gem/json_parser_test.rb +8 -1
- data/test/json_gem/test_helper.rb +7 -3
- data/test/test_compat.rb +25 -0
- data/test/test_custom.rb +13 -2
- data/test/test_file.rb +23 -7
- data/test/test_gc.rb +11 -0
- data/test/test_object.rb +3 -10
- data/test/test_parser.rb +3 -19
- data/test/test_parser_debug.rb +27 -0
- data/test/test_parser_saj.rb +92 -2
- data/test/test_scp.rb +2 -4
- data/test/test_strict.rb +2 -0
- data/test/test_various.rb +8 -3
- data/test/test_wab.rb +2 -0
- data/test/tests.rb +9 -0
- data/test/tests_mimic.rb +9 -0
- data/test/tests_mimic_addition.rb +9 -0
- metadata +7 -107
data/ext/oj/parser.h
CHANGED
@@ -80,6 +80,7 @@ typedef struct _ojParser {
|
|
80
80
|
|
81
81
|
char token[8];
|
82
82
|
long line;
|
83
|
+
long cur; // only set before call to a function
|
83
84
|
long col;
|
84
85
|
int ri;
|
85
86
|
uint32_t ucode;
|
@@ -87,4 +88,15 @@ typedef struct _ojParser {
|
|
87
88
|
bool just_one;
|
88
89
|
} * ojParser;
|
89
90
|
|
91
|
+
// Create a new parser without setting the delegate. The parser is
|
92
|
+
// wrapped. The parser is (ojParser)DATA_PTR(value) where value is the return
|
93
|
+
// from this function. A delegate must be added before the parser can be
|
94
|
+
// used. Optionally oj_parser_set_options can be called if the options are not
|
95
|
+
// set directly.
|
96
|
+
extern VALUE oj_parser_new();
|
97
|
+
|
98
|
+
// Set set the options from a hash (ropts).
|
99
|
+
extern void oj_parser_set_option(ojParser p, VALUE ropts);
|
100
|
+
|
101
|
+
|
90
102
|
#endif /* OJ_PARSER_H */
|
data/ext/oj/rails.c
CHANGED
@@ -320,7 +320,6 @@ static void dump_time(VALUE obj, int depth, Out out, bool as_ok) {
|
|
320
320
|
long long sec;
|
321
321
|
long long nsec;
|
322
322
|
|
323
|
-
#ifdef HAVE_RB_TIME_TIMESPEC
|
324
323
|
if (16 <= sizeof(struct timespec)) {
|
325
324
|
struct timespec ts = rb_time_timespec(obj);
|
326
325
|
|
@@ -330,10 +329,6 @@ static void dump_time(VALUE obj, int depth, Out out, bool as_ok) {
|
|
330
329
|
sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
331
330
|
nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
332
331
|
}
|
333
|
-
#else
|
334
|
-
sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
335
|
-
nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
336
|
-
#endif
|
337
332
|
dump_sec_nano(obj, sec, nsec, out);
|
338
333
|
}
|
339
334
|
|
@@ -522,7 +517,7 @@ static void dump_as_string(VALUE obj, int depth, Out out, bool as_ok) {
|
|
522
517
|
static void dump_as_json(VALUE obj, int depth, Out out, bool as_ok) {
|
523
518
|
volatile VALUE ja;
|
524
519
|
|
525
|
-
if (Yes == out->opts->trace) {
|
520
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
526
521
|
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
|
527
522
|
}
|
528
523
|
// Some classes elect to not take an options argument so check the arity
|
@@ -532,7 +527,7 @@ static void dump_as_json(VALUE obj, int depth, Out out, bool as_ok) {
|
|
532
527
|
} else {
|
533
528
|
ja = rb_funcall2(obj, oj_as_json_id, out->argc, out->argv);
|
534
529
|
}
|
535
|
-
if (Yes == out->opts->trace) {
|
530
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
536
531
|
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
|
537
532
|
}
|
538
533
|
|
@@ -1469,7 +1464,7 @@ static DumpFunc rails_funcs[] = {
|
|
1469
1464
|
static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok) {
|
1470
1465
|
int type = rb_type(obj);
|
1471
1466
|
|
1472
|
-
if (Yes == out->opts->trace) {
|
1467
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
1473
1468
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
1474
1469
|
}
|
1475
1470
|
if (MAX_DEPTH < depth) {
|
@@ -1480,14 +1475,14 @@ static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1480
1475
|
|
1481
1476
|
if (NULL != f) {
|
1482
1477
|
f(obj, depth, out, as_ok);
|
1483
|
-
if (Yes == out->opts->trace) {
|
1478
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
1484
1479
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
1485
1480
|
}
|
1486
1481
|
return;
|
1487
1482
|
}
|
1488
1483
|
}
|
1489
1484
|
oj_dump_nil(Qnil, depth, out, false);
|
1490
|
-
if (Yes == out->opts->trace) {
|
1485
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
1491
1486
|
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
1492
1487
|
}
|
1493
1488
|
}
|
data/ext/oj/saj2.c
CHANGED
@@ -3,21 +3,11 @@
|
|
3
3
|
#include "cache.h"
|
4
4
|
#include "oj.h"
|
5
5
|
#include "parser.h"
|
6
|
-
|
7
|
-
typedef struct _delegate {
|
8
|
-
VALUE handler;
|
9
|
-
VALUE * keys;
|
10
|
-
VALUE * tail;
|
11
|
-
size_t klen;
|
12
|
-
struct _cache *str_cache;
|
13
|
-
uint8_t cache_str;
|
14
|
-
bool cache_keys;
|
15
|
-
bool thread_safe;
|
16
|
-
} * Delegate;
|
6
|
+
#include "saj2.h"
|
17
7
|
|
18
8
|
static VALUE get_key(ojParser p) {
|
19
|
-
|
20
|
-
const char
|
9
|
+
Saj d = (Saj)p->ctx;
|
10
|
+
const char *key = buf_str(&p->key);
|
21
11
|
size_t len = buf_len(&p->key);
|
22
12
|
volatile VALUE rkey;
|
23
13
|
|
@@ -29,7 +19,7 @@ static VALUE get_key(ojParser p) {
|
|
29
19
|
return rkey;
|
30
20
|
}
|
31
21
|
|
32
|
-
static void push_key(
|
22
|
+
static void push_key(Saj d, VALUE key) {
|
33
23
|
if (d->klen <= (size_t)(d->tail - d->keys)) {
|
34
24
|
size_t off = d->tail - d->keys;
|
35
25
|
|
@@ -45,31 +35,55 @@ static void noop(ojParser p) {
|
|
45
35
|
}
|
46
36
|
|
47
37
|
static void open_object(ojParser p) {
|
48
|
-
rb_funcall(((
|
38
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_hash_start_id, 1, Qnil);
|
39
|
+
}
|
40
|
+
|
41
|
+
static void open_object_loc(ojParser p) {
|
42
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_hash_start_id, 3, Qnil, LONG2FIX(p->line), LONG2FIX(p->cur - p->col));
|
49
43
|
}
|
50
44
|
|
51
45
|
static void open_object_key(ojParser p) {
|
52
|
-
|
46
|
+
Saj d = (Saj)p->ctx;
|
53
47
|
volatile VALUE key = get_key(p);
|
54
48
|
|
55
49
|
push_key(d, key);
|
56
50
|
rb_funcall(d->handler, oj_hash_start_id, 1, key);
|
57
51
|
}
|
58
52
|
|
53
|
+
static void open_object_loc_key(ojParser p) {
|
54
|
+
Saj d = (Saj)p->ctx;
|
55
|
+
volatile VALUE key = get_key(p);
|
56
|
+
|
57
|
+
push_key(d, key);
|
58
|
+
rb_funcall(d->handler, oj_hash_start_id, 3, key, LONG2FIX(p->line), LONG2FIX(p->cur - p->col));
|
59
|
+
}
|
60
|
+
|
59
61
|
static void open_array(ojParser p) {
|
60
|
-
rb_funcall(((
|
62
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_array_start_id, 1, Qnil);
|
63
|
+
}
|
64
|
+
|
65
|
+
static void open_array_loc(ojParser p) {
|
66
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_array_start_id, 3, Qnil, LONG2FIX(p->line), LONG2FIX(p->cur - p->col));
|
61
67
|
}
|
62
68
|
|
63
69
|
static void open_array_key(ojParser p) {
|
64
|
-
|
70
|
+
Saj d = (Saj)p->ctx;
|
65
71
|
volatile VALUE key = get_key(p);
|
66
72
|
|
67
73
|
push_key(d, key);
|
68
74
|
rb_funcall(d->handler, oj_array_start_id, 1, key);
|
69
75
|
}
|
70
76
|
|
77
|
+
static void open_array_loc_key(ojParser p) {
|
78
|
+
Saj d = (Saj)p->ctx;
|
79
|
+
volatile VALUE key = get_key(p);
|
80
|
+
|
81
|
+
push_key(d, key);
|
82
|
+
rb_funcall(d->handler, oj_array_start_id, 3, key, LONG2FIX(p->line), LONG2FIX(p->cur - p->col));
|
83
|
+
}
|
84
|
+
|
71
85
|
static void close_object(ojParser p) {
|
72
|
-
|
86
|
+
Saj d = (Saj)p->ctx;
|
73
87
|
VALUE key = Qnil;
|
74
88
|
|
75
89
|
if (OBJECT_FUN == p->stack[p->depth]) {
|
@@ -82,8 +96,22 @@ static void close_object(ojParser p) {
|
|
82
96
|
rb_funcall(d->handler, oj_hash_end_id, 1, key);
|
83
97
|
}
|
84
98
|
|
99
|
+
static void close_object_loc(ojParser p) {
|
100
|
+
Saj d = (Saj)p->ctx;
|
101
|
+
VALUE key = Qnil;
|
102
|
+
|
103
|
+
if (OBJECT_FUN == p->stack[p->depth]) {
|
104
|
+
d->tail--;
|
105
|
+
if (d->tail < d->keys) {
|
106
|
+
rb_raise(rb_eIndexError, "accessing key stack");
|
107
|
+
}
|
108
|
+
key = *d->tail;
|
109
|
+
}
|
110
|
+
rb_funcall(d->handler, oj_hash_end_id, 3, key, LONG2FIX(p->line), LONG2FIX(p->cur - p->col));
|
111
|
+
}
|
112
|
+
|
85
113
|
static void close_array(ojParser p) {
|
86
|
-
|
114
|
+
Saj d = (Saj)p->ctx;
|
87
115
|
VALUE key = Qnil;
|
88
116
|
|
89
117
|
if (OBJECT_FUN == p->stack[p->depth]) {
|
@@ -96,66 +124,200 @@ static void close_array(ojParser p) {
|
|
96
124
|
rb_funcall(d->handler, oj_array_end_id, 1, key);
|
97
125
|
}
|
98
126
|
|
127
|
+
static void close_array_loc(ojParser p) {
|
128
|
+
Saj d = (Saj)p->ctx;
|
129
|
+
VALUE key = Qnil;
|
130
|
+
|
131
|
+
if (OBJECT_FUN == p->stack[p->depth]) {
|
132
|
+
d->tail--;
|
133
|
+
if (d->tail < d->keys) {
|
134
|
+
rb_raise(rb_eIndexError, "accessing key stack");
|
135
|
+
}
|
136
|
+
key = *d->tail;
|
137
|
+
}
|
138
|
+
rb_funcall(d->handler, oj_array_end_id, 3, key, LONG2FIX(p->line), LONG2FIX(p->cur - p->col));
|
139
|
+
}
|
140
|
+
|
99
141
|
static void add_null(ojParser p) {
|
100
|
-
rb_funcall(((
|
142
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 2, Qnil, Qnil);
|
143
|
+
}
|
144
|
+
|
145
|
+
static void add_null_loc(ojParser p) {
|
146
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
147
|
+
oj_add_value_id,
|
148
|
+
4,
|
149
|
+
Qnil,
|
150
|
+
Qnil,
|
151
|
+
LONG2FIX(p->line),
|
152
|
+
LONG2FIX(p->cur - p->col));
|
101
153
|
}
|
102
154
|
|
103
155
|
static void add_null_key(ojParser p) {
|
104
|
-
rb_funcall(((
|
156
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 2, Qnil, get_key(p));
|
157
|
+
}
|
158
|
+
|
159
|
+
static void add_null_key_loc(ojParser p) {
|
160
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
161
|
+
oj_add_value_id,
|
162
|
+
4,
|
163
|
+
Qnil,
|
164
|
+
get_key(p),
|
165
|
+
LONG2FIX(p->line),
|
166
|
+
LONG2FIX(p->cur - p->col));
|
105
167
|
}
|
106
168
|
|
107
169
|
static void add_true(ojParser p) {
|
108
|
-
rb_funcall(((
|
170
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 2, Qtrue, Qnil);
|
171
|
+
}
|
172
|
+
|
173
|
+
static void add_true_loc(ojParser p) {
|
174
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
175
|
+
oj_add_value_id,
|
176
|
+
4,
|
177
|
+
Qtrue,
|
178
|
+
Qnil,
|
179
|
+
LONG2FIX(p->line),
|
180
|
+
LONG2FIX(p->cur - p->col));
|
109
181
|
}
|
110
182
|
|
111
183
|
static void add_true_key(ojParser p) {
|
112
|
-
rb_funcall(((
|
184
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 2, Qtrue, get_key(p));
|
185
|
+
}
|
186
|
+
|
187
|
+
static void add_true_key_loc(ojParser p) {
|
188
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
189
|
+
oj_add_value_id,
|
190
|
+
4,
|
191
|
+
Qtrue,
|
192
|
+
get_key(p),
|
193
|
+
LONG2FIX(p->line),
|
194
|
+
LONG2FIX(p->cur - p->col));
|
113
195
|
}
|
114
196
|
|
115
197
|
static void add_false(ojParser p) {
|
116
|
-
rb_funcall(((
|
198
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 2, Qfalse, Qnil);
|
199
|
+
}
|
200
|
+
|
201
|
+
static void add_false_loc(ojParser p) {
|
202
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
203
|
+
oj_add_value_id,
|
204
|
+
4,
|
205
|
+
Qfalse,
|
206
|
+
Qnil,
|
207
|
+
LONG2FIX(p->line),
|
208
|
+
LONG2FIX(p->cur - p->col));
|
117
209
|
}
|
118
210
|
|
119
211
|
static void add_false_key(ojParser p) {
|
120
|
-
rb_funcall(((
|
212
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 2, Qfalse, get_key(p));
|
213
|
+
}
|
214
|
+
|
215
|
+
static void add_false_key_loc(ojParser p) {
|
216
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
217
|
+
oj_add_value_id,
|
218
|
+
4,
|
219
|
+
Qfalse,
|
220
|
+
get_key(p),
|
221
|
+
LONG2FIX(p->line),
|
222
|
+
LONG2FIX(p->cur - p->col));
|
121
223
|
}
|
122
224
|
|
123
225
|
static void add_int(ojParser p) {
|
124
|
-
rb_funcall(((
|
226
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 2, LONG2NUM(p->num.fixnum), Qnil);
|
227
|
+
}
|
228
|
+
|
229
|
+
static void add_int_loc(ojParser p) {
|
230
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
231
|
+
oj_add_value_id,
|
232
|
+
4,
|
233
|
+
LONG2NUM(p->num.fixnum),
|
234
|
+
Qnil,
|
235
|
+
LONG2FIX(p->line),
|
236
|
+
LONG2FIX(p->cur - p->col));
|
125
237
|
}
|
126
238
|
|
127
239
|
static void add_int_key(ojParser p) {
|
128
|
-
rb_funcall(((
|
240
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 2, LONG2NUM(p->num.fixnum), get_key(p));
|
241
|
+
}
|
242
|
+
|
243
|
+
static void add_int_key_loc(ojParser p) {
|
244
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
245
|
+
oj_add_value_id,
|
246
|
+
4,
|
247
|
+
LONG2NUM(p->num.fixnum),
|
248
|
+
get_key(p),
|
249
|
+
LONG2FIX(p->line),
|
250
|
+
LONG2FIX(p->cur - p->col));
|
129
251
|
}
|
130
252
|
|
131
253
|
static void add_float(ojParser p) {
|
132
|
-
rb_funcall(((
|
254
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 2, rb_float_new(p->num.dub), Qnil);
|
255
|
+
}
|
256
|
+
|
257
|
+
static void add_float_loc(ojParser p) {
|
258
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
259
|
+
oj_add_value_id,
|
260
|
+
4,
|
261
|
+
rb_float_new(p->num.dub),
|
262
|
+
Qnil,
|
263
|
+
LONG2FIX(p->line),
|
264
|
+
LONG2FIX(p->cur - p->col));
|
133
265
|
}
|
134
266
|
|
135
267
|
static void add_float_key(ojParser p) {
|
136
|
-
rb_funcall(((
|
268
|
+
rb_funcall(((Saj)p->ctx)->handler, oj_add_value_id, 2, rb_float_new(p->num.dub), get_key(p));
|
269
|
+
}
|
270
|
+
|
271
|
+
static void add_float_key_loc(ojParser p) {
|
272
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
273
|
+
oj_add_value_id,
|
274
|
+
4,
|
275
|
+
rb_float_new(p->num.dub),
|
276
|
+
get_key(p),
|
277
|
+
LONG2FIX(p->line),
|
278
|
+
LONG2FIX(p->cur - p->col));
|
137
279
|
}
|
138
280
|
|
139
281
|
static void add_big(ojParser p) {
|
140
|
-
rb_funcall((
|
282
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
141
283
|
oj_add_value_id,
|
142
284
|
2,
|
143
285
|
rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new(buf_str(&p->buf), buf_len(&p->buf))),
|
144
286
|
Qnil);
|
145
287
|
}
|
146
288
|
|
289
|
+
static void add_big_loc(ojParser p) {
|
290
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
291
|
+
oj_add_value_id,
|
292
|
+
4,
|
293
|
+
rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new(buf_str(&p->buf), buf_len(&p->buf))),
|
294
|
+
Qnil,
|
295
|
+
LONG2FIX(p->line),
|
296
|
+
LONG2FIX(p->cur - p->col));
|
297
|
+
}
|
298
|
+
|
147
299
|
static void add_big_key(ojParser p) {
|
148
|
-
rb_funcall((
|
300
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
149
301
|
oj_add_value_id,
|
150
302
|
2,
|
151
303
|
rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new(buf_str(&p->buf), buf_len(&p->buf))),
|
152
304
|
get_key(p));
|
153
305
|
}
|
154
306
|
|
307
|
+
static void add_big_key_loc(ojParser p) {
|
308
|
+
rb_funcall(((Saj)p->ctx)->handler,
|
309
|
+
oj_add_value_id,
|
310
|
+
4,
|
311
|
+
rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new(buf_str(&p->buf), buf_len(&p->buf))),
|
312
|
+
get_key(p),
|
313
|
+
LONG2FIX(p->line),
|
314
|
+
LONG2FIX(p->cur - p->col));
|
315
|
+
}
|
316
|
+
|
155
317
|
static void add_str(ojParser p) {
|
156
|
-
|
318
|
+
Saj d = (Saj)p->ctx;
|
157
319
|
volatile VALUE rstr;
|
158
|
-
const char
|
320
|
+
const char *str = buf_str(&p->buf);
|
159
321
|
size_t len = buf_len(&p->buf);
|
160
322
|
|
161
323
|
if (d->cache_str < len) {
|
@@ -166,10 +328,24 @@ static void add_str(ojParser p) {
|
|
166
328
|
rb_funcall(d->handler, oj_add_value_id, 2, rstr, Qnil);
|
167
329
|
}
|
168
330
|
|
331
|
+
static void add_str_loc(ojParser p) {
|
332
|
+
Saj d = (Saj)p->ctx;
|
333
|
+
volatile VALUE rstr;
|
334
|
+
const char *str = buf_str(&p->buf);
|
335
|
+
size_t len = buf_len(&p->buf);
|
336
|
+
|
337
|
+
if (d->cache_str < len) {
|
338
|
+
rstr = cache_intern(d->str_cache, str, len);
|
339
|
+
} else {
|
340
|
+
rstr = rb_utf8_str_new(str, len);
|
341
|
+
}
|
342
|
+
rb_funcall(d->handler, oj_add_value_id, 4, rstr, Qnil, LONG2FIX(p->line), LONG2FIX(p->cur - p->col));
|
343
|
+
}
|
344
|
+
|
169
345
|
static void add_str_key(ojParser p) {
|
170
|
-
|
346
|
+
Saj d = (Saj)p->ctx;
|
171
347
|
volatile VALUE rstr;
|
172
|
-
const char
|
348
|
+
const char *str = buf_str(&p->buf);
|
173
349
|
size_t len = buf_len(&p->buf);
|
174
350
|
|
175
351
|
if (d->cache_str < len) {
|
@@ -180,6 +356,20 @@ static void add_str_key(ojParser p) {
|
|
180
356
|
rb_funcall(d->handler, oj_add_value_id, 2, rstr, get_key(p));
|
181
357
|
}
|
182
358
|
|
359
|
+
static void add_str_key_loc(ojParser p) {
|
360
|
+
Saj d = (Saj)p->ctx;
|
361
|
+
volatile VALUE rstr;
|
362
|
+
const char *str = buf_str(&p->buf);
|
363
|
+
size_t len = buf_len(&p->buf);
|
364
|
+
|
365
|
+
if (d->cache_str < len) {
|
366
|
+
rstr = cache_intern(d->str_cache, str, len);
|
367
|
+
} else {
|
368
|
+
rstr = rb_utf8_str_new(str, len);
|
369
|
+
}
|
370
|
+
rb_funcall(d->handler, oj_add_value_id, 4, rstr, get_key(p), LONG2FIX(p->line), LONG2FIX(p->cur - p->col));
|
371
|
+
}
|
372
|
+
|
183
373
|
static void reset(ojParser p) {
|
184
374
|
Funcs end = p->funcs + 3;
|
185
375
|
Funcs f;
|
@@ -200,7 +390,7 @@ static void reset(ojParser p) {
|
|
200
390
|
}
|
201
391
|
|
202
392
|
static VALUE option(ojParser p, const char *key, VALUE value) {
|
203
|
-
|
393
|
+
Saj d = (Saj)p->ctx;
|
204
394
|
|
205
395
|
if (0 == strcmp(key, "handler")) {
|
206
396
|
return d->handler;
|
@@ -210,53 +400,107 @@ static VALUE option(ojParser p, const char *key, VALUE value) {
|
|
210
400
|
d->handler = value;
|
211
401
|
reset(p);
|
212
402
|
if (rb_respond_to(value, oj_hash_start_id)) {
|
213
|
-
|
214
|
-
|
215
|
-
|
403
|
+
if (1 == rb_obj_method_arity(value, oj_hash_start_id)) {
|
404
|
+
p->funcs[TOP_FUN].open_object = open_object;
|
405
|
+
p->funcs[ARRAY_FUN].open_object = open_object;
|
406
|
+
p->funcs[OBJECT_FUN].open_object = open_object_key;
|
407
|
+
} else {
|
408
|
+
p->funcs[TOP_FUN].open_object = open_object_loc;
|
409
|
+
p->funcs[ARRAY_FUN].open_object = open_object_loc;
|
410
|
+
p->funcs[OBJECT_FUN].open_object = open_object_loc_key;
|
411
|
+
}
|
216
412
|
}
|
217
413
|
if (rb_respond_to(value, oj_array_start_id)) {
|
218
|
-
|
219
|
-
|
220
|
-
|
414
|
+
if (1 == rb_obj_method_arity(value, oj_array_start_id)) {
|
415
|
+
p->funcs[TOP_FUN].open_array = open_array;
|
416
|
+
p->funcs[ARRAY_FUN].open_array = open_array;
|
417
|
+
p->funcs[OBJECT_FUN].open_array = open_array_key;
|
418
|
+
} else {
|
419
|
+
p->funcs[TOP_FUN].open_array = open_array_loc;
|
420
|
+
p->funcs[ARRAY_FUN].open_array = open_array_loc;
|
421
|
+
p->funcs[OBJECT_FUN].open_array = open_array_loc_key;
|
422
|
+
}
|
221
423
|
}
|
222
424
|
if (rb_respond_to(value, oj_hash_end_id)) {
|
223
|
-
|
224
|
-
|
225
|
-
|
425
|
+
if (1 == rb_obj_method_arity(value, oj_hash_end_id)) {
|
426
|
+
p->funcs[TOP_FUN].close_object = close_object;
|
427
|
+
p->funcs[ARRAY_FUN].close_object = close_object;
|
428
|
+
p->funcs[OBJECT_FUN].close_object = close_object;
|
429
|
+
} else {
|
430
|
+
p->funcs[TOP_FUN].close_object = close_object_loc;
|
431
|
+
p->funcs[ARRAY_FUN].close_object = close_object_loc;
|
432
|
+
p->funcs[OBJECT_FUN].close_object = close_object_loc;
|
433
|
+
}
|
226
434
|
}
|
227
435
|
if (rb_respond_to(value, oj_array_end_id)) {
|
228
|
-
|
229
|
-
|
230
|
-
|
436
|
+
if (1 == rb_obj_method_arity(value, oj_array_end_id)) {
|
437
|
+
p->funcs[TOP_FUN].close_array = close_array;
|
438
|
+
p->funcs[ARRAY_FUN].close_array = close_array;
|
439
|
+
p->funcs[OBJECT_FUN].close_array = close_array;
|
440
|
+
} else {
|
441
|
+
p->funcs[TOP_FUN].close_array = close_array_loc;
|
442
|
+
p->funcs[ARRAY_FUN].close_array = close_array_loc;
|
443
|
+
p->funcs[OBJECT_FUN].close_array = close_array_loc;
|
444
|
+
}
|
231
445
|
}
|
232
446
|
if (rb_respond_to(value, oj_add_value_id)) {
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
447
|
+
if (2 == rb_obj_method_arity(value, oj_add_value_id)) {
|
448
|
+
p->funcs[TOP_FUN].add_null = add_null;
|
449
|
+
p->funcs[ARRAY_FUN].add_null = add_null;
|
450
|
+
p->funcs[OBJECT_FUN].add_null = add_null_key;
|
451
|
+
|
452
|
+
p->funcs[TOP_FUN].add_true = add_true;
|
453
|
+
p->funcs[ARRAY_FUN].add_true = add_true;
|
454
|
+
p->funcs[OBJECT_FUN].add_true = add_true_key;
|
455
|
+
|
456
|
+
p->funcs[TOP_FUN].add_false = add_false;
|
457
|
+
p->funcs[ARRAY_FUN].add_false = add_false;
|
458
|
+
p->funcs[OBJECT_FUN].add_false = add_false_key;
|
459
|
+
|
460
|
+
p->funcs[TOP_FUN].add_int = add_int;
|
461
|
+
p->funcs[ARRAY_FUN].add_int = add_int;
|
462
|
+
p->funcs[OBJECT_FUN].add_int = add_int_key;
|
463
|
+
|
464
|
+
p->funcs[TOP_FUN].add_float = add_float;
|
465
|
+
p->funcs[ARRAY_FUN].add_float = add_float;
|
466
|
+
p->funcs[OBJECT_FUN].add_float = add_float_key;
|
467
|
+
|
468
|
+
p->funcs[TOP_FUN].add_big = add_big;
|
469
|
+
p->funcs[ARRAY_FUN].add_big = add_big;
|
470
|
+
p->funcs[OBJECT_FUN].add_big = add_big_key;
|
471
|
+
|
472
|
+
p->funcs[TOP_FUN].add_str = add_str;
|
473
|
+
p->funcs[ARRAY_FUN].add_str = add_str;
|
474
|
+
p->funcs[OBJECT_FUN].add_str = add_str_key;
|
475
|
+
} else {
|
476
|
+
p->funcs[TOP_FUN].add_null = add_null_loc;
|
477
|
+
p->funcs[ARRAY_FUN].add_null = add_null_loc;
|
478
|
+
p->funcs[OBJECT_FUN].add_null = add_null_key_loc;
|
479
|
+
|
480
|
+
p->funcs[TOP_FUN].add_true = add_true_loc;
|
481
|
+
p->funcs[ARRAY_FUN].add_true = add_true_loc;
|
482
|
+
p->funcs[OBJECT_FUN].add_true = add_true_key_loc;
|
483
|
+
|
484
|
+
p->funcs[TOP_FUN].add_false = add_false_loc;
|
485
|
+
p->funcs[ARRAY_FUN].add_false = add_false_loc;
|
486
|
+
p->funcs[OBJECT_FUN].add_false = add_false_key_loc;
|
487
|
+
|
488
|
+
p->funcs[TOP_FUN].add_int = add_int_loc;
|
489
|
+
p->funcs[ARRAY_FUN].add_int = add_int_loc;
|
490
|
+
p->funcs[OBJECT_FUN].add_int = add_int_key_loc;
|
491
|
+
|
492
|
+
p->funcs[TOP_FUN].add_float = add_float_loc;
|
493
|
+
p->funcs[ARRAY_FUN].add_float = add_float_loc;
|
494
|
+
p->funcs[OBJECT_FUN].add_float = add_float_key_loc;
|
495
|
+
|
496
|
+
p->funcs[TOP_FUN].add_big = add_big_loc;
|
497
|
+
p->funcs[ARRAY_FUN].add_big = add_big_loc;
|
498
|
+
p->funcs[OBJECT_FUN].add_big = add_big_key_loc;
|
499
|
+
|
500
|
+
p->funcs[TOP_FUN].add_str = add_str_loc;
|
501
|
+
p->funcs[ARRAY_FUN].add_str = add_str_loc;
|
502
|
+
p->funcs[OBJECT_FUN].add_str = add_str_key_loc;
|
503
|
+
}
|
260
504
|
}
|
261
505
|
return Qnil;
|
262
506
|
}
|
@@ -283,7 +527,7 @@ static VALUE option(ojParser p, const char *key, VALUE value) {
|
|
283
527
|
|
284
528
|
return INT2NUM((int)d->cache_str);
|
285
529
|
}
|
286
|
-
rb_raise(rb_eArgError, "%s is not an option for the SAJ (Simple API for JSON)
|
530
|
+
rb_raise(rb_eArgError, "%s is not an option for the SAJ (Simple API for JSON) saj", key);
|
287
531
|
|
288
532
|
return Qnil; // Never reached due to the raise but required by the compiler.
|
289
533
|
}
|
@@ -293,13 +537,13 @@ static VALUE result(ojParser p) {
|
|
293
537
|
}
|
294
538
|
|
295
539
|
static void start(ojParser p) {
|
296
|
-
|
540
|
+
Saj d = (Saj)p->ctx;
|
297
541
|
|
298
542
|
d->tail = d->keys;
|
299
543
|
}
|
300
544
|
|
301
545
|
static void dfree(ojParser p) {
|
302
|
-
|
546
|
+
Saj d = (Saj)p->ctx;
|
303
547
|
|
304
548
|
if (NULL != d->keys) {
|
305
549
|
xfree(d->keys);
|
@@ -309,11 +553,11 @@ static void dfree(ojParser p) {
|
|
309
553
|
}
|
310
554
|
|
311
555
|
static void mark(ojParser p) {
|
312
|
-
if (NULL == p->ctx) {
|
556
|
+
if (NULL == p || NULL == p->ctx) {
|
313
557
|
return;
|
314
558
|
}
|
315
|
-
|
316
|
-
VALUE
|
559
|
+
Saj d = (Saj)p->ctx;
|
560
|
+
VALUE *kp;
|
317
561
|
|
318
562
|
cache_mark(d->str_cache);
|
319
563
|
if (Qnil != d->handler) {
|
@@ -330,9 +574,7 @@ static VALUE form_str(const char *str, size_t len) {
|
|
330
574
|
return rb_str_freeze(rb_utf8_str_new(str, len));
|
331
575
|
}
|
332
576
|
|
333
|
-
void
|
334
|
-
Delegate d = ALLOC(struct _delegate);
|
335
|
-
|
577
|
+
void oj_init_saj(ojParser p, Saj d) {
|
336
578
|
d->klen = 256;
|
337
579
|
d->keys = ALLOC_N(VALUE, d->klen);
|
338
580
|
d->tail = d->keys;
|
@@ -346,3 +588,9 @@ void oj_set_parser_saj(ojParser p) {
|
|
346
588
|
p->mark = mark;
|
347
589
|
p->start = start;
|
348
590
|
}
|
591
|
+
|
592
|
+
void oj_set_parser_saj(ojParser p) {
|
593
|
+
Saj d = ALLOC(struct _saj);
|
594
|
+
|
595
|
+
oj_init_saj(p, d);
|
596
|
+
}
|