oj 3.13.7 → 3.13.23
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 +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);
|