oj 3.16.3 → 3.17.4
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 +99 -0
- data/README.md +0 -16
- data/ext/oj/compat.c +3 -3
- data/ext/oj/custom.c +17 -11
- data/ext/oj/dump.c +619 -88
- data/ext/oj/dump.h +9 -2
- data/ext/oj/dump_compat.c +16 -9
- data/ext/oj/dump_leaf.c +1 -1
- data/ext/oj/dump_object.c +52 -27
- data/ext/oj/dump_strict.c +20 -14
- data/ext/oj/extconf.rb +11 -9
- data/ext/oj/fast.c +90 -65
- data/ext/oj/intern.c +1 -1
- data/ext/oj/mimic_json.c +14 -8
- data/ext/oj/object.c +18 -12
- data/ext/oj/oj.c +426 -11
- data/ext/oj/oj.h +60 -52
- data/ext/oj/parse.c +252 -48
- data/ext/oj/parse.h +0 -1
- data/ext/oj/parser.c +179 -47
- data/ext/oj/parser.h +4 -2
- data/ext/oj/rails.c +57 -36
- data/ext/oj/reader.c +17 -5
- data/ext/oj/rxclass.c +17 -1
- data/ext/oj/rxclass.h +2 -1
- data/ext/oj/safe.c +230 -0
- data/ext/oj/safe.h +79 -0
- data/ext/oj/saj.c +55 -20
- data/ext/oj/scp.c +3 -6
- data/ext/oj/simd.h +219 -0
- data/ext/oj/sparse.c +15 -3
- data/ext/oj/stream_writer.c +19 -14
- data/ext/oj/strict.c +2 -4
- data/ext/oj/string_writer.c +26 -14
- data/ext/oj/usual.c +37 -35
- data/ext/oj/wab.c +5 -4
- data/lib/oj/mimic.rb +1 -5
- data/lib/oj/schandler.rb +5 -4
- data/lib/oj/version.rb +1 -1
- data/pages/Encoding.md +1 -1
- metadata +22 -100
- data/test/_test_active.rb +0 -75
- data/test/_test_active_mimic.rb +0 -95
- data/test/_test_mimic_rails.rb +0 -123
- data/test/activerecord/result_test.rb +0 -31
- data/test/activesupport6/abstract_unit.rb +0 -44
- data/test/activesupport6/decoding_test.rb +0 -133
- data/test/activesupport6/encoding_test.rb +0 -507
- data/test/activesupport6/encoding_test_cases.rb +0 -98
- data/test/activesupport6/test_common.rb +0 -17
- data/test/activesupport6/test_helper.rb +0 -163
- data/test/activesupport6/time_zone_test_helpers.rb +0 -39
- data/test/activesupport7/abstract_unit.rb +0 -49
- data/test/activesupport7/decoding_test.rb +0 -125
- data/test/activesupport7/encoding_test.rb +0 -486
- data/test/activesupport7/encoding_test_cases.rb +0 -104
- data/test/activesupport7/time_zone_test_helpers.rb +0 -47
- data/test/files.rb +0 -29
- data/test/foo.rb +0 -14
- data/test/helper.rb +0 -39
- data/test/isolated/shared.rb +0 -309
- data/test/isolated/test_mimic_after.rb +0 -13
- data/test/isolated/test_mimic_alone.rb +0 -12
- data/test/isolated/test_mimic_as_json.rb +0 -45
- data/test/isolated/test_mimic_before.rb +0 -13
- data/test/isolated/test_mimic_define.rb +0 -28
- data/test/isolated/test_mimic_rails_after.rb +0 -22
- data/test/isolated/test_mimic_rails_before.rb +0 -21
- data/test/isolated/test_mimic_redefine.rb +0 -15
- data/test/json_gem/json_addition_test.rb +0 -216
- data/test/json_gem/json_common_interface_test.rb +0 -155
- data/test/json_gem/json_encoding_test.rb +0 -107
- data/test/json_gem/json_ext_parser_test.rb +0 -21
- data/test/json_gem/json_fixtures_test.rb +0 -36
- data/test/json_gem/json_generator_test.rb +0 -413
- data/test/json_gem/json_generic_object_test.rb +0 -90
- data/test/json_gem/json_parser_test.rb +0 -477
- data/test/json_gem/json_string_matching_test.rb +0 -42
- data/test/json_gem/test_helper.rb +0 -30
- data/test/mem.rb +0 -34
- data/test/perf.rb +0 -102
- data/test/perf_compat.rb +0 -128
- data/test/perf_dump.rb +0 -50
- data/test/perf_fast.rb +0 -162
- data/test/perf_file.rb +0 -62
- data/test/perf_object.rb +0 -134
- data/test/perf_once.rb +0 -59
- data/test/perf_parser.rb +0 -183
- data/test/perf_saj.rb +0 -101
- data/test/perf_scp.rb +0 -140
- data/test/perf_simple.rb +0 -289
- data/test/perf_strict.rb +0 -137
- data/test/perf_wab.rb +0 -129
- data/test/prec.rb +0 -23
- data/test/sample/change.rb +0 -13
- data/test/sample/dir.rb +0 -18
- data/test/sample/doc.rb +0 -35
- data/test/sample/file.rb +0 -47
- data/test/sample/group.rb +0 -15
- data/test/sample/hasprops.rb +0 -15
- data/test/sample/layer.rb +0 -11
- data/test/sample/line.rb +0 -20
- data/test/sample/oval.rb +0 -10
- data/test/sample/rect.rb +0 -9
- data/test/sample/shape.rb +0 -34
- data/test/sample/text.rb +0 -19
- data/test/sample.rb +0 -54
- data/test/sample_json.rb +0 -37
- data/test/test_compat.rb +0 -567
- data/test/test_custom.rb +0 -555
- data/test/test_debian.rb +0 -50
- data/test/test_fast.rb +0 -526
- data/test/test_file.rb +0 -250
- data/test/test_gc.rb +0 -60
- data/test/test_generate.rb +0 -21
- data/test/test_hash.rb +0 -39
- data/test/test_integer_range.rb +0 -72
- data/test/test_null.rb +0 -376
- data/test/test_object.rb +0 -1030
- data/test/test_parser.rb +0 -11
- data/test/test_parser_debug.rb +0 -27
- data/test/test_parser_saj.rb +0 -337
- data/test/test_parser_usual.rb +0 -227
- data/test/test_rails.rb +0 -35
- data/test/test_saj.rb +0 -188
- data/test/test_scp.rb +0 -431
- data/test/test_strict.rb +0 -441
- data/test/test_various.rb +0 -801
- data/test/test_wab.rb +0 -311
- data/test/test_writer.rb +0 -380
- data/test/tests.rb +0 -33
- data/test/tests_mimic.rb +0 -23
- data/test/tests_mimic_addition.rb +0 -16
data/ext/oj/dump.h
CHANGED
|
@@ -7,12 +7,17 @@
|
|
|
7
7
|
#include <ruby.h>
|
|
8
8
|
|
|
9
9
|
#include "oj.h"
|
|
10
|
+
#include "simd.h"
|
|
10
11
|
|
|
11
12
|
#define MAX_DEPTH 1000
|
|
12
13
|
|
|
13
14
|
// Extra padding at end of buffer.
|
|
14
15
|
#define BUFFER_EXTRA 64
|
|
15
16
|
|
|
17
|
+
#ifdef HAVE_SIMD_NEON
|
|
18
|
+
extern void initialize_neon(void);
|
|
19
|
+
#endif /* HAVE_SIMD_NEON */
|
|
20
|
+
|
|
16
21
|
extern void oj_dump_nil(VALUE obj, int depth, Out out, bool as_ok);
|
|
17
22
|
extern void oj_dump_true(VALUE obj, int depth, Out out, bool as_ok);
|
|
18
23
|
extern void oj_dump_false(VALUE obj, int depth, Out out, bool as_ok);
|
|
@@ -30,7 +35,7 @@ extern void oj_dump_xml_time(VALUE obj, Out out);
|
|
|
30
35
|
extern void oj_dump_time(VALUE obj, Out out, int withZone);
|
|
31
36
|
extern void oj_dump_obj_to_s(VALUE obj, Out out);
|
|
32
37
|
|
|
33
|
-
extern const char *oj_nan_str(VALUE obj, int opt, int mode, bool plus,
|
|
38
|
+
extern const char *oj_nan_str(VALUE obj, int opt, int mode, bool plus, size_t *lenp);
|
|
34
39
|
|
|
35
40
|
// initialize an out buffer with the provided stack allocated memory
|
|
36
41
|
extern void oj_out_init(Out out);
|
|
@@ -53,10 +58,12 @@ extern void oj_dump_raw_json(VALUE obj, int depth, Out out);
|
|
|
53
58
|
extern VALUE oj_add_to_json(int argc, VALUE *argv, VALUE self);
|
|
54
59
|
extern VALUE oj_remove_to_json(int argc, VALUE *argv, VALUE self);
|
|
55
60
|
|
|
56
|
-
extern
|
|
61
|
+
extern size_t oj_dump_float_printf(char *buf, size_t blen, VALUE obj, double d, const char *format);
|
|
57
62
|
|
|
58
63
|
extern time_t oj_sec_from_time_hard_way(VALUE obj);
|
|
59
64
|
|
|
65
|
+
extern bool oj_key_skip(VALUE key, const char *only, const char *except);
|
|
66
|
+
|
|
60
67
|
inline static void assure_size(Out out, size_t len) {
|
|
61
68
|
if (out->end - out->cur <= (long)len) {
|
|
62
69
|
oj_grow_out(out, len);
|
data/ext/oj/dump_compat.c
CHANGED
|
@@ -103,7 +103,7 @@ static void dump_values_array(VALUE *values, int depth, Out out) {
|
|
|
103
103
|
static void dump_to_json(VALUE obj, Out out) {
|
|
104
104
|
volatile VALUE rs;
|
|
105
105
|
const char *s;
|
|
106
|
-
|
|
106
|
+
size_t len;
|
|
107
107
|
|
|
108
108
|
TRACE(out->opts->trace, "to_json", obj, 0, TraceRubyIn);
|
|
109
109
|
if (0 == rb_obj_method_arity(obj, oj_to_json_id)) {
|
|
@@ -115,7 +115,7 @@ static void dump_to_json(VALUE obj, Out out) {
|
|
|
115
115
|
|
|
116
116
|
StringValue(rs);
|
|
117
117
|
s = RSTRING_PTR(rs);
|
|
118
|
-
len =
|
|
118
|
+
len = RSTRING_LEN(rs);
|
|
119
119
|
|
|
120
120
|
assure_size(out, len + 1);
|
|
121
121
|
APPEND_CHARS(out->cur, s, len);
|
|
@@ -124,7 +124,8 @@ static void dump_to_json(VALUE obj, Out out) {
|
|
|
124
124
|
|
|
125
125
|
static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
|
126
126
|
size_t size;
|
|
127
|
-
|
|
127
|
+
size_t i;
|
|
128
|
+
size_t cnt;
|
|
128
129
|
int d2 = depth + 1;
|
|
129
130
|
long id = oj_check_circular(a, out);
|
|
130
131
|
|
|
@@ -136,7 +137,7 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
|
|
136
137
|
dump_to_json(a, out);
|
|
137
138
|
return;
|
|
138
139
|
}
|
|
139
|
-
cnt =
|
|
140
|
+
cnt = RARRAY_LEN(a);
|
|
140
141
|
*out->cur++ = '[';
|
|
141
142
|
assure_size(out, 2);
|
|
142
143
|
if (0 == cnt) {
|
|
@@ -147,10 +148,10 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
|
|
147
148
|
} else {
|
|
148
149
|
size = d2 * out->indent + 2;
|
|
149
150
|
}
|
|
150
|
-
assure_size(out, size * cnt);
|
|
151
151
|
cnt--;
|
|
152
152
|
for (i = 0; i <= cnt; i++) {
|
|
153
153
|
if (out->opts->dump_opts.use) {
|
|
154
|
+
assure_size(out, size);
|
|
154
155
|
if (0 < out->opts->dump_opts.array_size) {
|
|
155
156
|
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
|
156
157
|
}
|
|
@@ -161,6 +162,7 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
|
|
161
162
|
}
|
|
162
163
|
}
|
|
163
164
|
} else {
|
|
165
|
+
assure_size(out, size);
|
|
164
166
|
fill_indent(out, d2);
|
|
165
167
|
}
|
|
166
168
|
oj_dump_compat_val(RARRAY_AREF(a, i), d2, out, true);
|
|
@@ -552,7 +554,7 @@ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
|
|
552
554
|
char buf[64];
|
|
553
555
|
char *b;
|
|
554
556
|
double d = rb_num2dbl(obj);
|
|
555
|
-
|
|
557
|
+
size_t cnt = 0;
|
|
556
558
|
|
|
557
559
|
if (0.0 == d) {
|
|
558
560
|
b = buf;
|
|
@@ -590,7 +592,7 @@ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
|
|
590
592
|
volatile VALUE rstr = oj_safe_string_convert(obj);
|
|
591
593
|
|
|
592
594
|
strcpy(buf, RSTRING_PTR(rstr));
|
|
593
|
-
cnt =
|
|
595
|
+
cnt = RSTRING_LEN(rstr);
|
|
594
596
|
}
|
|
595
597
|
assure_size(out, cnt);
|
|
596
598
|
APPEND_CHARS(out->cur, buf, cnt);
|
|
@@ -604,6 +606,11 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
|
604
606
|
if (out->omit_nil && Qnil == value) {
|
|
605
607
|
return ST_CONTINUE;
|
|
606
608
|
}
|
|
609
|
+
if (NULL != out->opts->dump_opts.only || NULL != out->opts->dump_opts.except) {
|
|
610
|
+
if (oj_key_skip(key, out->opts->dump_opts.only, out->opts->dump_opts.except)) {
|
|
611
|
+
return ST_CONTINUE;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
607
614
|
if (!out->opts->dump_opts.use) {
|
|
608
615
|
assure_size(out, depth * out->indent + 1);
|
|
609
616
|
fill_indent(out, depth);
|
|
@@ -800,7 +807,7 @@ static void dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
|
|
|
800
807
|
// rb_big2str can not so unless overridden by using add_to_json(Integer)
|
|
801
808
|
// this must use to_s to pass the json gem unit tests.
|
|
802
809
|
volatile VALUE rs;
|
|
803
|
-
|
|
810
|
+
size_t cnt;
|
|
804
811
|
bool dump_as_string = false;
|
|
805
812
|
|
|
806
813
|
if (use_bignum_alt) {
|
|
@@ -809,7 +816,7 @@ static void dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
|
|
|
809
816
|
rs = oj_safe_string_convert(obj);
|
|
810
817
|
}
|
|
811
818
|
rb_check_type(rs, T_STRING);
|
|
812
|
-
cnt =
|
|
819
|
+
cnt = RSTRING_LEN(rs);
|
|
813
820
|
|
|
814
821
|
if (out->opts->int_range_min != 0 || out->opts->int_range_max != 0) {
|
|
815
822
|
dump_as_string = true; // Bignum cannot be inside of Fixnum range
|
data/ext/oj/dump_leaf.c
CHANGED
|
@@ -17,7 +17,7 @@ inline static void dump_chars(const char *s, size_t size, Out out) {
|
|
|
17
17
|
static void dump_leaf_str(Leaf leaf, Out out) {
|
|
18
18
|
switch (leaf->value_type) {
|
|
19
19
|
case STR_VAL: oj_dump_cstr(leaf->str, strlen(leaf->str), 0, 0, out); break;
|
|
20
|
-
case RUBY_VAL: oj_dump_cstr(StringValueCStr(leaf->value),
|
|
20
|
+
case RUBY_VAL: oj_dump_cstr(StringValueCStr(leaf->value), RSTRING_LEN(leaf->value), 0, 0, out); break;
|
|
21
21
|
case COL_VAL:
|
|
22
22
|
default: rb_raise(rb_eTypeError, "Unexpected value type %02x.\n", leaf->value_type); break;
|
|
23
23
|
}
|
data/ext/oj/dump_object.c
CHANGED
|
@@ -10,6 +10,24 @@ static const char hex_chars[17] = "0123456789abcdef";
|
|
|
10
10
|
|
|
11
11
|
static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out);
|
|
12
12
|
|
|
13
|
+
// An odd class is dumped as {"^O":class,...} and is rebuilt with a create
|
|
14
|
+
// function when loaded so there is no place to put a "^i" circular id on it.
|
|
15
|
+
// Registering it in the circular cache would consume an id that is never
|
|
16
|
+
// written and any later occurrence would then be dumped as a "^r" that refers
|
|
17
|
+
// to nothing. Instead dump odd classes in full each time they are encountered
|
|
18
|
+
// just like Time, Rational, and Complex are.
|
|
19
|
+
static void dump_circular_obj(VALUE obj, VALUE clas, int depth, Out out) {
|
|
20
|
+
if (NULL != oj_get_odd(clas)) {
|
|
21
|
+
dump_obj_attrs(obj, clas, 0, depth, out);
|
|
22
|
+
} else {
|
|
23
|
+
long id = oj_check_circular(obj, out);
|
|
24
|
+
|
|
25
|
+
if (0 <= id) {
|
|
26
|
+
dump_obj_attrs(obj, clas, id, depth, out);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
13
31
|
static void dump_time(VALUE obj, Out out) {
|
|
14
32
|
switch (out->opts->time_format) {
|
|
15
33
|
case RubyTime:
|
|
@@ -33,7 +51,7 @@ static void dump_data(VALUE obj, int depth, Out out, bool as_ok) {
|
|
|
33
51
|
if (oj_bigdecimal_class == clas) {
|
|
34
52
|
volatile VALUE rstr = oj_safe_string_convert(obj);
|
|
35
53
|
const char *str = RSTRING_PTR(rstr);
|
|
36
|
-
|
|
54
|
+
size_t len = RSTRING_LEN(rstr);
|
|
37
55
|
|
|
38
56
|
if (No != out->opts->bigdec_as_num) {
|
|
39
57
|
oj_dump_raw(str, len, out);
|
|
@@ -47,11 +65,7 @@ static void dump_data(VALUE obj, int depth, Out out, bool as_ok) {
|
|
|
47
65
|
oj_dump_cstr(str, len, 0, 0, out);
|
|
48
66
|
}
|
|
49
67
|
} else {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (0 <= id) {
|
|
53
|
-
dump_obj_attrs(obj, clas, id, depth, out);
|
|
54
|
-
}
|
|
68
|
+
dump_circular_obj(obj, clas, depth, out);
|
|
55
69
|
}
|
|
56
70
|
}
|
|
57
71
|
}
|
|
@@ -62,7 +76,7 @@ static void dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
|
|
|
62
76
|
if (oj_bigdecimal_class == clas) {
|
|
63
77
|
volatile VALUE rstr = oj_safe_string_convert(obj);
|
|
64
78
|
const char *str = RSTRING_PTR(rstr);
|
|
65
|
-
|
|
79
|
+
size_t len = RSTRING_LEN(rstr);
|
|
66
80
|
|
|
67
81
|
if (0 == strcasecmp("Infinity", str)) {
|
|
68
82
|
str = oj_nan_str(obj, out->opts->dump_opts.nan_dump, out->opts->mode, true, &len);
|
|
@@ -74,11 +88,7 @@ static void dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
|
|
|
74
88
|
oj_dump_raw(str, len, out);
|
|
75
89
|
}
|
|
76
90
|
} else {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (0 <= id) {
|
|
80
|
-
dump_obj_attrs(obj, clas, id, depth, out);
|
|
81
|
-
}
|
|
91
|
+
dump_circular_obj(obj, clas, depth, out);
|
|
82
92
|
}
|
|
83
93
|
}
|
|
84
94
|
|
|
@@ -95,7 +105,8 @@ static void dump_class(VALUE obj, int depth, Out out, bool as_ok) {
|
|
|
95
105
|
|
|
96
106
|
static void dump_array_class(VALUE a, VALUE clas, int depth, Out out) {
|
|
97
107
|
size_t size;
|
|
98
|
-
|
|
108
|
+
size_t i;
|
|
109
|
+
size_t cnt;
|
|
99
110
|
int d2 = depth + 1;
|
|
100
111
|
long id = oj_check_circular(a, out);
|
|
101
112
|
|
|
@@ -106,7 +117,7 @@ static void dump_array_class(VALUE a, VALUE clas, int depth, Out out) {
|
|
|
106
117
|
dump_obj_attrs(a, clas, 0, depth, out);
|
|
107
118
|
return;
|
|
108
119
|
}
|
|
109
|
-
cnt =
|
|
120
|
+
cnt = RARRAY_LEN(a);
|
|
110
121
|
*out->cur++ = '[';
|
|
111
122
|
if (0 < id) {
|
|
112
123
|
assure_size(out, d2 * out->indent + 16);
|
|
@@ -181,7 +192,7 @@ static void dump_str_class(VALUE obj, VALUE clas, int depth, Out out) {
|
|
|
181
192
|
dump_obj_attrs(obj, clas, 0, depth, out);
|
|
182
193
|
} else {
|
|
183
194
|
const char *s = RSTRING_PTR(obj);
|
|
184
|
-
size_t len =
|
|
195
|
+
size_t len = RSTRING_LEN(obj);
|
|
185
196
|
char s1 = s[1];
|
|
186
197
|
|
|
187
198
|
oj_dump_cstr(s, len, 0, (':' == *s || ('^' == *s && ('r' == s1 || 'i' == s1))), out);
|
|
@@ -195,7 +206,7 @@ static void dump_str(VALUE obj, int depth, Out out, bool as_ok) {
|
|
|
195
206
|
static void dump_sym(VALUE obj, int depth, Out out, bool as_ok) {
|
|
196
207
|
volatile VALUE s = rb_sym2str(obj);
|
|
197
208
|
|
|
198
|
-
oj_dump_cstr(RSTRING_PTR(s),
|
|
209
|
+
oj_dump_cstr(RSTRING_PTR(s), RSTRING_LEN(s), 1, 0, out);
|
|
199
210
|
}
|
|
200
211
|
|
|
201
212
|
static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
@@ -209,6 +220,11 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
|
209
220
|
if (out->omit_nil && Qnil == value) {
|
|
210
221
|
return ST_CONTINUE;
|
|
211
222
|
}
|
|
223
|
+
if (NULL != out->opts->dump_opts.only || NULL != out->opts->dump_opts.except) {
|
|
224
|
+
if (oj_key_skip(key, out->opts->dump_opts.only, out->opts->dump_opts.except)) {
|
|
225
|
+
return ST_CONTINUE;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
212
228
|
assure_size(out, size);
|
|
213
229
|
fill_indent(out, depth);
|
|
214
230
|
switch (rb_type(key)) {
|
|
@@ -389,7 +405,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
|
|
|
389
405
|
rb_raise(rb_eEncodingError, "Invalid type for raw JSON.");
|
|
390
406
|
} else {
|
|
391
407
|
const char *s = RSTRING_PTR(v);
|
|
392
|
-
|
|
408
|
+
size_t len = RSTRING_LEN(v);
|
|
393
409
|
const char *name = rb_id2name(*odd->attrs);
|
|
394
410
|
size_t nlen = strlen(name);
|
|
395
411
|
|
|
@@ -489,7 +505,7 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
|
|
|
489
505
|
*out->cur++ = ',';
|
|
490
506
|
fill_indent(out, d2);
|
|
491
507
|
APPEND_CHARS(out->cur, "\"self\":", 7);
|
|
492
|
-
oj_dump_cstr(RSTRING_PTR(obj),
|
|
508
|
+
oj_dump_cstr(RSTRING_PTR(obj), RSTRING_LEN(obj), 0, 0, out);
|
|
493
509
|
break;
|
|
494
510
|
case T_ARRAY:
|
|
495
511
|
assure_size(out, d2 * out->indent + 14);
|
|
@@ -564,11 +580,12 @@ static void dump_regexp(VALUE obj, int depth, Out out, bool as_ok) {
|
|
|
564
580
|
static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
565
581
|
VALUE clas = rb_obj_class(obj);
|
|
566
582
|
const char *class_name = rb_class2name(clas);
|
|
567
|
-
|
|
568
|
-
int d2
|
|
569
|
-
int d3
|
|
570
|
-
size_t len
|
|
571
|
-
size_t size
|
|
583
|
+
size_t i;
|
|
584
|
+
int d2 = depth + 1;
|
|
585
|
+
int d3 = d2 + 1;
|
|
586
|
+
size_t len = strlen(class_name);
|
|
587
|
+
size_t size = d2 * out->indent + d3 * out->indent + 10 + len;
|
|
588
|
+
char circular = out->opts->circular;
|
|
572
589
|
|
|
573
590
|
assure_size(out, size);
|
|
574
591
|
*out->cur++ = '{';
|
|
@@ -577,14 +594,14 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
|
577
594
|
if ('#' == *class_name) {
|
|
578
595
|
VALUE ma = rb_struct_s_members(clas);
|
|
579
596
|
const char *name;
|
|
580
|
-
|
|
597
|
+
size_t cnt = RARRAY_LEN(ma);
|
|
581
598
|
|
|
582
599
|
*out->cur++ = '[';
|
|
583
600
|
for (i = 0; i < cnt; i++) {
|
|
584
601
|
volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
|
|
585
602
|
|
|
586
603
|
name = RSTRING_PTR(s);
|
|
587
|
-
len =
|
|
604
|
+
len = RSTRING_LEN(s);
|
|
588
605
|
size = len + 3;
|
|
589
606
|
assure_size(out, size);
|
|
590
607
|
if (0 < i) {
|
|
@@ -607,14 +624,18 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
|
607
624
|
{
|
|
608
625
|
VALUE v;
|
|
609
626
|
int cnt;
|
|
627
|
+
|
|
610
628
|
#if RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
|
611
629
|
cnt = (int)NUM2LONG(RSTRUCT_LEN(obj));
|
|
612
630
|
#else // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
|
613
631
|
cnt = (int)RSTRUCT_LEN(obj);
|
|
614
632
|
#endif // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
|
615
633
|
|
|
616
|
-
|
|
617
|
-
|
|
634
|
+
if (0 == strcmp(class_name, "Range")) {
|
|
635
|
+
out->opts->circular = 'n';
|
|
636
|
+
}
|
|
637
|
+
for (i = 0; i < (size_t)cnt; i++) {
|
|
638
|
+
v = RSTRUCT_GET(obj, (int)i);
|
|
618
639
|
if (dump_ignore(out->opts, v)) {
|
|
619
640
|
v = Qnil;
|
|
620
641
|
}
|
|
@@ -630,6 +651,9 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
|
630
651
|
// class in interpreted Ruby so length() may not be defined.
|
|
631
652
|
int slen = FIX2INT(rb_funcall2(obj, oj_length_id, 0, 0));
|
|
632
653
|
|
|
654
|
+
if (0 == strcmp(class_name, "Range")) {
|
|
655
|
+
out->opts->circular = 'n';
|
|
656
|
+
}
|
|
633
657
|
for (i = 0; i < slen; i++) {
|
|
634
658
|
assure_size(out, size);
|
|
635
659
|
fill_indent(out, d3);
|
|
@@ -641,6 +665,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
|
641
665
|
}
|
|
642
666
|
}
|
|
643
667
|
#endif
|
|
668
|
+
out->opts->circular = circular;
|
|
644
669
|
out->cur--;
|
|
645
670
|
APPEND_CHARS(out->cur, "]}", 2);
|
|
646
671
|
*out->cur = '\0';
|
data/ext/oj/dump_strict.c
CHANGED
|
@@ -30,7 +30,7 @@ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
|
|
30
30
|
char buf[64];
|
|
31
31
|
char* b;
|
|
32
32
|
double d = rb_num2dbl(obj);
|
|
33
|
-
|
|
33
|
+
size_t cnt = 0;
|
|
34
34
|
|
|
35
35
|
if (0.0 == d) {
|
|
36
36
|
b = buf;
|
|
@@ -92,7 +92,7 @@ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
|
|
92
92
|
} else if (0 == out->opts->float_prec) {
|
|
93
93
|
volatile VALUE rstr = oj_safe_string_convert(obj);
|
|
94
94
|
|
|
95
|
-
cnt =
|
|
95
|
+
cnt = RSTRING_LEN(rstr);
|
|
96
96
|
if ((int)sizeof(buf) <= cnt) {
|
|
97
97
|
cnt = sizeof(buf) - 1;
|
|
98
98
|
}
|
|
@@ -109,7 +109,8 @@ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
|
|
109
109
|
|
|
110
110
|
static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
|
111
111
|
size_t size;
|
|
112
|
-
|
|
112
|
+
size_t i;
|
|
113
|
+
size_t cnt;
|
|
113
114
|
int d2 = depth + 1;
|
|
114
115
|
|
|
115
116
|
if (Yes == out->opts->circular) {
|
|
@@ -118,7 +119,7 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
|
|
118
119
|
return;
|
|
119
120
|
}
|
|
120
121
|
}
|
|
121
|
-
cnt =
|
|
122
|
+
cnt = RARRAY_LEN(a);
|
|
122
123
|
*out->cur++ = '[';
|
|
123
124
|
size = 2;
|
|
124
125
|
assure_size(out, size);
|
|
@@ -192,14 +193,19 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
|
192
193
|
if (out->omit_nil && Qnil == value) {
|
|
193
194
|
return ST_CONTINUE;
|
|
194
195
|
}
|
|
196
|
+
if (NULL != out->opts->dump_opts.only || NULL != out->opts->dump_opts.except) {
|
|
197
|
+
if (oj_key_skip(key, out->opts->dump_opts.only, out->opts->dump_opts.except)) {
|
|
198
|
+
return ST_CONTINUE;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
195
201
|
if (!out->opts->dump_opts.use) {
|
|
196
202
|
size = depth * out->indent + 1;
|
|
197
203
|
assure_size(out, size);
|
|
198
204
|
fill_indent(out, depth);
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
205
|
+
switch (rtype) {
|
|
206
|
+
case T_STRING: oj_dump_str(key, 0, out, false); break;
|
|
207
|
+
case T_SYMBOL: oj_dump_sym(key, 0, out, false); break;
|
|
208
|
+
default: oj_dump_str(oj_safe_string_convert(key), 0, out, false); break;
|
|
203
209
|
}
|
|
204
210
|
*out->cur++ = ':';
|
|
205
211
|
} else {
|
|
@@ -214,10 +220,10 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
|
214
220
|
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
|
215
221
|
}
|
|
216
222
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
223
|
+
switch (rtype) {
|
|
224
|
+
case T_STRING: oj_dump_str(key, 0, out, false); break;
|
|
225
|
+
case T_SYMBOL: oj_dump_sym(key, 0, out, false); break;
|
|
226
|
+
default: oj_dump_str(oj_safe_string_convert(key), 0, out, false); break;
|
|
221
227
|
}
|
|
222
228
|
size = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
|
|
223
229
|
assure_size(out, size);
|
|
@@ -290,7 +296,7 @@ static void dump_data_strict(VALUE obj, int depth, Out out, bool as_ok) {
|
|
|
290
296
|
if (oj_bigdecimal_class == clas) {
|
|
291
297
|
volatile VALUE rstr = oj_safe_string_convert(obj);
|
|
292
298
|
|
|
293
|
-
oj_dump_raw(RSTRING_PTR(rstr),
|
|
299
|
+
oj_dump_raw(RSTRING_PTR(rstr), RSTRING_LEN(rstr), out);
|
|
294
300
|
} else {
|
|
295
301
|
raise_strict(obj);
|
|
296
302
|
}
|
|
@@ -302,7 +308,7 @@ static void dump_data_null(VALUE obj, int depth, Out out, bool as_ok) {
|
|
|
302
308
|
if (oj_bigdecimal_class == clas) {
|
|
303
309
|
volatile VALUE rstr = oj_safe_string_convert(obj);
|
|
304
310
|
|
|
305
|
-
oj_dump_raw(RSTRING_PTR(rstr),
|
|
311
|
+
oj_dump_raw(RSTRING_PTR(rstr), RSTRING_LEN(rstr), out);
|
|
306
312
|
} else {
|
|
307
313
|
oj_dump_nil(Qnil, depth, out, false);
|
|
308
314
|
}
|
data/ext/oj/extconf.rb
CHANGED
|
@@ -29,20 +29,22 @@ dflags = {
|
|
|
29
29
|
have_func('rb_gc_mark_movable')
|
|
30
30
|
have_func('stpcpy')
|
|
31
31
|
have_func('pthread_mutex_init')
|
|
32
|
+
have_func('getrlimit', 'sys/resource.h')
|
|
32
33
|
have_func('rb_enc_interned_str')
|
|
33
34
|
have_func('rb_ext_ractor_safe', 'ruby.h')
|
|
34
|
-
# rb_hash_bulk_insert is deep down in a header not included in normal build and that seems to fool have_func.
|
|
35
|
-
have_func('rb_hash_bulk_insert', 'ruby.h') unless '2' == version[0] && '6' == version[1]
|
|
36
35
|
|
|
37
36
|
dflags['OJ_DEBUG'] = true unless ENV['OJ_DEBUG'].nil?
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
# SIMD optimizations use runtime CPU detection and function-level target attributes
|
|
39
|
+
# We do NOT add global -msse4.2/-msse2 flags here because:
|
|
40
|
+
# 1. It would cause illegal instruction errors on CPUs without SSE4.2
|
|
41
|
+
# 2. The code uses __attribute__((target("sse4.2"))) for SSE4.2 functions
|
|
42
|
+
# 3. Runtime detection in oj_get_simd_implementation() selects the right path
|
|
43
|
+
#
|
|
44
|
+
# We only add -msse2 if available, since SSE2 is baseline for all x86_64 CPUs
|
|
45
|
+
# and needed for compiling the SSE2 fallback code on 32-bit x86
|
|
46
|
+
if try_cflags('-msse2')
|
|
47
|
+
$CPPFLAGS += ' -msse2'
|
|
46
48
|
end
|
|
47
49
|
|
|
48
50
|
if enable_config('trace-log', false)
|