oj 3.14.1 → 3.14.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 +9 -1
- data/README.md +0 -1
- data/ext/oj/buf.h +7 -6
- data/ext/oj/cache.c +25 -24
- 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 +2 -2
- data/ext/oj/code.h +2 -2
- data/ext/oj/compat.c +7 -14
- data/ext/oj/custom.c +3 -2
- data/ext/oj/debug.c +3 -9
- data/ext/oj/dump.c +18 -17
- data/ext/oj/dump_compat.c +551 -576
- data/ext/oj/dump_leaf.c +3 -5
- data/ext/oj/dump_object.c +37 -37
- data/ext/oj/dump_strict.c +2 -4
- 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 +1 -1
- data/ext/oj/fast.c +33 -46
- data/ext/oj/intern.c +44 -46
- 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 +20 -25
- data/ext/oj/object.c +7 -7
- data/ext/oj/odd.c +8 -6
- data/ext/oj/odd.h +4 -4
- data/ext/oj/oj.c +71 -85
- data/ext/oj/oj.h +53 -54
- data/ext/oj/parse.c +67 -128
- data/ext/oj/parse.h +5 -10
- data/ext/oj/parser.c +13 -14
- data/ext/oj/parser.h +7 -8
- data/ext/oj/rails.c +36 -66
- data/ext/oj/reader.c +8 -11
- 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 +9 -8
- data/ext/oj/saj2.c +36 -52
- data/ext/oj/saj2.h +1 -1
- data/ext/oj/scp.c +3 -14
- data/ext/oj/sparse.c +22 -70
- data/ext/oj/stream_writer.c +9 -21
- data/ext/oj/strict.c +7 -13
- data/ext/oj/string_writer.c +11 -18
- data/ext/oj/trace.h +27 -16
- data/ext/oj/usual.c +89 -87
- data/ext/oj/usual.h +6 -6
- data/ext/oj/util.h +1 -1
- data/ext/oj/val_stack.h +8 -7
- data/ext/oj/wab.c +7 -9
- data/lib/oj/active_support_helper.rb +0 -1
- 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 +4 -2
- data/lib/oj/mimic.rb +4 -2
- data/lib/oj/state.rb +8 -5
- data/lib/oj/version.rb +1 -2
- data/lib/oj.rb +0 -1
- data/test/_test_active.rb +0 -1
- data/test/_test_active_mimic.rb +0 -1
- data/test/_test_mimic_rails.rb +0 -1
- data/test/activerecord/result_test.rb +5 -6
- data/test/bar.rb +3 -3
- data/test/files.rb +1 -1
- data/test/foo.rb +5 -3
- data/test/helper.rb +1 -4
- 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 +4 -4
- 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 +43 -32
- data/test/json_gem/json_generic_object_test.rb +11 -11
- data/test/json_gem/json_parser_test.rb +46 -46
- data/test/json_gem/json_string_matching_test.rb +9 -9
- data/test/mem.rb +7 -7
- data/test/perf.rb +2 -2
- data/test/perf_compat.rb +1 -1
- data/test/perf_fast.rb +1 -1
- data/test/perf_file.rb +2 -2
- data/test/perf_object.rb +1 -2
- data/test/perf_once.rb +4 -4
- data/test/perf_parser.rb +2 -2
- data/test/perf_saj.rb +1 -2
- data/test/perf_scp.rb +1 -1
- data/test/perf_simple.rb +3 -3
- data/test/perf_strict.rb +1 -1
- data/test/perf_wab.rb +1 -1
- 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 +2 -3
- data/test/sample_json.rb +0 -1
- data/test/test_compat.rb +11 -9
- data/test/test_custom.rb +5 -9
- data/test/test_debian.rb +1 -1
- data/test/test_fast.rb +10 -20
- data/test/test_file.rb +8 -8
- data/test/test_integer_range.rb +2 -2
- data/test/test_null.rb +5 -3
- data/test/test_object.rb +6 -5
- data/test/test_parser_saj.rb +23 -21
- data/test/test_parser_usual.rb +3 -3
- data/test/test_saj.rb +2 -0
- data/test/test_scp.rb +6 -6
- data/test/test_strict.rb +6 -4
- data/test/test_various.rb +21 -24
- data/test/test_wab.rb +6 -5
- data/test/test_writer.rb +1 -1
- metadata +20 -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/ext/oj/string_writer.c
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
#include "dump.h"
|
5
5
|
#include "encode.h"
|
6
|
+
#include "mem.h"
|
6
7
|
|
7
8
|
extern VALUE Oj;
|
8
9
|
|
@@ -20,7 +21,7 @@ static void push_type(StrWriter sw, DumpType type) {
|
|
20
21
|
if (sw->types_end <= sw->types + sw->depth + 1) {
|
21
22
|
size_t size = (sw->types_end - sw->types) * 2;
|
22
23
|
|
23
|
-
|
24
|
+
OJ_R_REALLOC_N(sw->types, char, size);
|
24
25
|
sw->types_end = sw->types + size;
|
25
26
|
}
|
26
27
|
sw->depth++;
|
@@ -43,7 +44,7 @@ static void maybe_comma(StrWriter sw) {
|
|
43
44
|
void oj_str_writer_init(StrWriter sw, int buf_size) {
|
44
45
|
sw->opts = oj_default_options;
|
45
46
|
sw->depth = 0;
|
46
|
-
sw->types =
|
47
|
+
sw->types = OJ_R_ALLOC_N(char, 256);
|
47
48
|
sw->types_end = sw->types + 256;
|
48
49
|
*sw->types = '\0';
|
49
50
|
sw->keyWritten = 0;
|
@@ -55,10 +56,10 @@ void oj_str_writer_init(StrWriter sw, int buf_size) {
|
|
55
56
|
}
|
56
57
|
// Must be allocated. Using the out.stack_buffer results in double frees
|
57
58
|
// and I haven't figured out why yet.
|
58
|
-
sw->out.buf
|
59
|
-
sw->out.cur
|
60
|
-
sw->out.end
|
61
|
-
sw->out.allocated
|
59
|
+
sw->out.buf = OJ_R_ALLOC_N(char, buf_size);
|
60
|
+
sw->out.cur = sw->out.buf;
|
61
|
+
sw->out.end = sw->out.buf + buf_size - BUFFER_EXTRA;
|
62
|
+
sw->out.allocated = true;
|
62
63
|
|
63
64
|
*sw->out.cur = '\0';
|
64
65
|
sw->out.circ_cache = NULL;
|
@@ -235,8 +236,8 @@ static void str_writer_free(void *ptr) {
|
|
235
236
|
|
236
237
|
oj_out_free(&sw->out);
|
237
238
|
|
238
|
-
|
239
|
-
|
239
|
+
OJ_R_FREE(sw->types);
|
240
|
+
OJ_R_FREE(ptr);
|
240
241
|
}
|
241
242
|
|
242
243
|
/* Document-method: new
|
@@ -256,7 +257,7 @@ static void str_writer_free(void *ptr) {
|
|
256
257
|
* - *options* [_Hash_] formatting options
|
257
258
|
*/
|
258
259
|
static VALUE str_writer_new(int argc, VALUE *argv, VALUE self) {
|
259
|
-
StrWriter sw =
|
260
|
+
StrWriter sw = OJ_R_ALLOC(struct _strWriter);
|
260
261
|
|
261
262
|
oj_str_writer_init(sw, 0);
|
262
263
|
if (1 == argc) {
|
@@ -280,7 +281,6 @@ static VALUE str_writer_new(int argc, VALUE *argv, VALUE self) {
|
|
280
281
|
static VALUE str_writer_push_key(VALUE self, VALUE key) {
|
281
282
|
StrWriter sw = (StrWriter)DATA_PTR(self);
|
282
283
|
|
283
|
-
rb_check_type(key, T_STRING);
|
284
284
|
oj_str_writer_push_key(sw, StringValuePtr(key));
|
285
285
|
|
286
286
|
return Qnil;
|
@@ -302,7 +302,6 @@ static VALUE str_writer_push_object(int argc, VALUE *argv, VALUE self) {
|
|
302
302
|
if (Qnil == argv[0]) {
|
303
303
|
oj_str_writer_push_object(sw, 0);
|
304
304
|
} else {
|
305
|
-
rb_check_type(argv[0], T_STRING);
|
306
305
|
oj_str_writer_push_object(sw, StringValuePtr(argv[0]));
|
307
306
|
}
|
308
307
|
break;
|
@@ -331,7 +330,6 @@ static VALUE str_writer_push_array(int argc, VALUE *argv, VALUE self) {
|
|
331
330
|
if (Qnil == argv[0]) {
|
332
331
|
oj_str_writer_push_array(sw, 0);
|
333
332
|
} else {
|
334
|
-
rb_check_type(argv[0], T_STRING);
|
335
333
|
oj_str_writer_push_array(sw, StringValuePtr(argv[0]));
|
336
334
|
}
|
337
335
|
break;
|
@@ -358,7 +356,6 @@ static VALUE str_writer_push_value(int argc, VALUE *argv, VALUE self) {
|
|
358
356
|
if (Qnil == argv[1]) {
|
359
357
|
oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, 0);
|
360
358
|
} else {
|
361
|
-
rb_check_type(argv[1], T_STRING);
|
362
359
|
oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, StringValuePtr(argv[1]));
|
363
360
|
}
|
364
361
|
break;
|
@@ -377,17 +374,13 @@ static VALUE str_writer_push_value(int argc, VALUE *argv, VALUE self) {
|
|
377
374
|
* - *key* [_String_] the key if adding to an object in the JSON document
|
378
375
|
*/
|
379
376
|
static VALUE str_writer_push_json(int argc, VALUE *argv, VALUE self) {
|
380
|
-
rb_check_type(argv[0], T_STRING);
|
381
377
|
switch (argc) {
|
382
378
|
case 1: oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), 0); break;
|
383
379
|
case 2:
|
384
380
|
if (Qnil == argv[1]) {
|
385
381
|
oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), 0);
|
386
382
|
} else {
|
387
|
-
|
388
|
-
oj_str_writer_push_json((StrWriter)DATA_PTR(self),
|
389
|
-
StringValuePtr(*argv),
|
390
|
-
StringValuePtr(argv[1]));
|
383
|
+
oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), StringValuePtr(argv[1]));
|
391
384
|
}
|
392
385
|
break;
|
393
386
|
default: rb_raise(rb_eArgError, "Wrong number of argument to 'push_json'."); break;
|
data/ext/oj/trace.h
CHANGED
@@ -17,28 +17,39 @@ typedef enum {
|
|
17
17
|
|
18
18
|
struct _parseInfo;
|
19
19
|
|
20
|
-
extern void
|
21
|
-
oj_trace(const char *func, VALUE obj, const char *file, int line, int depth, TraceWhere where);
|
20
|
+
extern void oj_trace(const char *func, VALUE obj, const char *file, int line, int depth, TraceWhere where);
|
22
21
|
extern void oj_trace_parse_in(const char *func, struct _parseInfo *pi, const char *file, int line);
|
23
|
-
extern void
|
24
|
-
oj_trace_parse_call(const char *func, struct _parseInfo *pi, const char *file, int line, VALUE obj);
|
22
|
+
extern void oj_trace_parse_call(const char *func, struct _parseInfo *pi, const char *file, int line, VALUE obj);
|
25
23
|
extern void oj_trace_parse_hash_end(struct _parseInfo *pi, const char *file, int line);
|
26
24
|
extern void oj_trace_parse_array_end(struct _parseInfo *pi, const char *file, int line);
|
27
25
|
|
28
|
-
|
29
26
|
#ifdef OJ_ENABLE_TRACE_LOG
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
27
|
+
#define TRACE(option, func, obj, depth, where) \
|
28
|
+
if (RB_UNLIKELY(Yes == option)) { \
|
29
|
+
oj_trace(func, obj, __FILE__, __LINE__, depth, where); \
|
30
|
+
}
|
31
|
+
#define TRACE_PARSE_IN(option, func, pi) \
|
32
|
+
if (RB_UNLIKELY(Yes == option)) { \
|
33
|
+
oj_trace_parse_in(func, pi, __FILE__, __LINE__); \
|
34
|
+
}
|
35
|
+
#define TRACE_PARSE_CALL(option, func, pi, obj) \
|
36
|
+
if (RB_UNLIKELY(Yes == option)) { \
|
37
|
+
oj_trace_parse_call(func, pi, __FILE__, __LINE__, obj); \
|
38
|
+
}
|
39
|
+
#define TRACE_PARSE_HASH_END(option, pi) \
|
40
|
+
if (RB_UNLIKELY(Yes == option)) { \
|
41
|
+
oj_trace_parse_hash_end(pi, __FILE__, __LINE__); \
|
42
|
+
}
|
43
|
+
#define TRACE_PARSE_ARRAY_END(option, pi) \
|
44
|
+
if (RB_UNLIKELY(Yes == option)) { \
|
45
|
+
oj_trace_parse_array_end(pi, __FILE__, __LINE__); \
|
46
|
+
}
|
35
47
|
#else
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
48
|
+
#define TRACE(option, func, obj, depth, where)
|
49
|
+
#define TRACE_PARSE_IN(option, func, pi)
|
50
|
+
#define TRACE_PARSE_CALL(option, func, pi, obj)
|
51
|
+
#define TRACE_PARSE_HASH_END(option, pi)
|
52
|
+
#define TRACE_PARSE_ARRAY_END(option, pi)
|
41
53
|
#endif
|
42
54
|
|
43
|
-
|
44
55
|
#endif /* OJ_TRACE_H */
|
data/ext/oj/usual.c
CHANGED
@@ -1,9 +1,11 @@
|
|
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
|
-
#include "usual.h"
|
7
9
|
|
8
10
|
// The Usual delegate builds Ruby objects during parsing. It makes use of
|
9
11
|
// three stacks. The first is the value stack. This is where parsed values are
|
@@ -34,7 +36,7 @@ static ID ltlt_id = 0;
|
|
34
36
|
static ID hset_id = 0;
|
35
37
|
|
36
38
|
static char *str_dup(const char *s, size_t len) {
|
37
|
-
char *d =
|
39
|
+
char *d = OJ_R_ALLOC_N(char, len + 1);
|
38
40
|
|
39
41
|
memcpy(d, s, len);
|
40
42
|
d[len] = '\0';
|
@@ -54,7 +56,7 @@ static VALUE form_attr(const char *str, size_t len) {
|
|
54
56
|
char buf[256];
|
55
57
|
|
56
58
|
if (sizeof(buf) - 2 <= len) {
|
57
|
-
char *b =
|
59
|
+
char *b = OJ_R_ALLOC_N(char, len + 2);
|
58
60
|
ID id;
|
59
61
|
|
60
62
|
*b = '@';
|
@@ -62,7 +64,7 @@ static VALUE form_attr(const char *str, size_t len) {
|
|
62
64
|
b[len + 1] = '\0';
|
63
65
|
|
64
66
|
id = rb_intern3(buf, len + 1, oj_utf8_encoding);
|
65
|
-
|
67
|
+
OJ_R_FREE(b);
|
66
68
|
return id;
|
67
69
|
}
|
68
70
|
*buf = '@';
|
@@ -89,8 +91,8 @@ static VALUE resolve_classname(VALUE mod, const char *classname, bool auto_defin
|
|
89
91
|
static VALUE resolve_classpath(const char *name, size_t len, bool auto_define) {
|
90
92
|
char class_name[1024];
|
91
93
|
VALUE clas;
|
92
|
-
char
|
93
|
-
char
|
94
|
+
char *end = class_name + sizeof(class_name) - 1;
|
95
|
+
char *s;
|
94
96
|
const char *n = name;
|
95
97
|
|
96
98
|
clas = rb_cObject;
|
@@ -130,7 +132,7 @@ static void assure_cstack(Usual d) {
|
|
130
132
|
long pos = d->ctail - d->chead;
|
131
133
|
|
132
134
|
cap *= 2;
|
133
|
-
|
135
|
+
OJ_R_REALLOC_N(d->chead, struct _col, cap);
|
134
136
|
d->ctail = d->chead + pos;
|
135
137
|
d->cend = d->chead + cap;
|
136
138
|
}
|
@@ -144,7 +146,7 @@ static void push(ojParser p, VALUE v) {
|
|
144
146
|
long pos = d->vtail - d->vhead;
|
145
147
|
|
146
148
|
cap *= 2;
|
147
|
-
|
149
|
+
OJ_R_REALLOC_N(d->vhead, VALUE, cap);
|
148
150
|
d->vtail = d->vhead + pos;
|
149
151
|
d->vend = d->vhead + cap;
|
150
152
|
}
|
@@ -185,7 +187,7 @@ static ID get_attr_id(ojParser p, Key kp) {
|
|
185
187
|
}
|
186
188
|
|
187
189
|
static void push_key(ojParser p) {
|
188
|
-
Usual
|
190
|
+
Usual d = (Usual)p->ctx;
|
189
191
|
size_t klen = buf_len(&p->key);
|
190
192
|
const char *key = buf_str(&p->key);
|
191
193
|
|
@@ -194,7 +196,7 @@ static void push_key(ojParser p) {
|
|
194
196
|
long pos = d->ktail - d->khead;
|
195
197
|
|
196
198
|
cap *= 2;
|
197
|
-
|
199
|
+
OJ_R_REALLOC_N(d->khead, union _key, cap);
|
198
200
|
d->ktail = d->khead + pos;
|
199
201
|
d->kend = d->khead + cap;
|
200
202
|
}
|
@@ -216,7 +218,7 @@ static void push2(ojParser p, VALUE v) {
|
|
216
218
|
long pos = d->vtail - d->vhead;
|
217
219
|
|
218
220
|
cap *= 2;
|
219
|
-
|
221
|
+
OJ_R_REALLOC_N(d->vhead, VALUE, cap);
|
220
222
|
d->vtail = d->vhead + pos;
|
221
223
|
d->vend = d->vhead + cap;
|
222
224
|
}
|
@@ -269,21 +271,21 @@ static void open_array_key(ojParser p) {
|
|
269
271
|
}
|
270
272
|
|
271
273
|
static void close_object(ojParser p) {
|
272
|
-
VALUE *
|
273
|
-
Usual
|
274
|
+
VALUE *vp;
|
275
|
+
Usual d = (Usual)p->ctx;
|
274
276
|
|
275
277
|
d->ctail--;
|
276
278
|
|
277
279
|
Col c = d->ctail;
|
278
280
|
Key kp = d->khead + c->ki;
|
279
|
-
VALUE
|
281
|
+
VALUE *head = d->vhead + c->vi + 1;
|
280
282
|
volatile VALUE obj = rb_hash_new();
|
281
283
|
|
282
284
|
#if HAVE_RB_HASH_BULK_INSERT
|
283
285
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
284
286
|
*vp = d->get_key(p, kp);
|
285
287
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
286
|
-
|
288
|
+
OJ_R_FREE(kp->key);
|
287
289
|
}
|
288
290
|
}
|
289
291
|
rb_hash_bulk_insert(d->vtail - head, head, obj);
|
@@ -291,7 +293,7 @@ static void close_object(ojParser p) {
|
|
291
293
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
292
294
|
rb_hash_aset(obj, d->get_key(p, kp), *(vp + 1));
|
293
295
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
294
|
-
|
296
|
+
OJ_R_FREE(kp->key);
|
295
297
|
}
|
296
298
|
}
|
297
299
|
#endif
|
@@ -302,20 +304,20 @@ static void close_object(ojParser p) {
|
|
302
304
|
}
|
303
305
|
|
304
306
|
static void close_object_class(ojParser p) {
|
305
|
-
VALUE *
|
306
|
-
Usual
|
307
|
+
VALUE *vp;
|
308
|
+
Usual d = (Usual)p->ctx;
|
307
309
|
|
308
310
|
d->ctail--;
|
309
311
|
|
310
312
|
Col c = d->ctail;
|
311
313
|
Key kp = d->khead + c->ki;
|
312
|
-
VALUE
|
314
|
+
VALUE *head = d->vhead + c->vi + 1;
|
313
315
|
volatile VALUE obj = rb_class_new_instance(0, NULL, d->hash_class);
|
314
316
|
|
315
317
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
316
318
|
rb_funcall(obj, hset_id, 2, d->get_key(p, kp), *(vp + 1));
|
317
319
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
318
|
-
|
320
|
+
OJ_R_FREE(kp->key);
|
319
321
|
}
|
320
322
|
}
|
321
323
|
d->ktail = d->khead + c->ki;
|
@@ -325,14 +327,14 @@ static void close_object_class(ojParser p) {
|
|
325
327
|
}
|
326
328
|
|
327
329
|
static void close_object_create(ojParser p) {
|
328
|
-
VALUE *
|
329
|
-
Usual
|
330
|
+
VALUE *vp;
|
331
|
+
Usual d = (Usual)p->ctx;
|
330
332
|
|
331
333
|
d->ctail--;
|
332
334
|
|
333
335
|
Col c = d->ctail;
|
334
336
|
Key kp = d->khead + c->ki;
|
335
|
-
VALUE
|
337
|
+
VALUE *head = d->vhead + c->vi;
|
336
338
|
volatile VALUE obj;
|
337
339
|
|
338
340
|
if (Qundef == *head) {
|
@@ -343,7 +345,7 @@ static void close_object_create(ojParser p) {
|
|
343
345
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
344
346
|
*vp = d->get_key(p, kp);
|
345
347
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
346
|
-
|
348
|
+
OJ_R_FREE(kp->key);
|
347
349
|
}
|
348
350
|
}
|
349
351
|
rb_hash_bulk_insert(d->vtail - head, head, obj);
|
@@ -351,7 +353,7 @@ static void close_object_create(ojParser p) {
|
|
351
353
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
352
354
|
rb_hash_aset(obj, d->get_key(p, kp), *(vp + 1));
|
353
355
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
354
|
-
|
356
|
+
OJ_R_FREE(kp->key);
|
355
357
|
}
|
356
358
|
}
|
357
359
|
#endif
|
@@ -360,7 +362,7 @@ static void close_object_create(ojParser p) {
|
|
360
362
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
361
363
|
rb_funcall(obj, hset_id, 2, d->get_key(p, kp), *(vp + 1));
|
362
364
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
363
|
-
|
365
|
+
OJ_R_FREE(kp->key);
|
364
366
|
}
|
365
367
|
}
|
366
368
|
}
|
@@ -375,7 +377,7 @@ static void close_object_create(ojParser p) {
|
|
375
377
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
376
378
|
*vp = d->get_key(p, kp);
|
377
379
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
378
|
-
|
380
|
+
OJ_R_FREE(kp->key);
|
379
381
|
}
|
380
382
|
}
|
381
383
|
rb_hash_bulk_insert(d->vtail - head, head, arg);
|
@@ -383,7 +385,7 @@ static void close_object_create(ojParser p) {
|
|
383
385
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
384
386
|
rb_hash_aset(arg, d->get_key(p, kp), *(vp + 1));
|
385
387
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
386
|
-
|
388
|
+
OJ_R_FREE(kp->key);
|
387
389
|
}
|
388
390
|
}
|
389
391
|
#endif
|
@@ -393,7 +395,7 @@ static void close_object_create(ojParser p) {
|
|
393
395
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
394
396
|
rb_ivar_set(obj, get_attr_id(p, kp), *(vp + 1));
|
395
397
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
396
|
-
|
398
|
+
OJ_R_FREE(kp->key);
|
397
399
|
}
|
398
400
|
}
|
399
401
|
}
|
@@ -408,7 +410,7 @@ static void close_array(ojParser p) {
|
|
408
410
|
Usual d = (Usual)p->ctx;
|
409
411
|
|
410
412
|
d->ctail--;
|
411
|
-
VALUE
|
413
|
+
VALUE *head = d->vhead + d->ctail->vi + 1;
|
412
414
|
volatile VALUE a = rb_ary_new_from_values(d->vtail - head, head);
|
413
415
|
|
414
416
|
d->vtail = head;
|
@@ -417,11 +419,11 @@ static void close_array(ojParser p) {
|
|
417
419
|
}
|
418
420
|
|
419
421
|
static void close_array_class(ojParser p) {
|
420
|
-
VALUE *
|
421
|
-
Usual
|
422
|
+
VALUE *vp;
|
423
|
+
Usual d = (Usual)p->ctx;
|
422
424
|
|
423
425
|
d->ctail--;
|
424
|
-
VALUE
|
426
|
+
VALUE *head = d->vhead + d->ctail->vi + 1;
|
425
427
|
volatile VALUE a = rb_class_new_instance(0, NULL, d->array_class);
|
426
428
|
|
427
429
|
for (vp = head; vp < d->vtail; vp++) {
|
@@ -531,9 +533,9 @@ static void add_big_as_ruby_key(ojParser p) {
|
|
531
533
|
}
|
532
534
|
|
533
535
|
static void add_str(ojParser p) {
|
534
|
-
Usual
|
536
|
+
Usual d = (Usual)p->ctx;
|
535
537
|
volatile VALUE rstr;
|
536
|
-
const char
|
538
|
+
const char *str = buf_str(&p->buf);
|
537
539
|
size_t len = buf_len(&p->buf);
|
538
540
|
|
539
541
|
if (len < d->cache_str) {
|
@@ -545,9 +547,9 @@ static void add_str(ojParser p) {
|
|
545
547
|
}
|
546
548
|
|
547
549
|
static void add_str_key(ojParser p) {
|
548
|
-
Usual
|
550
|
+
Usual d = (Usual)p->ctx;
|
549
551
|
volatile VALUE rstr;
|
550
|
-
const char
|
552
|
+
const char *str = buf_str(&p->buf);
|
551
553
|
size_t len = buf_len(&p->buf);
|
552
554
|
|
553
555
|
if (len < d->cache_str) {
|
@@ -560,11 +562,11 @@ static void add_str_key(ojParser p) {
|
|
560
562
|
}
|
561
563
|
|
562
564
|
static void add_str_key_create(ojParser p) {
|
563
|
-
Usual
|
565
|
+
Usual d = (Usual)p->ctx;
|
564
566
|
volatile VALUE rstr;
|
565
|
-
const char
|
567
|
+
const char *str = buf_str(&p->buf);
|
566
568
|
size_t len = buf_len(&p->buf);
|
567
|
-
const char
|
569
|
+
const char *key = buf_str(&p->key);
|
568
570
|
size_t klen = buf_len(&p->key);
|
569
571
|
|
570
572
|
if (klen == (size_t)d->create_id_len && 0 == strncmp(d->create_id, key, klen)) {
|
@@ -621,11 +623,11 @@ static void dfree(ojParser p) {
|
|
621
623
|
if (NULL != d->class_cache) {
|
622
624
|
cache_free(d->class_cache);
|
623
625
|
}
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
626
|
+
OJ_R_FREE(d->vhead);
|
627
|
+
OJ_R_FREE(d->chead);
|
628
|
+
OJ_R_FREE(d->khead);
|
629
|
+
OJ_R_FREE(d->create_id);
|
630
|
+
OJ_R_FREE(p->ctx);
|
629
631
|
p->ctx = NULL;
|
630
632
|
}
|
631
633
|
|
@@ -633,8 +635,8 @@ static void mark(ojParser p) {
|
|
633
635
|
if (NULL == p || NULL == p->ctx) {
|
634
636
|
return;
|
635
637
|
}
|
636
|
-
Usual
|
637
|
-
VALUE *
|
638
|
+
Usual d = (Usual)p->ctx;
|
639
|
+
VALUE *vp;
|
638
640
|
|
639
641
|
if (NULL == d) {
|
640
642
|
return;
|
@@ -728,7 +730,7 @@ static VALUE opt_cache_strings(ojParser p, VALUE value) {
|
|
728
730
|
|
729
731
|
static VALUE opt_cache_strings_set(ojParser p, VALUE value) {
|
730
732
|
Usual d = (Usual)p->ctx;
|
731
|
-
int
|
733
|
+
int limit = NUM2INT(value);
|
732
734
|
|
733
735
|
if (CACHE_MAX_KEY < limit) {
|
734
736
|
limit = CACHE_MAX_KEY;
|
@@ -748,7 +750,7 @@ static VALUE opt_cache_expunge(ojParser p, VALUE value) {
|
|
748
750
|
|
749
751
|
static VALUE opt_cache_expunge_set(ojParser p, VALUE value) {
|
750
752
|
Usual d = (Usual)p->ctx;
|
751
|
-
int
|
753
|
+
int rate = NUM2INT(value);
|
752
754
|
|
753
755
|
if (rate < 0) {
|
754
756
|
rate = 0;
|
@@ -772,19 +774,19 @@ static VALUE opt_capacity(ojParser p, VALUE value) {
|
|
772
774
|
|
773
775
|
static VALUE opt_capacity_set(ojParser p, VALUE value) {
|
774
776
|
Usual d = (Usual)p->ctx;
|
775
|
-
long
|
777
|
+
long cap = NUM2LONG(value);
|
776
778
|
|
777
779
|
if (d->vend - d->vhead < cap) {
|
778
780
|
long pos = d->vtail - d->vhead;
|
779
781
|
|
780
|
-
|
782
|
+
OJ_R_REALLOC_N(d->vhead, VALUE, cap);
|
781
783
|
d->vtail = d->vhead + pos;
|
782
784
|
d->vend = d->vhead + cap;
|
783
785
|
}
|
784
786
|
if (d->kend - d->khead < cap) {
|
785
787
|
long pos = d->ktail - d->khead;
|
786
788
|
|
787
|
-
|
789
|
+
OJ_R_REALLOC_N(d->khead, union _key, cap);
|
788
790
|
d->ktail = d->khead + pos;
|
789
791
|
d->kend = d->khead + cap;
|
790
792
|
}
|
@@ -870,7 +872,7 @@ static VALUE opt_decimal(ojParser p, VALUE value) {
|
|
870
872
|
}
|
871
873
|
|
872
874
|
static VALUE opt_decimal_set(ojParser p, VALUE value) {
|
873
|
-
const char
|
875
|
+
const char *mode;
|
874
876
|
volatile VALUE s;
|
875
877
|
|
876
878
|
switch (rb_type(value)) {
|
@@ -986,8 +988,8 @@ static VALUE opt_missing_class(ojParser p, VALUE value) {
|
|
986
988
|
}
|
987
989
|
|
988
990
|
static VALUE opt_missing_class_set(ojParser p, VALUE value) {
|
989
|
-
Usual
|
990
|
-
const char
|
991
|
+
Usual d = (Usual)p->ctx;
|
992
|
+
const char *mode;
|
991
993
|
volatile VALUE s;
|
992
994
|
|
993
995
|
switch (rb_type(value)) {
|
@@ -1067,33 +1069,33 @@ static VALUE opt_symbol_keys_set(ojParser p, VALUE value) {
|
|
1067
1069
|
static VALUE option(ojParser p, const char *key, VALUE value) {
|
1068
1070
|
struct opt *op;
|
1069
1071
|
struct opt opts[] = {
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1072
|
+
{.name = "array_class", .func = opt_array_class},
|
1073
|
+
{.name = "array_class=", .func = opt_array_class_set},
|
1074
|
+
{.name = "cache_keys", .func = opt_cache_keys},
|
1075
|
+
{.name = "cache_keys=", .func = opt_cache_keys_set},
|
1076
|
+
{.name = "cache_strings", .func = opt_cache_strings},
|
1077
|
+
{.name = "cache_strings=", .func = opt_cache_strings_set},
|
1078
|
+
{.name = "cache_expunge", .func = opt_cache_expunge},
|
1079
|
+
{.name = "cache_expunge=", .func = opt_cache_expunge_set},
|
1080
|
+
{.name = "capacity", .func = opt_capacity},
|
1081
|
+
{.name = "capacity=", .func = opt_capacity_set},
|
1082
|
+
{.name = "class_cache", .func = opt_class_cache},
|
1083
|
+
{.name = "class_cache=", .func = opt_class_cache_set},
|
1084
|
+
{.name = "create_id", .func = opt_create_id},
|
1085
|
+
{.name = "create_id=", .func = opt_create_id_set},
|
1086
|
+
{.name = "decimal", .func = opt_decimal},
|
1087
|
+
{.name = "decimal=", .func = opt_decimal_set},
|
1088
|
+
{.name = "hash_class", .func = opt_hash_class},
|
1089
|
+
{.name = "hash_class=", .func = opt_hash_class_set},
|
1090
|
+
{.name = "ignore_json_create", .func = opt_ignore_json_create},
|
1091
|
+
{.name = "ignore_json_create=", .func = opt_ignore_json_create_set},
|
1092
|
+
{.name = "missing_class", .func = opt_missing_class},
|
1093
|
+
{.name = "missing_class=", .func = opt_missing_class_set},
|
1094
|
+
{.name = "omit_null", .func = opt_omit_null},
|
1095
|
+
{.name = "omit_null=", .func = opt_omit_null_set},
|
1096
|
+
{.name = "symbol_keys", .func = opt_symbol_keys},
|
1097
|
+
{.name = "symbol_keys=", .func = opt_symbol_keys_set},
|
1098
|
+
{.name = NULL},
|
1097
1099
|
};
|
1098
1100
|
|
1099
1101
|
for (op = opts; NULL != op->name; op++) {
|
@@ -1109,18 +1111,18 @@ static VALUE option(ojParser p, const char *key, VALUE value) {
|
|
1109
1111
|
///// the set up //////////////////////////////////////////////////////////////
|
1110
1112
|
|
1111
1113
|
void oj_init_usual(ojParser p, Usual d) {
|
1112
|
-
int
|
1114
|
+
int cap = 4096;
|
1113
1115
|
|
1114
|
-
d->vhead =
|
1116
|
+
d->vhead = OJ_R_ALLOC_N(VALUE, cap);
|
1115
1117
|
d->vend = d->vhead + cap;
|
1116
1118
|
d->vtail = d->vhead;
|
1117
1119
|
|
1118
|
-
d->khead =
|
1120
|
+
d->khead = OJ_R_ALLOC_N(union _key, cap);
|
1119
1121
|
d->kend = d->khead + cap;
|
1120
1122
|
d->ktail = d->khead;
|
1121
1123
|
|
1122
1124
|
cap = 256;
|
1123
|
-
d->chead =
|
1125
|
+
d->chead = OJ_R_ALLOC_N(struct _col, cap);
|
1124
1126
|
d->cend = d->chead + cap;
|
1125
1127
|
d->ctail = d->chead;
|
1126
1128
|
|
@@ -1201,7 +1203,7 @@ void oj_init_usual(ojParser p, Usual d) {
|
|
1201
1203
|
}
|
1202
1204
|
|
1203
1205
|
void oj_set_parser_usual(ojParser p) {
|
1204
|
-
Usual d =
|
1206
|
+
Usual d = OJ_R_ALLOC(struct _usual);
|
1205
1207
|
|
1206
1208
|
oj_init_usual(p, d);
|
1207
1209
|
}
|
data/ext/oj/usual.h
CHANGED
@@ -13,7 +13,7 @@ struct _ojParser;
|
|
13
13
|
typedef struct _col {
|
14
14
|
long vi; // value stack index
|
15
15
|
long ki; // key stack index if an hash else -1 for an array
|
16
|
-
} *
|
16
|
+
} *Col;
|
17
17
|
|
18
18
|
typedef union _key {
|
19
19
|
struct {
|
@@ -22,9 +22,9 @@ typedef union _key {
|
|
22
22
|
};
|
23
23
|
struct {
|
24
24
|
int16_t xlen; // should be the same as len
|
25
|
-
char
|
25
|
+
char *key;
|
26
26
|
};
|
27
|
-
} *
|
27
|
+
} *Key;
|
28
28
|
|
29
29
|
#define MISS_AUTO 'A'
|
30
30
|
#define MISS_RAISE 'R'
|
@@ -43,7 +43,7 @@ typedef struct _usual {
|
|
43
43
|
Key ktail;
|
44
44
|
Key kend;
|
45
45
|
|
46
|
-
VALUE (*get_key)(
|
46
|
+
VALUE (*get_key)(struct _ojParser *p, Key kp);
|
47
47
|
struct _cache *key_cache; // same as str_cache or sym_cache
|
48
48
|
struct _cache *str_cache;
|
49
49
|
struct _cache *sym_cache;
|
@@ -53,14 +53,14 @@ typedef struct _usual {
|
|
53
53
|
VALUE array_class;
|
54
54
|
VALUE hash_class;
|
55
55
|
|
56
|
-
char
|
56
|
+
char *create_id;
|
57
57
|
uint8_t create_id_len;
|
58
58
|
uint8_t cache_str;
|
59
59
|
uint8_t cache_xrate;
|
60
60
|
uint8_t miss_class;
|
61
61
|
bool cache_keys;
|
62
62
|
bool ignore_json_create;
|
63
|
-
} *
|
63
|
+
} *Usual;
|
64
64
|
|
65
65
|
// Initialize the parser with the usual delegate. If the usual delegate is
|
66
66
|
// wrapped then this function is called first and then the parser functions
|