oj 3.11.1 → 3.11.6
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/README.md +6 -1
- data/ext/oj/buf.h +34 -38
- data/ext/oj/cache8.c +59 -62
- data/ext/oj/cache8.h +8 -7
- data/ext/oj/circarray.c +33 -35
- data/ext/oj/circarray.h +11 -9
- data/ext/oj/code.c +170 -174
- data/ext/oj/code.h +21 -20
- data/ext/oj/compat.c +159 -166
- data/ext/oj/custom.c +802 -851
- data/ext/oj/dump.c +766 -778
- data/ext/oj/dump.h +49 -51
- data/ext/oj/dump_compat.c +1 -0
- data/ext/oj/dump_leaf.c +116 -157
- data/ext/oj/dump_object.c +609 -628
- data/ext/oj/dump_strict.c +318 -327
- data/ext/oj/encode.h +3 -4
- data/ext/oj/err.c +39 -25
- data/ext/oj/err.h +24 -15
- data/ext/oj/extconf.rb +2 -1
- data/ext/oj/fast.c +1042 -1041
- data/ext/oj/hash.c +62 -66
- data/ext/oj/hash.h +7 -6
- data/ext/oj/hash_test.c +450 -443
- data/ext/oj/mimic_json.c +412 -402
- data/ext/oj/object.c +559 -528
- data/ext/oj/odd.c +123 -128
- data/ext/oj/odd.h +27 -25
- data/ext/oj/oj.c +1123 -924
- data/ext/oj/oj.h +286 -298
- data/ext/oj/parse.c +938 -930
- data/ext/oj/parse.h +70 -69
- data/ext/oj/rails.c +836 -839
- data/ext/oj/rails.h +7 -7
- data/ext/oj/reader.c +135 -140
- data/ext/oj/reader.h +66 -79
- data/ext/oj/resolve.c +43 -43
- data/ext/oj/resolve.h +3 -2
- data/ext/oj/rxclass.c +67 -68
- data/ext/oj/rxclass.h +12 -10
- data/ext/oj/saj.c +451 -479
- data/ext/oj/scp.c +93 -103
- data/ext/oj/sparse.c +770 -730
- data/ext/oj/stream_writer.c +120 -149
- data/ext/oj/strict.c +71 -86
- data/ext/oj/string_writer.c +198 -243
- data/ext/oj/trace.c +29 -33
- data/ext/oj/trace.h +14 -11
- data/ext/oj/util.c +103 -103
- data/ext/oj/util.h +3 -2
- data/ext/oj/val_stack.c +47 -47
- data/ext/oj/val_stack.h +79 -86
- data/ext/oj/wab.c +291 -309
- data/lib/oj/bag.rb +1 -0
- data/lib/oj/easy_hash.rb +5 -4
- data/lib/oj/mimic.rb +0 -12
- data/lib/oj/version.rb +1 -1
- data/test/activerecord/result_test.rb +7 -2
- data/test/foo.rb +35 -32
- data/test/test_fast.rb +32 -2
- data/test/test_generate.rb +21 -0
- data/test/test_hash.rb +10 -0
- data/test/test_scp.rb +1 -1
- metadata +4 -2
data/ext/oj/dump_object.c
CHANGED
@@ -1,97 +1,94 @@
|
|
1
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.
|
2
3
|
|
3
4
|
#include "dump.h"
|
4
5
|
#include "odd.h"
|
5
6
|
#include "trace.h"
|
6
7
|
|
7
|
-
static const char
|
8
|
+
static const char hex_chars[17] = "0123456789abcdef";
|
8
9
|
|
9
|
-
static void
|
10
|
+
static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out);
|
10
11
|
|
11
|
-
static void
|
12
|
-
dump_time(VALUE obj, Out out) {
|
12
|
+
static void dump_time(VALUE obj, Out out) {
|
13
13
|
switch (out->opts->time_format) {
|
14
14
|
case RubyTime:
|
15
|
-
case XmlTime:
|
16
|
-
case UnixZTime:
|
15
|
+
case XmlTime: oj_dump_xml_time(obj, out); break;
|
16
|
+
case UnixZTime: oj_dump_time(obj, out, 1); break;
|
17
17
|
case UnixTime:
|
18
|
-
default:
|
18
|
+
default: oj_dump_time(obj, out, 0); break;
|
19
19
|
}
|
20
20
|
}
|
21
21
|
|
22
|
-
static void
|
23
|
-
|
24
|
-
VALUE clas = rb_obj_class(obj);
|
22
|
+
static void dump_data(VALUE obj, int depth, Out out, bool as_ok) {
|
23
|
+
VALUE clas = rb_obj_class(obj);
|
25
24
|
|
26
25
|
if (rb_cTime == clas) {
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
26
|
+
assure_size(out, 6);
|
27
|
+
*out->cur++ = '{';
|
28
|
+
*out->cur++ = '"';
|
29
|
+
*out->cur++ = '^';
|
30
|
+
*out->cur++ = 't';
|
31
|
+
*out->cur++ = '"';
|
32
|
+
*out->cur++ = ':';
|
33
|
+
dump_time(obj, out);
|
34
|
+
*out->cur++ = '}';
|
35
|
+
*out->cur = '\0';
|
37
36
|
} else {
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
37
|
+
if (oj_bigdecimal_class == clas) {
|
38
|
+
volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
|
39
|
+
const char * str = rb_string_value_ptr((VALUE *)&rstr);
|
40
|
+
int len = (int)RSTRING_LEN(rstr);
|
41
|
+
|
42
|
+
if (No != out->opts->bigdec_as_num) {
|
43
|
+
oj_dump_raw(str, len, out);
|
44
|
+
} else if (0 == strcasecmp("Infinity", str)) {
|
45
|
+
str = oj_nan_str(obj, out->opts->dump_opts.nan_dump, out->opts->mode, true, &len);
|
46
|
+
oj_dump_raw(str, len, out);
|
47
|
+
} else if (0 == strcasecmp("-Infinity", str)) {
|
48
|
+
str = oj_nan_str(obj, out->opts->dump_opts.nan_dump, out->opts->mode, false, &len);
|
49
|
+
oj_dump_raw(str, len, out);
|
50
|
+
} else {
|
51
|
+
oj_dump_cstr(str, len, 0, 0, out);
|
52
|
+
}
|
53
|
+
} else {
|
54
|
+
long id = oj_check_circular(obj, out);
|
55
|
+
|
56
|
+
if (0 <= id) {
|
57
|
+
dump_obj_attrs(obj, clas, id, depth, out);
|
58
|
+
}
|
59
|
+
}
|
61
60
|
}
|
62
61
|
}
|
63
62
|
|
64
|
-
static void
|
65
|
-
|
66
|
-
VALUE clas = rb_obj_class(obj);
|
63
|
+
static void dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
|
64
|
+
VALUE clas = rb_obj_class(obj);
|
67
65
|
|
68
66
|
if (oj_bigdecimal_class == clas) {
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
67
|
+
volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
|
68
|
+
const char * str = rb_string_value_ptr((VALUE *)&rstr);
|
69
|
+
int len = (int)RSTRING_LEN(rstr);
|
70
|
+
|
71
|
+
if (0 == strcasecmp("Infinity", str)) {
|
72
|
+
str = oj_nan_str(obj, out->opts->dump_opts.nan_dump, out->opts->mode, true, &len);
|
73
|
+
oj_dump_raw(str, len, out);
|
74
|
+
} else if (0 == strcasecmp("-Infinity", str)) {
|
75
|
+
str = oj_nan_str(obj, out->opts->dump_opts.nan_dump, out->opts->mode, false, &len);
|
76
|
+
oj_dump_raw(str, len, out);
|
77
|
+
} else {
|
78
|
+
oj_dump_raw(str, len, out);
|
79
|
+
}
|
82
80
|
} else {
|
83
|
-
|
81
|
+
long id = oj_check_circular(obj, out);
|
84
82
|
|
85
|
-
|
86
|
-
|
87
|
-
|
83
|
+
if (0 <= id) {
|
84
|
+
dump_obj_attrs(obj, clas, id, depth, out);
|
85
|
+
}
|
88
86
|
}
|
89
87
|
}
|
90
88
|
|
91
|
-
static void
|
92
|
-
|
93
|
-
|
94
|
-
size_t len = strlen(s);
|
89
|
+
static void dump_class(VALUE obj, int depth, Out out, bool as_ok) {
|
90
|
+
const char *s = rb_class2name(obj);
|
91
|
+
size_t len = strlen(s);
|
95
92
|
|
96
93
|
assure_size(out, 6);
|
97
94
|
*out->cur++ = '{';
|
@@ -102,597 +99,584 @@ dump_class(VALUE obj, int depth, Out out, bool as_ok) {
|
|
102
99
|
*out->cur++ = ':';
|
103
100
|
oj_dump_cstr(s, len, 0, 0, out);
|
104
101
|
*out->cur++ = '}';
|
105
|
-
*out->cur
|
102
|
+
*out->cur = '\0';
|
106
103
|
}
|
107
104
|
|
108
|
-
static void
|
109
|
-
|
110
|
-
|
111
|
-
int
|
112
|
-
|
113
|
-
long id = oj_check_circular(a, out);
|
105
|
+
static void dump_array_class(VALUE a, VALUE clas, int depth, Out out) {
|
106
|
+
size_t size;
|
107
|
+
int i, cnt;
|
108
|
+
int d2 = depth + 1;
|
109
|
+
long id = oj_check_circular(a, out);
|
114
110
|
|
115
111
|
if (id < 0) {
|
116
|
-
|
112
|
+
return;
|
117
113
|
}
|
118
114
|
if (Qundef != clas && rb_cArray != clas && ObjectMode == out->opts->mode) {
|
119
|
-
|
120
|
-
|
115
|
+
dump_obj_attrs(a, clas, 0, depth, out);
|
116
|
+
return;
|
121
117
|
}
|
122
|
-
cnt
|
118
|
+
cnt = (int)RARRAY_LEN(a);
|
123
119
|
*out->cur++ = '[';
|
124
120
|
if (0 < id) {
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
121
|
+
assure_size(out, d2 * out->indent + 16);
|
122
|
+
fill_indent(out, d2);
|
123
|
+
*out->cur++ = '"';
|
124
|
+
*out->cur++ = '^';
|
125
|
+
*out->cur++ = 'i';
|
126
|
+
dump_ulong(id, out);
|
127
|
+
*out->cur++ = '"';
|
132
128
|
}
|
133
129
|
size = 2;
|
134
130
|
assure_size(out, 2);
|
135
131
|
if (0 == cnt) {
|
136
|
-
|
132
|
+
*out->cur++ = ']';
|
137
133
|
} else {
|
138
|
-
|
139
|
-
|
140
|
-
|
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
|
-
|
134
|
+
if (0 < id) {
|
135
|
+
*out->cur++ = ',';
|
136
|
+
}
|
137
|
+
if (out->opts->dump_opts.use) {
|
138
|
+
size = d2 * out->opts->dump_opts.indent_size + out->opts->dump_opts.array_size + 1;
|
139
|
+
} else {
|
140
|
+
size = d2 * out->indent + 2;
|
141
|
+
}
|
142
|
+
cnt--;
|
143
|
+
for (i = 0; i <= cnt; i++) {
|
144
|
+
assure_size(out, size);
|
145
|
+
if (out->opts->dump_opts.use) {
|
146
|
+
if (0 < out->opts->dump_opts.array_size) {
|
147
|
+
strcpy(out->cur, out->opts->dump_opts.array_nl);
|
148
|
+
out->cur += out->opts->dump_opts.array_size;
|
149
|
+
}
|
150
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
151
|
+
int i;
|
152
|
+
for (i = d2; 0 < i; i--) {
|
153
|
+
strcpy(out->cur, out->opts->dump_opts.indent_str);
|
154
|
+
out->cur += out->opts->dump_opts.indent_size;
|
155
|
+
}
|
156
|
+
}
|
157
|
+
} else {
|
158
|
+
fill_indent(out, d2);
|
159
|
+
}
|
160
|
+
oj_dump_obj_val(rb_ary_entry(a, i), d2, out);
|
161
|
+
if (i < cnt) {
|
162
|
+
*out->cur++ = ',';
|
163
|
+
}
|
164
|
+
}
|
165
|
+
size = depth * out->indent + 1;
|
166
|
+
assure_size(out, size);
|
167
|
+
if (out->opts->dump_opts.use) {
|
168
|
+
// printf("*** d2: %u indent: %u '%s'\n", d2, out->opts->dump_opts->indent_size,
|
169
|
+
// out->opts->dump_opts->indent);
|
170
|
+
if (0 < out->opts->dump_opts.array_size) {
|
171
|
+
strcpy(out->cur, out->opts->dump_opts.array_nl);
|
172
|
+
out->cur += out->opts->dump_opts.array_size;
|
173
|
+
}
|
174
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
175
|
+
int i;
|
176
|
+
|
177
|
+
for (i = depth; 0 < i; i--) {
|
178
|
+
strcpy(out->cur, out->opts->dump_opts.indent_str);
|
179
|
+
out->cur += out->opts->dump_opts.indent_size;
|
180
|
+
}
|
181
|
+
}
|
182
|
+
} else {
|
183
|
+
fill_indent(out, depth);
|
184
|
+
}
|
185
|
+
*out->cur++ = ']';
|
189
186
|
}
|
190
187
|
*out->cur = '\0';
|
191
188
|
}
|
192
189
|
|
193
|
-
static void
|
194
|
-
dump_array(VALUE obj, int depth, Out out, bool as_ok) {
|
190
|
+
static void dump_array(VALUE obj, int depth, Out out, bool as_ok) {
|
195
191
|
dump_array_class(obj, rb_obj_class(obj), depth, out);
|
196
192
|
}
|
197
193
|
|
198
|
-
static void
|
199
|
-
dump_str_class(VALUE obj, VALUE clas, int depth, Out out) {
|
194
|
+
static void dump_str_class(VALUE obj, VALUE clas, int depth, Out out) {
|
200
195
|
if (Qundef != clas && rb_cString != clas) {
|
201
|
-
|
196
|
+
dump_obj_attrs(obj, clas, 0, depth, out);
|
202
197
|
} else {
|
203
|
-
|
204
|
-
|
205
|
-
|
198
|
+
const char *s = rb_string_value_ptr((VALUE *)&obj);
|
199
|
+
size_t len = (int)RSTRING_LEN(obj);
|
200
|
+
char s1 = s[1];
|
206
201
|
|
207
|
-
|
202
|
+
oj_dump_cstr(s, len, 0, (':' == *s || ('^' == *s && ('r' == s1 || 'i' == s1))), out);
|
208
203
|
}
|
209
204
|
}
|
210
205
|
|
211
|
-
static void
|
212
|
-
dump_str(VALUE obj, int depth, Out out, bool as_ok) {
|
206
|
+
static void dump_str(VALUE obj, int depth, Out out, bool as_ok) {
|
213
207
|
dump_str_class(obj, rb_obj_class(obj), depth, out);
|
214
208
|
}
|
215
209
|
|
216
|
-
static void
|
217
|
-
|
218
|
-
volatile VALUE s = rb_sym_to_s(obj);
|
210
|
+
static void dump_sym(VALUE obj, int depth, Out out, bool as_ok) {
|
211
|
+
volatile VALUE s = rb_sym_to_s(obj);
|
219
212
|
|
220
|
-
oj_dump_cstr(rb_string_value_ptr((VALUE*)&s), (int)RSTRING_LEN(s), 1, 0, out);
|
213
|
+
oj_dump_cstr(rb_string_value_ptr((VALUE *)&s), (int)RSTRING_LEN(s), 1, 0, out);
|
221
214
|
}
|
222
215
|
|
223
|
-
static int
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
long size = depth * out->indent + 1;
|
216
|
+
static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
217
|
+
Out out = (Out)ov;
|
218
|
+
int depth = out->depth;
|
219
|
+
long size = depth * out->indent + 1;
|
228
220
|
|
229
221
|
if (oj_dump_ignore(out->opts, value)) {
|
230
|
-
|
222
|
+
return ST_CONTINUE;
|
231
223
|
}
|
232
224
|
if (out->omit_nil && Qnil == value) {
|
233
|
-
|
225
|
+
return ST_CONTINUE;
|
234
226
|
}
|
235
227
|
assure_size(out, size);
|
236
228
|
fill_indent(out, depth);
|
237
229
|
if (rb_type(key) == T_STRING) {
|
238
|
-
|
239
|
-
|
240
|
-
|
230
|
+
dump_str_class(key, Qundef, depth, out);
|
231
|
+
*out->cur++ = ':';
|
232
|
+
oj_dump_obj_val(value, depth, out);
|
241
233
|
} else if (rb_type(key) == T_SYMBOL) {
|
242
|
-
|
243
|
-
|
244
|
-
|
234
|
+
dump_sym(key, 0, out, false);
|
235
|
+
*out->cur++ = ':';
|
236
|
+
oj_dump_obj_val(value, depth, out);
|
245
237
|
} else {
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
}
|
279
|
-
out->depth
|
238
|
+
int d2 = depth + 1;
|
239
|
+
long s2 = size + out->indent + 1;
|
240
|
+
int i;
|
241
|
+
int started = 0;
|
242
|
+
uint8_t b;
|
243
|
+
|
244
|
+
assure_size(out, s2 + 15);
|
245
|
+
*out->cur++ = '"';
|
246
|
+
*out->cur++ = '^';
|
247
|
+
*out->cur++ = '#';
|
248
|
+
out->hash_cnt++;
|
249
|
+
for (i = 28; 0 <= i; i -= 4) {
|
250
|
+
b = (uint8_t)((out->hash_cnt >> i) & 0x0000000F);
|
251
|
+
if ('\0' != b) {
|
252
|
+
started = 1;
|
253
|
+
}
|
254
|
+
if (started) {
|
255
|
+
*out->cur++ = hex_chars[b];
|
256
|
+
}
|
257
|
+
}
|
258
|
+
*out->cur++ = '"';
|
259
|
+
*out->cur++ = ':';
|
260
|
+
*out->cur++ = '[';
|
261
|
+
fill_indent(out, d2);
|
262
|
+
oj_dump_obj_val(key, d2, out);
|
263
|
+
assure_size(out, s2);
|
264
|
+
*out->cur++ = ',';
|
265
|
+
fill_indent(out, d2);
|
266
|
+
oj_dump_obj_val(value, d2, out);
|
267
|
+
assure_size(out, size);
|
268
|
+
fill_indent(out, depth);
|
269
|
+
*out->cur++ = ']';
|
270
|
+
}
|
271
|
+
out->depth = depth;
|
280
272
|
*out->cur++ = ',';
|
281
273
|
|
282
274
|
return ST_CONTINUE;
|
283
275
|
}
|
284
276
|
|
285
|
-
static void
|
286
|
-
|
287
|
-
|
288
|
-
size_t size;
|
277
|
+
static void dump_hash_class(VALUE obj, VALUE clas, int depth, Out out) {
|
278
|
+
int cnt;
|
279
|
+
size_t size;
|
289
280
|
|
290
281
|
if (Qundef != clas && rb_cHash != clas) {
|
291
|
-
|
292
|
-
|
282
|
+
dump_obj_attrs(obj, clas, 0, depth, out);
|
283
|
+
return;
|
293
284
|
}
|
294
|
-
cnt
|
285
|
+
cnt = (int)RHASH_SIZE(obj);
|
295
286
|
size = depth * out->indent + 2;
|
296
287
|
assure_size(out, 2);
|
297
288
|
if (0 == cnt) {
|
298
|
-
|
299
|
-
|
289
|
+
*out->cur++ = '{';
|
290
|
+
*out->cur++ = '}';
|
300
291
|
} else {
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
292
|
+
long id = oj_check_circular(obj, out);
|
293
|
+
|
294
|
+
if (0 > id) {
|
295
|
+
return;
|
296
|
+
}
|
297
|
+
*out->cur++ = '{';
|
298
|
+
if (0 < id) {
|
299
|
+
assure_size(out, size + 16);
|
300
|
+
fill_indent(out, depth + 1);
|
301
|
+
*out->cur++ = '"';
|
302
|
+
*out->cur++ = '^';
|
303
|
+
*out->cur++ = 'i';
|
304
|
+
*out->cur++ = '"';
|
305
|
+
*out->cur++ = ':';
|
306
|
+
dump_ulong(id, out);
|
307
|
+
*out->cur++ = ',';
|
308
|
+
}
|
309
|
+
out->depth = depth + 1;
|
310
|
+
rb_hash_foreach(obj, hash_cb, (VALUE)out);
|
311
|
+
if (',' == *(out->cur - 1)) {
|
312
|
+
out->cur--; // backup to overwrite last comma
|
313
|
+
}
|
314
|
+
if (!out->opts->dump_opts.use) {
|
315
|
+
assure_size(out, size);
|
316
|
+
fill_indent(out, depth);
|
317
|
+
} else {
|
318
|
+
size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
|
319
|
+
assure_size(out, size);
|
320
|
+
if (0 < out->opts->dump_opts.hash_size) {
|
321
|
+
strcpy(out->cur, out->opts->dump_opts.hash_nl);
|
322
|
+
out->cur += out->opts->dump_opts.hash_size;
|
323
|
+
}
|
324
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
325
|
+
int i;
|
326
|
+
|
327
|
+
for (i = depth; 0 < i; i--) {
|
328
|
+
strcpy(out->cur, out->opts->dump_opts.indent_str);
|
329
|
+
out->cur += out->opts->dump_opts.indent_size;
|
330
|
+
}
|
331
|
+
}
|
332
|
+
}
|
333
|
+
*out->cur++ = '}';
|
343
334
|
}
|
344
335
|
*out->cur = '\0';
|
345
336
|
}
|
346
337
|
|
347
338
|
#ifdef HAVE_RB_IVAR_FOREACH
|
348
|
-
static int
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
const char *attr = rb_id2name(key);
|
339
|
+
static int dump_attr_cb(ID key, VALUE value, VALUE ov) {
|
340
|
+
Out out = (Out)ov;
|
341
|
+
int depth = out->depth;
|
342
|
+
size_t size = depth * out->indent + 1;
|
343
|
+
const char *attr = rb_id2name(key);
|
354
344
|
|
355
345
|
if (oj_dump_ignore(out->opts, value)) {
|
356
|
-
|
346
|
+
return ST_CONTINUE;
|
357
347
|
}
|
358
348
|
if (out->omit_nil && Qnil == value) {
|
359
|
-
|
349
|
+
return ST_CONTINUE;
|
360
350
|
}
|
361
351
|
// Some exceptions such as NoMethodError have an invisible attribute where
|
362
352
|
// the key name is NULL. Not an empty string but NULL.
|
363
353
|
if (NULL == attr) {
|
364
|
-
|
354
|
+
attr = "";
|
365
355
|
} else if (Yes == out->opts->ignore_under && '@' == *attr && '_' == attr[1]) {
|
366
|
-
|
356
|
+
return ST_CONTINUE;
|
367
357
|
}
|
368
358
|
if (0 == strcmp("bt", attr) || 0 == strcmp("mesg", attr)) {
|
369
|
-
|
359
|
+
return ST_CONTINUE;
|
370
360
|
}
|
371
361
|
assure_size(out, size);
|
372
362
|
fill_indent(out, depth);
|
373
363
|
if ('@' == *attr) {
|
374
|
-
|
375
|
-
|
364
|
+
attr++;
|
365
|
+
oj_dump_cstr(attr, strlen(attr), 0, 0, out);
|
376
366
|
} else {
|
377
|
-
|
367
|
+
char buf[32];
|
378
368
|
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
369
|
+
*buf = '~';
|
370
|
+
strncpy(buf + 1, attr, sizeof(buf) - 2);
|
371
|
+
buf[sizeof(buf) - 1] = '\0';
|
372
|
+
oj_dump_cstr(buf, strlen(buf), 0, 0, out);
|
383
373
|
}
|
384
374
|
*out->cur++ = ':';
|
385
375
|
oj_dump_obj_val(value, depth, out);
|
386
|
-
out->depth
|
376
|
+
out->depth = depth;
|
387
377
|
*out->cur++ = ',';
|
388
378
|
|
389
379
|
return ST_CONTINUE;
|
390
380
|
}
|
391
381
|
#endif
|
392
382
|
|
393
|
-
static void
|
394
|
-
dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
|
383
|
+
static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
|
395
384
|
dump_hash_class(obj, rb_obj_class(obj), depth, out);
|
396
385
|
}
|
397
386
|
|
398
|
-
static void
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
int d2 = depth + 1;
|
387
|
+
static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
|
388
|
+
ID * idp;
|
389
|
+
AttrGetFunc * fp;
|
390
|
+
volatile VALUE v;
|
391
|
+
const char * name;
|
392
|
+
size_t size;
|
393
|
+
int d2 = depth + 1;
|
406
394
|
|
407
395
|
assure_size(out, 2);
|
408
396
|
*out->cur++ = '{';
|
409
397
|
if (Qundef != clas) {
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
398
|
+
const char *class_name = rb_class2name(clas);
|
399
|
+
int clen = (int)strlen(class_name);
|
400
|
+
|
401
|
+
size = d2 * out->indent + clen + 10;
|
402
|
+
assure_size(out, size);
|
403
|
+
fill_indent(out, d2);
|
404
|
+
*out->cur++ = '"';
|
405
|
+
*out->cur++ = '^';
|
406
|
+
*out->cur++ = 'O';
|
407
|
+
*out->cur++ = '"';
|
408
|
+
*out->cur++ = ':';
|
409
|
+
oj_dump_cstr(class_name, clen, 0, 0, out);
|
410
|
+
*out->cur++ = ',';
|
423
411
|
}
|
424
412
|
if (odd->raw) {
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
413
|
+
v = rb_funcall(obj, *odd->attrs, 0);
|
414
|
+
if (Qundef == v || T_STRING != rb_type(v)) {
|
415
|
+
rb_raise(rb_eEncodingError, "Invalid type for raw JSON.");
|
416
|
+
} else {
|
417
|
+
const char *s = rb_string_value_ptr((VALUE *)&v);
|
418
|
+
int len = (int)RSTRING_LEN(v);
|
419
|
+
const char *name = rb_id2name(*odd->attrs);
|
420
|
+
size_t nlen = strlen(name);
|
421
|
+
|
422
|
+
size = len + d2 * out->indent + nlen + 10;
|
423
|
+
assure_size(out, size);
|
424
|
+
fill_indent(out, d2);
|
425
|
+
*out->cur++ = '"';
|
426
|
+
memcpy(out->cur, name, nlen);
|
427
|
+
out->cur += nlen;
|
428
|
+
*out->cur++ = '"';
|
429
|
+
*out->cur++ = ':';
|
430
|
+
memcpy(out->cur, s, len);
|
431
|
+
out->cur += len;
|
432
|
+
*out->cur = '\0';
|
433
|
+
}
|
446
434
|
} else {
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
435
|
+
size = d2 * out->indent + 1;
|
436
|
+
for (idp = odd->attrs, fp = odd->attrFuncs; 0 != *idp; idp++, fp++) {
|
437
|
+
size_t nlen;
|
438
|
+
|
439
|
+
assure_size(out, size);
|
440
|
+
name = rb_id2name(*idp);
|
441
|
+
nlen = strlen(name);
|
442
|
+
if (0 != *fp) {
|
443
|
+
v = (*fp)(obj);
|
444
|
+
} else if (0 == strchr(name, '.')) {
|
445
|
+
v = rb_funcall(obj, *idp, 0);
|
446
|
+
} else {
|
447
|
+
char nbuf[256];
|
448
|
+
char *n2 = nbuf;
|
449
|
+
char *n;
|
450
|
+
char *end;
|
451
|
+
ID i;
|
452
|
+
|
453
|
+
if (sizeof(nbuf) <= nlen) {
|
454
|
+
if (NULL == (n2 = strdup(name))) {
|
455
|
+
rb_raise(rb_eNoMemError, "for attribute name.");
|
456
|
+
}
|
457
|
+
} else {
|
458
|
+
strcpy(n2, name);
|
459
|
+
}
|
460
|
+
n = n2;
|
461
|
+
v = obj;
|
462
|
+
while (0 != (end = strchr(n, '.'))) {
|
463
|
+
*end = '\0';
|
464
|
+
i = rb_intern(n);
|
465
|
+
v = rb_funcall(v, i, 0);
|
466
|
+
n = end + 1;
|
467
|
+
}
|
468
|
+
i = rb_intern(n);
|
469
|
+
v = rb_funcall(v, i, 0);
|
470
|
+
if (nbuf != n2) {
|
471
|
+
free(n2);
|
472
|
+
}
|
473
|
+
}
|
474
|
+
fill_indent(out, d2);
|
475
|
+
oj_dump_cstr(name, nlen, 0, 0, out);
|
476
|
+
*out->cur++ = ':';
|
477
|
+
oj_dump_obj_val(v, d2, out);
|
478
|
+
assure_size(out, 2);
|
479
|
+
*out->cur++ = ',';
|
480
|
+
}
|
481
|
+
out->cur--;
|
494
482
|
}
|
495
483
|
*out->cur++ = '}';
|
496
|
-
*out->cur
|
484
|
+
*out->cur = '\0';
|
497
485
|
}
|
498
486
|
|
499
|
-
static void
|
500
|
-
|
501
|
-
|
502
|
-
int
|
503
|
-
|
504
|
-
Odd odd;
|
487
|
+
static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out) {
|
488
|
+
size_t size = 0;
|
489
|
+
int d2 = depth + 1;
|
490
|
+
int type = rb_type(obj);
|
491
|
+
Odd odd;
|
505
492
|
|
506
493
|
if (0 != (odd = oj_get_odd(clas))) {
|
507
|
-
|
508
|
-
|
494
|
+
dump_odd(obj, odd, clas, depth + 1, out);
|
495
|
+
return;
|
509
496
|
}
|
510
497
|
assure_size(out, 2);
|
511
498
|
*out->cur++ = '{';
|
512
499
|
if (Qundef != clas) {
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
500
|
+
const char *class_name = rb_class2name(clas);
|
501
|
+
int clen = (int)strlen(class_name);
|
502
|
+
|
503
|
+
assure_size(out, d2 * out->indent + clen + 10);
|
504
|
+
fill_indent(out, d2);
|
505
|
+
*out->cur++ = '"';
|
506
|
+
*out->cur++ = '^';
|
507
|
+
*out->cur++ = 'o';
|
508
|
+
*out->cur++ = '"';
|
509
|
+
*out->cur++ = ':';
|
510
|
+
oj_dump_cstr(class_name, clen, 0, 0, out);
|
524
511
|
}
|
525
512
|
if (0 < id) {
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
513
|
+
assure_size(out, d2 * out->indent + 16);
|
514
|
+
*out->cur++ = ',';
|
515
|
+
fill_indent(out, d2);
|
516
|
+
*out->cur++ = '"';
|
517
|
+
*out->cur++ = '^';
|
518
|
+
*out->cur++ = 'i';
|
519
|
+
*out->cur++ = '"';
|
520
|
+
*out->cur++ = ':';
|
521
|
+
dump_ulong(id, out);
|
535
522
|
}
|
536
523
|
switch (type) {
|
537
524
|
case T_STRING:
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
525
|
+
assure_size(out, d2 * out->indent + 14);
|
526
|
+
*out->cur++ = ',';
|
527
|
+
fill_indent(out, d2);
|
528
|
+
*out->cur++ = '"';
|
529
|
+
*out->cur++ = 's';
|
530
|
+
*out->cur++ = 'e';
|
531
|
+
*out->cur++ = 'l';
|
532
|
+
*out->cur++ = 'f';
|
533
|
+
*out->cur++ = '"';
|
534
|
+
*out->cur++ = ':';
|
535
|
+
oj_dump_cstr(rb_string_value_ptr((VALUE *)&obj), (int)RSTRING_LEN(obj), 0, 0, out);
|
536
|
+
break;
|
550
537
|
case T_ARRAY:
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
538
|
+
assure_size(out, d2 * out->indent + 14);
|
539
|
+
*out->cur++ = ',';
|
540
|
+
fill_indent(out, d2);
|
541
|
+
*out->cur++ = '"';
|
542
|
+
*out->cur++ = 's';
|
543
|
+
*out->cur++ = 'e';
|
544
|
+
*out->cur++ = 'l';
|
545
|
+
*out->cur++ = 'f';
|
546
|
+
*out->cur++ = '"';
|
547
|
+
*out->cur++ = ':';
|
548
|
+
dump_array_class(obj, Qundef, depth + 1, out);
|
549
|
+
break;
|
563
550
|
case T_HASH:
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
default:
|
577
|
-
break;
|
551
|
+
assure_size(out, d2 * out->indent + 14);
|
552
|
+
*out->cur++ = ',';
|
553
|
+
fill_indent(out, d2);
|
554
|
+
*out->cur++ = '"';
|
555
|
+
*out->cur++ = 's';
|
556
|
+
*out->cur++ = 'e';
|
557
|
+
*out->cur++ = 'l';
|
558
|
+
*out->cur++ = 'f';
|
559
|
+
*out->cur++ = '"';
|
560
|
+
*out->cur++ = ':';
|
561
|
+
dump_hash_class(obj, Qundef, depth + 1, out);
|
562
|
+
break;
|
563
|
+
default: break;
|
578
564
|
}
|
579
565
|
{
|
580
|
-
|
566
|
+
int cnt;
|
581
567
|
#ifdef HAVE_RB_IVAR_COUNT
|
582
|
-
|
568
|
+
cnt = (int)rb_ivar_count(obj);
|
583
569
|
#else
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
570
|
+
volatile VALUE vars = rb_funcall2(obj, oj_instance_variables_id, 0, 0);
|
571
|
+
VALUE * np = RARRAY_PTR(vars);
|
572
|
+
ID vid;
|
573
|
+
const char * attr;
|
574
|
+
int i;
|
575
|
+
int first = 1;
|
576
|
+
|
577
|
+
cnt = (int)RARRAY_LEN(vars);
|
592
578
|
#endif
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
579
|
+
if (Qundef != clas && 0 < cnt) {
|
580
|
+
*out->cur++ = ',';
|
581
|
+
}
|
582
|
+
if (0 == cnt && Qundef == clas) {
|
583
|
+
// Might be something special like an Enumerable.
|
584
|
+
if (Qtrue == rb_obj_is_kind_of(obj, oj_enumerable_class)) {
|
585
|
+
out->cur--;
|
586
|
+
oj_dump_obj_val(rb_funcall(obj, rb_intern("entries"), 0), depth, out);
|
587
|
+
return;
|
588
|
+
}
|
589
|
+
}
|
590
|
+
out->depth = depth + 1;
|
605
591
|
#ifdef HAVE_RB_IVAR_FOREACH
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
592
|
+
rb_ivar_foreach(obj, dump_attr_cb, (VALUE)out);
|
593
|
+
if (',' == *(out->cur - 1)) {
|
594
|
+
out->cur--; // backup to overwrite last comma
|
595
|
+
}
|
610
596
|
#else
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
597
|
+
size = d2 * out->indent + 1;
|
598
|
+
for (i = cnt; 0 < i; i--, np++) {
|
599
|
+
VALUE value;
|
600
|
+
|
601
|
+
vid = rb_to_id(*np);
|
602
|
+
attr = rb_id2name(vid);
|
603
|
+
if (Yes == out->opts->ignore_under && '@' == *attr && '_' == attr[1]) {
|
604
|
+
continue;
|
605
|
+
}
|
606
|
+
value = rb_ivar_get(obj, vid);
|
607
|
+
|
608
|
+
if (oj_dump_ignore(out->opts, value)) {
|
609
|
+
continue;
|
610
|
+
}
|
611
|
+
if (out->omit_nil && Qnil == value) {
|
612
|
+
continue;
|
613
|
+
}
|
614
|
+
if (first) {
|
615
|
+
first = 0;
|
616
|
+
} else {
|
617
|
+
*out->cur++ = ',';
|
618
|
+
}
|
619
|
+
assure_size(out, size);
|
620
|
+
fill_indent(out, d2);
|
621
|
+
if ('@' == *attr) {
|
622
|
+
attr++;
|
623
|
+
oj_dump_cstr(attr, strlen(attr), 0, 0, out);
|
624
|
+
} else {
|
625
|
+
char buf[32];
|
626
|
+
|
627
|
+
*buf = '~';
|
628
|
+
strncpy(buf + 1, attr, sizeof(buf) - 2);
|
629
|
+
buf[sizeof(buf) - 1] = '\0';
|
630
|
+
oj_dump_cstr(buf, strlen(attr) + 1, 0, 0, out);
|
631
|
+
}
|
632
|
+
*out->cur++ = ':';
|
633
|
+
oj_dump_obj_val(value, d2, out);
|
634
|
+
assure_size(out, 2);
|
635
|
+
}
|
650
636
|
#endif
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
637
|
+
if (rb_obj_is_kind_of(obj, rb_eException)) {
|
638
|
+
volatile VALUE rv;
|
639
|
+
|
640
|
+
if (',' != *(out->cur - 1)) {
|
641
|
+
*out->cur++ = ',';
|
642
|
+
}
|
643
|
+
// message
|
644
|
+
assure_size(out, size);
|
645
|
+
fill_indent(out, d2);
|
646
|
+
oj_dump_cstr("~mesg", 5, 0, 0, out);
|
647
|
+
*out->cur++ = ':';
|
648
|
+
rv = rb_funcall2(obj, rb_intern("message"), 0, 0);
|
649
|
+
oj_dump_obj_val(rv, d2, out);
|
650
|
+
assure_size(out, 2);
|
651
|
+
*out->cur++ = ',';
|
652
|
+
// backtrace
|
653
|
+
assure_size(out, size);
|
654
|
+
fill_indent(out, d2);
|
655
|
+
oj_dump_cstr("~bt", 3, 0, 0, out);
|
656
|
+
*out->cur++ = ':';
|
657
|
+
rv = rb_funcall2(obj, rb_intern("backtrace"), 0, 0);
|
658
|
+
oj_dump_obj_val(rv, d2, out);
|
659
|
+
assure_size(out, 2);
|
660
|
+
}
|
661
|
+
out->depth = depth;
|
676
662
|
}
|
677
663
|
fill_indent(out, depth);
|
678
664
|
*out->cur++ = '}';
|
679
|
-
*out->cur
|
665
|
+
*out->cur = '\0';
|
680
666
|
}
|
681
667
|
|
682
|
-
static void
|
683
|
-
dump_regexp(VALUE obj, int depth, Out out, bool as_ok) {
|
668
|
+
static void dump_regexp(VALUE obj, int depth, Out out, bool as_ok) {
|
684
669
|
dump_obj_attrs(obj, rb_obj_class(obj), 0, depth, out);
|
685
670
|
}
|
686
671
|
|
687
|
-
static void
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
int
|
692
|
-
int
|
693
|
-
|
694
|
-
size_t
|
695
|
-
size_t size = d2 * out->indent + d3 * out->indent + 10 + len;
|
672
|
+
static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
673
|
+
VALUE clas = rb_obj_class(obj);
|
674
|
+
const char *class_name = rb_class2name(clas);
|
675
|
+
int i;
|
676
|
+
int d2 = depth + 1;
|
677
|
+
int d3 = d2 + 1;
|
678
|
+
size_t len = strlen(class_name);
|
679
|
+
size_t size = d2 * out->indent + d3 * out->indent + 10 + len;
|
696
680
|
|
697
681
|
assure_size(out, size);
|
698
682
|
*out->cur++ = '{';
|
@@ -704,138 +688,135 @@ dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
704
688
|
*out->cur++ = ':';
|
705
689
|
*out->cur++ = '[';
|
706
690
|
if ('#' == *class_name) {
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
691
|
+
VALUE ma = rb_struct_s_members(clas);
|
692
|
+
const char *name;
|
693
|
+
int cnt = (int)RARRAY_LEN(ma);
|
694
|
+
|
695
|
+
*out->cur++ = '[';
|
696
|
+
for (i = 0; i < cnt; i++) {
|
697
|
+
volatile VALUE s = rb_sym_to_s(rb_ary_entry(ma, i));
|
698
|
+
|
699
|
+
name = rb_string_value_ptr((VALUE *)&s);
|
700
|
+
len = (int)RSTRING_LEN(s);
|
701
|
+
size = len + 3;
|
702
|
+
assure_size(out, size);
|
703
|
+
if (0 < i) {
|
704
|
+
*out->cur++ = ',';
|
705
|
+
}
|
706
|
+
*out->cur++ = '"';
|
707
|
+
memcpy(out->cur, name, len);
|
708
|
+
out->cur += len;
|
709
|
+
*out->cur++ = '"';
|
710
|
+
}
|
711
|
+
*out->cur++ = ']';
|
728
712
|
} else {
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
713
|
+
fill_indent(out, d3);
|
714
|
+
*out->cur++ = '"';
|
715
|
+
memcpy(out->cur, class_name, len);
|
716
|
+
out->cur += len;
|
717
|
+
*out->cur++ = '"';
|
734
718
|
}
|
735
719
|
*out->cur++ = ',';
|
736
|
-
size
|
720
|
+
size = d3 * out->indent + 2;
|
737
721
|
#ifdef RSTRUCT_LEN
|
738
722
|
{
|
739
|
-
|
740
|
-
|
723
|
+
VALUE v;
|
724
|
+
int cnt;
|
741
725
|
#if RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
742
|
-
|
743
|
-
#else
|
744
|
-
|
745
|
-
#endif
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
726
|
+
cnt = (int)NUM2LONG(RSTRUCT_LEN(obj));
|
727
|
+
#else // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
728
|
+
cnt = (int)RSTRUCT_LEN(obj);
|
729
|
+
#endif // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
730
|
+
|
731
|
+
for (i = 0; i < cnt; i++) {
|
732
|
+
v = RSTRUCT_GET(obj, i);
|
733
|
+
if (oj_dump_ignore(out->opts, v)) {
|
734
|
+
v = Qnil;
|
735
|
+
}
|
736
|
+
assure_size(out, size);
|
737
|
+
fill_indent(out, d3);
|
738
|
+
oj_dump_obj_val(v, d3, out);
|
739
|
+
*out->cur++ = ',';
|
740
|
+
}
|
757
741
|
}
|
758
742
|
#else
|
759
743
|
{
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
744
|
+
// This is a bit risky as a struct in C ruby is not the same as a Struct
|
745
|
+
// class in interpreted Ruby so length() may not be defined.
|
746
|
+
int slen = FIX2INT(rb_funcall2(obj, oj_length_id, 0, 0));
|
747
|
+
|
748
|
+
for (i = 0; i < slen; i++) {
|
749
|
+
assure_size(out, size);
|
750
|
+
fill_indent(out, d3);
|
751
|
+
if (oj_dump_ignore(out->opts, v)) {
|
752
|
+
v = Qnil;
|
753
|
+
}
|
754
|
+
oj_dump_obj_val(rb_struct_aref(obj, INT2FIX(i)), d3, out, 0, 0, true);
|
755
|
+
*out->cur++ = ',';
|
756
|
+
}
|
773
757
|
}
|
774
758
|
#endif
|
775
759
|
out->cur--;
|
776
760
|
*out->cur++ = ']';
|
777
761
|
*out->cur++ = '}';
|
778
|
-
*out->cur
|
762
|
+
*out->cur = '\0';
|
779
763
|
}
|
780
764
|
|
781
|
-
static void
|
782
|
-
dump_complex(VALUE obj, int depth, Out out, bool as_ok) {
|
765
|
+
static void dump_complex(VALUE obj, int depth, Out out, bool as_ok) {
|
783
766
|
dump_obj_attrs(obj, rb_obj_class(obj), 0, depth, out);
|
784
767
|
}
|
785
768
|
|
786
|
-
static void
|
787
|
-
dump_rational(VALUE obj, int depth, Out out, bool as_ok) {
|
769
|
+
static void dump_rational(VALUE obj, int depth, Out out, bool as_ok) {
|
788
770
|
dump_obj_attrs(obj, rb_obj_class(obj), 0, depth, out);
|
789
771
|
}
|
790
772
|
|
791
|
-
static DumpFunc
|
792
|
-
NULL,
|
793
|
-
dump_obj,
|
794
|
-
dump_class,
|
795
|
-
dump_class,
|
796
|
-
oj_dump_float,
|
797
|
-
dump_str,
|
798
|
-
dump_regexp,
|
799
|
-
dump_array,
|
800
|
-
dump_hash,
|
801
|
-
dump_struct,
|
802
|
-
oj_dump_bignum,
|
803
|
-
NULL,
|
804
|
-
dump_data,
|
805
|
-
NULL,
|
806
|
-
dump_complex,
|
807
|
-
dump_rational,
|
808
|
-
NULL,
|
809
|
-
oj_dump_nil,
|
810
|
-
oj_dump_true,
|
811
|
-
oj_dump_false,
|
812
|
-
dump_sym,
|
813
|
-
oj_dump_fixnum,
|
773
|
+
static DumpFunc obj_funcs[] = {
|
774
|
+
NULL, // RUBY_T_NONE = 0x00,
|
775
|
+
dump_obj, // RUBY_T_OBJECT = 0x01,
|
776
|
+
dump_class, // RUBY_T_CLASS = 0x02,
|
777
|
+
dump_class, // RUBY_T_MODULE = 0x03,
|
778
|
+
oj_dump_float, // RUBY_T_FLOAT = 0x04,
|
779
|
+
dump_str, // RUBY_T_STRING = 0x05,
|
780
|
+
dump_regexp, // RUBY_T_REGEXP = 0x06,
|
781
|
+
dump_array, // RUBY_T_ARRAY = 0x07,
|
782
|
+
dump_hash, // RUBY_T_HASH = 0x08,
|
783
|
+
dump_struct, // RUBY_T_STRUCT = 0x09,
|
784
|
+
oj_dump_bignum, // RUBY_T_BIGNUM = 0x0a,
|
785
|
+
NULL, // RUBY_T_FILE = 0x0b,
|
786
|
+
dump_data, // RUBY_T_DATA = 0x0c,
|
787
|
+
NULL, // RUBY_T_MATCH = 0x0d,
|
788
|
+
dump_complex, // RUBY_T_COMPLEX = 0x0e,
|
789
|
+
dump_rational, // RUBY_T_RATIONAL = 0x0f,
|
790
|
+
NULL, // 0x10
|
791
|
+
oj_dump_nil, // RUBY_T_NIL = 0x11,
|
792
|
+
oj_dump_true, // RUBY_T_TRUE = 0x12,
|
793
|
+
oj_dump_false, // RUBY_T_FALSE = 0x13,
|
794
|
+
dump_sym, // RUBY_T_SYMBOL = 0x14,
|
795
|
+
oj_dump_fixnum, // RUBY_T_FIXNUM = 0x15,
|
814
796
|
};
|
815
797
|
|
816
|
-
void
|
817
|
-
|
818
|
-
int type = rb_type(obj);
|
798
|
+
void oj_dump_obj_val(VALUE obj, int depth, Out out) {
|
799
|
+
int type = rb_type(obj);
|
819
800
|
|
820
801
|
if (Yes == out->opts->trace) {
|
821
|
-
|
802
|
+
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
822
803
|
}
|
823
804
|
if (MAX_DEPTH < depth) {
|
824
|
-
|
805
|
+
rb_raise(rb_eNoMemError, "Too deeply nested.\n");
|
825
806
|
}
|
826
807
|
if (0 < type && type <= RUBY_T_FIXNUM) {
|
827
|
-
|
808
|
+
DumpFunc f = obj_funcs[type];
|
828
809
|
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
810
|
+
if (NULL != f) {
|
811
|
+
f(obj, depth, out, false);
|
812
|
+
if (Yes == out->opts->trace) {
|
813
|
+
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
814
|
+
}
|
815
|
+
return;
|
816
|
+
}
|
836
817
|
}
|
837
818
|
oj_dump_nil(Qnil, depth, out, false);
|
838
819
|
if (Yes == out->opts->trace) {
|
839
|
-
|
820
|
+
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
840
821
|
}
|
841
822
|
}
|