oj 3.13.17 → 3.16.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
}
|