oj 3.13.23 → 3.14.2
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 +16 -0
- data/README.md +2 -1
- data/ext/oj/buf.h +6 -5
- data/ext/oj/cache.c +11 -10
- data/ext/oj/cache8.c +3 -2
- data/ext/oj/circarray.c +6 -5
- data/ext/oj/compat.c +12 -31
- data/ext/oj/custom.c +16 -31
- data/ext/oj/dump.c +10 -13
- data/ext/oj/dump_compat.c +9 -19
- data/ext/oj/dump_object.c +8 -13
- data/ext/oj/dump_strict.c +8 -18
- data/ext/oj/extconf.rb +10 -2
- data/ext/oj/fast.c +31 -47
- data/ext/oj/intern.c +7 -5
- data/ext/oj/mem.c +324 -0
- data/ext/oj/mem.h +53 -0
- data/ext/oj/mimic_json.c +3 -2
- data/ext/oj/object.c +9 -13
- data/ext/oj/odd.c +7 -6
- data/ext/oj/oj.c +12 -5
- data/ext/oj/oj.h +6 -0
- data/ext/oj/parse.c +18 -13
- data/ext/oj/parser.c +7 -7
- data/ext/oj/rails.c +19 -28
- data/ext/oj/reader.c +4 -3
- data/ext/oj/reader.h +3 -1
- data/ext/oj/rxclass.c +5 -4
- data/ext/oj/saj.c +6 -5
- data/ext/oj/saj2.c +10 -5
- data/ext/oj/sparse.c +5 -4
- data/ext/oj/stream_writer.c +5 -4
- data/ext/oj/strict.c +4 -12
- data/ext/oj/string_writer.c +7 -6
- data/ext/oj/trace.h +16 -0
- data/ext/oj/usual.c +28 -27
- data/ext/oj/val_stack.h +4 -3
- data/ext/oj/wab.c +9 -21
- data/lib/oj/version.rb +1 -1
- data/pages/InstallOptions.md +20 -0
- data/test/foo.rb +46 -65
- data/test/perf_parser.rb +1 -0
- data/test/test_compat.rb +9 -0
- metadata +7 -3
data/ext/oj/parse.c
CHANGED
@@ -10,12 +10,17 @@
|
|
10
10
|
#include <string.h>
|
11
11
|
#include <unistd.h>
|
12
12
|
|
13
|
+
#include "mem.h"
|
13
14
|
#include "buf.h"
|
14
15
|
#include "encode.h"
|
15
16
|
#include "oj.h"
|
16
17
|
#include "rxclass.h"
|
17
18
|
#include "val_stack.h"
|
18
19
|
|
20
|
+
#ifdef OJ_USE_SSE4_2
|
21
|
+
#include <nmmintrin.h>
|
22
|
+
#endif
|
23
|
+
|
19
24
|
// Workaround in case INFINITY is not defined in math.h or if the OS is CentOS
|
20
25
|
#define OJ_INFINITY (1.0 / 0.0)
|
21
26
|
|
@@ -83,7 +88,7 @@ static void add_value(ParseInfo pi, VALUE rval) {
|
|
83
88
|
pi->hash_set_value(pi, parent, rval);
|
84
89
|
if (0 != parent->key && 0 < parent->klen &&
|
85
90
|
(parent->key < pi->json || pi->cur < parent->key)) {
|
86
|
-
|
91
|
+
OJ_R_FREE((char *)parent->key);
|
87
92
|
parent->key = 0;
|
88
93
|
}
|
89
94
|
parent->next = NEXT_HASH_COMMA;
|
@@ -232,7 +237,8 @@ static void read_escaped_str(ParseInfo pi, const char *start) {
|
|
232
237
|
|
233
238
|
for (s = pi->cur; '"' != *s;) {
|
234
239
|
const char *scanned = scan_func(s, pi->end);
|
235
|
-
if (scanned >= pi->end) {
|
240
|
+
if (scanned >= pi->end || '\0' == *scanned) {
|
241
|
+
//if (scanned >= pi->end) {
|
236
242
|
oj_set_error_at(pi,
|
237
243
|
oj_parse_error_class,
|
238
244
|
__FILE__,
|
@@ -241,7 +247,6 @@ static void read_escaped_str(ParseInfo pi, const char *start) {
|
|
241
247
|
buf_cleanup(&buf);
|
242
248
|
return;
|
243
249
|
}
|
244
|
-
|
245
250
|
buf_append_string(&buf, s, (size_t)(scanned - s));
|
246
251
|
s = scanned;
|
247
252
|
|
@@ -330,7 +335,7 @@ static void read_escaped_str(ParseInfo pi, const char *start) {
|
|
330
335
|
case NEXT_HASH_KEY:
|
331
336
|
if (Qundef == (parent->key_val = pi->hash_key(pi, buf.head, buf_len(&buf)))) {
|
332
337
|
parent->klen = buf_len(&buf);
|
333
|
-
parent->key =
|
338
|
+
parent->key = OJ_MALLOC(parent->klen + 1);
|
334
339
|
memcpy((char *)parent->key, buf.head, parent->klen);
|
335
340
|
*(char *)(parent->key + parent->klen) = '\0';
|
336
341
|
} else {
|
@@ -344,7 +349,7 @@ static void read_escaped_str(ParseInfo pi, const char *start) {
|
|
344
349
|
pi->hash_set_cstr(pi, parent, buf.head, buf_len(&buf), start);
|
345
350
|
if (0 != parent->key && 0 < parent->klen &&
|
346
351
|
(parent->key < pi->json || pi->cur < parent->key)) {
|
347
|
-
|
352
|
+
OJ_R_FREE((char *)parent->key);
|
348
353
|
parent->key = 0;
|
349
354
|
}
|
350
355
|
parent->next = NEXT_HASH_COMMA;
|
@@ -414,7 +419,7 @@ static void read_str(ParseInfo pi) {
|
|
414
419
|
pi->hash_set_cstr(pi, parent, str, pi->cur - str, str);
|
415
420
|
if (0 != parent->key && 0 < parent->klen &&
|
416
421
|
(parent->key < pi->json || pi->cur < parent->key)) {
|
417
|
-
|
422
|
+
OJ_R_FREE((char *)parent->key);
|
418
423
|
parent->key = 0;
|
419
424
|
}
|
420
425
|
parent->next = NEXT_HASH_COMMA;
|
@@ -613,7 +618,7 @@ static void read_num(ParseInfo pi) {
|
|
613
618
|
pi->hash_set_num(pi, parent, &ni);
|
614
619
|
if (0 != parent->key && 0 < parent->klen &&
|
615
620
|
(parent->key < pi->json || pi->cur < parent->key)) {
|
616
|
-
|
621
|
+
OJ_R_FREE((char *)parent->key);
|
617
622
|
parent->key = 0;
|
618
623
|
}
|
619
624
|
parent->next = NEXT_HASH_COMMA;
|
@@ -867,12 +872,12 @@ oj_num_as_value(NumInfo ni) {
|
|
867
872
|
buf[ni->len] = '\0';
|
868
873
|
rnum = rb_cstr_to_inum(buf, 10, 0);
|
869
874
|
} else {
|
870
|
-
char *buf =
|
875
|
+
char *buf = OJ_R_ALLOC_N(char, ni->len + 1);
|
871
876
|
|
872
877
|
memcpy(buf, ni->str, ni->len);
|
873
878
|
buf[ni->len] = '\0';
|
874
879
|
rnum = rb_cstr_to_inum(buf, 10, 0);
|
875
|
-
|
880
|
+
OJ_R_FREE(buf);
|
876
881
|
}
|
877
882
|
} else {
|
878
883
|
if (ni->neg) {
|
@@ -1073,12 +1078,12 @@ oj_pi_parse(int argc, VALUE *argv, ParseInfo pi, char *json, size_t len, int yie
|
|
1073
1078
|
size_t len = lseek(fd, 0, SEEK_END);
|
1074
1079
|
|
1075
1080
|
lseek(fd, 0, SEEK_SET);
|
1076
|
-
buf =
|
1081
|
+
buf = OJ_R_ALLOC_N(char, len + 1);
|
1077
1082
|
pi->json = buf;
|
1078
1083
|
pi->end = buf + len;
|
1079
1084
|
if (0 >= (cnt = read(fd, (char *)pi->json, len)) || cnt != (ssize_t)len) {
|
1080
1085
|
if (0 != buf) {
|
1081
|
-
|
1086
|
+
OJ_R_FREE(buf);
|
1082
1087
|
}
|
1083
1088
|
rb_raise(rb_eIOError, "failed to read from IO Object.");
|
1084
1089
|
}
|
@@ -1160,9 +1165,9 @@ CLEANUP:
|
|
1160
1165
|
oj_circ_array_free(pi->circ_array);
|
1161
1166
|
}
|
1162
1167
|
if (0 != buf) {
|
1163
|
-
|
1168
|
+
OJ_R_FREE(buf);
|
1164
1169
|
} else if (free_json) {
|
1165
|
-
|
1170
|
+
OJ_R_FREE(json);
|
1166
1171
|
}
|
1167
1172
|
stack_cleanup(&pi->stack);
|
1168
1173
|
if (pi->str_rx.head != oj_default_options.str_rx.head) {
|
data/ext/oj/parser.c
CHANGED
@@ -1148,7 +1148,7 @@ static void parser_free(void *ptr) {
|
|
1148
1148
|
if (NULL != p->free) {
|
1149
1149
|
p->free(p);
|
1150
1150
|
}
|
1151
|
-
|
1151
|
+
OJ_R_FREE(ptr);
|
1152
1152
|
}
|
1153
1153
|
|
1154
1154
|
static void parser_mark(void *ptr) {
|
@@ -1205,7 +1205,7 @@ static int opt_cb(VALUE rkey, VALUE value, VALUE ptr) {
|
|
1205
1205
|
* Oj::Parser.new(:usual, cache_keys: true).
|
1206
1206
|
*/
|
1207
1207
|
static VALUE parser_new(int argc, VALUE *argv, VALUE self) {
|
1208
|
-
ojParser p =
|
1208
|
+
ojParser p = OJ_R_ALLOC(struct _ojParser);
|
1209
1209
|
|
1210
1210
|
#if HAVE_RB_EXT_RACTOR_SAFE
|
1211
1211
|
// This doesn't seem to do anything.
|
@@ -1263,8 +1263,8 @@ static VALUE parser_new(int argc, VALUE *argv, VALUE self) {
|
|
1263
1263
|
// from this function. A delegate must be added before the parser can be
|
1264
1264
|
// used. Optionally oj_parser_set_options can be called if the options are not
|
1265
1265
|
// set directly.
|
1266
|
-
VALUE oj_parser_new() {
|
1267
|
-
ojParser p =
|
1266
|
+
VALUE oj_parser_new(void) {
|
1267
|
+
ojParser p = OJ_R_ALLOC(struct _ojParser);
|
1268
1268
|
|
1269
1269
|
#if HAVE_RB_EXT_RACTOR_SAFE
|
1270
1270
|
// This doesn't seem to do anything.
|
@@ -1499,7 +1499,7 @@ static VALUE usual_parser = Qundef;
|
|
1499
1499
|
*/
|
1500
1500
|
static VALUE parser_usual(VALUE self) {
|
1501
1501
|
if (Qundef == usual_parser) {
|
1502
|
-
ojParser p =
|
1502
|
+
ojParser p = OJ_R_ALLOC(struct _ojParser);
|
1503
1503
|
|
1504
1504
|
memset(p, 0, sizeof(struct _ojParser));
|
1505
1505
|
buf_init(&p->key);
|
@@ -1522,7 +1522,7 @@ static VALUE saj_parser = Qundef;
|
|
1522
1522
|
*/
|
1523
1523
|
static VALUE parser_saj(VALUE self) {
|
1524
1524
|
if (Qundef == saj_parser) {
|
1525
|
-
ojParser p =
|
1525
|
+
ojParser p = OJ_R_ALLOC(struct _ojParser);
|
1526
1526
|
|
1527
1527
|
memset(p, 0, sizeof(struct _ojParser));
|
1528
1528
|
buf_init(&p->key);
|
@@ -1544,7 +1544,7 @@ static VALUE validate_parser = Qundef;
|
|
1544
1544
|
*/
|
1545
1545
|
static VALUE parser_validate(VALUE self) {
|
1546
1546
|
if (Qundef == validate_parser) {
|
1547
|
-
ojParser p =
|
1547
|
+
ojParser p = OJ_R_ALLOC(struct _ojParser);
|
1548
1548
|
|
1549
1549
|
memset(p, 0, sizeof(struct _ojParser));
|
1550
1550
|
buf_init(&p->key);
|
data/ext/oj/rails.c
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
#include "rails.h"
|
5
5
|
|
6
|
+
#include "mem.h"
|
6
7
|
#include "code.h"
|
7
8
|
#include "encode.h"
|
8
9
|
#include "trace.h"
|
@@ -76,7 +77,7 @@ static ROptTable copy_opts(ROptTable src, ROptTable dest) {
|
|
76
77
|
if (NULL == src->table) {
|
77
78
|
dest->table = NULL;
|
78
79
|
} else {
|
79
|
-
dest->table =
|
80
|
+
dest->table = OJ_R_ALLOC_N(struct _rOpt, dest->alen);
|
80
81
|
memcpy(dest->table, src->table, sizeof(struct _rOpt) * dest->alen);
|
81
82
|
}
|
82
83
|
return NULL;
|
@@ -198,7 +199,7 @@ static void dump_enumerable(VALUE obj, int depth, Out out, bool as_ok) {
|
|
198
199
|
}
|
199
200
|
|
200
201
|
static void dump_bigdecimal(VALUE obj, int depth, Out out, bool as_ok) {
|
201
|
-
volatile VALUE rstr =
|
202
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
202
203
|
const char * str = RSTRING_PTR(rstr);
|
203
204
|
|
204
205
|
if ('I' == *str || 'N' == *str || ('-' == *str && 'I' == str[1])) {
|
@@ -345,7 +346,7 @@ static void dump_timewithzone(VALUE obj, int depth, Out out, bool as_ok) {
|
|
345
346
|
}
|
346
347
|
|
347
348
|
static void dump_to_s(VALUE obj, int depth, Out out, bool as_ok) {
|
348
|
-
volatile VALUE rstr =
|
349
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
349
350
|
|
350
351
|
oj_dump_cstr(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), 0, 0, out);
|
351
352
|
}
|
@@ -373,11 +374,11 @@ static StrLen columns_array(VALUE rcols, int *ccnt) {
|
|
373
374
|
int cnt = (int)RARRAY_LEN(rcols);
|
374
375
|
|
375
376
|
*ccnt = cnt;
|
376
|
-
cols =
|
377
|
+
cols = OJ_R_ALLOC_N(struct _strLen, cnt);
|
377
378
|
for (i = 0, cp = cols; i < cnt; i++, cp++) {
|
378
379
|
v = RARRAY_AREF(rcols, i);
|
379
380
|
if (T_STRING != rb_type(v)) {
|
380
|
-
v =
|
381
|
+
v = oj_safe_string_convert(v);
|
381
382
|
}
|
382
383
|
cp->str = StringValuePtr(v);
|
383
384
|
cp->len = (int)RSTRING_LEN(v);
|
@@ -481,7 +482,7 @@ static void dump_activerecord_result(VALUE obj, int depth, Out out, bool as_ok)
|
|
481
482
|
*out->cur++ = ',';
|
482
483
|
}
|
483
484
|
}
|
484
|
-
|
485
|
+
OJ_R_FREE(cols);
|
485
486
|
size = depth * out->indent + 1;
|
486
487
|
assure_size(out, size);
|
487
488
|
if (out->opts->dump_opts.use) {
|
@@ -517,9 +518,7 @@ static void dump_as_string(VALUE obj, int depth, Out out, bool as_ok) {
|
|
517
518
|
static void dump_as_json(VALUE obj, int depth, Out out, bool as_ok) {
|
518
519
|
volatile VALUE ja;
|
519
520
|
|
520
|
-
|
521
|
-
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
|
522
|
-
}
|
521
|
+
TRACE(out->opts->trace, "as_json", obj, depth + 1, TraceRubyIn);
|
523
522
|
// Some classes elect to not take an options argument so check the arity
|
524
523
|
// of as_json.
|
525
524
|
if (0 == rb_obj_method_arity(obj, oj_as_json_id)) {
|
@@ -527,9 +526,7 @@ static void dump_as_json(VALUE obj, int depth, Out out, bool as_ok) {
|
|
527
526
|
} else {
|
528
527
|
ja = rb_funcall2(obj, oj_as_json_id, out->argc, out->argv);
|
529
528
|
}
|
530
|
-
|
531
|
-
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
|
532
|
-
}
|
529
|
+
TRACE(out->opts->trace, "as_json", obj, depth + 1, TraceRubyOut);
|
533
530
|
|
534
531
|
out->argc = 0;
|
535
532
|
if (ja == obj || !as_ok) {
|
@@ -587,11 +584,11 @@ static ROpt create_opt(ROptTable rot, VALUE clas) {
|
|
587
584
|
rot->len++;
|
588
585
|
if (NULL == rot->table) {
|
589
586
|
rot->alen = 256;
|
590
|
-
rot->table =
|
587
|
+
rot->table = OJ_R_ALLOC_N(struct _rOpt, rot->alen);
|
591
588
|
memset(rot->table, 0, sizeof(struct _rOpt) * rot->alen);
|
592
589
|
} else if (rot->alen <= rot->len) {
|
593
590
|
rot->alen *= 2;
|
594
|
-
|
591
|
+
OJ_R_REALLOC_N(rot->table, struct _rOpt, rot->alen);
|
595
592
|
memset(rot->table + olen, 0, sizeof(struct _rOpt) * olen);
|
596
593
|
}
|
597
594
|
if (0 == olen) {
|
@@ -644,9 +641,9 @@ static void encoder_free(void *ptr) {
|
|
644
641
|
Encoder e = (Encoder)ptr;
|
645
642
|
|
646
643
|
if (NULL != e->ropts.table) {
|
647
|
-
|
644
|
+
OJ_R_FREE(e->ropts.table);
|
648
645
|
}
|
649
|
-
|
646
|
+
OJ_R_FREE(ptr);
|
650
647
|
}
|
651
648
|
}
|
652
649
|
|
@@ -667,7 +664,7 @@ static void encoder_mark(void *ptr) {
|
|
667
664
|
* - *options* [_Hash_] formatting options
|
668
665
|
*/
|
669
666
|
static VALUE encoder_new(int argc, VALUE *argv, VALUE self) {
|
670
|
-
Encoder e =
|
667
|
+
Encoder e = OJ_R_ALLOC(struct _encoder);
|
671
668
|
|
672
669
|
e->opts = oj_default_options;
|
673
670
|
e->arg = Qnil;
|
@@ -1208,7 +1205,7 @@ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1208
1205
|
} else if (oj_rails_float_opt) {
|
1209
1206
|
cnt = oj_dump_float_printf(buf, sizeof(buf), obj, d, "%0.16g");
|
1210
1207
|
} else {
|
1211
|
-
volatile VALUE rstr =
|
1208
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
1212
1209
|
|
1213
1210
|
strcpy(buf, RSTRING_PTR(rstr));
|
1214
1211
|
cnt = (int)RSTRING_LEN(rstr);
|
@@ -1301,7 +1298,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
1301
1298
|
return ST_CONTINUE;
|
1302
1299
|
}
|
1303
1300
|
if (rtype != T_STRING && rtype != T_SYMBOL) {
|
1304
|
-
key =
|
1301
|
+
key = oj_safe_string_convert(key);
|
1305
1302
|
rtype = rb_type(key);
|
1306
1303
|
}
|
1307
1304
|
if (!out->opts->dump_opts.use) {
|
@@ -1464,9 +1461,7 @@ static DumpFunc rails_funcs[] = {
|
|
1464
1461
|
static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok) {
|
1465
1462
|
int type = rb_type(obj);
|
1466
1463
|
|
1467
|
-
|
1468
|
-
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
1469
|
-
}
|
1464
|
+
TRACE(out->opts->trace, "dump", obj, depth, TraceIn);
|
1470
1465
|
if (MAX_DEPTH < depth) {
|
1471
1466
|
rb_raise(rb_eNoMemError, "Too deeply nested.\n");
|
1472
1467
|
}
|
@@ -1475,16 +1470,12 @@ static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1475
1470
|
|
1476
1471
|
if (NULL != f) {
|
1477
1472
|
f(obj, depth, out, as_ok);
|
1478
|
-
|
1479
|
-
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
1480
|
-
}
|
1473
|
+
TRACE(out->opts->trace, "dump", obj, depth, TraceOut);
|
1481
1474
|
return;
|
1482
1475
|
}
|
1483
1476
|
}
|
1484
1477
|
oj_dump_nil(Qnil, depth, out, false);
|
1485
|
-
|
1486
|
-
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
1487
|
-
}
|
1478
|
+
TRACE(out->opts->trace, "dump", Qnil, depth, TraceOut);
|
1488
1479
|
}
|
1489
1480
|
|
1490
1481
|
void oj_dump_rails_val(VALUE obj, int depth, Out out) {
|
data/ext/oj/reader.c
CHANGED
@@ -14,6 +14,7 @@
|
|
14
14
|
#include <time.h>
|
15
15
|
#include <unistd.h>
|
16
16
|
|
17
|
+
#include "mem.h"
|
17
18
|
#include "oj.h"
|
18
19
|
#include "reader.h"
|
19
20
|
#include "ruby.h"
|
@@ -75,7 +76,7 @@ void oj_reader_init(Reader reader, VALUE io, int fd, bool to_s) {
|
|
75
76
|
reader->read_func = read_from_io;
|
76
77
|
reader->io = io;
|
77
78
|
} else if (to_s) {
|
78
|
-
volatile VALUE rstr =
|
79
|
+
volatile VALUE rstr = oj_safe_string_convert(io);
|
79
80
|
|
80
81
|
reader->read_func = 0;
|
81
82
|
reader->in_str = StringValuePtr(rstr);
|
@@ -107,10 +108,10 @@ int oj_reader_read(Reader reader) {
|
|
107
108
|
size_t size = reader->end - reader->head + BUF_PAD;
|
108
109
|
|
109
110
|
if (reader->head == reader->base) {
|
110
|
-
reader->head =
|
111
|
+
reader->head = OJ_R_ALLOC_N(char, size * 2);
|
111
112
|
memcpy((char *)reader->head, old, size);
|
112
113
|
} else {
|
113
|
-
|
114
|
+
OJ_R_REALLOC_N(reader->head, char, size * 2);
|
114
115
|
}
|
115
116
|
reader->free_head = 1;
|
116
117
|
reader->end = reader->head + size * 2 - BUF_PAD;
|
data/ext/oj/reader.h
CHANGED
@@ -4,6 +4,8 @@
|
|
4
4
|
#ifndef OJ_READER_H
|
5
5
|
#define OJ_READER_H
|
6
6
|
|
7
|
+
#include "mem.h"
|
8
|
+
|
7
9
|
typedef struct _reader {
|
8
10
|
char base[0x00001000];
|
9
11
|
char *head;
|
@@ -114,7 +116,7 @@ static inline int reader_expect(Reader reader, const char *s) {
|
|
114
116
|
|
115
117
|
static inline void reader_cleanup(Reader reader) {
|
116
118
|
if (reader->free_head && 0 != reader->head) {
|
117
|
-
|
119
|
+
OJ_R_FREE((char *)reader->head);
|
118
120
|
reader->head = 0;
|
119
121
|
reader->free_head = 0;
|
120
122
|
}
|
data/ext/oj/rxclass.c
CHANGED
@@ -10,6 +10,7 @@
|
|
10
10
|
#include <regex.h>
|
11
11
|
#endif
|
12
12
|
|
13
|
+
#include "mem.h"
|
13
14
|
#include "rxclass.h"
|
14
15
|
|
15
16
|
typedef struct _rxC {
|
@@ -37,13 +38,13 @@ void oj_rxclass_cleanup(RxClass rc) {
|
|
37
38
|
if (Qnil == rxc->rrx) {
|
38
39
|
regfree(&rxc->rx);
|
39
40
|
}
|
40
|
-
|
41
|
+
OJ_R_FREE(rxc);
|
41
42
|
#endif
|
42
43
|
}
|
43
44
|
}
|
44
45
|
|
45
46
|
void oj_rxclass_rappend(RxClass rc, VALUE rx, VALUE clas) {
|
46
|
-
RxC rxc =
|
47
|
+
RxC rxc = OJ_R_ALLOC_N(struct _rxC, 1);
|
47
48
|
|
48
49
|
memset(rxc, 0, sizeof(struct _rxC));
|
49
50
|
rxc->rrx = rx;
|
@@ -70,7 +71,7 @@ int oj_rxclass_append(RxClass rc, const char *expr, VALUE clas) {
|
|
70
71
|
(unsigned long)sizeof(rxc->src));
|
71
72
|
return EINVAL;
|
72
73
|
}
|
73
|
-
rxc =
|
74
|
+
rxc = OJ_R_ALLOC_N(struct _rxC, 1);
|
74
75
|
rxc->next = 0;
|
75
76
|
rxc->clas = clas;
|
76
77
|
|
@@ -80,7 +81,7 @@ int oj_rxclass_append(RxClass rc, const char *expr, VALUE clas) {
|
|
80
81
|
rxc->rrx = Qnil;
|
81
82
|
if (0 != (err = regcomp(&rxc->rx, expr, flags))) {
|
82
83
|
regerror(err, &rxc->rx, rc->err, sizeof(rc->err));
|
83
|
-
|
84
|
+
OJ_FREE(rxc);
|
84
85
|
return err;
|
85
86
|
}
|
86
87
|
#endif
|
data/ext/oj/saj.c
CHANGED
@@ -14,6 +14,7 @@
|
|
14
14
|
// Workaround in case INFINITY is not defined in math.h or if the OS is CentOS
|
15
15
|
#define OJ_INFINITY (1.0 / 0.0)
|
16
16
|
|
17
|
+
#include "mem.h"
|
17
18
|
#include "encode.h"
|
18
19
|
#include "oj.h"
|
19
20
|
|
@@ -631,7 +632,7 @@ oj_saj_parse(int argc, VALUE *argv, VALUE self) {
|
|
631
632
|
if (rb_type(input) == T_STRING) {
|
632
633
|
// the json string gets modified so make a copy of it
|
633
634
|
len = RSTRING_LEN(input) + 1;
|
634
|
-
json =
|
635
|
+
json = OJ_R_ALLOC_N(char, len);
|
635
636
|
strcpy(json, StringValuePtr(input));
|
636
637
|
} else {
|
637
638
|
VALUE clas = rb_obj_class(input);
|
@@ -640,7 +641,7 @@ oj_saj_parse(int argc, VALUE *argv, VALUE self) {
|
|
640
641
|
if (oj_stringio_class == clas) {
|
641
642
|
s = rb_funcall2(input, oj_string_id, 0, 0);
|
642
643
|
len = RSTRING_LEN(s) + 1;
|
643
|
-
json =
|
644
|
+
json = OJ_R_ALLOC_N(char, len);
|
644
645
|
strcpy(json, rb_string_value_cstr((VALUE *)&s));
|
645
646
|
#if !IS_WINDOWS
|
646
647
|
} else if (rb_cFile == clas && 0 == FIX2INT(rb_funcall(input, oj_pos_id, 0))) {
|
@@ -649,7 +650,7 @@ oj_saj_parse(int argc, VALUE *argv, VALUE self) {
|
|
649
650
|
|
650
651
|
len = lseek(fd, 0, SEEK_END);
|
651
652
|
lseek(fd, 0, SEEK_SET);
|
652
|
-
json =
|
653
|
+
json = OJ_R_ALLOC_N(char, len + 1);
|
653
654
|
if (0 >= (cnt = read(fd, json, len)) || cnt != (ssize_t)len) {
|
654
655
|
rb_raise(rb_eIOError, "failed to read from IO Object.");
|
655
656
|
}
|
@@ -658,14 +659,14 @@ oj_saj_parse(int argc, VALUE *argv, VALUE self) {
|
|
658
659
|
} else if (rb_respond_to(input, oj_read_id)) {
|
659
660
|
s = rb_funcall2(input, oj_read_id, 0, 0);
|
660
661
|
len = RSTRING_LEN(s) + 1;
|
661
|
-
json =
|
662
|
+
json = OJ_R_ALLOC_N(char, len);
|
662
663
|
strcpy(json, rb_string_value_cstr((VALUE *)&s));
|
663
664
|
} else {
|
664
665
|
rb_raise(rb_eArgError, "saj_parse() expected a String or IO Object.");
|
665
666
|
}
|
666
667
|
}
|
667
668
|
saj_parse(*argv, json);
|
668
|
-
|
669
|
+
OJ_R_FREE(json);
|
669
670
|
|
670
671
|
return Qnil;
|
671
672
|
}
|
data/ext/oj/saj2.c
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
// Copyright (c) 2021, Peter Ohler, All rights reserved.
|
2
2
|
|
3
|
+
#include "mem.h"
|
3
4
|
#include "cache.h"
|
4
5
|
#include "oj.h"
|
5
6
|
#include "parser.h"
|
@@ -24,7 +25,7 @@ static void push_key(Saj d, VALUE key) {
|
|
24
25
|
size_t off = d->tail - d->keys;
|
25
26
|
|
26
27
|
d->klen += d->klen / 2;
|
27
|
-
|
28
|
+
OJ_R_REALLOC_N(d->keys, VALUE, d->klen);
|
28
29
|
d->tail = d->keys + off;
|
29
30
|
}
|
30
31
|
*d->tail = key;
|
@@ -546,10 +547,10 @@ static void dfree(ojParser p) {
|
|
546
547
|
Saj d = (Saj)p->ctx;
|
547
548
|
|
548
549
|
if (NULL != d->keys) {
|
549
|
-
|
550
|
+
OJ_R_FREE(d->keys);
|
550
551
|
}
|
551
552
|
cache_free(d->str_cache);
|
552
|
-
|
553
|
+
OJ_R_FREE(p->ctx);
|
553
554
|
}
|
554
555
|
|
555
556
|
static void mark(ojParser p) {
|
@@ -576,9 +577,13 @@ static VALUE form_str(const char *str, size_t len) {
|
|
576
577
|
|
577
578
|
void oj_init_saj(ojParser p, Saj d) {
|
578
579
|
d->klen = 256;
|
579
|
-
d->keys =
|
580
|
+
d->keys = OJ_R_ALLOC_N(VALUE, d->klen);
|
580
581
|
d->tail = d->keys;
|
582
|
+
d->handler = Qnil;
|
581
583
|
d->str_cache = cache_create(0, form_str, true, false);
|
584
|
+
d->cache_str = 16;
|
585
|
+
d->cache_keys = true;
|
586
|
+
d->thread_safe = false;
|
582
587
|
|
583
588
|
p->ctx = (void *)d;
|
584
589
|
reset(p);
|
@@ -590,7 +595,7 @@ void oj_init_saj(ojParser p, Saj d) {
|
|
590
595
|
}
|
591
596
|
|
592
597
|
void oj_set_parser_saj(ojParser p) {
|
593
|
-
Saj d =
|
598
|
+
Saj d = OJ_R_ALLOC(struct _saj);
|
594
599
|
|
595
600
|
oj_init_saj(p, d);
|
596
601
|
}
|
data/ext/oj/sparse.c
CHANGED
@@ -7,6 +7,7 @@
|
|
7
7
|
#include <string.h>
|
8
8
|
#include <unistd.h>
|
9
9
|
|
10
|
+
#include "mem.h"
|
10
11
|
#include "buf.h"
|
11
12
|
#include "encode.h"
|
12
13
|
#include "intern.h" // for oj_strndup()
|
@@ -71,7 +72,7 @@ static void add_value(ParseInfo pi, VALUE rval) {
|
|
71
72
|
case NEXT_HASH_VALUE:
|
72
73
|
pi->hash_set_value(pi, parent, rval);
|
73
74
|
if (parent->kalloc) {
|
74
|
-
|
75
|
+
OJ_R_FREE((char *)parent->key);
|
75
76
|
}
|
76
77
|
parent->key = 0;
|
77
78
|
parent->kalloc = 0;
|
@@ -110,7 +111,7 @@ static void add_num_value(ParseInfo pi, NumInfo ni) {
|
|
110
111
|
case NEXT_HASH_VALUE:
|
111
112
|
pi->hash_set_num(pi, parent, ni);
|
112
113
|
if (parent->kalloc) {
|
113
|
-
|
114
|
+
OJ_R_FREE((char *)parent->key);
|
114
115
|
}
|
115
116
|
parent->key = 0;
|
116
117
|
parent->kalloc = 0;
|
@@ -315,7 +316,7 @@ static void read_escaped_str(ParseInfo pi) {
|
|
315
316
|
case NEXT_HASH_VALUE:
|
316
317
|
pi->hash_set_cstr(pi, parent, buf.head, buf_len(&buf), pi->rd.str);
|
317
318
|
if (parent->kalloc) {
|
318
|
-
|
319
|
+
OJ_R_FREE((char *)parent->key);
|
319
320
|
}
|
320
321
|
parent->key = 0;
|
321
322
|
parent->kalloc = 0;
|
@@ -386,7 +387,7 @@ static void read_str(ParseInfo pi) {
|
|
386
387
|
case NEXT_HASH_VALUE:
|
387
388
|
pi->hash_set_cstr(pi, parent, pi->rd.str, pi->rd.tail - pi->rd.str - 1, pi->rd.str);
|
388
389
|
if (parent->kalloc) {
|
389
|
-
|
390
|
+
OJ_R_FREE((char *)parent->key);
|
390
391
|
}
|
391
392
|
parent->key = 0;
|
392
393
|
parent->kalloc = 0;
|
data/ext/oj/stream_writer.c
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
#include <errno.h>
|
5
5
|
#include <ruby.h>
|
6
6
|
|
7
|
+
#include "mem.h"
|
7
8
|
#include "encode.h"
|
8
9
|
|
9
10
|
extern VALUE Oj;
|
@@ -15,9 +16,9 @@ static void stream_writer_free(void *ptr) {
|
|
15
16
|
return;
|
16
17
|
}
|
17
18
|
sw = (StreamWriter)ptr;
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
OJ_R_FREE(sw->sw.out.buf);
|
20
|
+
OJ_R_FREE(sw->sw.types);
|
21
|
+
OJ_R_FREE(ptr);
|
21
22
|
}
|
22
23
|
|
23
24
|
static void stream_writer_reset_buf(StreamWriter sw) {
|
@@ -91,7 +92,7 @@ static VALUE stream_writer_new(int argc, VALUE *argv, VALUE self) {
|
|
91
92
|
} else {
|
92
93
|
rb_raise(rb_eArgError, "expected an IO Object.");
|
93
94
|
}
|
94
|
-
sw =
|
95
|
+
sw = OJ_R_ALLOC(struct _streamWriter);
|
95
96
|
if (2 == argc && T_HASH == rb_type(argv[1])) {
|
96
97
|
volatile VALUE v;
|
97
98
|
int buf_size = 0;
|
data/ext/oj/strict.c
CHANGED
@@ -50,15 +50,11 @@ VALUE oj_calc_hash_key(ParseInfo pi, Val parent) {
|
|
50
50
|
}
|
51
51
|
|
52
52
|
static void hash_end(ParseInfo pi) {
|
53
|
-
|
54
|
-
oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
|
55
|
-
}
|
53
|
+
TRACE_PARSE_HASH_END(pi->options.trace, pi);
|
56
54
|
}
|
57
55
|
|
58
56
|
static void array_end(ParseInfo pi) {
|
59
|
-
|
60
|
-
oj_trace_parse_array_end(pi, __FILE__, __LINE__);
|
61
|
-
}
|
57
|
+
TRACE_PARSE_ARRAY_END(pi->options.trace, pi);
|
62
58
|
}
|
63
59
|
|
64
60
|
static VALUE noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
|
@@ -95,9 +91,7 @@ static VALUE start_hash(ParseInfo pi) {
|
|
95
91
|
if (Qnil != pi->options.hash_class) {
|
96
92
|
return rb_class_new_instance(0, NULL, pi->options.hash_class);
|
97
93
|
}
|
98
|
-
|
99
|
-
oj_trace_parse_in("start_hash", pi, __FILE__, __LINE__);
|
100
|
-
}
|
94
|
+
TRACE_PARSE_IN(pi->options.trace, "start_hash", pi);
|
101
95
|
return rb_hash_new();
|
102
96
|
}
|
103
97
|
|
@@ -137,9 +131,7 @@ static void hash_set_value(ParseInfo pi, Val parent, VALUE value) {
|
|
137
131
|
}
|
138
132
|
|
139
133
|
static VALUE start_array(ParseInfo pi) {
|
140
|
-
|
141
|
-
oj_trace_parse_in("start_array", pi, __FILE__, __LINE__);
|
142
|
-
}
|
134
|
+
TRACE_PARSE_IN(pi->options.trace, "start_array", pi);
|
143
135
|
return rb_ary_new();
|
144
136
|
}
|
145
137
|
|