oj 3.13.17 → 3.16.3
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 +77 -0
- data/README.md +4 -2
- data/ext/oj/buf.h +7 -6
- data/ext/oj/cache.c +29 -26
- data/ext/oj/cache.h +3 -2
- data/ext/oj/cache8.c +10 -9
- data/ext/oj/circarray.c +7 -5
- data/ext/oj/circarray.h +2 -2
- data/ext/oj/code.c +5 -12
- data/ext/oj/code.h +2 -2
- data/ext/oj/compat.c +20 -60
- data/ext/oj/custom.c +44 -96
- data/ext/oj/debug.c +3 -9
- data/ext/oj/dump.c +69 -39
- data/ext/oj/dump.h +1 -4
- data/ext/oj/dump_compat.c +557 -592
- data/ext/oj/dump_leaf.c +3 -5
- data/ext/oj/dump_object.c +42 -48
- data/ext/oj/dump_strict.c +10 -22
- data/ext/oj/encoder.c +1 -1
- data/ext/oj/err.c +2 -13
- data/ext/oj/err.h +9 -12
- data/ext/oj/extconf.rb +16 -6
- data/ext/oj/fast.c +76 -106
- data/ext/oj/intern.c +63 -51
- data/ext/oj/intern.h +3 -7
- data/ext/oj/mem.c +318 -0
- data/ext/oj/mem.h +53 -0
- data/ext/oj/mimic_json.c +43 -30
- data/ext/oj/object.c +61 -70
- data/ext/oj/odd.c +8 -6
- data/ext/oj/odd.h +4 -4
- data/ext/oj/oj.c +243 -205
- data/ext/oj/oj.h +82 -78
- data/ext/oj/parse.c +123 -188
- data/ext/oj/parse.h +23 -24
- data/ext/oj/parser.c +103 -63
- data/ext/oj/parser.h +19 -9
- data/ext/oj/rails.c +68 -92
- data/ext/oj/reader.c +10 -15
- data/ext/oj/reader.h +4 -2
- data/ext/oj/resolve.c +3 -4
- data/ext/oj/rxclass.c +6 -5
- data/ext/oj/rxclass.h +1 -1
- data/ext/oj/saj.c +10 -9
- data/ext/oj/saj2.c +74 -92
- data/ext/oj/saj2.h +23 -0
- data/ext/oj/scp.c +3 -14
- data/ext/oj/sparse.c +22 -70
- data/ext/oj/stream_writer.c +43 -35
- data/ext/oj/strict.c +20 -52
- data/ext/oj/string_writer.c +60 -34
- data/ext/oj/trace.h +31 -4
- data/ext/oj/usual.c +125 -150
- data/ext/oj/usual.h +69 -0
- data/ext/oj/util.h +1 -1
- data/ext/oj/val_stack.c +14 -3
- data/ext/oj/val_stack.h +8 -7
- data/ext/oj/wab.c +25 -57
- data/lib/oj/active_support_helper.rb +1 -3
- data/lib/oj/bag.rb +7 -1
- data/lib/oj/easy_hash.rb +4 -5
- data/lib/oj/error.rb +0 -1
- data/lib/oj/json.rb +162 -150
- data/lib/oj/mimic.rb +6 -2
- data/lib/oj/state.rb +9 -6
- data/lib/oj/version.rb +1 -2
- data/lib/oj.rb +2 -0
- data/pages/Compatibility.md +1 -1
- data/pages/InstallOptions.md +20 -0
- data/pages/Options.md +10 -0
- data/test/_test_active.rb +8 -9
- data/test/_test_active_mimic.rb +7 -8
- data/test/_test_mimic_rails.rb +17 -20
- data/test/activerecord/result_test.rb +5 -6
- data/test/files.rb +15 -15
- data/test/foo.rb +9 -72
- data/test/helper.rb +11 -8
- data/test/isolated/shared.rb +3 -2
- data/test/json_gem/json_addition_test.rb +2 -2
- data/test/json_gem/json_common_interface_test.rb +8 -6
- data/test/json_gem/json_encoding_test.rb +0 -0
- data/test/json_gem/json_ext_parser_test.rb +1 -0
- data/test/json_gem/json_fixtures_test.rb +3 -2
- data/test/json_gem/json_generator_test.rb +53 -37
- data/test/json_gem/json_generic_object_test.rb +11 -11
- data/test/json_gem/json_parser_test.rb +47 -47
- data/test/json_gem/json_string_matching_test.rb +9 -9
- data/test/json_gem/test_helper.rb +7 -3
- data/test/mem.rb +13 -12
- data/test/perf.rb +21 -26
- data/test/perf_compat.rb +31 -33
- data/test/perf_dump.rb +28 -28
- data/test/perf_fast.rb +80 -82
- data/test/perf_file.rb +27 -29
- data/test/perf_object.rb +65 -69
- data/test/perf_once.rb +12 -11
- data/test/perf_parser.rb +42 -48
- data/test/perf_saj.rb +46 -54
- data/test/perf_scp.rb +57 -69
- data/test/perf_simple.rb +41 -39
- data/test/perf_strict.rb +68 -70
- data/test/perf_wab.rb +67 -69
- data/test/prec.rb +5 -5
- data/test/sample/change.rb +0 -1
- data/test/sample/dir.rb +0 -1
- data/test/sample/doc.rb +0 -1
- data/test/sample/file.rb +0 -1
- data/test/sample/group.rb +0 -1
- data/test/sample/hasprops.rb +0 -1
- data/test/sample/layer.rb +0 -1
- data/test/sample/rect.rb +0 -1
- data/test/sample/shape.rb +0 -1
- data/test/sample/text.rb +0 -1
- data/test/sample.rb +16 -16
- data/test/sample_json.rb +8 -8
- data/test/test_compat.rb +80 -53
- data/test/test_custom.rb +73 -51
- data/test/test_debian.rb +7 -10
- data/test/test_fast.rb +86 -90
- data/test/test_file.rb +28 -35
- data/test/test_gc.rb +16 -5
- data/test/test_generate.rb +5 -5
- data/test/test_hash.rb +4 -4
- data/test/test_integer_range.rb +9 -9
- data/test/test_null.rb +20 -20
- data/test/test_object.rb +94 -96
- data/test/test_parser.rb +6 -22
- data/test/test_parser_debug.rb +27 -0
- data/test/test_parser_saj.rb +61 -22
- data/test/test_parser_usual.rb +16 -6
- data/test/test_rails.rb +2 -2
- data/test/test_saj.rb +10 -8
- data/test/test_scp.rb +37 -39
- data/test/test_strict.rb +40 -32
- data/test/test_various.rb +148 -100
- data/test/test_wab.rb +48 -44
- data/test/test_writer.rb +47 -47
- data/test/tests.rb +13 -4
- data/test/tests_mimic.rb +12 -3
- data/test/tests_mimic_addition.rb +12 -3
- metadata +36 -27
- data/test/activesupport4/decoding_test.rb +0 -108
- data/test/activesupport4/encoding_test.rb +0 -531
- data/test/activesupport4/test_helper.rb +0 -41
- data/test/activesupport5/abstract_unit.rb +0 -45
- data/test/activesupport5/decoding_test.rb +0 -133
- data/test/activesupport5/encoding_test.rb +0 -500
- data/test/activesupport5/encoding_test_cases.rb +0 -98
- data/test/activesupport5/test_helper.rb +0 -72
- data/test/activesupport5/time_zone_test_helpers.rb +0 -39
- data/test/bar.rb +0 -11
- data/test/baz.rb +0 -16
- data/test/bug.rb +0 -16
- data/test/zoo.rb +0 -13
data/ext/oj/usual.c
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
// Copyright (c) 2021, Peter Ohler, All rights reserved.
|
2
2
|
|
3
|
+
#include "usual.h"
|
4
|
+
|
3
5
|
#include "cache.h"
|
6
|
+
#include "mem.h"
|
4
7
|
#include "oj.h"
|
5
8
|
#include "parser.h"
|
6
9
|
|
@@ -28,67 +31,12 @@
|
|
28
31
|
|
29
32
|
#define DEBUG 0
|
30
33
|
|
31
|
-
// Used to mark the start of each Hash, Array, or Object. The members point at
|
32
|
-
// positions of the start in the value stack and if not an Array into the key
|
33
|
-
// stack.
|
34
|
-
typedef struct _col {
|
35
|
-
long vi; // value stack index
|
36
|
-
long ki; // key stack index if an hash else -1 for an array
|
37
|
-
} * Col;
|
38
|
-
|
39
|
-
typedef union _key {
|
40
|
-
struct {
|
41
|
-
int16_t len;
|
42
|
-
char buf[30];
|
43
|
-
};
|
44
|
-
struct {
|
45
|
-
int16_t xlen; // should be the same as len
|
46
|
-
char * key;
|
47
|
-
};
|
48
|
-
} * Key;
|
49
|
-
|
50
|
-
#define MISS_AUTO 'A'
|
51
|
-
#define MISS_RAISE 'R'
|
52
|
-
#define MISS_IGNORE 'I'
|
53
|
-
|
54
|
-
typedef struct _delegate {
|
55
|
-
VALUE *vhead;
|
56
|
-
VALUE *vtail;
|
57
|
-
VALUE *vend;
|
58
|
-
|
59
|
-
Col chead;
|
60
|
-
Col ctail;
|
61
|
-
Col cend;
|
62
|
-
|
63
|
-
Key khead;
|
64
|
-
Key ktail;
|
65
|
-
Key kend;
|
66
|
-
|
67
|
-
VALUE (*get_key)(ojParser p, Key kp);
|
68
|
-
struct _cache *key_cache; // same as str_cache or sym_cache
|
69
|
-
struct _cache *str_cache;
|
70
|
-
struct _cache *sym_cache;
|
71
|
-
struct _cache *class_cache;
|
72
|
-
struct _cache *attr_cache;
|
73
|
-
|
74
|
-
VALUE array_class;
|
75
|
-
VALUE hash_class;
|
76
|
-
|
77
|
-
char * create_id;
|
78
|
-
uint8_t create_id_len;
|
79
|
-
uint8_t cache_str;
|
80
|
-
uint8_t cache_xrate;
|
81
|
-
uint8_t miss_class;
|
82
|
-
bool cache_keys;
|
83
|
-
bool ignore_json_create;
|
84
|
-
} * Delegate;
|
85
|
-
|
86
34
|
static ID to_f_id = 0;
|
87
35
|
static ID ltlt_id = 0;
|
88
36
|
static ID hset_id = 0;
|
89
37
|
|
90
38
|
static char *str_dup(const char *s, size_t len) {
|
91
|
-
char *d =
|
39
|
+
char *d = OJ_R_ALLOC_N(char, len + 1);
|
92
40
|
|
93
41
|
memcpy(d, s, len);
|
94
42
|
d[len] = '\0';
|
@@ -108,7 +56,7 @@ static VALUE form_attr(const char *str, size_t len) {
|
|
108
56
|
char buf[256];
|
109
57
|
|
110
58
|
if (sizeof(buf) - 2 <= len) {
|
111
|
-
char *b =
|
59
|
+
char *b = OJ_R_ALLOC_N(char, len + 2);
|
112
60
|
ID id;
|
113
61
|
|
114
62
|
*b = '@';
|
@@ -116,7 +64,7 @@ static VALUE form_attr(const char *str, size_t len) {
|
|
116
64
|
b[len + 1] = '\0';
|
117
65
|
|
118
66
|
id = rb_intern3(buf, len + 1, oj_utf8_encoding);
|
119
|
-
|
67
|
+
OJ_R_FREE(b);
|
120
68
|
return id;
|
121
69
|
}
|
122
70
|
*buf = '@';
|
@@ -143,8 +91,8 @@ static VALUE resolve_classname(VALUE mod, const char *classname, bool auto_defin
|
|
143
91
|
static VALUE resolve_classpath(const char *name, size_t len, bool auto_define) {
|
144
92
|
char class_name[1024];
|
145
93
|
VALUE clas;
|
146
|
-
char
|
147
|
-
char
|
94
|
+
char *end = class_name + sizeof(class_name) - 1;
|
95
|
+
char *s;
|
148
96
|
const char *n = name;
|
149
97
|
|
150
98
|
clas = rb_cObject;
|
@@ -178,27 +126,27 @@ static VALUE form_class_auto(const char *str, size_t len) {
|
|
178
126
|
return resolve_classpath(str, len, true);
|
179
127
|
}
|
180
128
|
|
181
|
-
static void assure_cstack(
|
129
|
+
static void assure_cstack(Usual d) {
|
182
130
|
if (d->cend <= d->ctail + 1) {
|
183
131
|
size_t cap = d->cend - d->chead;
|
184
132
|
long pos = d->ctail - d->chead;
|
185
133
|
|
186
134
|
cap *= 2;
|
187
|
-
|
135
|
+
OJ_R_REALLOC_N(d->chead, struct _col, cap);
|
188
136
|
d->ctail = d->chead + pos;
|
189
137
|
d->cend = d->chead + cap;
|
190
138
|
}
|
191
139
|
}
|
192
140
|
|
193
141
|
static void push(ojParser p, VALUE v) {
|
194
|
-
|
142
|
+
Usual d = (Usual)p->ctx;
|
195
143
|
|
196
144
|
if (d->vend <= d->vtail) {
|
197
145
|
size_t cap = d->vend - d->vhead;
|
198
146
|
long pos = d->vtail - d->vhead;
|
199
147
|
|
200
148
|
cap *= 2;
|
201
|
-
|
149
|
+
OJ_R_REALLOC_N(d->vhead, VALUE, cap);
|
202
150
|
d->vtail = d->vhead + pos;
|
203
151
|
d->vend = d->vhead + cap;
|
204
152
|
}
|
@@ -207,7 +155,7 @@ static void push(ojParser p, VALUE v) {
|
|
207
155
|
}
|
208
156
|
|
209
157
|
static VALUE cache_key(ojParser p, Key kp) {
|
210
|
-
|
158
|
+
Usual d = (Usual)p->ctx;
|
211
159
|
|
212
160
|
if ((size_t)kp->len < sizeof(kp->buf)) {
|
213
161
|
return cache_intern(d->key_cache, kp->buf, kp->len);
|
@@ -230,7 +178,7 @@ static VALUE sym_key(ojParser p, Key kp) {
|
|
230
178
|
}
|
231
179
|
|
232
180
|
static ID get_attr_id(ojParser p, Key kp) {
|
233
|
-
|
181
|
+
Usual d = (Usual)p->ctx;
|
234
182
|
|
235
183
|
if ((size_t)kp->len < sizeof(kp->buf)) {
|
236
184
|
return (ID)cache_intern(d->attr_cache, kp->buf, kp->len);
|
@@ -239,7 +187,7 @@ static ID get_attr_id(ojParser p, Key kp) {
|
|
239
187
|
}
|
240
188
|
|
241
189
|
static void push_key(ojParser p) {
|
242
|
-
|
190
|
+
Usual d = (Usual)p->ctx;
|
243
191
|
size_t klen = buf_len(&p->key);
|
244
192
|
const char *key = buf_str(&p->key);
|
245
193
|
|
@@ -248,7 +196,7 @@ static void push_key(ojParser p) {
|
|
248
196
|
long pos = d->ktail - d->khead;
|
249
197
|
|
250
198
|
cap *= 2;
|
251
|
-
|
199
|
+
OJ_R_REALLOC_N(d->khead, union _key, cap);
|
252
200
|
d->ktail = d->khead + pos;
|
253
201
|
d->kend = d->khead + cap;
|
254
202
|
}
|
@@ -263,14 +211,14 @@ static void push_key(ojParser p) {
|
|
263
211
|
}
|
264
212
|
|
265
213
|
static void push2(ojParser p, VALUE v) {
|
266
|
-
|
214
|
+
Usual d = (Usual)p->ctx;
|
267
215
|
|
268
216
|
if (d->vend <= d->vtail + 1) {
|
269
217
|
size_t cap = d->vend - d->vhead;
|
270
218
|
long pos = d->vtail - d->vhead;
|
271
219
|
|
272
220
|
cap *= 2;
|
273
|
-
|
221
|
+
OJ_R_REALLOC_N(d->vhead, VALUE, cap);
|
274
222
|
d->vtail = d->vhead + pos;
|
275
223
|
d->vend = d->vhead + cap;
|
276
224
|
}
|
@@ -281,7 +229,7 @@ static void push2(ojParser p, VALUE v) {
|
|
281
229
|
}
|
282
230
|
|
283
231
|
static void open_object(ojParser p) {
|
284
|
-
|
232
|
+
Usual d = (Usual)p->ctx;
|
285
233
|
|
286
234
|
assure_cstack(d);
|
287
235
|
d->ctail->vi = d->vtail - d->vhead;
|
@@ -291,7 +239,7 @@ static void open_object(ojParser p) {
|
|
291
239
|
}
|
292
240
|
|
293
241
|
static void open_object_key(ojParser p) {
|
294
|
-
|
242
|
+
Usual d = (Usual)p->ctx;
|
295
243
|
|
296
244
|
push_key(p);
|
297
245
|
assure_cstack(d);
|
@@ -302,7 +250,7 @@ static void open_object_key(ojParser p) {
|
|
302
250
|
}
|
303
251
|
|
304
252
|
static void open_array(ojParser p) {
|
305
|
-
|
253
|
+
Usual d = (Usual)p->ctx;
|
306
254
|
|
307
255
|
assure_cstack(d);
|
308
256
|
d->ctail->vi = d->vtail - d->vhead;
|
@@ -312,7 +260,7 @@ static void open_array(ojParser p) {
|
|
312
260
|
}
|
313
261
|
|
314
262
|
static void open_array_key(ojParser p) {
|
315
|
-
|
263
|
+
Usual d = (Usual)p->ctx;
|
316
264
|
|
317
265
|
push_key(p);
|
318
266
|
assure_cstack(d);
|
@@ -323,21 +271,21 @@ static void open_array_key(ojParser p) {
|
|
323
271
|
}
|
324
272
|
|
325
273
|
static void close_object(ojParser p) {
|
326
|
-
VALUE *
|
327
|
-
|
274
|
+
VALUE *vp;
|
275
|
+
Usual d = (Usual)p->ctx;
|
328
276
|
|
329
277
|
d->ctail--;
|
330
278
|
|
331
279
|
Col c = d->ctail;
|
332
280
|
Key kp = d->khead + c->ki;
|
333
|
-
VALUE
|
281
|
+
VALUE *head = d->vhead + c->vi + 1;
|
334
282
|
volatile VALUE obj = rb_hash_new();
|
335
283
|
|
336
284
|
#if HAVE_RB_HASH_BULK_INSERT
|
337
285
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
338
286
|
*vp = d->get_key(p, kp);
|
339
287
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
340
|
-
|
288
|
+
OJ_R_FREE(kp->key);
|
341
289
|
}
|
342
290
|
}
|
343
291
|
rb_hash_bulk_insert(d->vtail - head, head, obj);
|
@@ -345,7 +293,7 @@ static void close_object(ojParser p) {
|
|
345
293
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
346
294
|
rb_hash_aset(obj, d->get_key(p, kp), *(vp + 1));
|
347
295
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
348
|
-
|
296
|
+
OJ_R_FREE(kp->key);
|
349
297
|
}
|
350
298
|
}
|
351
299
|
#endif
|
@@ -356,20 +304,20 @@ static void close_object(ojParser p) {
|
|
356
304
|
}
|
357
305
|
|
358
306
|
static void close_object_class(ojParser p) {
|
359
|
-
VALUE *
|
360
|
-
|
307
|
+
VALUE *vp;
|
308
|
+
Usual d = (Usual)p->ctx;
|
361
309
|
|
362
310
|
d->ctail--;
|
363
311
|
|
364
312
|
Col c = d->ctail;
|
365
313
|
Key kp = d->khead + c->ki;
|
366
|
-
VALUE
|
314
|
+
VALUE *head = d->vhead + c->vi + 1;
|
367
315
|
volatile VALUE obj = rb_class_new_instance(0, NULL, d->hash_class);
|
368
316
|
|
369
317
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
370
318
|
rb_funcall(obj, hset_id, 2, d->get_key(p, kp), *(vp + 1));
|
371
319
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
372
|
-
|
320
|
+
OJ_R_FREE(kp->key);
|
373
321
|
}
|
374
322
|
}
|
375
323
|
d->ktail = d->khead + c->ki;
|
@@ -379,14 +327,14 @@ static void close_object_class(ojParser p) {
|
|
379
327
|
}
|
380
328
|
|
381
329
|
static void close_object_create(ojParser p) {
|
382
|
-
VALUE *
|
383
|
-
|
330
|
+
VALUE *vp;
|
331
|
+
Usual d = (Usual)p->ctx;
|
384
332
|
|
385
333
|
d->ctail--;
|
386
334
|
|
387
335
|
Col c = d->ctail;
|
388
336
|
Key kp = d->khead + c->ki;
|
389
|
-
VALUE
|
337
|
+
VALUE *head = d->vhead + c->vi;
|
390
338
|
volatile VALUE obj;
|
391
339
|
|
392
340
|
if (Qundef == *head) {
|
@@ -397,7 +345,7 @@ static void close_object_create(ojParser p) {
|
|
397
345
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
398
346
|
*vp = d->get_key(p, kp);
|
399
347
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
400
|
-
|
348
|
+
OJ_R_FREE(kp->key);
|
401
349
|
}
|
402
350
|
}
|
403
351
|
rb_hash_bulk_insert(d->vtail - head, head, obj);
|
@@ -405,7 +353,7 @@ static void close_object_create(ojParser p) {
|
|
405
353
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
406
354
|
rb_hash_aset(obj, d->get_key(p, kp), *(vp + 1));
|
407
355
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
408
|
-
|
356
|
+
OJ_R_FREE(kp->key);
|
409
357
|
}
|
410
358
|
}
|
411
359
|
#endif
|
@@ -414,7 +362,7 @@ static void close_object_create(ojParser p) {
|
|
414
362
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
415
363
|
rb_funcall(obj, hset_id, 2, d->get_key(p, kp), *(vp + 1));
|
416
364
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
417
|
-
|
365
|
+
OJ_R_FREE(kp->key);
|
418
366
|
}
|
419
367
|
}
|
420
368
|
}
|
@@ -429,7 +377,7 @@ static void close_object_create(ojParser p) {
|
|
429
377
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
430
378
|
*vp = d->get_key(p, kp);
|
431
379
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
432
|
-
|
380
|
+
OJ_R_FREE(kp->key);
|
433
381
|
}
|
434
382
|
}
|
435
383
|
rb_hash_bulk_insert(d->vtail - head, head, arg);
|
@@ -437,7 +385,7 @@ static void close_object_create(ojParser p) {
|
|
437
385
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
438
386
|
rb_hash_aset(arg, d->get_key(p, kp), *(vp + 1));
|
439
387
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
440
|
-
|
388
|
+
OJ_R_FREE(kp->key);
|
441
389
|
}
|
442
390
|
}
|
443
391
|
#endif
|
@@ -447,7 +395,7 @@ static void close_object_create(ojParser p) {
|
|
447
395
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
448
396
|
rb_ivar_set(obj, get_attr_id(p, kp), *(vp + 1));
|
449
397
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
450
|
-
|
398
|
+
OJ_R_FREE(kp->key);
|
451
399
|
}
|
452
400
|
}
|
453
401
|
}
|
@@ -459,10 +407,10 @@ static void close_object_create(ojParser p) {
|
|
459
407
|
}
|
460
408
|
|
461
409
|
static void close_array(ojParser p) {
|
462
|
-
|
410
|
+
Usual d = (Usual)p->ctx;
|
463
411
|
|
464
412
|
d->ctail--;
|
465
|
-
VALUE
|
413
|
+
VALUE *head = d->vhead + d->ctail->vi + 1;
|
466
414
|
volatile VALUE a = rb_ary_new_from_values(d->vtail - head, head);
|
467
415
|
|
468
416
|
d->vtail = head;
|
@@ -471,11 +419,11 @@ static void close_array(ojParser p) {
|
|
471
419
|
}
|
472
420
|
|
473
421
|
static void close_array_class(ojParser p) {
|
474
|
-
VALUE *
|
475
|
-
|
422
|
+
VALUE *vp;
|
423
|
+
Usual d = (Usual)p->ctx;
|
476
424
|
|
477
425
|
d->ctail--;
|
478
|
-
VALUE
|
426
|
+
VALUE *head = d->vhead + d->ctail->vi + 1;
|
479
427
|
volatile VALUE a = rb_class_new_instance(0, NULL, d->array_class);
|
480
428
|
|
481
429
|
for (vp = head; vp < d->vtail; vp++) {
|
@@ -585,9 +533,9 @@ static void add_big_as_ruby_key(ojParser p) {
|
|
585
533
|
}
|
586
534
|
|
587
535
|
static void add_str(ojParser p) {
|
588
|
-
|
536
|
+
Usual d = (Usual)p->ctx;
|
589
537
|
volatile VALUE rstr;
|
590
|
-
const char
|
538
|
+
const char *str = buf_str(&p->buf);
|
591
539
|
size_t len = buf_len(&p->buf);
|
592
540
|
|
593
541
|
if (len < d->cache_str) {
|
@@ -599,9 +547,9 @@ static void add_str(ojParser p) {
|
|
599
547
|
}
|
600
548
|
|
601
549
|
static void add_str_key(ojParser p) {
|
602
|
-
|
550
|
+
Usual d = (Usual)p->ctx;
|
603
551
|
volatile VALUE rstr;
|
604
|
-
const char
|
552
|
+
const char *str = buf_str(&p->buf);
|
605
553
|
size_t len = buf_len(&p->buf);
|
606
554
|
|
607
555
|
if (len < d->cache_str) {
|
@@ -614,11 +562,11 @@ static void add_str_key(ojParser p) {
|
|
614
562
|
}
|
615
563
|
|
616
564
|
static void add_str_key_create(ojParser p) {
|
617
|
-
|
565
|
+
Usual d = (Usual)p->ctx;
|
618
566
|
volatile VALUE rstr;
|
619
|
-
const char
|
567
|
+
const char *str = buf_str(&p->buf);
|
620
568
|
size_t len = buf_len(&p->buf);
|
621
|
-
const char
|
569
|
+
const char *key = buf_str(&p->key);
|
622
570
|
size_t klen = buf_len(&p->key);
|
623
571
|
|
624
572
|
if (klen == (size_t)d->create_id_len && 0 == strncmp(d->create_id, key, klen)) {
|
@@ -648,16 +596,19 @@ static void add_str_key_create(ojParser p) {
|
|
648
596
|
}
|
649
597
|
|
650
598
|
static VALUE result(ojParser p) {
|
651
|
-
|
599
|
+
Usual d = (Usual)p->ctx;
|
652
600
|
|
653
601
|
if (d->vhead < d->vtail) {
|
654
602
|
return *d->vhead;
|
655
603
|
}
|
604
|
+
if (d->raise_on_empty) {
|
605
|
+
rb_raise(oj_parse_error_class, "empty string");
|
606
|
+
}
|
656
607
|
return Qnil;
|
657
608
|
}
|
658
609
|
|
659
610
|
static void start(ojParser p) {
|
660
|
-
|
611
|
+
Usual d = (Usual)p->ctx;
|
661
612
|
|
662
613
|
d->vtail = d->vhead;
|
663
614
|
d->ctail = d->chead;
|
@@ -665,7 +616,7 @@ static void start(ojParser p) {
|
|
665
616
|
}
|
666
617
|
|
667
618
|
static void dfree(ojParser p) {
|
668
|
-
|
619
|
+
Usual d = (Usual)p->ctx;
|
669
620
|
|
670
621
|
cache_free(d->str_cache);
|
671
622
|
cache_free(d->attr_cache);
|
@@ -675,20 +626,20 @@ static void dfree(ojParser p) {
|
|
675
626
|
if (NULL != d->class_cache) {
|
676
627
|
cache_free(d->class_cache);
|
677
628
|
}
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
629
|
+
OJ_R_FREE(d->vhead);
|
630
|
+
OJ_R_FREE(d->chead);
|
631
|
+
OJ_R_FREE(d->khead);
|
632
|
+
OJ_R_FREE(d->create_id);
|
633
|
+
OJ_R_FREE(p->ctx);
|
683
634
|
p->ctx = NULL;
|
684
635
|
}
|
685
636
|
|
686
637
|
static void mark(ojParser p) {
|
687
|
-
if (NULL == p->ctx) {
|
638
|
+
if (NULL == p || NULL == p->ctx) {
|
688
639
|
return;
|
689
640
|
}
|
690
|
-
|
691
|
-
VALUE *
|
641
|
+
Usual d = (Usual)p->ctx;
|
642
|
+
VALUE *vp;
|
692
643
|
|
693
644
|
if (NULL == d) {
|
694
645
|
return;
|
@@ -720,13 +671,13 @@ struct opt {
|
|
720
671
|
};
|
721
672
|
|
722
673
|
static VALUE opt_array_class(ojParser p, VALUE value) {
|
723
|
-
|
674
|
+
Usual d = (Usual)p->ctx;
|
724
675
|
|
725
676
|
return d->array_class;
|
726
677
|
}
|
727
678
|
|
728
679
|
static VALUE opt_array_class_set(ojParser p, VALUE value) {
|
729
|
-
|
680
|
+
Usual d = (Usual)p->ctx;
|
730
681
|
|
731
682
|
if (Qnil == value) {
|
732
683
|
p->funcs[TOP_FUN].close_array = close_array;
|
@@ -747,13 +698,13 @@ static VALUE opt_array_class_set(ojParser p, VALUE value) {
|
|
747
698
|
}
|
748
699
|
|
749
700
|
static VALUE opt_cache_keys(ojParser p, VALUE value) {
|
750
|
-
|
701
|
+
Usual d = (Usual)p->ctx;
|
751
702
|
|
752
703
|
return d->cache_keys ? Qtrue : Qfalse;
|
753
704
|
}
|
754
705
|
|
755
706
|
static VALUE opt_cache_keys_set(ojParser p, VALUE value) {
|
756
|
-
|
707
|
+
Usual d = (Usual)p->ctx;
|
757
708
|
|
758
709
|
if (Qtrue == value) {
|
759
710
|
d->cache_keys = true;
|
@@ -775,14 +726,14 @@ static VALUE opt_cache_keys_set(ojParser p, VALUE value) {
|
|
775
726
|
}
|
776
727
|
|
777
728
|
static VALUE opt_cache_strings(ojParser p, VALUE value) {
|
778
|
-
|
729
|
+
Usual d = (Usual)p->ctx;
|
779
730
|
|
780
731
|
return INT2NUM((int)d->cache_str);
|
781
732
|
}
|
782
733
|
|
783
734
|
static VALUE opt_cache_strings_set(ojParser p, VALUE value) {
|
784
|
-
|
785
|
-
int
|
735
|
+
Usual d = (Usual)p->ctx;
|
736
|
+
int limit = NUM2INT(value);
|
786
737
|
|
787
738
|
if (CACHE_MAX_KEY < limit) {
|
788
739
|
limit = CACHE_MAX_KEY;
|
@@ -795,14 +746,14 @@ static VALUE opt_cache_strings_set(ojParser p, VALUE value) {
|
|
795
746
|
}
|
796
747
|
|
797
748
|
static VALUE opt_cache_expunge(ojParser p, VALUE value) {
|
798
|
-
|
749
|
+
Usual d = (Usual)p->ctx;
|
799
750
|
|
800
751
|
return INT2NUM((int)d->cache_xrate);
|
801
752
|
}
|
802
753
|
|
803
754
|
static VALUE opt_cache_expunge_set(ojParser p, VALUE value) {
|
804
|
-
|
805
|
-
int
|
755
|
+
Usual d = (Usual)p->ctx;
|
756
|
+
int rate = NUM2INT(value);
|
806
757
|
|
807
758
|
if (rate < 0) {
|
808
759
|
rate = 0;
|
@@ -819,26 +770,26 @@ static VALUE opt_cache_expunge_set(ojParser p, VALUE value) {
|
|
819
770
|
}
|
820
771
|
|
821
772
|
static VALUE opt_capacity(ojParser p, VALUE value) {
|
822
|
-
|
773
|
+
Usual d = (Usual)p->ctx;
|
823
774
|
|
824
775
|
return ULONG2NUM(d->vend - d->vhead);
|
825
776
|
}
|
826
777
|
|
827
778
|
static VALUE opt_capacity_set(ojParser p, VALUE value) {
|
828
|
-
|
829
|
-
long
|
779
|
+
Usual d = (Usual)p->ctx;
|
780
|
+
long cap = NUM2LONG(value);
|
830
781
|
|
831
782
|
if (d->vend - d->vhead < cap) {
|
832
783
|
long pos = d->vtail - d->vhead;
|
833
784
|
|
834
|
-
|
785
|
+
OJ_R_REALLOC_N(d->vhead, VALUE, cap);
|
835
786
|
d->vtail = d->vhead + pos;
|
836
787
|
d->vend = d->vhead + cap;
|
837
788
|
}
|
838
789
|
if (d->kend - d->khead < cap) {
|
839
790
|
long pos = d->ktail - d->khead;
|
840
791
|
|
841
|
-
|
792
|
+
OJ_R_REALLOC_N(d->khead, union _key, cap);
|
842
793
|
d->ktail = d->khead + pos;
|
843
794
|
d->kend = d->khead + cap;
|
844
795
|
}
|
@@ -846,13 +797,13 @@ static VALUE opt_capacity_set(ojParser p, VALUE value) {
|
|
846
797
|
}
|
847
798
|
|
848
799
|
static VALUE opt_class_cache(ojParser p, VALUE value) {
|
849
|
-
|
800
|
+
Usual d = (Usual)p->ctx;
|
850
801
|
|
851
802
|
return (NULL != d->class_cache) ? Qtrue : Qfalse;
|
852
803
|
}
|
853
804
|
|
854
805
|
static VALUE opt_class_cache_set(ojParser p, VALUE value) {
|
855
|
-
|
806
|
+
Usual d = (Usual)p->ctx;
|
856
807
|
|
857
808
|
if (Qtrue == value) {
|
858
809
|
if (NULL == d->class_cache) {
|
@@ -866,7 +817,7 @@ static VALUE opt_class_cache_set(ojParser p, VALUE value) {
|
|
866
817
|
}
|
867
818
|
|
868
819
|
static VALUE opt_create_id(ojParser p, VALUE value) {
|
869
|
-
|
820
|
+
Usual d = (Usual)p->ctx;
|
870
821
|
|
871
822
|
if (NULL == d->create_id) {
|
872
823
|
return Qnil;
|
@@ -875,7 +826,7 @@ static VALUE opt_create_id(ojParser p, VALUE value) {
|
|
875
826
|
}
|
876
827
|
|
877
828
|
static VALUE opt_create_id_set(ojParser p, VALUE value) {
|
878
|
-
|
829
|
+
Usual d = (Usual)p->ctx;
|
879
830
|
|
880
831
|
if (Qnil == value) {
|
881
832
|
d->create_id = NULL;
|
@@ -924,7 +875,7 @@ static VALUE opt_decimal(ojParser p, VALUE value) {
|
|
924
875
|
}
|
925
876
|
|
926
877
|
static VALUE opt_decimal_set(ojParser p, VALUE value) {
|
927
|
-
const char
|
878
|
+
const char *mode;
|
928
879
|
volatile VALUE s;
|
929
880
|
|
930
881
|
switch (rb_type(value)) {
|
@@ -985,13 +936,13 @@ static VALUE opt_decimal_set(ojParser p, VALUE value) {
|
|
985
936
|
}
|
986
937
|
|
987
938
|
static VALUE opt_hash_class(ojParser p, VALUE value) {
|
988
|
-
|
939
|
+
Usual d = (Usual)p->ctx;
|
989
940
|
|
990
941
|
return d->hash_class;
|
991
942
|
}
|
992
943
|
|
993
944
|
static VALUE opt_hash_class_set(ojParser p, VALUE value) {
|
994
|
-
|
945
|
+
Usual d = (Usual)p->ctx;
|
995
946
|
|
996
947
|
if (Qnil != value) {
|
997
948
|
rb_check_type(value, T_CLASS);
|
@@ -1015,13 +966,13 @@ static VALUE opt_hash_class_set(ojParser p, VALUE value) {
|
|
1015
966
|
}
|
1016
967
|
|
1017
968
|
static VALUE opt_ignore_json_create(ojParser p, VALUE value) {
|
1018
|
-
|
969
|
+
Usual d = (Usual)p->ctx;
|
1019
970
|
|
1020
971
|
return d->ignore_json_create ? Qtrue : Qfalse;
|
1021
972
|
}
|
1022
973
|
|
1023
974
|
static VALUE opt_ignore_json_create_set(ojParser p, VALUE value) {
|
1024
|
-
|
975
|
+
Usual d = (Usual)p->ctx;
|
1025
976
|
|
1026
977
|
d->ignore_json_create = (Qtrue == value);
|
1027
978
|
|
@@ -1029,7 +980,7 @@ static VALUE opt_ignore_json_create_set(ojParser p, VALUE value) {
|
|
1029
980
|
}
|
1030
981
|
|
1031
982
|
static VALUE opt_missing_class(ojParser p, VALUE value) {
|
1032
|
-
|
983
|
+
Usual d = (Usual)p->ctx;
|
1033
984
|
|
1034
985
|
switch (d->miss_class) {
|
1035
986
|
case MISS_AUTO: return ID2SYM(rb_intern("auto"));
|
@@ -1040,8 +991,8 @@ static VALUE opt_missing_class(ojParser p, VALUE value) {
|
|
1040
991
|
}
|
1041
992
|
|
1042
993
|
static VALUE opt_missing_class_set(ojParser p, VALUE value) {
|
1043
|
-
|
1044
|
-
const char
|
994
|
+
Usual d = (Usual)p->ctx;
|
995
|
+
const char *mode;
|
1045
996
|
volatile VALUE s;
|
1046
997
|
|
1047
998
|
switch (rb_type(value)) {
|
@@ -1091,13 +1042,13 @@ static VALUE opt_omit_null_set(ojParser p, VALUE value) {
|
|
1091
1042
|
}
|
1092
1043
|
|
1093
1044
|
static VALUE opt_symbol_keys(ojParser p, VALUE value) {
|
1094
|
-
|
1045
|
+
Usual d = (Usual)p->ctx;
|
1095
1046
|
|
1096
1047
|
return (NULL != d->sym_cache) ? Qtrue : Qfalse;
|
1097
1048
|
}
|
1098
1049
|
|
1099
1050
|
static VALUE opt_symbol_keys_set(ojParser p, VALUE value) {
|
1100
|
-
|
1051
|
+
Usual d = (Usual)p->ctx;
|
1101
1052
|
|
1102
1053
|
if (Qtrue == value) {
|
1103
1054
|
d->sym_cache = cache_create(0, form_sym, true, false);
|
@@ -1118,6 +1069,20 @@ static VALUE opt_symbol_keys_set(ojParser p, VALUE value) {
|
|
1118
1069
|
return (NULL != d->sym_cache) ? Qtrue : Qfalse;
|
1119
1070
|
}
|
1120
1071
|
|
1072
|
+
static VALUE opt_raise_on_empty(ojParser p, VALUE value) {
|
1073
|
+
Usual d = (Usual)p->ctx;
|
1074
|
+
|
1075
|
+
return d->raise_on_empty ? Qtrue : Qfalse;
|
1076
|
+
}
|
1077
|
+
|
1078
|
+
static VALUE opt_raise_on_empty_set(ojParser p, VALUE value) {
|
1079
|
+
Usual d = (Usual)p->ctx;
|
1080
|
+
|
1081
|
+
d->raise_on_empty = (Qtrue == value);
|
1082
|
+
|
1083
|
+
return d->raise_on_empty ? Qtrue : Qfalse;
|
1084
|
+
}
|
1085
|
+
|
1121
1086
|
static VALUE option(ojParser p, const char *key, VALUE value) {
|
1122
1087
|
struct opt *op;
|
1123
1088
|
struct opt opts[] = {
|
@@ -1147,6 +1112,8 @@ static VALUE option(ojParser p, const char *key, VALUE value) {
|
|
1147
1112
|
{.name = "omit_null=", .func = opt_omit_null_set},
|
1148
1113
|
{.name = "symbol_keys", .func = opt_symbol_keys},
|
1149
1114
|
{.name = "symbol_keys=", .func = opt_symbol_keys_set},
|
1115
|
+
{.name = "raise_on_empty", .func = opt_raise_on_empty},
|
1116
|
+
{.name = "raise_on_empty=", .func = opt_raise_on_empty_set},
|
1150
1117
|
{.name = NULL},
|
1151
1118
|
};
|
1152
1119
|
|
@@ -1162,26 +1129,26 @@ static VALUE option(ojParser p, const char *key, VALUE value) {
|
|
1162
1129
|
|
1163
1130
|
///// the set up //////////////////////////////////////////////////////////////
|
1164
1131
|
|
1165
|
-
void
|
1166
|
-
|
1167
|
-
int cap = 4096;
|
1132
|
+
void oj_init_usual(ojParser p, Usual d) {
|
1133
|
+
int cap = 4096;
|
1168
1134
|
|
1169
|
-
d->vhead =
|
1135
|
+
d->vhead = OJ_R_ALLOC_N(VALUE, cap);
|
1170
1136
|
d->vend = d->vhead + cap;
|
1171
1137
|
d->vtail = d->vhead;
|
1172
1138
|
|
1173
|
-
d->khead =
|
1139
|
+
d->khead = OJ_R_ALLOC_N(union _key, cap);
|
1174
1140
|
d->kend = d->khead + cap;
|
1175
1141
|
d->ktail = d->khead;
|
1176
1142
|
|
1177
1143
|
cap = 256;
|
1178
|
-
d->chead =
|
1144
|
+
d->chead = OJ_R_ALLOC_N(struct _col, cap);
|
1179
1145
|
d->cend = d->chead + cap;
|
1180
1146
|
d->ctail = d->chead;
|
1181
1147
|
|
1182
1148
|
d->get_key = cache_key;
|
1183
1149
|
d->cache_keys = true;
|
1184
1150
|
d->ignore_json_create = false;
|
1151
|
+
d->raise_on_empty = false;
|
1185
1152
|
d->cache_str = 6;
|
1186
1153
|
d->array_class = Qnil;
|
1187
1154
|
d->hash_class = Qnil;
|
@@ -1235,6 +1202,8 @@ void oj_set_parser_usual(ojParser p) {
|
|
1235
1202
|
d->class_cache = NULL;
|
1236
1203
|
d->key_cache = d->str_cache;
|
1237
1204
|
|
1205
|
+
// The parser fields are set but the functions can be replaced by a
|
1206
|
+
// delegate that wraps the usual delegate.
|
1238
1207
|
p->ctx = (void *)d;
|
1239
1208
|
p->option = option;
|
1240
1209
|
p->result = result;
|
@@ -1252,3 +1221,9 @@ void oj_set_parser_usual(ojParser p) {
|
|
1252
1221
|
hset_id = rb_intern("[]=");
|
1253
1222
|
}
|
1254
1223
|
}
|
1224
|
+
|
1225
|
+
void oj_set_parser_usual(ojParser p) {
|
1226
|
+
Usual d = OJ_R_ALLOC(struct _usual);
|
1227
|
+
|
1228
|
+
oj_init_usual(p, d);
|
1229
|
+
}
|