oj 3.9.1 → 3.16.11
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 +1452 -0
- data/README.md +21 -6
- data/RELEASE_NOTES.md +61 -0
- data/ext/oj/buf.h +50 -68
- data/ext/oj/cache.c +329 -0
- data/ext/oj/cache.h +22 -0
- data/ext/oj/cache8.c +60 -62
- data/ext/oj/cache8.h +9 -36
- data/ext/oj/circarray.c +38 -42
- data/ext/oj/circarray.h +12 -13
- data/ext/oj/code.c +158 -179
- data/ext/oj/code.h +20 -22
- data/ext/oj/compat.c +145 -205
- data/ext/oj/custom.c +740 -880
- data/ext/oj/debug.c +126 -0
- data/ext/oj/dump.c +1145 -844
- data/ext/oj/dump.h +71 -57
- data/ext/oj/dump_compat.c +575 -655
- data/ext/oj/dump_leaf.c +96 -186
- data/ext/oj/dump_object.c +533 -660
- data/ext/oj/dump_strict.c +306 -340
- data/ext/oj/encode.h +4 -33
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/err.c +28 -28
- data/ext/oj/err.h +39 -42
- data/ext/oj/extconf.rb +28 -7
- data/ext/oj/fast.c +1052 -1113
- data/ext/oj/intern.c +313 -0
- data/ext/oj/intern.h +22 -0
- data/ext/oj/mem.c +318 -0
- data/ext/oj/mem.h +53 -0
- data/ext/oj/mimic_json.c +471 -430
- data/ext/oj/object.c +532 -580
- data/ext/oj/odd.c +156 -142
- data/ext/oj/odd.h +25 -26
- data/ext/oj/oj.c +1346 -961
- data/ext/oj/oj.h +307 -290
- data/ext/oj/parse.c +954 -858
- data/ext/oj/parse.h +74 -72
- data/ext/oj/parser.c +1600 -0
- data/ext/oj/parser.h +103 -0
- data/ext/oj/rails.c +819 -836
- data/ext/oj/rails.h +8 -11
- data/ext/oj/reader.c +136 -147
- data/ext/oj/reader.h +69 -83
- data/ext/oj/resolve.c +41 -63
- data/ext/oj/resolve.h +4 -6
- data/ext/oj/rxclass.c +69 -72
- data/ext/oj/rxclass.h +12 -13
- data/ext/oj/saj.c +440 -485
- data/ext/oj/saj2.c +584 -0
- data/ext/oj/saj2.h +23 -0
- data/ext/oj/scp.c +79 -118
- data/ext/oj/simd.h +10 -0
- data/ext/oj/sparse.c +739 -709
- data/ext/oj/stream_writer.c +141 -175
- data/ext/oj/strict.c +103 -128
- data/ext/oj/string_writer.c +244 -261
- data/ext/oj/trace.c +34 -41
- data/ext/oj/trace.h +42 -15
- data/ext/oj/usual.c +1218 -0
- data/ext/oj/usual.h +69 -0
- data/ext/oj/util.c +107 -107
- data/ext/oj/util.h +4 -3
- data/ext/oj/val_stack.c +61 -78
- data/ext/oj/val_stack.h +80 -114
- data/ext/oj/validate.c +46 -0
- data/ext/oj/wab.c +316 -361
- data/lib/oj/active_support_helper.rb +1 -3
- data/lib/oj/bag.rb +8 -1
- data/lib/oj/easy_hash.rb +9 -9
- data/lib/oj/error.rb +1 -2
- data/lib/oj/json.rb +162 -150
- data/lib/oj/mimic.rb +54 -20
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/schandler.rb +5 -4
- data/lib/oj/state.rb +12 -8
- data/lib/oj/version.rb +1 -2
- data/lib/oj.rb +2 -8
- data/pages/Compatibility.md +1 -1
- data/pages/Encoding.md +1 -1
- data/pages/InstallOptions.md +20 -0
- data/pages/JsonGem.md +15 -0
- data/pages/Modes.md +9 -3
- data/pages/Options.md +62 -12
- data/pages/Parser.md +309 -0
- data/pages/Rails.md +73 -22
- metadata +68 -192
- data/ext/oj/hash.c +0 -163
- data/ext/oj/hash.h +0 -46
- data/ext/oj/hash_test.c +0 -512
- data/test/_test_active.rb +0 -76
- data/test/_test_active_mimic.rb +0 -96
- data/test/_test_mimic_rails.rb +0 -126
- data/test/activerecord/result_test.rb +0 -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/decoding_test.rb +0 -125
- data/test/activesupport5/encoding_test.rb +0 -485
- data/test/activesupport5/encoding_test_cases.rb +0 -90
- data/test/activesupport5/test_helper.rb +0 -50
- data/test/activesupport5/time_zone_test_helpers.rb +0 -24
- data/test/bar.rb +0 -25
- data/test/files.rb +0 -29
- data/test/foo.rb +0 -21
- data/test/helper.rb +0 -26
- data/test/isolated/shared.rb +0 -308
- 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 -148
- data/test/json_gem/json_encoding_test.rb +0 -107
- data/test/json_gem/json_ext_parser_test.rb +0 -20
- data/test/json_gem/json_fixtures_test.rb +0 -35
- data/test/json_gem/json_generator_test.rb +0 -383
- data/test/json_gem/json_generic_object_test.rb +0 -90
- data/test/json_gem/json_parser_test.rb +0 -470
- data/test/json_gem/json_string_matching_test.rb +0 -42
- data/test/json_gem/test_helper.rb +0 -18
- data/test/perf.rb +0 -107
- data/test/perf_compat.rb +0 -130
- data/test/perf_fast.rb +0 -164
- data/test/perf_file.rb +0 -64
- data/test/perf_object.rb +0 -138
- data/test/perf_saj.rb +0 -109
- data/test/perf_scp.rb +0 -151
- data/test/perf_simple.rb +0 -287
- data/test/perf_strict.rb +0 -145
- data/test/perf_wab.rb +0 -131
- data/test/sample/change.rb +0 -14
- data/test/sample/dir.rb +0 -19
- data/test/sample/doc.rb +0 -36
- data/test/sample/file.rb +0 -48
- data/test/sample/group.rb +0 -16
- data/test/sample/hasprops.rb +0 -16
- data/test/sample/layer.rb +0 -12
- data/test/sample/line.rb +0 -20
- data/test/sample/oval.rb +0 -10
- data/test/sample/rect.rb +0 -10
- data/test/sample/shape.rb +0 -35
- data/test/sample/text.rb +0 -20
- data/test/sample.rb +0 -54
- data/test/sample_json.rb +0 -37
- data/test/test_compat.rb +0 -509
- data/test/test_custom.rb +0 -503
- data/test/test_debian.rb +0 -53
- data/test/test_fast.rb +0 -470
- data/test/test_file.rb +0 -239
- data/test/test_gc.rb +0 -49
- data/test/test_hash.rb +0 -29
- data/test/test_integer_range.rb +0 -73
- data/test/test_null.rb +0 -376
- data/test/test_object.rb +0 -1018
- data/test/test_saj.rb +0 -186
- data/test/test_scp.rb +0 -433
- data/test/test_strict.rb +0 -410
- data/test/test_various.rb +0 -741
- data/test/test_wab.rb +0 -307
- data/test/test_writer.rb +0 -380
- data/test/tests.rb +0 -24
- data/test/tests_mimic.rb +0 -14
- data/test/tests_mimic_addition.rb +0 -7
- data/test/zoo.rb +0 -13
data/ext/oj/dump_compat.c
CHANGED
@@ -1,7 +1,5 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
1
|
+
// Copyright (c) 2012, 2017 Peter Ohler. All rights reserved.
|
2
|
+
// Licensed under the MIT License. See LICENSE file in the project root for license details.
|
5
3
|
|
6
4
|
#include "code.h"
|
7
5
|
#include "dump.h"
|
@@ -9,242 +7,220 @@
|
|
9
7
|
#include "trace.h"
|
10
8
|
|
11
9
|
// Workaround in case INFINITY is not defined in math.h or if the OS is CentOS
|
12
|
-
#define OJ_INFINITY (1.0/0.0)
|
10
|
+
#define OJ_INFINITY (1.0 / 0.0)
|
13
11
|
|
14
|
-
bool
|
15
|
-
bool
|
12
|
+
bool oj_use_hash_alt = false;
|
13
|
+
bool oj_use_array_alt = false;
|
16
14
|
|
17
|
-
static bool
|
18
|
-
static bool
|
19
|
-
static bool
|
15
|
+
static bool use_struct_alt = false;
|
16
|
+
static bool use_exception_alt = false;
|
17
|
+
static bool use_bignum_alt = false;
|
20
18
|
|
21
|
-
static void
|
22
|
-
raise_json_err(const char *msg, const char *err_classname) {
|
19
|
+
static void raise_json_err(const char *msg, const char *err_classname) {
|
23
20
|
rb_raise(oj_get_json_err_class(err_classname), "%s", msg);
|
24
21
|
}
|
25
22
|
|
26
|
-
static void
|
27
|
-
|
28
|
-
|
29
|
-
size_t
|
30
|
-
size_t
|
31
|
-
size_t size = d2 * out->indent + 10 + len + out->opts->create_id_len + sep_len;
|
23
|
+
static void dump_obj_classname(const char *classname, int depth, Out out) {
|
24
|
+
int d2 = depth + 1;
|
25
|
+
size_t len = strlen(classname);
|
26
|
+
size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
|
27
|
+
size_t size = d2 * out->indent + 10 + len + out->opts->create_id_len + sep_len;
|
32
28
|
|
33
29
|
assure_size(out, size);
|
34
30
|
*out->cur++ = '{';
|
35
31
|
fill_indent(out, d2);
|
36
32
|
*out->cur++ = '"';
|
37
|
-
|
38
|
-
out->cur += out->opts->create_id_len;
|
33
|
+
APPEND_CHARS(out->cur, out->opts->create_id, out->opts->create_id_len);
|
39
34
|
*out->cur++ = '"';
|
40
35
|
if (0 < out->opts->dump_opts.before_size) {
|
41
|
-
|
42
|
-
out->cur += out->opts->dump_opts.before_size;
|
36
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
|
43
37
|
}
|
44
38
|
*out->cur++ = ':';
|
45
39
|
if (0 < out->opts->dump_opts.after_size) {
|
46
|
-
|
47
|
-
out->cur += out->opts->dump_opts.after_size;
|
40
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
|
48
41
|
}
|
49
42
|
*out->cur++ = '"';
|
50
|
-
|
51
|
-
out->cur += len;
|
43
|
+
APPEND_CHARS(out->cur, classname, len);
|
52
44
|
*out->cur++ = '"';
|
53
45
|
}
|
54
46
|
|
55
|
-
static void
|
56
|
-
|
57
|
-
|
58
|
-
int d2 = depth + 1;
|
47
|
+
static void dump_values_array(VALUE *values, int depth, Out out) {
|
48
|
+
size_t size;
|
49
|
+
int d2 = depth + 1;
|
59
50
|
|
60
51
|
assure_size(out, d2 * out->indent + 3);
|
61
52
|
*out->cur++ = '[';
|
62
53
|
if (Qundef == *values) {
|
63
|
-
|
54
|
+
*out->cur++ = ']';
|
64
55
|
} else {
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
} else {
|
110
|
-
fill_indent(out, depth);
|
111
|
-
}
|
112
|
-
*out->cur++ = ']';
|
56
|
+
if (out->opts->dump_opts.use) {
|
57
|
+
size = d2 * out->opts->dump_opts.indent_size + out->opts->dump_opts.array_size + 2;
|
58
|
+
size += out->opts->dump_opts.array_size;
|
59
|
+
size += out->opts->dump_opts.indent_size;
|
60
|
+
} else {
|
61
|
+
size = d2 * out->indent + 3;
|
62
|
+
}
|
63
|
+
for (; Qundef != *values; values++) {
|
64
|
+
assure_size(out, size);
|
65
|
+
if (out->opts->dump_opts.use) {
|
66
|
+
if (0 < out->opts->dump_opts.array_size) {
|
67
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
68
|
+
}
|
69
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
70
|
+
int i;
|
71
|
+
|
72
|
+
for (i = d2; 0 < i; i--) {
|
73
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
74
|
+
}
|
75
|
+
}
|
76
|
+
} else {
|
77
|
+
fill_indent(out, d2);
|
78
|
+
}
|
79
|
+
oj_dump_compat_val(*values, d2, out, true);
|
80
|
+
if (Qundef != *(values + 1)) {
|
81
|
+
*out->cur++ = ',';
|
82
|
+
}
|
83
|
+
}
|
84
|
+
assure_size(out, size);
|
85
|
+
if (out->opts->dump_opts.use) {
|
86
|
+
if (0 < out->opts->dump_opts.array_size) {
|
87
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
88
|
+
}
|
89
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
90
|
+
int i;
|
91
|
+
|
92
|
+
for (i = depth; 0 < i; i--) {
|
93
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
94
|
+
}
|
95
|
+
}
|
96
|
+
} else {
|
97
|
+
fill_indent(out, depth);
|
98
|
+
}
|
99
|
+
*out->cur++ = ']';
|
113
100
|
}
|
114
101
|
}
|
115
102
|
|
116
|
-
static void
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
int len;
|
103
|
+
static void dump_to_json(VALUE obj, Out out) {
|
104
|
+
volatile VALUE rs;
|
105
|
+
const char *s;
|
106
|
+
size_t len;
|
121
107
|
|
122
|
-
|
123
|
-
oj_trace("to_json", obj, __FILE__, __LINE__, 0, TraceRubyIn);
|
124
|
-
}
|
108
|
+
TRACE(out->opts->trace, "to_json", obj, 0, TraceRubyIn);
|
125
109
|
if (0 == rb_obj_method_arity(obj, oj_to_json_id)) {
|
126
|
-
|
110
|
+
rs = rb_funcall(obj, oj_to_json_id, 0);
|
127
111
|
} else {
|
128
|
-
|
129
|
-
}
|
130
|
-
if (Yes == out->opts->trace) {
|
131
|
-
oj_trace("to_json", obj, __FILE__, __LINE__, 0, TraceRubyOut);
|
112
|
+
rs = rb_funcall2(obj, oj_to_json_id, out->argc, out->argv);
|
132
113
|
}
|
114
|
+
TRACE(out->opts->trace, "to_json", obj, 0, TraceRubyOut);
|
133
115
|
|
134
|
-
|
135
|
-
|
116
|
+
StringValue(rs);
|
117
|
+
s = RSTRING_PTR(rs);
|
118
|
+
len = RSTRING_LEN(rs);
|
136
119
|
|
137
120
|
assure_size(out, len + 1);
|
138
|
-
|
139
|
-
out->cur += len;
|
121
|
+
APPEND_CHARS(out->cur, s, len);
|
140
122
|
*out->cur = '\0';
|
141
123
|
}
|
142
124
|
|
143
|
-
static void
|
144
|
-
|
145
|
-
size_t
|
146
|
-
|
147
|
-
int
|
148
|
-
long
|
125
|
+
static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
126
|
+
size_t size;
|
127
|
+
size_t i;
|
128
|
+
size_t cnt;
|
129
|
+
int d2 = depth + 1;
|
130
|
+
long id = oj_check_circular(a, out);
|
149
131
|
|
150
132
|
if (0 > id) {
|
151
|
-
|
152
|
-
|
133
|
+
raise_json_err("Too deeply nested", "NestingError");
|
134
|
+
return;
|
153
135
|
}
|
154
|
-
if (as_ok && !
|
155
|
-
|
156
|
-
|
136
|
+
if (as_ok && !oj_use_array_alt && rb_obj_class(a) != rb_cArray && rb_respond_to(a, oj_to_json_id)) {
|
137
|
+
dump_to_json(a, out);
|
138
|
+
return;
|
157
139
|
}
|
158
|
-
cnt
|
140
|
+
cnt = RARRAY_LEN(a);
|
159
141
|
*out->cur++ = '[';
|
160
142
|
assure_size(out, 2);
|
161
143
|
if (0 == cnt) {
|
162
|
-
|
144
|
+
*out->cur++ = ']';
|
163
145
|
} else {
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
assure_size(out, size);
|
210
|
-
fill_indent(out, depth);
|
211
|
-
}
|
212
|
-
*out->cur++ = ']';
|
146
|
+
if (out->opts->dump_opts.use) {
|
147
|
+
size = d2 * out->opts->dump_opts.indent_size + out->opts->dump_opts.array_size + 1;
|
148
|
+
} else {
|
149
|
+
size = d2 * out->indent + 2;
|
150
|
+
}
|
151
|
+
assure_size(out, size * cnt);
|
152
|
+
cnt--;
|
153
|
+
for (i = 0; i <= cnt; i++) {
|
154
|
+
if (out->opts->dump_opts.use) {
|
155
|
+
if (0 < out->opts->dump_opts.array_size) {
|
156
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
157
|
+
}
|
158
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
159
|
+
int i;
|
160
|
+
for (i = d2; 0 < i; i--) {
|
161
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
162
|
+
}
|
163
|
+
}
|
164
|
+
} else {
|
165
|
+
fill_indent(out, d2);
|
166
|
+
}
|
167
|
+
oj_dump_compat_val(RARRAY_AREF(a, i), d2, out, true);
|
168
|
+
if (i < cnt) {
|
169
|
+
*out->cur++ = ',';
|
170
|
+
}
|
171
|
+
}
|
172
|
+
if (out->opts->dump_opts.use) {
|
173
|
+
size = out->opts->dump_opts.array_size + out->opts->dump_opts.indent_size * depth + 1;
|
174
|
+
assure_size(out, size);
|
175
|
+
if (0 < out->opts->dump_opts.array_size) {
|
176
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
177
|
+
}
|
178
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
179
|
+
int i;
|
180
|
+
|
181
|
+
for (i = depth; 0 < i; i--) {
|
182
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
183
|
+
}
|
184
|
+
}
|
185
|
+
} else {
|
186
|
+
size = depth * out->indent + 1;
|
187
|
+
assure_size(out, size);
|
188
|
+
fill_indent(out, depth);
|
189
|
+
}
|
190
|
+
*out->cur++ = ']';
|
213
191
|
}
|
214
192
|
*out->cur = '\0';
|
215
193
|
}
|
216
194
|
|
217
|
-
static ID
|
195
|
+
static ID _dump_id = 0;
|
218
196
|
|
219
|
-
static void
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
{ NULL, 0, Qnil },
|
197
|
+
static void bigdecimal_alt(VALUE obj, int depth, Out out) {
|
198
|
+
struct _attr attrs[] = {
|
199
|
+
{"b", 1, Qnil},
|
200
|
+
{NULL, 0, Qnil},
|
224
201
|
};
|
225
202
|
|
226
203
|
if (0 == _dump_id) {
|
227
|
-
|
204
|
+
_dump_id = rb_intern("_dump");
|
228
205
|
}
|
229
206
|
attrs[0].value = rb_funcall(obj, _dump_id, 0);
|
230
207
|
|
231
208
|
oj_code_attrs(obj, attrs, depth, out, true);
|
232
209
|
}
|
233
210
|
|
234
|
-
static ID
|
235
|
-
static ID
|
211
|
+
static ID real_id = 0;
|
212
|
+
static ID imag_id = 0;
|
236
213
|
|
237
|
-
static void
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
{ NULL, 0, Qnil },
|
214
|
+
static void complex_alt(VALUE obj, int depth, Out out) {
|
215
|
+
struct _attr attrs[] = {
|
216
|
+
{"r", 1, Qnil},
|
217
|
+
{"i", 1, Qnil},
|
218
|
+
{NULL, 0, Qnil},
|
243
219
|
};
|
244
220
|
|
245
221
|
if (0 == real_id) {
|
246
|
-
|
247
|
-
|
222
|
+
real_id = rb_intern("real");
|
223
|
+
imag_id = rb_intern("imag");
|
248
224
|
}
|
249
225
|
attrs[0].value = rb_funcall(obj, real_id, 0);
|
250
226
|
attrs[1].value = rb_funcall(obj, imag_id, 0);
|
@@ -252,25 +228,24 @@ complex_alt(VALUE obj, int depth, Out out) {
|
|
252
228
|
oj_code_attrs(obj, attrs, depth, out, true);
|
253
229
|
}
|
254
230
|
|
255
|
-
static ID
|
256
|
-
static ID
|
257
|
-
static ID
|
258
|
-
static ID
|
259
|
-
|
260
|
-
static void
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
{ NULL, 0, Qnil },
|
231
|
+
static ID year_id = 0;
|
232
|
+
static ID month_id = 0;
|
233
|
+
static ID day_id = 0;
|
234
|
+
static ID start_id = 0;
|
235
|
+
|
236
|
+
static void date_alt(VALUE obj, int depth, Out out) {
|
237
|
+
struct _attr attrs[] = {
|
238
|
+
{"y", 1, Qnil},
|
239
|
+
{"m", 1, Qnil},
|
240
|
+
{"d", 1, Qnil},
|
241
|
+
{"sg", 2, Qnil},
|
242
|
+
{NULL, 0, Qnil},
|
268
243
|
};
|
269
244
|
if (0 == year_id) {
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
245
|
+
year_id = rb_intern("year");
|
246
|
+
month_id = rb_intern("month");
|
247
|
+
day_id = rb_intern("day");
|
248
|
+
start_id = rb_intern("start");
|
274
249
|
}
|
275
250
|
attrs[0].value = rb_funcall(obj, year_id, 0);
|
276
251
|
attrs[1].value = rb_funcall(obj, month_id, 0);
|
@@ -280,33 +255,32 @@ date_alt(VALUE obj, int depth, Out out) {
|
|
280
255
|
oj_code_attrs(obj, attrs, depth, out, true);
|
281
256
|
}
|
282
257
|
|
283
|
-
static ID
|
284
|
-
static ID
|
285
|
-
static ID
|
286
|
-
static ID
|
287
|
-
|
288
|
-
static void
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
{ NULL, 0, Qnil },
|
258
|
+
static ID hour_id = 0;
|
259
|
+
static ID min_id = 0;
|
260
|
+
static ID sec_id = 0;
|
261
|
+
static ID offset_id = 0;
|
262
|
+
|
263
|
+
static void datetime_alt(VALUE obj, int depth, Out out) {
|
264
|
+
struct _attr attrs[] = {
|
265
|
+
{"y", 1, Qnil},
|
266
|
+
{"m", 1, Qnil},
|
267
|
+
{"d", 1, Qnil},
|
268
|
+
{"H", 1, Qnil},
|
269
|
+
{"M", 1, Qnil},
|
270
|
+
{"S", 1, Qnil},
|
271
|
+
{"of", 2, Qnil},
|
272
|
+
{"sg", 2, Qnil},
|
273
|
+
{NULL, 0, Qnil},
|
300
274
|
};
|
301
275
|
if (0 == hour_id) {
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
276
|
+
year_id = rb_intern("year");
|
277
|
+
month_id = rb_intern("month");
|
278
|
+
day_id = rb_intern("day");
|
279
|
+
hour_id = rb_intern("hour");
|
280
|
+
min_id = rb_intern("min");
|
281
|
+
sec_id = rb_intern("sec");
|
282
|
+
offset_id = rb_intern("offset");
|
283
|
+
start_id = rb_intern("start");
|
310
284
|
}
|
311
285
|
attrs[0].value = rb_funcall(obj, year_id, 0);
|
312
286
|
attrs[1].value = rb_funcall(obj, month_id, 0);
|
@@ -314,103 +288,88 @@ datetime_alt(VALUE obj, int depth, Out out) {
|
|
314
288
|
attrs[3].value = rb_funcall(obj, hour_id, 0);
|
315
289
|
attrs[4].value = rb_funcall(obj, min_id, 0);
|
316
290
|
attrs[5].value = rb_funcall(obj, sec_id, 0);
|
317
|
-
attrs[6].value =
|
291
|
+
attrs[6].value = oj_safe_string_convert(rb_funcall(obj, offset_id, 0));
|
318
292
|
attrs[7].value = rb_funcall(obj, start_id, 0);
|
319
293
|
|
320
294
|
oj_code_attrs(obj, attrs, depth, out, true);
|
321
295
|
}
|
322
296
|
|
323
|
-
static ID
|
324
|
-
static ID
|
297
|
+
static ID message_id = 0;
|
298
|
+
static ID backtrace_id = 0;
|
325
299
|
|
326
|
-
static void
|
327
|
-
|
328
|
-
|
329
|
-
size_t
|
330
|
-
size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
|
300
|
+
static void exception_alt(VALUE obj, int depth, Out out) {
|
301
|
+
int d3 = depth + 2;
|
302
|
+
size_t size = d3 * out->indent + 2;
|
303
|
+
size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
|
331
304
|
|
332
305
|
if (0 == message_id) {
|
333
|
-
|
334
|
-
|
306
|
+
message_id = rb_intern("message");
|
307
|
+
backtrace_id = rb_intern("backtrace");
|
335
308
|
}
|
336
309
|
dump_obj_classname(rb_class2name(rb_obj_class(obj)), depth, out);
|
337
310
|
|
338
311
|
assure_size(out, size + sep_len + 6);
|
339
312
|
*out->cur++ = ',';
|
340
313
|
fill_indent(out, d3);
|
341
|
-
|
342
|
-
*out->cur++ = 'm';
|
343
|
-
*out->cur++ = '"';
|
314
|
+
APPEND_CHARS(out->cur, "\"m\"", 3);
|
344
315
|
if (0 < out->opts->dump_opts.before_size) {
|
345
|
-
|
346
|
-
out->cur += out->opts->dump_opts.before_size;
|
316
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
|
347
317
|
}
|
348
318
|
*out->cur++ = ':';
|
349
319
|
if (0 < out->opts->dump_opts.after_size) {
|
350
|
-
|
351
|
-
out->cur += out->opts->dump_opts.after_size;
|
320
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
|
352
321
|
}
|
353
322
|
oj_dump_str(rb_funcall(obj, message_id, 0), 0, out, false);
|
354
323
|
assure_size(out, size + sep_len + 6);
|
355
324
|
*out->cur++ = ',';
|
356
325
|
fill_indent(out, d3);
|
357
|
-
|
358
|
-
*out->cur++ = 'b';
|
359
|
-
*out->cur++ = '"';
|
326
|
+
APPEND_CHARS(out->cur, "\"b\"", 3);
|
360
327
|
if (0 < out->opts->dump_opts.before_size) {
|
361
|
-
|
362
|
-
out->cur += out->opts->dump_opts.before_size;
|
328
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
|
363
329
|
}
|
364
330
|
*out->cur++ = ':';
|
365
331
|
if (0 < out->opts->dump_opts.after_size) {
|
366
|
-
|
367
|
-
out->cur += out->opts->dump_opts.after_size;
|
332
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
|
368
333
|
}
|
369
334
|
dump_array(rb_funcall(obj, backtrace_id, 0), depth, out, false);
|
370
335
|
fill_indent(out, depth);
|
371
336
|
*out->cur++ = '}';
|
372
|
-
*out->cur
|
337
|
+
*out->cur = '\0';
|
373
338
|
}
|
374
339
|
|
375
|
-
static ID
|
340
|
+
static ID table_id = 0;
|
376
341
|
|
377
|
-
static void
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
{ NULL, 0, Qnil },
|
342
|
+
static void openstruct_alt(VALUE obj, int depth, Out out) {
|
343
|
+
struct _attr attrs[] = {
|
344
|
+
{"t", 1, Qnil},
|
345
|
+
{NULL, 0, Qnil},
|
382
346
|
};
|
383
347
|
if (0 == table_id) {
|
384
|
-
|
348
|
+
table_id = rb_intern("table");
|
385
349
|
}
|
386
350
|
attrs[0].value = rb_funcall(obj, table_id, 0);
|
387
351
|
|
388
352
|
oj_code_attrs(obj, attrs, depth, out, true);
|
389
353
|
}
|
390
354
|
|
391
|
-
static void
|
392
|
-
|
393
|
-
|
394
|
-
size_t
|
395
|
-
|
396
|
-
VALUE args[] = { Qundef, Qundef, Qundef, Qundef };
|
355
|
+
static void range_alt(VALUE obj, int depth, Out out) {
|
356
|
+
int d3 = depth + 2;
|
357
|
+
size_t size = d3 * out->indent + 2;
|
358
|
+
size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
|
359
|
+
VALUE args[] = {Qundef, Qundef, Qundef, Qundef};
|
397
360
|
|
398
361
|
dump_obj_classname(rb_class2name(rb_obj_class(obj)), depth, out);
|
399
362
|
|
400
363
|
assure_size(out, size + sep_len + 6);
|
401
364
|
*out->cur++ = ',';
|
402
365
|
fill_indent(out, d3);
|
403
|
-
|
404
|
-
*out->cur++ = 'a';
|
405
|
-
*out->cur++ = '"';
|
366
|
+
APPEND_CHARS(out->cur, "\"a\"", 3);
|
406
367
|
if (0 < out->opts->dump_opts.before_size) {
|
407
|
-
|
408
|
-
out->cur += out->opts->dump_opts.before_size;
|
368
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
|
409
369
|
}
|
410
370
|
*out->cur++ = ':';
|
411
371
|
if (0 < out->opts->dump_opts.after_size) {
|
412
|
-
|
413
|
-
out->cur += out->opts->dump_opts.after_size;
|
372
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
|
414
373
|
}
|
415
374
|
args[0] = rb_funcall(obj, oj_begin_id, 0);
|
416
375
|
args[1] = rb_funcall(obj, oj_end_id, 0);
|
@@ -418,22 +377,21 @@ range_alt(VALUE obj, int depth, Out out) {
|
|
418
377
|
dump_values_array(args, depth, out);
|
419
378
|
fill_indent(out, depth);
|
420
379
|
*out->cur++ = '}';
|
421
|
-
*out->cur
|
380
|
+
*out->cur = '\0';
|
422
381
|
}
|
423
382
|
|
424
|
-
static ID
|
425
|
-
static ID
|
383
|
+
static ID numerator_id = 0;
|
384
|
+
static ID denominator_id = 0;
|
426
385
|
|
427
|
-
static void
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
{ NULL, 0, Qnil },
|
386
|
+
static void rational_alt(VALUE obj, int depth, Out out) {
|
387
|
+
struct _attr attrs[] = {
|
388
|
+
{"n", 1, Qnil},
|
389
|
+
{"d", 1, Qnil},
|
390
|
+
{NULL, 0, Qnil},
|
433
391
|
};
|
434
392
|
if (0 == numerator_id) {
|
435
|
-
|
436
|
-
|
393
|
+
numerator_id = rb_intern("numerator");
|
394
|
+
denominator_id = rb_intern("denominator");
|
437
395
|
}
|
438
396
|
attrs[0].value = rb_funcall(obj, numerator_id, 0);
|
439
397
|
attrs[1].value = rb_funcall(obj, denominator_id, 0);
|
@@ -441,19 +399,18 @@ rational_alt(VALUE obj, int depth, Out out) {
|
|
441
399
|
oj_code_attrs(obj, attrs, depth, out, true);
|
442
400
|
}
|
443
401
|
|
444
|
-
static ID
|
445
|
-
static ID
|
402
|
+
static ID options_id = 0;
|
403
|
+
static ID source_id = 0;
|
446
404
|
|
447
|
-
static void
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
{ NULL, 0, Qnil },
|
405
|
+
static void regexp_alt(VALUE obj, int depth, Out out) {
|
406
|
+
struct _attr attrs[] = {
|
407
|
+
{"o", 1, Qnil},
|
408
|
+
{"s", 1, Qnil},
|
409
|
+
{NULL, 0, Qnil},
|
453
410
|
};
|
454
411
|
if (0 == options_id) {
|
455
|
-
|
456
|
-
|
412
|
+
options_id = rb_intern("options");
|
413
|
+
source_id = rb_intern("source");
|
457
414
|
}
|
458
415
|
attrs[0].value = rb_funcall(obj, options_id, 0);
|
459
416
|
attrs[1].value = rb_funcall(obj, source_id, 0);
|
@@ -461,30 +418,24 @@ regexp_alt(VALUE obj, int depth, Out out) {
|
|
461
418
|
oj_code_attrs(obj, attrs, depth, out, true);
|
462
419
|
}
|
463
420
|
|
464
|
-
static void
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
{ NULL, 0, Qnil },
|
421
|
+
static void time_alt(VALUE obj, int depth, Out out) {
|
422
|
+
struct _attr attrs[] = {
|
423
|
+
{"s", 1, Qundef, 0, Qundef},
|
424
|
+
{"n", 1, Qundef, 0, Qundef},
|
425
|
+
{NULL, 0, Qnil},
|
470
426
|
};
|
471
|
-
time_t
|
472
|
-
long long
|
427
|
+
time_t sec;
|
428
|
+
long long nsec;
|
473
429
|
|
474
|
-
#ifdef HAVE_RB_TIME_TIMESPEC
|
475
430
|
if (16 <= sizeof(struct timespec)) {
|
476
|
-
|
431
|
+
struct timespec ts = rb_time_timespec(obj);
|
477
432
|
|
478
|
-
|
479
|
-
|
433
|
+
sec = (long long)ts.tv_sec;
|
434
|
+
nsec = ts.tv_nsec;
|
480
435
|
} else {
|
481
|
-
|
482
|
-
|
436
|
+
sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
437
|
+
nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
483
438
|
}
|
484
|
-
#else
|
485
|
-
sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
486
|
-
nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
487
|
-
#endif
|
488
439
|
|
489
440
|
attrs[0].num = sec;
|
490
441
|
attrs[1].num = nsec;
|
@@ -492,68 +443,68 @@ time_alt(VALUE obj, int depth, Out out) {
|
|
492
443
|
oj_code_attrs(obj, attrs, depth, out, true);
|
493
444
|
}
|
494
445
|
|
495
|
-
struct _code
|
496
|
-
{
|
497
|
-
{
|
498
|
-
{
|
499
|
-
{
|
500
|
-
{
|
501
|
-
{
|
502
|
-
{
|
503
|
-
{
|
504
|
-
{
|
446
|
+
struct _code oj_compat_codes[] = {
|
447
|
+
{"BigDecimal", Qnil, bigdecimal_alt, NULL, false},
|
448
|
+
{"Complex", Qnil, complex_alt, NULL, false},
|
449
|
+
{"Date", Qnil, date_alt, false},
|
450
|
+
{"DateTime", Qnil, datetime_alt, NULL, false},
|
451
|
+
{"OpenStruct", Qnil, openstruct_alt, NULL, false},
|
452
|
+
{"Range", Qnil, range_alt, NULL, false},
|
453
|
+
{"Rational", Qnil, rational_alt, NULL, false},
|
454
|
+
{"Regexp", Qnil, regexp_alt, NULL, false},
|
455
|
+
{"Time", Qnil, time_alt, NULL, false},
|
505
456
|
// TBD the rest of the library classes
|
506
|
-
{
|
457
|
+
{NULL, Qundef, NULL, NULL, false},
|
507
458
|
};
|
508
459
|
|
509
460
|
VALUE
|
510
461
|
oj_add_to_json(int argc, VALUE *argv, VALUE self) {
|
511
|
-
Code
|
462
|
+
Code a;
|
512
463
|
|
513
464
|
if (0 == argc) {
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
465
|
+
for (a = oj_compat_codes; NULL != a->name; a++) {
|
466
|
+
if (Qnil == a->clas || Qundef == a->clas) {
|
467
|
+
a->clas = rb_const_get_at(rb_cObject, rb_intern(a->name));
|
468
|
+
}
|
469
|
+
a->active = true;
|
470
|
+
}
|
471
|
+
use_struct_alt = true;
|
472
|
+
use_exception_alt = true;
|
473
|
+
use_bignum_alt = true;
|
474
|
+
oj_use_hash_alt = true;
|
475
|
+
oj_use_array_alt = true;
|
525
476
|
} else {
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
477
|
+
for (; 0 < argc; argc--, argv++) {
|
478
|
+
if (rb_cStruct == *argv) {
|
479
|
+
use_struct_alt = true;
|
480
|
+
continue;
|
481
|
+
}
|
482
|
+
if (rb_eException == *argv) {
|
483
|
+
use_exception_alt = true;
|
484
|
+
continue;
|
485
|
+
}
|
486
|
+
if (rb_cInteger == *argv) {
|
487
|
+
use_bignum_alt = true;
|
488
|
+
continue;
|
489
|
+
}
|
490
|
+
if (rb_cHash == *argv) {
|
491
|
+
oj_use_hash_alt = true;
|
492
|
+
continue;
|
493
|
+
}
|
494
|
+
if (rb_cArray == *argv) {
|
495
|
+
oj_use_array_alt = true;
|
496
|
+
continue;
|
497
|
+
}
|
498
|
+
for (a = oj_compat_codes; NULL != a->name; a++) {
|
499
|
+
if (Qnil == a->clas || Qundef == a->clas) {
|
500
|
+
a->clas = rb_const_get_at(rb_cObject, rb_intern(a->name));
|
501
|
+
}
|
502
|
+
if (*argv == a->clas) {
|
503
|
+
a->active = true;
|
504
|
+
break;
|
505
|
+
}
|
506
|
+
}
|
507
|
+
}
|
557
508
|
}
|
558
509
|
return Qnil;
|
559
510
|
}
|
@@ -561,36 +512,36 @@ oj_add_to_json(int argc, VALUE *argv, VALUE self) {
|
|
561
512
|
VALUE
|
562
513
|
oj_remove_to_json(int argc, VALUE *argv, VALUE self) {
|
563
514
|
if (0 == argc) {
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
515
|
+
oj_code_set_active(oj_compat_codes, Qnil, false);
|
516
|
+
use_struct_alt = false;
|
517
|
+
use_exception_alt = false;
|
518
|
+
use_bignum_alt = false;
|
519
|
+
oj_use_hash_alt = false;
|
520
|
+
oj_use_array_alt = false;
|
570
521
|
} else {
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
522
|
+
for (; 0 < argc; argc--, argv++) {
|
523
|
+
if (rb_cStruct == *argv) {
|
524
|
+
use_struct_alt = false;
|
525
|
+
continue;
|
526
|
+
}
|
527
|
+
if (rb_eException == *argv) {
|
528
|
+
use_exception_alt = false;
|
529
|
+
continue;
|
530
|
+
}
|
531
|
+
if (rb_cInteger == *argv) {
|
532
|
+
use_bignum_alt = false;
|
533
|
+
continue;
|
534
|
+
}
|
535
|
+
if (rb_cHash == *argv) {
|
536
|
+
oj_use_hash_alt = false;
|
537
|
+
continue;
|
538
|
+
}
|
539
|
+
if (rb_cArray == *argv) {
|
540
|
+
oj_use_array_alt = false;
|
541
|
+
continue;
|
542
|
+
}
|
543
|
+
oj_code_set_active(oj_compat_codes, *argv, false);
|
544
|
+
}
|
594
545
|
}
|
595
546
|
return Qnil;
|
596
547
|
}
|
@@ -598,380 +549,349 @@ oj_remove_to_json(int argc, VALUE *argv, VALUE self) {
|
|
598
549
|
// The JSON gem is inconsistent with handling of infinity. Using
|
599
550
|
// JSON.dump(0.1/0) returns the string Infinity but (0.1/0).to_json raise and
|
600
551
|
// exception. Worse, for BigDecimals a quoted "Infinity" is returned.
|
601
|
-
static void
|
602
|
-
|
603
|
-
char
|
604
|
-
|
605
|
-
|
606
|
-
int cnt = 0;
|
552
|
+
static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
553
|
+
char buf[64];
|
554
|
+
char *b;
|
555
|
+
double d = rb_num2dbl(obj);
|
556
|
+
size_t cnt = 0;
|
607
557
|
|
608
558
|
if (0.0 == d) {
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
559
|
+
b = buf;
|
560
|
+
*b++ = '0';
|
561
|
+
*b++ = '.';
|
562
|
+
*b++ = '0';
|
563
|
+
*b++ = '\0';
|
564
|
+
cnt = 3;
|
615
565
|
} else if (OJ_INFINITY == d) {
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
566
|
+
if (WordNan == out->opts->dump_opts.nan_dump) {
|
567
|
+
strcpy(buf, "Infinity");
|
568
|
+
cnt = 8;
|
569
|
+
} else {
|
570
|
+
raise_json_err("Infinity not allowed in JSON.", "GeneratorError");
|
571
|
+
}
|
621
572
|
} else if (-OJ_INFINITY == d) {
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
573
|
+
if (WordNan == out->opts->dump_opts.nan_dump) {
|
574
|
+
strcpy(buf, "-Infinity");
|
575
|
+
cnt = 9;
|
576
|
+
} else {
|
577
|
+
raise_json_err("-Infinity not allowed in JSON.", "GeneratorError");
|
578
|
+
}
|
627
579
|
} else if (isnan(d)) {
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
580
|
+
if (WordNan == out->opts->dump_opts.nan_dump) {
|
581
|
+
strcpy(buf, "NaN");
|
582
|
+
cnt = 3;
|
583
|
+
} else {
|
584
|
+
raise_json_err("NaN not allowed in JSON.", "GeneratorError");
|
585
|
+
}
|
633
586
|
} else if (d == (double)(long long int)d) {
|
634
|
-
|
587
|
+
cnt = snprintf(buf, sizeof(buf), "%.1f", d);
|
635
588
|
} else if (oj_rails_float_opt) {
|
636
|
-
|
589
|
+
cnt = oj_dump_float_printf(buf, sizeof(buf), obj, d, "%0.16g");
|
637
590
|
} else {
|
638
|
-
|
591
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
639
592
|
|
640
|
-
|
641
|
-
|
593
|
+
strcpy(buf, RSTRING_PTR(rstr));
|
594
|
+
cnt = RSTRING_LEN(rstr);
|
642
595
|
}
|
643
596
|
assure_size(out, cnt);
|
644
|
-
|
645
|
-
*out->cur++ = *b;
|
646
|
-
}
|
597
|
+
APPEND_CHARS(out->cur, buf, cnt);
|
647
598
|
*out->cur = '\0';
|
648
599
|
}
|
649
600
|
|
650
|
-
static int
|
651
|
-
|
652
|
-
int
|
601
|
+
static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
602
|
+
Out out = (Out)ov;
|
603
|
+
int depth = out->depth;
|
653
604
|
|
654
605
|
if (out->omit_nil && Qnil == value) {
|
655
|
-
|
606
|
+
return ST_CONTINUE;
|
656
607
|
}
|
657
608
|
if (!out->opts->dump_opts.use) {
|
658
|
-
|
659
|
-
|
609
|
+
assure_size(out, depth * out->indent + 1);
|
610
|
+
fill_indent(out, depth);
|
660
611
|
} else {
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
}
|
672
|
-
}
|
612
|
+
assure_size(out, depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
|
613
|
+
if (0 < out->opts->dump_opts.hash_size) {
|
614
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
|
615
|
+
}
|
616
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
617
|
+
int i;
|
618
|
+
for (i = depth; 0 < i; i--) {
|
619
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
620
|
+
}
|
621
|
+
}
|
673
622
|
}
|
674
623
|
switch (rb_type(key)) {
|
675
|
-
case T_STRING:
|
676
|
-
|
677
|
-
break;
|
678
|
-
case T_SYMBOL:
|
679
|
-
oj_dump_sym(key, 0, out, false);
|
680
|
-
break;
|
624
|
+
case T_STRING: oj_dump_str(key, 0, out, false); break;
|
625
|
+
case T_SYMBOL: oj_dump_sym(key, 0, out, false); break;
|
681
626
|
default:
|
682
|
-
|
683
|
-
|
684
|
-
|
627
|
+
/*rb_raise(rb_eTypeError, "In :compat mode all Hash keys must be Strings or Symbols, not %s.\n",
|
628
|
+
* rb_class2name(rb_obj_class(key)));*/
|
629
|
+
oj_dump_str(oj_safe_string_convert(key), 0, out, false);
|
630
|
+
break;
|
685
631
|
}
|
686
632
|
if (!out->opts->dump_opts.use) {
|
687
|
-
|
633
|
+
*out->cur++ = ':';
|
688
634
|
} else {
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
out->cur += out->opts->dump_opts.after_size;
|
698
|
-
}
|
635
|
+
assure_size(out, out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2);
|
636
|
+
if (0 < out->opts->dump_opts.before_size) {
|
637
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
|
638
|
+
}
|
639
|
+
*out->cur++ = ':';
|
640
|
+
if (0 < out->opts->dump_opts.after_size) {
|
641
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
|
642
|
+
}
|
699
643
|
}
|
700
644
|
oj_dump_compat_val(value, depth, out, true);
|
701
|
-
out->depth
|
645
|
+
out->depth = depth;
|
702
646
|
*out->cur++ = ',';
|
703
647
|
|
704
648
|
return ST_CONTINUE;
|
705
649
|
}
|
706
650
|
|
707
|
-
static void
|
708
|
-
|
709
|
-
|
710
|
-
long id = oj_check_circular(obj, out);
|
651
|
+
static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
|
652
|
+
int cnt;
|
653
|
+
long id = oj_check_circular(obj, out);
|
711
654
|
|
712
655
|
if (0 > id) {
|
713
|
-
|
714
|
-
|
656
|
+
raise_json_err("Too deeply nested", "NestingError");
|
657
|
+
return;
|
715
658
|
}
|
716
659
|
if (as_ok && !oj_use_hash_alt && rb_obj_class(obj) != rb_cHash && rb_respond_to(obj, oj_to_json_id)) {
|
717
|
-
|
718
|
-
|
660
|
+
dump_to_json(obj, out);
|
661
|
+
return;
|
719
662
|
}
|
720
663
|
cnt = (int)RHASH_SIZE(obj);
|
721
664
|
assure_size(out, 2);
|
722
665
|
if (0 == cnt) {
|
723
|
-
|
724
|
-
*out->cur++ = '}';
|
666
|
+
APPEND_CHARS(out->cur, "{}", 2);
|
725
667
|
} else {
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
}
|
750
|
-
*out->cur++ = '}';
|
668
|
+
*out->cur++ = '{';
|
669
|
+
out->depth = depth + 1;
|
670
|
+
rb_hash_foreach(obj, hash_cb, (VALUE)out);
|
671
|
+
if (',' == *(out->cur - 1)) {
|
672
|
+
out->cur--; // backup to overwrite last comma
|
673
|
+
}
|
674
|
+
if (!out->opts->dump_opts.use) {
|
675
|
+
assure_size(out, depth * out->indent + 2);
|
676
|
+
fill_indent(out, depth);
|
677
|
+
} else {
|
678
|
+
assure_size(out, depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
|
679
|
+
if (0 < out->opts->dump_opts.hash_size) {
|
680
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
|
681
|
+
}
|
682
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
683
|
+
int i;
|
684
|
+
|
685
|
+
for (i = depth; 0 < i; i--) {
|
686
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
687
|
+
}
|
688
|
+
}
|
689
|
+
}
|
690
|
+
*out->cur++ = '}';
|
751
691
|
}
|
752
692
|
*out->cur = '\0';
|
753
693
|
}
|
754
694
|
|
755
695
|
// In compat mode only the first call check for to_json. After that to_s is
|
756
696
|
// called.
|
757
|
-
static void
|
758
|
-
dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
|
697
|
+
static void dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
|
759
698
|
if (oj_code_dump(oj_compat_codes, obj, depth, out)) {
|
760
|
-
|
699
|
+
return;
|
761
700
|
}
|
762
701
|
if (use_exception_alt && rb_obj_is_kind_of(obj, rb_eException)) {
|
763
|
-
|
764
|
-
|
702
|
+
exception_alt(obj, depth, out);
|
703
|
+
return;
|
765
704
|
}
|
766
705
|
if (Yes == out->opts->raw_json && rb_respond_to(obj, oj_raw_json_id)) {
|
767
|
-
|
768
|
-
|
706
|
+
oj_dump_raw_json(obj, depth, out);
|
707
|
+
return;
|
769
708
|
}
|
770
709
|
if (as_ok && rb_respond_to(obj, oj_to_json_id)) {
|
771
|
-
|
772
|
-
|
710
|
+
dump_to_json(obj, out);
|
711
|
+
return;
|
773
712
|
}
|
774
713
|
// Nothing else matched so encode as a JSON object with Ruby obj members
|
775
714
|
// as JSON object members.
|
776
715
|
oj_dump_obj_to_s(obj, out);
|
777
716
|
}
|
778
717
|
|
779
|
-
static void
|
780
|
-
|
781
|
-
VALUE clas = rb_obj_class(obj);
|
718
|
+
static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
719
|
+
VALUE clas = rb_obj_class(obj);
|
782
720
|
|
783
721
|
if (oj_code_dump(oj_compat_codes, obj, depth, out)) {
|
784
|
-
|
722
|
+
return;
|
785
723
|
}
|
786
724
|
if (rb_cRange == clas) {
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
return;
|
725
|
+
*out->cur++ = '"';
|
726
|
+
oj_dump_compat_val(rb_funcall(obj, oj_begin_id, 0), 0, out, false);
|
727
|
+
assure_size(out, 3);
|
728
|
+
APPEND_CHARS(out->cur, "..", 2);
|
729
|
+
if (Qtrue == rb_funcall(obj, oj_exclude_end_id, 0)) {
|
730
|
+
*out->cur++ = '.';
|
731
|
+
}
|
732
|
+
oj_dump_compat_val(rb_funcall(obj, oj_end_id, 0), 0, out, false);
|
733
|
+
*out->cur++ = '"';
|
734
|
+
|
735
|
+
return;
|
799
736
|
}
|
800
737
|
if (as_ok && rb_respond_to(obj, oj_to_json_id)) {
|
801
|
-
|
738
|
+
dump_to_json(obj, out);
|
802
739
|
|
803
|
-
|
740
|
+
return;
|
804
741
|
}
|
805
742
|
if (use_struct_alt) {
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
743
|
+
int d3 = depth + 2;
|
744
|
+
size_t size = d3 * out->indent + 2;
|
745
|
+
size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
|
746
|
+
const char *classname = rb_class2name(rb_obj_class(obj));
|
747
|
+
VALUE args[100];
|
748
|
+
int cnt;
|
749
|
+
int i;
|
750
|
+
|
751
|
+
if (NULL == classname || '#' == *classname) {
|
752
|
+
raise_json_err("Only named structs are supported.", "JSONError");
|
753
|
+
}
|
817
754
|
#ifdef RSTRUCT_LEN
|
818
755
|
#if RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
819
|
-
|
820
|
-
#else
|
821
|
-
|
822
|
-
#endif
|
756
|
+
cnt = (int)NUM2LONG(RSTRUCT_LEN(obj));
|
757
|
+
#else // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
758
|
+
cnt = (int)RSTRUCT_LEN(obj);
|
759
|
+
#endif // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
823
760
|
#else
|
824
|
-
|
825
|
-
|
826
|
-
|
761
|
+
// This is a bit risky as a struct in C ruby is not the same as a Struct
|
762
|
+
// class in interpreted Ruby so length() may not be defined.
|
763
|
+
cnt = FIX2INT(rb_funcall2(obj, oj_length_id, 0, 0));
|
827
764
|
#endif
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
strcpy(out->cur, out->opts->dump_opts.after_sep);
|
847
|
-
out->cur += out->opts->dump_opts.after_size;
|
848
|
-
}
|
849
|
-
for (i = 0; i < cnt; i++) {
|
765
|
+
if (sizeof(args) / sizeof(*args) <= (size_t)cnt) {
|
766
|
+
// TBD allocate and try again
|
767
|
+
cnt = 99;
|
768
|
+
}
|
769
|
+
dump_obj_classname(rb_class2name(rb_obj_class(obj)), depth, out);
|
770
|
+
|
771
|
+
assure_size(out, size + sep_len + 6);
|
772
|
+
*out->cur++ = ',';
|
773
|
+
fill_indent(out, d3);
|
774
|
+
APPEND_CHARS(out->cur, "\"v\"", 3);
|
775
|
+
if (0 < out->opts->dump_opts.before_size) {
|
776
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
|
777
|
+
}
|
778
|
+
*out->cur++ = ':';
|
779
|
+
if (0 < out->opts->dump_opts.after_size) {
|
780
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
|
781
|
+
}
|
782
|
+
for (i = 0; i < cnt; i++) {
|
850
783
|
#ifdef RSTRUCT_LEN
|
851
|
-
|
784
|
+
args[i] = RSTRUCT_GET(obj, i);
|
852
785
|
#else
|
853
|
-
|
786
|
+
args[i] = rb_struct_aref(obj, INT2FIX(i));
|
854
787
|
#endif
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
788
|
+
}
|
789
|
+
args[cnt] = Qundef;
|
790
|
+
dump_values_array(args, depth, out);
|
791
|
+
fill_indent(out, depth);
|
792
|
+
*out->cur++ = '}';
|
793
|
+
*out->cur = '\0';
|
861
794
|
} else {
|
862
|
-
|
795
|
+
oj_dump_obj_to_s(obj, out);
|
863
796
|
}
|
864
797
|
}
|
865
798
|
|
866
|
-
static void
|
867
|
-
dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
|
799
|
+
static void dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
|
868
800
|
// The json gem uses to_s explicitly. to_s can be overridden while
|
869
801
|
// rb_big2str can not so unless overridden by using add_to_json(Integer)
|
870
802
|
// this must use to_s to pass the json gem unit tests.
|
871
|
-
volatile VALUE
|
872
|
-
|
873
|
-
|
803
|
+
volatile VALUE rs;
|
804
|
+
size_t cnt;
|
805
|
+
bool dump_as_string = false;
|
874
806
|
|
875
807
|
if (use_bignum_alt) {
|
876
|
-
|
808
|
+
rs = rb_big2str(obj, 10);
|
877
809
|
} else {
|
878
|
-
|
810
|
+
rs = oj_safe_string_convert(obj);
|
879
811
|
}
|
880
812
|
rb_check_type(rs, T_STRING);
|
881
|
-
cnt =
|
882
|
-
|
883
|
-
if (out->opts->integer_range_min != 0 || out->opts->integer_range_max != 0) {
|
884
|
-
dump_as_string = true; // Bignum cannot be inside of Fixnum range
|
885
|
-
assure_size(out, cnt + 2);
|
886
|
-
*out->cur++ = '"';
|
887
|
-
} else {
|
888
|
-
assure_size(out, cnt);
|
889
|
-
}
|
890
|
-
|
891
|
-
memcpy(out->cur, rb_string_value_ptr((VALUE*)&rs), cnt);
|
892
|
-
out->cur += cnt;
|
893
|
-
|
894
|
-
if(dump_as_string) {
|
895
|
-
*out->cur++ = '"';
|
896
|
-
}
|
813
|
+
cnt = RSTRING_LEN(rs);
|
897
814
|
|
815
|
+
if (out->opts->int_range_min != 0 || out->opts->int_range_max != 0) {
|
816
|
+
dump_as_string = true; // Bignum cannot be inside of Fixnum range
|
817
|
+
assure_size(out, cnt + 2);
|
818
|
+
*out->cur++ = '"';
|
819
|
+
} else {
|
820
|
+
assure_size(out, cnt);
|
821
|
+
}
|
822
|
+
APPEND_CHARS(out->cur, RSTRING_PTR(rs), cnt);
|
823
|
+
if (dump_as_string) {
|
824
|
+
*out->cur++ = '"';
|
825
|
+
}
|
898
826
|
*out->cur = '\0';
|
899
827
|
}
|
900
828
|
|
901
|
-
static DumpFunc
|
902
|
-
NULL,
|
903
|
-
dump_obj,
|
904
|
-
oj_dump_class,
|
905
|
-
oj_dump_class,
|
906
|
-
dump_float,
|
907
|
-
oj_dump_str,
|
908
|
-
dump_obj,
|
909
|
-
dump_array,
|
910
|
-
dump_hash,
|
911
|
-
dump_struct,
|
912
|
-
dump_bignum,
|
913
|
-
NULL,
|
914
|
-
dump_obj,
|
915
|
-
NULL,
|
916
|
-
dump_obj,
|
917
|
-
dump_obj,
|
918
|
-
NULL,
|
919
|
-
oj_dump_nil,
|
920
|
-
oj_dump_true,
|
921
|
-
oj_dump_false,
|
922
|
-
oj_dump_sym,
|
923
|
-
oj_dump_fixnum,
|
829
|
+
static DumpFunc compat_funcs[] = {
|
830
|
+
NULL, // RUBY_T_NONE = 0x00,
|
831
|
+
dump_obj, // RUBY_T_OBJECT = 0x01,
|
832
|
+
oj_dump_class, // RUBY_T_CLASS = 0x02,
|
833
|
+
oj_dump_class, // RUBY_T_MODULE = 0x03,
|
834
|
+
dump_float, // RUBY_T_FLOAT = 0x04,
|
835
|
+
oj_dump_str, // RUBY_T_STRING = 0x05,
|
836
|
+
dump_obj, // RUBY_T_REGEXP = 0x06,
|
837
|
+
dump_array, // RUBY_T_ARRAY = 0x07,
|
838
|
+
dump_hash, // RUBY_T_HASH = 0x08,
|
839
|
+
dump_struct, // RUBY_T_STRUCT = 0x09,
|
840
|
+
dump_bignum, // RUBY_T_BIGNUM = 0x0a,
|
841
|
+
NULL, // RUBY_T_FILE = 0x0b,
|
842
|
+
dump_obj, // RUBY_T_DATA = 0x0c,
|
843
|
+
NULL, // RUBY_T_MATCH = 0x0d,
|
844
|
+
dump_obj, // RUBY_T_COMPLEX = 0x0e,
|
845
|
+
dump_obj, // RUBY_T_RATIONAL = 0x0f,
|
846
|
+
NULL, // 0x10
|
847
|
+
oj_dump_nil, // RUBY_T_NIL = 0x11,
|
848
|
+
oj_dump_true, // RUBY_T_TRUE = 0x12,
|
849
|
+
oj_dump_false, // RUBY_T_FALSE = 0x13,
|
850
|
+
oj_dump_sym, // RUBY_T_SYMBOL = 0x14,
|
851
|
+
oj_dump_fixnum, // RUBY_T_FIXNUM = 0x15,
|
924
852
|
};
|
925
853
|
|
926
|
-
static void
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
854
|
+
static void set_state_depth(VALUE state, int depth) {
|
855
|
+
if (0 == rb_const_defined(rb_cObject, rb_intern("JSON"))) {
|
856
|
+
rb_require("oj/json");
|
857
|
+
}
|
858
|
+
{
|
859
|
+
VALUE json_module = rb_const_get_at(rb_cObject, rb_intern("JSON"));
|
860
|
+
VALUE ext = rb_const_get(json_module, rb_intern("Ext"));
|
861
|
+
VALUE generator = rb_const_get(ext, rb_intern("Generator"));
|
862
|
+
VALUE state_class = rb_const_get(generator, rb_intern("State"));
|
932
863
|
|
933
|
-
|
934
|
-
|
864
|
+
if (state_class == rb_obj_class(state)) {
|
865
|
+
rb_funcall(state, rb_intern("depth="), 1, INT2NUM(depth));
|
866
|
+
}
|
935
867
|
}
|
936
868
|
}
|
937
869
|
|
938
|
-
void
|
939
|
-
|
940
|
-
int type = rb_type(obj);
|
870
|
+
void oj_dump_compat_val(VALUE obj, int depth, Out out, bool as_ok) {
|
871
|
+
int type = rb_type(obj);
|
941
872
|
|
942
|
-
|
943
|
-
|
944
|
-
|
873
|
+
TRACE(out->opts->trace, "dump", obj, depth, TraceIn);
|
874
|
+
// The max_nesting logic is that an empty Array or Hash is assumed to have
|
875
|
+
// content so the max_nesting should fail but a non-collection value is
|
876
|
+
// okay. That means a check for a collectable value is needed before
|
877
|
+
// raising.
|
945
878
|
if (out->opts->dump_opts.max_depth <= depth) {
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
set_state_depth(*out->argv, depth);
|
953
|
-
}
|
954
|
-
rb_raise(rb_eArgError, "Too deeply nested.");
|
955
|
-
} else if (out->opts->dump_opts.max_depth < depth) {
|
956
|
-
if (0 < out->argc) {
|
957
|
-
set_state_depth(*out->argv, depth - 1);
|
958
|
-
}
|
959
|
-
raise_json_err("Too deeply nested", "NestingError");
|
960
|
-
}
|
879
|
+
if (RUBY_T_ARRAY == type || RUBY_T_HASH == type) {
|
880
|
+
if (0 < out->argc) {
|
881
|
+
set_state_depth(*out->argv, depth);
|
882
|
+
}
|
883
|
+
raise_json_err("Too deeply nested", "NestingError");
|
884
|
+
}
|
961
885
|
}
|
962
886
|
if (0 < type && type <= RUBY_T_FIXNUM) {
|
963
|
-
|
887
|
+
DumpFunc f = compat_funcs[type];
|
964
888
|
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
return;
|
971
|
-
}
|
889
|
+
if (NULL != f) {
|
890
|
+
f(obj, depth, out, as_ok);
|
891
|
+
TRACE(out->opts->trace, "dump", obj, depth, TraceOut);
|
892
|
+
return;
|
893
|
+
}
|
972
894
|
}
|
973
895
|
oj_dump_nil(Qnil, depth, out, false);
|
974
|
-
|
975
|
-
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
976
|
-
}
|
896
|
+
TRACE(out->opts->trace, "dump", Qnil, depth, TraceOut);
|
977
897
|
}
|