oj 3.13.14 → 3.13.22
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/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
|
+
}
|