oj 3.13.7 → 3.13.23
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +75 -0
- data/README.md +11 -0
- data/ext/oj/buf.h +4 -0
- data/ext/oj/circarray.c +1 -1
- data/ext/oj/code.c +15 -22
- data/ext/oj/compat.c +10 -10
- data/ext/oj/custom.c +66 -112
- data/ext/oj/dump.c +147 -184
- data/ext/oj/dump.h +25 -8
- data/ext/oj/dump_compat.c +47 -89
- data/ext/oj/dump_leaf.c +14 -58
- data/ext/oj/dump_object.c +72 -188
- data/ext/oj/dump_strict.c +19 -31
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/extconf.rb +5 -4
- data/ext/oj/fast.c +36 -24
- data/ext/oj/intern.c +22 -12
- data/ext/oj/intern.h +1 -1
- data/ext/oj/mimic_json.c +74 -73
- data/ext/oj/object.c +54 -72
- data/ext/oj/odd.c +83 -63
- data/ext/oj/odd.h +13 -13
- data/ext/oj/oj.c +166 -175
- data/ext/oj/oj.h +25 -3
- data/ext/oj/parse.c +123 -79
- data/ext/oj/parse.h +2 -0
- data/ext/oj/parser.c +77 -21
- data/ext/oj/parser.h +12 -0
- data/ext/oj/rails.c +46 -70
- data/ext/oj/rails.h +1 -1
- data/ext/oj/reader.c +2 -0
- data/ext/oj/saj.c +11 -23
- data/ext/oj/saj2.c +333 -85
- data/ext/oj/saj2.h +23 -0
- data/ext/oj/sparse.c +4 -0
- data/ext/oj/stream_writer.c +3 -1
- data/ext/oj/strict.c +13 -13
- data/ext/oj/string_writer.c +12 -5
- data/ext/oj/usual.c +86 -131
- 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 +22 -27
- 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/pages/JsonGem.md +15 -0
- data/pages/Modes.md +6 -3
- data/pages/Options.md +6 -0
- data/pages/Rails.md +12 -0
- data/test/activesupport7/abstract_unit.rb +49 -0
- data/test/activesupport7/decoding_test.rb +125 -0
- data/test/activesupport7/encoding_test.rb +486 -0
- data/test/activesupport7/encoding_test_cases.rb +104 -0
- data/test/activesupport7/time_zone_test_helpers.rb +47 -0
- data/test/bar.rb +3 -8
- data/test/bug.rb +16 -0
- data/test/foo.rb +71 -7
- data/test/helper.rb +8 -2
- data/test/json_gem/json_generator_test.rb +5 -4
- data/test/json_gem/json_parser_test.rb +8 -1
- data/test/json_gem/test_helper.rb +7 -3
- data/test/perf_dump.rb +50 -0
- data/test/test_compat.rb +25 -0
- data/test/test_custom.rb +13 -2
- data/test/test_fast.rb +37 -7
- data/test/test_file.rb +23 -7
- data/test/test_gc.rb +11 -0
- data/test/test_object.rb +8 -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_saj.rb +1 -1
- data/test/test_scp.rb +2 -4
- data/test/test_strict.rb +2 -0
- data/test/test_various.rb +32 -2
- data/test/test_wab.rb +2 -0
- data/test/tests.rb +9 -1
- data/test/tests_mimic.rb +9 -0
- data/test/tests_mimic_addition.rb +9 -0
- metadata +15 -115
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
|
+
}
|
data/ext/oj/saj2.h
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
// Copyright (c) 2021, Peter Ohler, All rights reserved.
|
2
|
+
|
3
|
+
#include <ruby.h>
|
4
|
+
#include <stdbool.h>
|
5
|
+
|
6
|
+
struct _cache;
|
7
|
+
struct _ojParser;
|
8
|
+
|
9
|
+
typedef struct _saj {
|
10
|
+
VALUE handler;
|
11
|
+
VALUE *keys;
|
12
|
+
VALUE *tail;
|
13
|
+
size_t klen;
|
14
|
+
struct _cache *str_cache;
|
15
|
+
uint8_t cache_str;
|
16
|
+
bool cache_keys;
|
17
|
+
bool thread_safe;
|
18
|
+
} * Saj;
|
19
|
+
|
20
|
+
// Initialize the parser with the SAJ delegate. If the SAJ delegate is wrapped
|
21
|
+
// then this function is called first and then the parser functions can be
|
22
|
+
// replaced.
|
23
|
+
extern void oj_init_saj(struct _ojParser *p, Saj d);
|
data/ext/oj/sparse.c
CHANGED
data/ext/oj/stream_writer.c
CHANGED
@@ -315,8 +315,10 @@ static VALUE stream_writer_flush(VALUE self) {
|
|
315
315
|
* will create that element in the JSON document and subsequent pushes will add
|
316
316
|
* the elements to that array or object until a pop() is called.
|
317
317
|
*/
|
318
|
-
void oj_stream_writer_init() {
|
318
|
+
void oj_stream_writer_init(void) {
|
319
319
|
oj_stream_writer_class = rb_define_class_under(Oj, "StreamWriter", rb_cObject);
|
320
|
+
rb_gc_register_address(&oj_stream_writer_class);
|
321
|
+
rb_undef_alloc_func(oj_stream_writer_class);
|
320
322
|
rb_define_module_function(oj_stream_writer_class, "new", stream_writer_new, -1);
|
321
323
|
rb_define_method(oj_stream_writer_class, "push_key", stream_writer_push_key, 1);
|
322
324
|
rb_define_method(oj_stream_writer_class, "push_object", stream_writer_push_object, -1);
|