oj 3.7.4 → 3.13.21
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 +1352 -0
- data/README.md +29 -8
- data/RELEASE_NOTES.md +61 -0
- data/ext/oj/buf.h +53 -72
- data/ext/oj/cache.c +326 -0
- data/ext/oj/cache.h +21 -0
- data/ext/oj/cache8.c +61 -64
- data/ext/oj/cache8.h +12 -39
- data/ext/oj/circarray.c +37 -43
- data/ext/oj/circarray.h +16 -17
- data/ext/oj/code.c +165 -179
- data/ext/oj/code.h +27 -29
- data/ext/oj/compat.c +174 -194
- data/ext/oj/custom.c +809 -866
- data/ext/oj/debug.c +132 -0
- data/ext/oj/dump.c +848 -863
- data/ext/oj/dump.h +81 -67
- data/ext/oj/dump_compat.c +85 -123
- data/ext/oj/dump_leaf.c +100 -188
- data/ext/oj/dump_object.c +527 -656
- data/ext/oj/dump_strict.c +315 -338
- data/ext/oj/encode.h +7 -34
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/err.c +40 -29
- data/ext/oj/err.h +48 -48
- data/ext/oj/extconf.rb +17 -4
- data/ext/oj/fast.c +1070 -1087
- data/ext/oj/intern.c +301 -0
- data/ext/oj/intern.h +26 -0
- data/ext/oj/mimic_json.c +469 -436
- data/ext/oj/object.c +525 -593
- data/ext/oj/odd.c +154 -138
- data/ext/oj/odd.h +37 -38
- data/ext/oj/oj.c +1325 -986
- data/ext/oj/oj.h +333 -316
- data/ext/oj/parse.c +1002 -846
- data/ext/oj/parse.h +92 -87
- data/ext/oj/parser.c +1557 -0
- data/ext/oj/parser.h +91 -0
- data/ext/oj/rails.c +888 -878
- data/ext/oj/rails.h +11 -14
- data/ext/oj/reader.c +141 -147
- data/ext/oj/reader.h +73 -89
- data/ext/oj/resolve.c +41 -62
- data/ext/oj/resolve.h +7 -9
- data/ext/oj/rxclass.c +71 -75
- data/ext/oj/rxclass.h +18 -19
- data/ext/oj/saj.c +443 -486
- data/ext/oj/saj2.c +602 -0
- data/ext/oj/scp.c +88 -113
- data/ext/oj/sparse.c +787 -709
- data/ext/oj/stream_writer.c +133 -159
- data/ext/oj/strict.c +127 -118
- data/ext/oj/string_writer.c +230 -249
- data/ext/oj/trace.c +34 -41
- data/ext/oj/trace.h +19 -19
- data/ext/oj/usual.c +1254 -0
- data/ext/oj/util.c +136 -0
- data/ext/oj/util.h +20 -0
- data/ext/oj/val_stack.c +59 -67
- data/ext/oj/val_stack.h +91 -129
- data/ext/oj/validate.c +46 -0
- data/ext/oj/wab.c +342 -353
- data/lib/oj/bag.rb +1 -0
- data/lib/oj/easy_hash.rb +5 -4
- data/lib/oj/error.rb +1 -1
- data/lib/oj/json.rb +1 -1
- data/lib/oj/mimic.rb +48 -14
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/state.rb +8 -7
- data/lib/oj/version.rb +2 -2
- data/lib/oj.rb +0 -8
- data/pages/Compatibility.md +1 -1
- data/pages/JsonGem.md +15 -0
- data/pages/Modes.md +53 -46
- data/pages/Options.md +72 -11
- data/pages/Parser.md +309 -0
- data/pages/Rails.md +73 -22
- data/pages/Security.md +1 -1
- data/test/activerecord/result_test.rb +7 -2
- data/test/activesupport5/abstract_unit.rb +45 -0
- data/test/activesupport5/decoding_test.rb +68 -60
- data/test/activesupport5/encoding_test.rb +111 -96
- data/test/activesupport5/encoding_test_cases.rb +33 -25
- data/test/activesupport5/test_helper.rb +43 -21
- data/test/activesupport5/time_zone_test_helpers.rb +18 -3
- data/test/activesupport6/abstract_unit.rb +44 -0
- data/test/activesupport6/decoding_test.rb +133 -0
- data/test/activesupport6/encoding_test.rb +507 -0
- data/test/activesupport6/encoding_test_cases.rb +98 -0
- data/test/activesupport6/test_common.rb +17 -0
- data/test/activesupport6/test_helper.rb +163 -0
- data/test/activesupport6/time_zone_test_helpers.rb +39 -0
- data/test/activesupport7/abstract_unit.rb +49 -0
- data/test/activesupport7/decoding_test.rb +125 -0
- data/test/activesupport7/encoding_test.rb +486 -0
- data/test/activesupport7/encoding_test_cases.rb +104 -0
- data/test/activesupport7/time_zone_test_helpers.rb +47 -0
- data/test/bar.rb +6 -12
- data/test/baz.rb +16 -0
- data/test/bug.rb +16 -0
- data/test/foo.rb +69 -75
- data/test/helper.rb +16 -0
- data/test/json_gem/json_common_interface_test.rb +8 -3
- data/test/json_gem/json_generator_test.rb +18 -4
- data/test/json_gem/json_parser_test.rb +9 -0
- data/test/json_gem/test_helper.rb +12 -0
- data/test/mem.rb +33 -0
- data/test/perf.rb +1 -1
- data/test/perf_dump.rb +50 -0
- data/test/perf_once.rb +58 -0
- data/test/perf_parser.rb +189 -0
- data/test/perf_scp.rb +11 -10
- data/test/perf_strict.rb +17 -23
- data/test/prec.rb +23 -0
- data/test/sample_json.rb +1 -1
- data/test/test_compat.rb +46 -10
- data/test/test_custom.rb +147 -8
- data/test/test_fast.rb +62 -2
- data/test/test_file.rb +25 -2
- data/test/test_gc.rb +13 -0
- data/test/test_generate.rb +21 -0
- data/test/test_hash.rb +11 -1
- data/test/test_integer_range.rb +7 -2
- data/test/test_object.rb +85 -9
- data/test/test_parser.rb +27 -0
- data/test/test_parser_saj.rb +335 -0
- data/test/test_parser_usual.rb +217 -0
- data/test/test_rails.rb +35 -0
- data/test/test_saj.rb +1 -1
- data/test/test_scp.rb +5 -5
- data/test/test_strict.rb +26 -1
- data/test/test_various.rb +87 -65
- data/test/test_wab.rb +2 -0
- data/test/test_writer.rb +19 -2
- data/test/tests.rb +1 -1
- data/test/zoo.rb +13 -0
- metadata +60 -110
- data/ext/oj/hash.c +0 -163
- data/ext/oj/hash.h +0 -46
- data/ext/oj/hash_test.c +0 -512
data/ext/oj/dump_strict.c
CHANGED
|
@@ -1,433 +1,410 @@
|
|
|
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
|
-
#include <
|
|
7
|
-
#include <
|
|
4
|
+
#include <errno.h>
|
|
5
|
+
#include <math.h>
|
|
8
6
|
#include <stdio.h>
|
|
7
|
+
#include <stdlib.h>
|
|
9
8
|
#include <string.h>
|
|
10
|
-
#include <
|
|
9
|
+
#include <time.h>
|
|
11
10
|
#include <unistd.h>
|
|
12
|
-
#include <errno.h>
|
|
13
11
|
|
|
14
12
|
#include "dump.h"
|
|
15
13
|
#include "trace.h"
|
|
16
14
|
|
|
17
15
|
// Workaround in case INFINITY is not defined in math.h or if the OS is CentOS
|
|
18
|
-
#define OJ_INFINITY (1.0/0.0)
|
|
16
|
+
#define OJ_INFINITY (1.0 / 0.0)
|
|
19
17
|
|
|
20
|
-
typedef unsigned long
|
|
18
|
+
typedef unsigned long ulong;
|
|
21
19
|
|
|
22
|
-
static const char
|
|
23
|
-
static const char
|
|
24
|
-
static const char
|
|
20
|
+
static const char inf_val[] = INF_VAL;
|
|
21
|
+
static const char ninf_val[] = NINF_VAL;
|
|
22
|
+
static const char nan_val[] = NAN_VAL;
|
|
25
23
|
|
|
26
|
-
static void
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
static void raise_strict(VALUE obj) {
|
|
25
|
+
rb_raise(rb_eTypeError,
|
|
26
|
+
"Failed to dump %s Object to JSON in strict mode.\n",
|
|
27
|
+
rb_class2name(rb_obj_class(obj)));
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
// Removed dependencies on math due to problems with CentOS 5.4.
|
|
32
|
-
static void
|
|
33
|
-
|
|
34
|
-
char
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
int cnt = 0;
|
|
31
|
+
static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
|
32
|
+
char buf[64];
|
|
33
|
+
char * b;
|
|
34
|
+
double d = rb_num2dbl(obj);
|
|
35
|
+
int cnt = 0;
|
|
38
36
|
|
|
39
37
|
if (0.0 == d) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
b = buf;
|
|
39
|
+
*b++ = '0';
|
|
40
|
+
*b++ = '.';
|
|
41
|
+
*b++ = '0';
|
|
42
|
+
*b++ = '\0';
|
|
43
|
+
cnt = 3;
|
|
46
44
|
} else {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
strncpy(buf, rb_string_value_ptr((VALUE*)&rstr), cnt);
|
|
110
|
-
buf[cnt] = '\0';
|
|
111
|
-
} else {
|
|
112
|
-
cnt = oj_dump_float_printf(buf, sizeof(buf), obj, d, out->opts->float_fmt);
|
|
113
|
-
}
|
|
45
|
+
NanDump nd = out->opts->dump_opts.nan_dump;
|
|
46
|
+
|
|
47
|
+
if (AutoNan == nd) {
|
|
48
|
+
nd = RaiseNan;
|
|
49
|
+
}
|
|
50
|
+
if (OJ_INFINITY == d) {
|
|
51
|
+
switch (nd) {
|
|
52
|
+
case RaiseNan:
|
|
53
|
+
case WordNan: raise_strict(obj); break;
|
|
54
|
+
case NullNan:
|
|
55
|
+
strcpy(buf, "null");
|
|
56
|
+
cnt = 4;
|
|
57
|
+
break;
|
|
58
|
+
case HugeNan:
|
|
59
|
+
default:
|
|
60
|
+
strcpy(buf, inf_val);
|
|
61
|
+
cnt = sizeof(inf_val) - 1;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
} else if (-OJ_INFINITY == d) {
|
|
65
|
+
switch (nd) {
|
|
66
|
+
case RaiseNan:
|
|
67
|
+
case WordNan: raise_strict(obj); break;
|
|
68
|
+
case NullNan:
|
|
69
|
+
strcpy(buf, "null");
|
|
70
|
+
cnt = 4;
|
|
71
|
+
break;
|
|
72
|
+
case HugeNan:
|
|
73
|
+
default:
|
|
74
|
+
strcpy(buf, ninf_val);
|
|
75
|
+
cnt = sizeof(ninf_val) - 1;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
} else if (isnan(d)) {
|
|
79
|
+
switch (nd) {
|
|
80
|
+
case RaiseNan:
|
|
81
|
+
case WordNan: raise_strict(obj); break;
|
|
82
|
+
case NullNan:
|
|
83
|
+
strcpy(buf, "null");
|
|
84
|
+
cnt = 4;
|
|
85
|
+
break;
|
|
86
|
+
case HugeNan:
|
|
87
|
+
default:
|
|
88
|
+
strcpy(buf, nan_val);
|
|
89
|
+
cnt = sizeof(nan_val) - 1;
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
} else if (d == (double)(long long int)d) {
|
|
93
|
+
cnt = snprintf(buf, sizeof(buf), "%.1f", d);
|
|
94
|
+
} else if (0 == out->opts->float_prec) {
|
|
95
|
+
volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
|
|
96
|
+
|
|
97
|
+
cnt = (int)RSTRING_LEN(rstr);
|
|
98
|
+
if ((int)sizeof(buf) <= cnt) {
|
|
99
|
+
cnt = sizeof(buf) - 1;
|
|
100
|
+
}
|
|
101
|
+
memcpy(buf, RSTRING_PTR(rstr), cnt);
|
|
102
|
+
buf[cnt] = '\0';
|
|
103
|
+
} else {
|
|
104
|
+
cnt = oj_dump_float_printf(buf, sizeof(buf), obj, d, out->opts->float_fmt);
|
|
105
|
+
}
|
|
114
106
|
}
|
|
115
107
|
assure_size(out, cnt);
|
|
116
|
-
|
|
117
|
-
*out->cur++ = *b;
|
|
118
|
-
}
|
|
108
|
+
APPEND_CHARS(out->cur, buf, cnt);
|
|
119
109
|
*out->cur = '\0';
|
|
120
110
|
}
|
|
121
111
|
|
|
122
|
-
static void
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
int
|
|
126
|
-
int d2 = depth + 1;
|
|
112
|
+
static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
|
113
|
+
size_t size;
|
|
114
|
+
int i, cnt;
|
|
115
|
+
int d2 = depth + 1;
|
|
127
116
|
|
|
128
117
|
if (Yes == out->opts->circular) {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
118
|
+
if (0 > oj_check_circular(a, out)) {
|
|
119
|
+
oj_dump_nil(Qnil, 0, out, false);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
133
122
|
}
|
|
134
|
-
cnt
|
|
123
|
+
cnt = (int)RARRAY_LEN(a);
|
|
135
124
|
*out->cur++ = '[';
|
|
136
|
-
size
|
|
125
|
+
size = 2;
|
|
137
126
|
assure_size(out, size);
|
|
138
127
|
if (0 == cnt) {
|
|
139
|
-
|
|
128
|
+
*out->cur++ = ']';
|
|
140
129
|
} else {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
-
fill_indent(out, depth);
|
|
191
|
-
}
|
|
192
|
-
*out->cur++ = ']';
|
|
130
|
+
if (out->opts->dump_opts.use) {
|
|
131
|
+
size = d2 * out->opts->dump_opts.indent_size + out->opts->dump_opts.array_size + 1;
|
|
132
|
+
} else {
|
|
133
|
+
size = d2 * out->indent + 2;
|
|
134
|
+
}
|
|
135
|
+
assure_size(out, size * cnt);
|
|
136
|
+
cnt--;
|
|
137
|
+
for (i = 0; i <= cnt; i++) {
|
|
138
|
+
if (out->opts->dump_opts.use) {
|
|
139
|
+
if (0 < out->opts->dump_opts.array_size) {
|
|
140
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
|
141
|
+
}
|
|
142
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
|
143
|
+
int i;
|
|
144
|
+
for (i = d2; 0 < i; i--) {
|
|
145
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
} else {
|
|
149
|
+
fill_indent(out, d2);
|
|
150
|
+
}
|
|
151
|
+
if (NullMode == out->opts->mode) {
|
|
152
|
+
oj_dump_null_val(RARRAY_AREF(a, i), d2, out);
|
|
153
|
+
} else {
|
|
154
|
+
oj_dump_strict_val(RARRAY_AREF(a, i), d2, out);
|
|
155
|
+
}
|
|
156
|
+
if (i < cnt) {
|
|
157
|
+
*out->cur++ = ',';
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
size = depth * out->indent + 1;
|
|
161
|
+
assure_size(out, size);
|
|
162
|
+
if (out->opts->dump_opts.use) {
|
|
163
|
+
// printf("*** d2: %u indent: %u '%s'\n", d2, out->opts->dump_opts->indent_size,
|
|
164
|
+
// out->opts->dump_opts->indent);
|
|
165
|
+
if (0 < out->opts->dump_opts.array_size) {
|
|
166
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
|
167
|
+
}
|
|
168
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
|
169
|
+
int i;
|
|
170
|
+
|
|
171
|
+
for (i = depth; 0 < i; i--) {
|
|
172
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
} else {
|
|
176
|
+
fill_indent(out, depth);
|
|
177
|
+
}
|
|
178
|
+
*out->cur++ = ']';
|
|
193
179
|
}
|
|
194
180
|
*out->cur = '\0';
|
|
195
181
|
}
|
|
196
182
|
|
|
197
|
-
static int
|
|
198
|
-
|
|
199
|
-
int
|
|
200
|
-
long
|
|
201
|
-
int
|
|
202
|
-
|
|
183
|
+
static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
184
|
+
Out out = (Out)ov;
|
|
185
|
+
int depth = out->depth;
|
|
186
|
+
long size;
|
|
187
|
+
int rtype = rb_type(key);
|
|
188
|
+
|
|
203
189
|
if (rtype != T_STRING && rtype != T_SYMBOL) {
|
|
204
|
-
|
|
190
|
+
rb_raise(rb_eTypeError,
|
|
191
|
+
"In :strict and :null mode all Hash keys must be Strings or Symbols, not %s.\n",
|
|
192
|
+
rb_class2name(rb_obj_class(key)));
|
|
205
193
|
}
|
|
206
194
|
if (out->omit_nil && Qnil == value) {
|
|
207
|
-
|
|
195
|
+
return ST_CONTINUE;
|
|
208
196
|
}
|
|
209
197
|
if (!out->opts->dump_opts.use) {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
198
|
+
size = depth * out->indent + 1;
|
|
199
|
+
assure_size(out, size);
|
|
200
|
+
fill_indent(out, depth);
|
|
201
|
+
if (rtype == T_STRING) {
|
|
202
|
+
oj_dump_str(key, 0, out, false);
|
|
203
|
+
} else {
|
|
204
|
+
oj_dump_sym(key, 0, out, false);
|
|
205
|
+
}
|
|
206
|
+
*out->cur++ = ':';
|
|
219
207
|
} else {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
if (0 < out->opts->dump_opts.after_size) {
|
|
246
|
-
strcpy(out->cur, out->opts->dump_opts.after_sep);
|
|
247
|
-
out->cur += out->opts->dump_opts.after_size;
|
|
248
|
-
}
|
|
208
|
+
size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
|
|
209
|
+
assure_size(out, size);
|
|
210
|
+
if (0 < out->opts->dump_opts.hash_size) {
|
|
211
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
|
|
212
|
+
}
|
|
213
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
|
214
|
+
int i;
|
|
215
|
+
for (i = depth; 0 < i; i--) {
|
|
216
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (rtype == T_STRING) {
|
|
220
|
+
oj_dump_str(key, 0, out, false);
|
|
221
|
+
} else {
|
|
222
|
+
oj_dump_sym(key, 0, out, false);
|
|
223
|
+
}
|
|
224
|
+
size = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
|
|
225
|
+
assure_size(out, size);
|
|
226
|
+
if (0 < out->opts->dump_opts.before_size) {
|
|
227
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
|
|
228
|
+
}
|
|
229
|
+
*out->cur++ = ':';
|
|
230
|
+
if (0 < out->opts->dump_opts.after_size) {
|
|
231
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
|
|
232
|
+
}
|
|
249
233
|
}
|
|
250
234
|
if (NullMode == out->opts->mode) {
|
|
251
|
-
|
|
235
|
+
oj_dump_null_val(value, depth, out);
|
|
252
236
|
} else {
|
|
253
|
-
|
|
237
|
+
oj_dump_strict_val(value, depth, out);
|
|
254
238
|
}
|
|
255
|
-
out->depth
|
|
239
|
+
out->depth = depth;
|
|
256
240
|
*out->cur++ = ',';
|
|
257
241
|
|
|
258
242
|
return ST_CONTINUE;
|
|
259
243
|
}
|
|
260
244
|
|
|
261
|
-
static void
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
size_t size;
|
|
245
|
+
static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
|
|
246
|
+
int cnt;
|
|
247
|
+
size_t size;
|
|
265
248
|
|
|
266
249
|
if (Yes == out->opts->circular) {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
250
|
+
if (0 > oj_check_circular(obj, out)) {
|
|
251
|
+
oj_dump_nil(Qnil, 0, out, false);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
271
254
|
}
|
|
272
|
-
cnt
|
|
255
|
+
cnt = (int)RHASH_SIZE(obj);
|
|
273
256
|
size = depth * out->indent + 2;
|
|
274
257
|
assure_size(out, 2);
|
|
275
258
|
*out->cur++ = '{';
|
|
276
259
|
if (0 == cnt) {
|
|
277
|
-
|
|
260
|
+
*out->cur++ = '}';
|
|
278
261
|
} else {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
}
|
|
303
|
-
*out->cur++ = '}';
|
|
262
|
+
out->depth = depth + 1;
|
|
263
|
+
rb_hash_foreach(obj, hash_cb, (VALUE)out);
|
|
264
|
+
if (',' == *(out->cur - 1)) {
|
|
265
|
+
out->cur--; // backup to overwrite last comma
|
|
266
|
+
}
|
|
267
|
+
if (!out->opts->dump_opts.use) {
|
|
268
|
+
assure_size(out, size);
|
|
269
|
+
fill_indent(out, depth);
|
|
270
|
+
} else {
|
|
271
|
+
size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
|
|
272
|
+
assure_size(out, size);
|
|
273
|
+
if (0 < out->opts->dump_opts.hash_size) {
|
|
274
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
|
|
275
|
+
}
|
|
276
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
|
277
|
+
int i;
|
|
278
|
+
|
|
279
|
+
for (i = depth; 0 < i; i--) {
|
|
280
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
*out->cur++ = '}';
|
|
304
285
|
}
|
|
305
286
|
*out->cur = '\0';
|
|
306
287
|
}
|
|
307
288
|
|
|
308
|
-
static void
|
|
309
|
-
|
|
310
|
-
VALUE clas = rb_obj_class(obj);
|
|
289
|
+
static void dump_data_strict(VALUE obj, int depth, Out out, bool as_ok) {
|
|
290
|
+
VALUE clas = rb_obj_class(obj);
|
|
311
291
|
|
|
312
292
|
if (oj_bigdecimal_class == clas) {
|
|
313
|
-
|
|
293
|
+
volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
|
|
314
294
|
|
|
315
|
-
|
|
295
|
+
oj_dump_raw(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), out);
|
|
316
296
|
} else {
|
|
317
|
-
|
|
297
|
+
raise_strict(obj);
|
|
318
298
|
}
|
|
319
299
|
}
|
|
320
300
|
|
|
321
|
-
static void
|
|
322
|
-
|
|
323
|
-
VALUE clas = rb_obj_class(obj);
|
|
301
|
+
static void dump_data_null(VALUE obj, int depth, Out out, bool as_ok) {
|
|
302
|
+
VALUE clas = rb_obj_class(obj);
|
|
324
303
|
|
|
325
304
|
if (oj_bigdecimal_class == clas) {
|
|
326
|
-
|
|
305
|
+
volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
|
|
327
306
|
|
|
328
|
-
|
|
307
|
+
oj_dump_raw(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), out);
|
|
329
308
|
} else {
|
|
330
|
-
|
|
309
|
+
oj_dump_nil(Qnil, depth, out, false);
|
|
331
310
|
}
|
|
332
311
|
}
|
|
333
312
|
|
|
334
|
-
static DumpFunc
|
|
335
|
-
NULL,
|
|
336
|
-
dump_data_strict,
|
|
337
|
-
NULL,
|
|
338
|
-
NULL,
|
|
339
|
-
dump_float,
|
|
340
|
-
oj_dump_str,
|
|
341
|
-
NULL,
|
|
342
|
-
dump_array,
|
|
343
|
-
dump_hash,
|
|
344
|
-
NULL,
|
|
345
|
-
oj_dump_bignum,
|
|
346
|
-
NULL,
|
|
347
|
-
dump_data_strict,
|
|
348
|
-
NULL,
|
|
349
|
-
NULL,
|
|
350
|
-
NULL,
|
|
351
|
-
NULL,
|
|
352
|
-
oj_dump_nil,
|
|
353
|
-
oj_dump_true,
|
|
354
|
-
oj_dump_false,
|
|
355
|
-
oj_dump_sym,
|
|
356
|
-
oj_dump_fixnum,
|
|
313
|
+
static DumpFunc strict_funcs[] = {
|
|
314
|
+
NULL, // RUBY_T_NONE = 0x00,
|
|
315
|
+
dump_data_strict, // RUBY_T_OBJECT = 0x01,
|
|
316
|
+
NULL, // RUBY_T_CLASS = 0x02,
|
|
317
|
+
NULL, // RUBY_T_MODULE = 0x03,
|
|
318
|
+
dump_float, // RUBY_T_FLOAT = 0x04,
|
|
319
|
+
oj_dump_str, // RUBY_T_STRING = 0x05,
|
|
320
|
+
NULL, // RUBY_T_REGEXP = 0x06,
|
|
321
|
+
dump_array, // RUBY_T_ARRAY = 0x07,
|
|
322
|
+
dump_hash, // RUBY_T_HASH = 0x08,
|
|
323
|
+
NULL, // RUBY_T_STRUCT = 0x09,
|
|
324
|
+
oj_dump_bignum, // RUBY_T_BIGNUM = 0x0a,
|
|
325
|
+
NULL, // RUBY_T_FILE = 0x0b,
|
|
326
|
+
dump_data_strict, // RUBY_T_DATA = 0x0c,
|
|
327
|
+
NULL, // RUBY_T_MATCH = 0x0d,
|
|
328
|
+
NULL, // RUBY_T_COMPLEX = 0x0e,
|
|
329
|
+
NULL, // RUBY_T_RATIONAL = 0x0f,
|
|
330
|
+
NULL, // 0x10
|
|
331
|
+
oj_dump_nil, // RUBY_T_NIL = 0x11,
|
|
332
|
+
oj_dump_true, // RUBY_T_TRUE = 0x12,
|
|
333
|
+
oj_dump_false, // RUBY_T_FALSE = 0x13,
|
|
334
|
+
oj_dump_sym, // RUBY_T_SYMBOL = 0x14,
|
|
335
|
+
oj_dump_fixnum, // RUBY_T_FIXNUM = 0x15,
|
|
357
336
|
};
|
|
358
337
|
|
|
359
|
-
void
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
|
338
|
+
void oj_dump_strict_val(VALUE obj, int depth, Out out) {
|
|
339
|
+
int type = rb_type(obj);
|
|
340
|
+
|
|
341
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
|
342
|
+
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
|
365
343
|
}
|
|
366
344
|
if (MAX_DEPTH < depth) {
|
|
367
|
-
|
|
345
|
+
rb_raise(rb_eNoMemError, "Too deeply nested.\n");
|
|
368
346
|
}
|
|
369
347
|
if (0 < type && type <= RUBY_T_FIXNUM) {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
348
|
+
DumpFunc f = strict_funcs[type];
|
|
349
|
+
|
|
350
|
+
if (NULL != f) {
|
|
351
|
+
f(obj, depth, out, false);
|
|
352
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
|
353
|
+
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
|
354
|
+
}
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
379
357
|
}
|
|
380
358
|
raise_strict(obj);
|
|
381
359
|
}
|
|
382
360
|
|
|
383
|
-
static DumpFunc
|
|
384
|
-
NULL,
|
|
385
|
-
dump_data_null,
|
|
386
|
-
NULL,
|
|
387
|
-
NULL,
|
|
388
|
-
dump_float,
|
|
389
|
-
oj_dump_str,
|
|
390
|
-
NULL,
|
|
391
|
-
dump_array,
|
|
392
|
-
dump_hash,
|
|
393
|
-
NULL,
|
|
394
|
-
oj_dump_bignum,
|
|
395
|
-
NULL,
|
|
396
|
-
dump_data_null,
|
|
397
|
-
NULL,
|
|
398
|
-
NULL,
|
|
399
|
-
NULL,
|
|
400
|
-
NULL,
|
|
401
|
-
oj_dump_nil,
|
|
402
|
-
oj_dump_true,
|
|
403
|
-
oj_dump_false,
|
|
404
|
-
oj_dump_sym,
|
|
405
|
-
oj_dump_fixnum,
|
|
361
|
+
static DumpFunc null_funcs[] = {
|
|
362
|
+
NULL, // RUBY_T_NONE = 0x00,
|
|
363
|
+
dump_data_null, // RUBY_T_OBJECT = 0x01,
|
|
364
|
+
NULL, // RUBY_T_CLASS = 0x02,
|
|
365
|
+
NULL, // RUBY_T_MODULE = 0x03,
|
|
366
|
+
dump_float, // RUBY_T_FLOAT = 0x04,
|
|
367
|
+
oj_dump_str, // RUBY_T_STRING = 0x05,
|
|
368
|
+
NULL, // RUBY_T_REGEXP = 0x06,
|
|
369
|
+
dump_array, // RUBY_T_ARRAY = 0x07,
|
|
370
|
+
dump_hash, // RUBY_T_HASH = 0x08,
|
|
371
|
+
NULL, // RUBY_T_STRUCT = 0x09,
|
|
372
|
+
oj_dump_bignum, // RUBY_T_BIGNUM = 0x0a,
|
|
373
|
+
NULL, // RUBY_T_FILE = 0x0b,
|
|
374
|
+
dump_data_null, // RUBY_T_DATA = 0x0c,
|
|
375
|
+
NULL, // RUBY_T_MATCH = 0x0d,
|
|
376
|
+
NULL, // RUBY_T_COMPLEX = 0x0e,
|
|
377
|
+
NULL, // RUBY_T_RATIONAL = 0x0f,
|
|
378
|
+
NULL, // 0x10
|
|
379
|
+
oj_dump_nil, // RUBY_T_NIL = 0x11,
|
|
380
|
+
oj_dump_true, // RUBY_T_TRUE = 0x12,
|
|
381
|
+
oj_dump_false, // RUBY_T_FALSE = 0x13,
|
|
382
|
+
oj_dump_sym, // RUBY_T_SYMBOL = 0x14,
|
|
383
|
+
oj_dump_fixnum, // RUBY_T_FIXNUM = 0x15,
|
|
406
384
|
};
|
|
407
385
|
|
|
408
|
-
void
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
|
386
|
+
void oj_dump_null_val(VALUE obj, int depth, Out out) {
|
|
387
|
+
int type = rb_type(obj);
|
|
388
|
+
|
|
389
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
|
390
|
+
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
|
414
391
|
}
|
|
415
392
|
if (MAX_DEPTH < depth) {
|
|
416
|
-
|
|
393
|
+
rb_raise(rb_eNoMemError, "Too deeply nested.\n");
|
|
417
394
|
}
|
|
418
395
|
if (0 < type && type <= RUBY_T_FIXNUM) {
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
396
|
+
DumpFunc f = null_funcs[type];
|
|
397
|
+
|
|
398
|
+
if (NULL != f) {
|
|
399
|
+
f(obj, depth, out, false);
|
|
400
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
|
401
|
+
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
|
402
|
+
}
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
428
405
|
}
|
|
429
406
|
oj_dump_nil(Qnil, depth, out, false);
|
|
430
|
-
if (Yes == out->opts->trace) {
|
|
431
|
-
|
|
407
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
|
408
|
+
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
|
432
409
|
}
|
|
433
410
|
}
|