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/rails.c
CHANGED
@@ -1,159 +1,154 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
1
|
+
// Copyright (c) 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 "rails.h"
|
7
|
-
|
5
|
+
|
8
6
|
#include "code.h"
|
9
7
|
#include "encode.h"
|
8
|
+
#include "mem.h"
|
10
9
|
#include "trace.h"
|
11
10
|
#include "util.h"
|
12
11
|
|
13
|
-
#define OJ_INFINITY (1.0/0.0)
|
12
|
+
#define OJ_INFINITY (1.0 / 0.0)
|
14
13
|
|
15
14
|
// TBD keep static array of strings and functions to help with rails optimization
|
16
15
|
typedef struct _encoder {
|
17
|
-
struct _rOptTable
|
18
|
-
struct _options
|
19
|
-
VALUE
|
16
|
+
struct _rOptTable ropts;
|
17
|
+
struct _options opts;
|
18
|
+
VALUE arg;
|
20
19
|
} *Encoder;
|
21
20
|
|
22
|
-
bool
|
23
|
-
bool
|
24
|
-
bool
|
21
|
+
bool oj_rails_hash_opt = false;
|
22
|
+
bool oj_rails_array_opt = false;
|
23
|
+
bool oj_rails_float_opt = false;
|
25
24
|
|
26
|
-
extern void
|
25
|
+
extern void oj_mimic_json_methods(VALUE json);
|
27
26
|
|
28
|
-
static void
|
27
|
+
static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok);
|
29
28
|
|
30
|
-
extern VALUE
|
29
|
+
extern VALUE Oj;
|
31
30
|
|
32
|
-
static struct _rOptTable
|
31
|
+
static struct _rOptTable ropts = {0, 0, NULL};
|
33
32
|
|
34
|
-
static VALUE
|
35
|
-
static bool
|
36
|
-
static bool
|
33
|
+
static VALUE encoder_class = Qnil;
|
34
|
+
static bool escape_html = true;
|
35
|
+
static bool xml_time = true;
|
37
36
|
|
38
|
-
static ROpt
|
37
|
+
static ROpt create_opt(ROptTable rot, VALUE clas);
|
39
38
|
|
40
|
-
ROpt
|
41
|
-
oj_rails_get_opt(ROptTable rot, VALUE clas) {
|
39
|
+
ROpt oj_rails_get_opt(ROptTable rot, VALUE clas) {
|
42
40
|
if (NULL == rot) {
|
43
|
-
|
41
|
+
rot = &ropts;
|
44
42
|
}
|
45
43
|
if (0 < rot->len) {
|
46
|
-
|
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
|
-
|
44
|
+
int lo = 0;
|
45
|
+
int hi = rot->len - 1;
|
46
|
+
int mid;
|
47
|
+
VALUE v;
|
48
|
+
|
49
|
+
if (clas < rot->table->clas || rot->table[hi].clas < clas) {
|
50
|
+
return NULL;
|
51
|
+
}
|
52
|
+
if (rot->table[lo].clas == clas) {
|
53
|
+
return rot->table;
|
54
|
+
}
|
55
|
+
if (rot->table[hi].clas == clas) {
|
56
|
+
return &rot->table[hi];
|
57
|
+
}
|
58
|
+
while (2 <= hi - lo) {
|
59
|
+
mid = (hi + lo) / 2;
|
60
|
+
v = rot->table[mid].clas;
|
61
|
+
if (v == clas) {
|
62
|
+
return &rot->table[mid];
|
63
|
+
}
|
64
|
+
if (v < clas) {
|
65
|
+
lo = mid;
|
66
|
+
} else {
|
67
|
+
hi = mid;
|
68
|
+
}
|
69
|
+
}
|
72
70
|
}
|
73
71
|
return NULL;
|
74
72
|
}
|
75
73
|
|
76
|
-
static ROptTable
|
77
|
-
|
78
|
-
dest->len = src->len;
|
74
|
+
static ROptTable copy_opts(ROptTable src, ROptTable dest) {
|
75
|
+
dest->len = src->len;
|
79
76
|
dest->alen = src->alen;
|
80
77
|
if (NULL == src->table) {
|
81
|
-
|
78
|
+
dest->table = NULL;
|
82
79
|
} else {
|
83
|
-
|
84
|
-
|
80
|
+
dest->table = OJ_R_ALLOC_N(struct _rOpt, dest->alen);
|
81
|
+
memcpy(dest->table, src->table, sizeof(struct _rOpt) * dest->alen);
|
85
82
|
}
|
86
83
|
return NULL;
|
87
84
|
}
|
88
85
|
|
89
|
-
static int
|
90
|
-
|
91
|
-
int
|
92
|
-
size_t
|
93
|
-
const char
|
86
|
+
static int dump_attr_cb(ID key, VALUE value, VALUE ov) {
|
87
|
+
Out out = (Out)ov;
|
88
|
+
int depth = out->depth;
|
89
|
+
size_t size = depth * out->indent + 1;
|
90
|
+
const char *attr = rb_id2name(key);
|
94
91
|
|
95
92
|
// Some exceptions such as NoMethodError have an invisible attribute where
|
96
93
|
// the key name is NULL. Not an empty string but NULL.
|
97
94
|
if (NULL == attr) {
|
98
|
-
|
95
|
+
attr = "";
|
99
96
|
}
|
100
97
|
if (0 == strcmp("bt", attr) || 0 == strcmp("mesg", attr)) {
|
101
|
-
|
98
|
+
return ST_CONTINUE;
|
102
99
|
}
|
103
100
|
assure_size(out, size);
|
104
101
|
fill_indent(out, depth);
|
105
102
|
if ('@' == *attr) {
|
106
|
-
|
107
|
-
|
103
|
+
attr++;
|
104
|
+
oj_dump_cstr(attr, strlen(attr), 0, 0, out);
|
108
105
|
} else {
|
109
|
-
|
106
|
+
char buf[32];
|
110
107
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
108
|
+
*buf = '~';
|
109
|
+
strncpy(buf + 1, attr, sizeof(buf) - 2);
|
110
|
+
buf[sizeof(buf) - 1] = '\0';
|
111
|
+
oj_dump_cstr(buf, strlen(buf), 0, 0, out);
|
115
112
|
}
|
116
113
|
*out->cur++ = ':';
|
117
114
|
dump_rails_val(value, depth, out, true);
|
118
|
-
out->depth
|
115
|
+
out->depth = depth;
|
119
116
|
*out->cur++ = ',';
|
120
117
|
|
121
118
|
return ST_CONTINUE;
|
122
119
|
}
|
123
120
|
|
124
|
-
static void
|
125
|
-
dump_obj_attrs(VALUE obj, int depth, Out out, bool as_ok) {
|
121
|
+
static void dump_obj_attrs(VALUE obj, int depth, Out out, bool as_ok) {
|
126
122
|
assure_size(out, 2);
|
127
123
|
*out->cur++ = '{';
|
128
|
-
out->depth
|
124
|
+
out->depth = depth + 1;
|
129
125
|
rb_ivar_foreach(obj, dump_attr_cb, (VALUE)out);
|
130
126
|
if (',' == *(out->cur - 1)) {
|
131
|
-
|
127
|
+
out->cur--; // backup to overwrite last comma
|
132
128
|
}
|
133
129
|
out->depth = depth;
|
134
130
|
fill_indent(out, depth);
|
135
131
|
*out->cur++ = '}';
|
136
|
-
*out->cur
|
132
|
+
*out->cur = '\0';
|
137
133
|
}
|
138
134
|
|
139
|
-
static void
|
140
|
-
|
141
|
-
|
142
|
-
size_t
|
143
|
-
|
144
|
-
volatile VALUE
|
145
|
-
|
146
|
-
int
|
147
|
-
|
148
|
-
|
149
|
-
const char *name;
|
135
|
+
static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
136
|
+
int d3 = depth + 2;
|
137
|
+
size_t size = d3 * out->indent + 2;
|
138
|
+
size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
|
139
|
+
volatile VALUE ma;
|
140
|
+
volatile VALUE v;
|
141
|
+
int cnt;
|
142
|
+
int i;
|
143
|
+
size_t len;
|
144
|
+
const char *name;
|
150
145
|
|
151
146
|
#ifdef RSTRUCT_LEN
|
152
147
|
#if RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
153
148
|
cnt = (int)NUM2LONG(RSTRUCT_LEN(obj));
|
154
|
-
#else
|
149
|
+
#else // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
155
150
|
cnt = (int)RSTRUCT_LEN(obj);
|
156
|
-
#endif
|
151
|
+
#endif // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
157
152
|
#else
|
158
153
|
// This is a bit risky as a struct in C ruby is not the same as a Struct
|
159
154
|
// class in interpreted Ruby so length() may not be defined.
|
@@ -163,89 +158,85 @@ dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
163
158
|
assure_size(out, 2);
|
164
159
|
*out->cur++ = '{';
|
165
160
|
for (i = 0; i < cnt; i++) {
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
strcpy(out->cur, out->opts->dump_opts.after_sep);
|
186
|
-
out->cur += out->opts->dump_opts.after_size;
|
187
|
-
}
|
161
|
+
volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
|
162
|
+
|
163
|
+
name = RSTRING_PTR(s);
|
164
|
+
len = RSTRING_LEN(s);
|
165
|
+
assure_size(out, size + sep_len + 6);
|
166
|
+
if (0 < i) {
|
167
|
+
*out->cur++ = ',';
|
168
|
+
}
|
169
|
+
fill_indent(out, d3);
|
170
|
+
*out->cur++ = '"';
|
171
|
+
APPEND_CHARS(out->cur, name, len);
|
172
|
+
*out->cur++ = '"';
|
173
|
+
if (0 < out->opts->dump_opts.before_size) {
|
174
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
|
175
|
+
}
|
176
|
+
*out->cur++ = ':';
|
177
|
+
if (0 < out->opts->dump_opts.after_size) {
|
178
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
|
179
|
+
}
|
188
180
|
#ifdef RSTRUCT_LEN
|
189
|
-
|
181
|
+
v = RSTRUCT_GET(obj, i);
|
190
182
|
#else
|
191
|
-
|
183
|
+
v = rb_struct_aref(obj, INT2FIX(i));
|
192
184
|
#endif
|
193
|
-
|
185
|
+
dump_rails_val(v, d3, out, true);
|
194
186
|
}
|
195
187
|
fill_indent(out, depth);
|
196
188
|
*out->cur++ = '}';
|
197
|
-
*out->cur
|
189
|
+
*out->cur = '\0';
|
198
190
|
}
|
199
191
|
|
200
|
-
static ID
|
192
|
+
static ID to_a_id = 0;
|
201
193
|
|
202
|
-
static void
|
203
|
-
dump_enumerable(VALUE obj, int depth, Out out, bool as_ok) {
|
194
|
+
static void dump_enumerable(VALUE obj, int depth, Out out, bool as_ok) {
|
204
195
|
if (0 == to_a_id) {
|
205
|
-
|
196
|
+
to_a_id = rb_intern("to_a");
|
206
197
|
}
|
207
198
|
dump_rails_val(rb_funcall(obj, to_a_id, 0), depth, out, false);
|
208
199
|
}
|
209
200
|
|
210
|
-
static void
|
211
|
-
|
212
|
-
|
213
|
-
const char *str = rb_string_value_ptr((VALUE*)&rstr);
|
201
|
+
static void dump_bigdecimal(VALUE obj, int depth, Out out, bool as_ok) {
|
202
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
203
|
+
const char *str = RSTRING_PTR(rstr);
|
214
204
|
|
215
205
|
if ('I' == *str || 'N' == *str || ('-' == *str && 'I' == str[1])) {
|
216
|
-
|
206
|
+
oj_dump_nil(Qnil, depth, out, false);
|
207
|
+
} else if (out->opts->int_range_max != 0 || out->opts->int_range_min != 0) {
|
208
|
+
oj_dump_cstr(str, RSTRING_LEN(rstr), 0, 0, out);
|
217
209
|
} else if (Yes == out->opts->bigdec_as_num) {
|
218
|
-
|
210
|
+
oj_dump_raw(str, RSTRING_LEN(rstr), out);
|
219
211
|
} else {
|
220
|
-
|
212
|
+
oj_dump_cstr(str, RSTRING_LEN(rstr), 0, 0, out);
|
221
213
|
}
|
222
214
|
}
|
223
215
|
|
224
|
-
static void
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
long
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
int len;
|
216
|
+
static void dump_sec_nano(VALUE obj, int64_t sec, long nsec, Out out) {
|
217
|
+
char buf[64];
|
218
|
+
struct _timeInfo ti;
|
219
|
+
long one = 1000000000;
|
220
|
+
long tzsecs = NUM2LONG(rb_funcall2(obj, oj_utc_offset_id, 0, 0));
|
221
|
+
int tzhour, tzmin;
|
222
|
+
char tzsign = '+';
|
223
|
+
int len;
|
233
224
|
|
234
225
|
if (out->end - out->cur <= 36) {
|
235
|
-
|
226
|
+
assure_size(out, 36);
|
236
227
|
}
|
237
228
|
if (9 > out->opts->sec_prec) {
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
229
|
+
int i;
|
230
|
+
|
231
|
+
// Rails does not round when reducing precision but instead floors,
|
232
|
+
for (i = 9 - out->opts->sec_prec; 0 < i; i--) {
|
233
|
+
nsec = nsec / 10;
|
234
|
+
one /= 10;
|
235
|
+
}
|
236
|
+
if (one <= nsec) {
|
237
|
+
nsec -= one;
|
238
|
+
sec++;
|
239
|
+
}
|
249
240
|
}
|
250
241
|
// 2012-01-05T23:58:07.123456000+09:00 or 2012/01/05 23:58:07 +0900
|
251
242
|
sec += tzsecs;
|
@@ -253,509 +244,506 @@ dump_sec_nano(VALUE obj, int64_t sec, long nsec, Out out) {
|
|
253
244
|
if (0 > tzsecs) {
|
254
245
|
tzsign = '-';
|
255
246
|
tzhour = (int)(tzsecs / -3600);
|
256
|
-
tzmin
|
247
|
+
tzmin = (int)(tzsecs / -60) - (tzhour * 60);
|
257
248
|
} else {
|
258
249
|
tzhour = (int)(tzsecs / 3600);
|
259
|
-
tzmin
|
250
|
+
tzmin = (int)(tzsecs / 60) - (tzhour * 60);
|
260
251
|
}
|
261
252
|
if (!xml_time) {
|
262
|
-
|
253
|
+
len = sprintf(buf,
|
254
|
+
"%04d/%02d/%02d %02d:%02d:%02d %c%02d%02d",
|
255
|
+
ti.year,
|
256
|
+
ti.mon,
|
257
|
+
ti.day,
|
258
|
+
ti.hour,
|
259
|
+
ti.min,
|
260
|
+
ti.sec,
|
261
|
+
tzsign,
|
262
|
+
tzhour,
|
263
|
+
tzmin);
|
263
264
|
} else if (0 == out->opts->sec_prec) {
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
265
|
+
if (0 == tzsecs && rb_funcall2(obj, oj_utcq_id, 0, 0)) {
|
266
|
+
len = sprintf(buf, "%04d-%02d-%02dT%02d:%02d:%02dZ", ti.year, ti.mon, ti.day, ti.hour, ti.min, ti.sec);
|
267
|
+
} else {
|
268
|
+
len = sprintf(buf,
|
269
|
+
"%04d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d",
|
270
|
+
ti.year,
|
271
|
+
ti.mon,
|
272
|
+
ti.day,
|
273
|
+
ti.hour,
|
274
|
+
ti.min,
|
275
|
+
ti.sec,
|
276
|
+
tzsign,
|
277
|
+
tzhour,
|
278
|
+
tzmin);
|
279
|
+
}
|
269
280
|
} else if (0 == tzsecs && rb_funcall2(obj, oj_utcq_id, 0, 0)) {
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
281
|
+
char format[64] = "%04d-%02d-%02dT%02d:%02d:%02d.%09ldZ";
|
282
|
+
|
283
|
+
len = 30;
|
284
|
+
if (9 > out->opts->sec_prec) {
|
285
|
+
format[32] = '0' + out->opts->sec_prec;
|
286
|
+
len -= 9 - out->opts->sec_prec;
|
287
|
+
}
|
288
|
+
len = sprintf(buf, format, ti.year, ti.mon, ti.day, ti.hour, ti.min, ti.sec, nsec);
|
278
289
|
} else {
|
279
|
-
|
290
|
+
char format[64] = "%04d-%02d-%02dT%02d:%02d:%02d.%09ld%c%02d:%02d";
|
280
291
|
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
292
|
+
len = 35;
|
293
|
+
if (9 > out->opts->sec_prec) {
|
294
|
+
format[32] = '0' + out->opts->sec_prec;
|
295
|
+
len -= 9 - out->opts->sec_prec;
|
296
|
+
}
|
297
|
+
len = sprintf(buf, format, ti.year, ti.mon, ti.day, ti.hour, ti.min, ti.sec, nsec, tzsign, tzhour, tzmin);
|
287
298
|
}
|
288
299
|
oj_dump_cstr(buf, len, 0, 0, out);
|
289
300
|
}
|
290
301
|
|
291
|
-
static void
|
292
|
-
|
293
|
-
long long
|
294
|
-
long long nsec;
|
302
|
+
static void dump_time(VALUE obj, int depth, Out out, bool as_ok) {
|
303
|
+
long long sec;
|
304
|
+
long long nsec;
|
295
305
|
|
296
|
-
#ifdef HAVE_RB_TIME_TIMESPEC
|
297
306
|
if (16 <= sizeof(struct timespec)) {
|
298
|
-
|
307
|
+
struct timespec ts = rb_time_timespec(obj);
|
299
308
|
|
300
|
-
|
301
|
-
|
309
|
+
sec = (long long)ts.tv_sec;
|
310
|
+
nsec = ts.tv_nsec;
|
302
311
|
} else {
|
303
|
-
|
304
|
-
|
312
|
+
sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
313
|
+
nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
305
314
|
}
|
306
|
-
#else
|
307
|
-
sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
308
|
-
nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
309
|
-
#endif
|
310
315
|
dump_sec_nano(obj, sec, nsec, out);
|
311
316
|
}
|
312
317
|
|
313
|
-
static void
|
314
|
-
|
315
|
-
|
316
|
-
long long nsec = 0;
|
318
|
+
static void dump_timewithzone(VALUE obj, int depth, Out out, bool as_ok) {
|
319
|
+
int64_t sec = NUM2LONG(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
320
|
+
long long nsec = 0;
|
317
321
|
|
318
322
|
if (rb_respond_to(obj, oj_tv_nsec_id)) {
|
319
|
-
|
323
|
+
nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
320
324
|
} else if (rb_respond_to(obj, oj_tv_usec_id)) {
|
321
|
-
|
325
|
+
nsec = NUM2LL(rb_funcall2(obj, oj_tv_usec_id, 0, 0)) * 1000;
|
322
326
|
}
|
323
327
|
dump_sec_nano(obj, sec, nsec, out);
|
324
328
|
}
|
325
329
|
|
326
|
-
static void
|
327
|
-
|
328
|
-
volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
|
330
|
+
static void dump_to_s(VALUE obj, int depth, Out out, bool as_ok) {
|
331
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
329
332
|
|
330
|
-
oj_dump_cstr(
|
333
|
+
oj_dump_cstr(RSTRING_PTR(rstr), RSTRING_LEN(rstr), 0, 0, out);
|
331
334
|
}
|
332
335
|
|
333
|
-
static ID
|
336
|
+
static ID parameters_id = 0;
|
334
337
|
|
335
338
|
typedef struct _strLen {
|
336
|
-
const char
|
337
|
-
|
339
|
+
const char *str;
|
340
|
+
size_t len;
|
338
341
|
} *StrLen;
|
339
342
|
|
340
|
-
static void
|
341
|
-
dump_actioncontroller_parameters(VALUE obj, int depth, Out out, bool as_ok) {
|
343
|
+
static void dump_actioncontroller_parameters(VALUE obj, int depth, Out out, bool as_ok) {
|
342
344
|
if (0 == parameters_id) {
|
343
|
-
|
345
|
+
parameters_id = rb_intern("@parameters");
|
344
346
|
}
|
345
347
|
out->argc = 0;
|
346
348
|
dump_rails_val(rb_ivar_get(obj, parameters_id), depth, out, true);
|
347
349
|
}
|
348
350
|
|
349
|
-
static StrLen
|
350
|
-
|
351
|
-
|
352
|
-
StrLen
|
353
|
-
|
354
|
-
|
355
|
-
int cnt = (int)RARRAY_LEN(rcols);
|
351
|
+
static StrLen columns_array(VALUE rcols, int *ccnt) {
|
352
|
+
volatile VALUE v;
|
353
|
+
StrLen cp;
|
354
|
+
StrLen cols;
|
355
|
+
size_t i;
|
356
|
+
size_t cnt = RARRAY_LEN(rcols);
|
356
357
|
|
357
|
-
*ccnt = cnt;
|
358
|
-
cols
|
358
|
+
*ccnt = (int)cnt;
|
359
|
+
cols = OJ_R_ALLOC_N(struct _strLen, cnt);
|
359
360
|
for (i = 0, cp = cols; i < cnt; i++, cp++) {
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
361
|
+
v = RARRAY_AREF(rcols, i);
|
362
|
+
if (T_STRING != rb_type(v)) {
|
363
|
+
v = oj_safe_string_convert(v);
|
364
|
+
}
|
365
|
+
cp->str = StringValuePtr(v);
|
366
|
+
cp->len = RSTRING_LEN(v);
|
366
367
|
}
|
367
368
|
return cols;
|
368
369
|
}
|
369
370
|
|
370
|
-
static void
|
371
|
-
|
372
|
-
|
373
|
-
int
|
374
|
-
int i;
|
371
|
+
static void dump_row(VALUE row, StrLen cols, int ccnt, int depth, Out out) {
|
372
|
+
size_t size;
|
373
|
+
int d2 = depth + 1;
|
374
|
+
int i;
|
375
375
|
|
376
376
|
assure_size(out, 2);
|
377
377
|
*out->cur++ = '{';
|
378
|
-
size
|
378
|
+
size = depth * out->indent + 3;
|
379
379
|
for (i = 0; i < ccnt; i++, cols++) {
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
*out->cur++ = ',';
|
401
|
-
}
|
380
|
+
assure_size(out, size);
|
381
|
+
if (out->opts->dump_opts.use) {
|
382
|
+
if (0 < out->opts->dump_opts.array_size) {
|
383
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
384
|
+
}
|
385
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
386
|
+
int i;
|
387
|
+
for (i = d2; 0 < i; i--) {
|
388
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
389
|
+
}
|
390
|
+
}
|
391
|
+
} else {
|
392
|
+
fill_indent(out, d2);
|
393
|
+
}
|
394
|
+
oj_dump_cstr(cols->str, cols->len, 0, 0, out);
|
395
|
+
*out->cur++ = ':';
|
396
|
+
dump_rails_val(RARRAY_AREF(row, i), depth, out, true);
|
397
|
+
if (i < ccnt - 1) {
|
398
|
+
*out->cur++ = ',';
|
399
|
+
}
|
402
400
|
}
|
403
401
|
size = depth * out->indent + 1;
|
404
402
|
assure_size(out, size);
|
405
403
|
if (out->opts->dump_opts.use) {
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
}
|
417
|
-
}
|
404
|
+
if (0 < out->opts->dump_opts.array_size) {
|
405
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
406
|
+
}
|
407
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
408
|
+
int i;
|
409
|
+
|
410
|
+
for (i = depth; 0 < i; i--) {
|
411
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
412
|
+
}
|
413
|
+
}
|
418
414
|
} else {
|
419
|
-
|
415
|
+
fill_indent(out, depth);
|
420
416
|
}
|
421
417
|
*out->cur++ = '}';
|
422
418
|
}
|
423
419
|
|
424
|
-
static ID
|
425
|
-
static ID
|
420
|
+
static ID rows_id = 0;
|
421
|
+
static ID columns_id = 0;
|
426
422
|
|
427
|
-
static void
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
size_t
|
434
|
-
int
|
423
|
+
static void dump_activerecord_result(VALUE obj, int depth, Out out, bool as_ok) {
|
424
|
+
volatile VALUE rows;
|
425
|
+
StrLen cols;
|
426
|
+
int ccnt = 0;
|
427
|
+
size_t i;
|
428
|
+
size_t rcnt;
|
429
|
+
size_t size;
|
430
|
+
int d2 = depth + 1;
|
435
431
|
|
436
432
|
if (0 == rows_id) {
|
437
|
-
|
438
|
-
|
433
|
+
rows_id = rb_intern("@rows");
|
434
|
+
columns_id = rb_intern("@columns");
|
439
435
|
}
|
440
436
|
out->argc = 0;
|
441
|
-
cols
|
442
|
-
rows
|
443
|
-
rcnt
|
437
|
+
cols = columns_array(rb_ivar_get(obj, columns_id), &ccnt);
|
438
|
+
rows = rb_ivar_get(obj, rows_id);
|
439
|
+
rcnt = RARRAY_LEN(rows);
|
444
440
|
assure_size(out, 2);
|
445
441
|
*out->cur++ = '[';
|
446
442
|
if (out->opts->dump_opts.use) {
|
447
|
-
|
443
|
+
size = d2 * out->opts->dump_opts.indent_size + out->opts->dump_opts.array_size + 1;
|
448
444
|
} else {
|
449
|
-
|
445
|
+
size = d2 * out->indent + 2;
|
450
446
|
}
|
451
447
|
assure_size(out, 2);
|
452
448
|
for (i = 0; i < rcnt; i++) {
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
}
|
474
|
-
xfree(cols);
|
449
|
+
assure_size(out, size);
|
450
|
+
if (out->opts->dump_opts.use) {
|
451
|
+
if (0 < out->opts->dump_opts.array_size) {
|
452
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
453
|
+
}
|
454
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
455
|
+
int i;
|
456
|
+
for (i = d2; 0 < i; i--) {
|
457
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
458
|
+
}
|
459
|
+
}
|
460
|
+
} else {
|
461
|
+
fill_indent(out, d2);
|
462
|
+
}
|
463
|
+
dump_row(RARRAY_AREF(rows, i), cols, ccnt, d2, out);
|
464
|
+
if (i < rcnt - 1) {
|
465
|
+
*out->cur++ = ',';
|
466
|
+
}
|
467
|
+
}
|
468
|
+
OJ_R_FREE(cols);
|
475
469
|
size = depth * out->indent + 1;
|
476
470
|
assure_size(out, size);
|
477
471
|
if (out->opts->dump_opts.use) {
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
}
|
489
|
-
}
|
472
|
+
if (0 < out->opts->dump_opts.array_size) {
|
473
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
474
|
+
}
|
475
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
476
|
+
int i;
|
477
|
+
|
478
|
+
for (i = depth; 0 < i; i--) {
|
479
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
480
|
+
}
|
481
|
+
}
|
490
482
|
} else {
|
491
|
-
|
483
|
+
fill_indent(out, depth);
|
492
484
|
}
|
493
485
|
*out->cur++ = ']';
|
494
486
|
}
|
495
487
|
|
496
488
|
typedef struct _namedFunc {
|
497
|
-
const char
|
498
|
-
DumpFunc
|
489
|
+
const char *name;
|
490
|
+
DumpFunc func;
|
499
491
|
} *NamedFunc;
|
500
492
|
|
501
|
-
static void
|
502
|
-
dump_as_string(VALUE obj, int depth, Out out, bool as_ok) {
|
493
|
+
static void dump_as_string(VALUE obj, int depth, Out out, bool as_ok) {
|
503
494
|
if (oj_code_dump(oj_compat_codes, obj, depth, out)) {
|
504
|
-
|
505
|
-
|
495
|
+
out->argc = 0;
|
496
|
+
return;
|
506
497
|
}
|
507
498
|
oj_dump_obj_to_s(obj, out);
|
508
499
|
}
|
509
500
|
|
510
|
-
static void
|
511
|
-
|
512
|
-
volatile VALUE ja;
|
501
|
+
static void dump_as_json(VALUE obj, int depth, Out out, bool as_ok) {
|
502
|
+
volatile VALUE ja;
|
513
503
|
|
514
|
-
|
515
|
-
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
|
516
|
-
}
|
504
|
+
TRACE(out->opts->trace, "as_json", obj, depth + 1, TraceRubyIn);
|
517
505
|
// Some classes elect to not take an options argument so check the arity
|
518
506
|
// of as_json.
|
519
507
|
if (0 == rb_obj_method_arity(obj, oj_as_json_id)) {
|
520
|
-
|
508
|
+
ja = rb_funcall(obj, oj_as_json_id, 0);
|
521
509
|
} else {
|
522
|
-
|
523
|
-
}
|
524
|
-
if (Yes == out->opts->trace) {
|
525
|
-
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
|
510
|
+
ja = rb_funcall2(obj, oj_as_json_id, out->argc, out->argv);
|
526
511
|
}
|
512
|
+
TRACE(out->opts->trace, "as_json", obj, depth + 1, TraceRubyOut);
|
527
513
|
|
528
514
|
out->argc = 0;
|
529
515
|
if (ja == obj || !as_ok) {
|
530
|
-
|
531
|
-
|
532
|
-
|
516
|
+
// Once as_json is called it should never be called again on the same
|
517
|
+
// object with as_ok.
|
518
|
+
dump_rails_val(ja, depth, out, false);
|
533
519
|
} else {
|
534
|
-
|
520
|
+
int type = rb_type(ja);
|
535
521
|
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
522
|
+
if (T_HASH == type || T_ARRAY == type) {
|
523
|
+
dump_rails_val(ja, depth, out, true);
|
524
|
+
} else {
|
525
|
+
dump_rails_val(ja, depth, out, true);
|
526
|
+
}
|
541
527
|
}
|
542
528
|
}
|
543
529
|
|
544
|
-
static void
|
545
|
-
dump_regexp(VALUE obj, int depth, Out out, bool as_ok) {
|
530
|
+
static void dump_regexp(VALUE obj, int depth, Out out, bool as_ok) {
|
546
531
|
if (as_ok && rb_respond_to(obj, oj_as_json_id)) {
|
547
|
-
|
548
|
-
|
532
|
+
dump_as_json(obj, depth, out, false);
|
533
|
+
return;
|
549
534
|
}
|
550
535
|
dump_as_string(obj, depth, out, as_ok);
|
551
536
|
}
|
552
537
|
|
553
|
-
static struct _namedFunc
|
554
|
-
{
|
555
|
-
{
|
556
|
-
{
|
557
|
-
{
|
558
|
-
{
|
559
|
-
{
|
538
|
+
static struct _namedFunc dump_map[] = {
|
539
|
+
{"ActionController::Parameters", dump_actioncontroller_parameters},
|
540
|
+
{"ActiveRecord::Result", dump_activerecord_result},
|
541
|
+
{"ActiveSupport::TimeWithZone", dump_timewithzone},
|
542
|
+
{"BigDecimal", dump_bigdecimal},
|
543
|
+
{"Range", dump_to_s},
|
544
|
+
{"Regexp", dump_regexp},
|
560
545
|
//{ "Regexp", dump_to_s },
|
561
|
-
{
|
562
|
-
{
|
546
|
+
{"Time", dump_time},
|
547
|
+
{NULL, NULL},
|
563
548
|
};
|
564
549
|
|
565
|
-
static VALUE
|
566
|
-
static ID
|
550
|
+
static VALUE activerecord_base = Qundef;
|
551
|
+
static ID attributes_id = 0;
|
567
552
|
|
568
|
-
static void
|
569
|
-
dump_activerecord(VALUE obj, int depth, Out out, bool as_ok) {
|
553
|
+
static void dump_activerecord(VALUE obj, int depth, Out out, bool as_ok) {
|
570
554
|
if (0 == attributes_id) {
|
571
|
-
|
555
|
+
attributes_id = rb_intern("@attributes");
|
572
556
|
}
|
573
557
|
out->argc = 0;
|
574
558
|
dump_rails_val(rb_ivar_get(obj, attributes_id), depth, out, true);
|
575
559
|
}
|
576
560
|
|
577
|
-
static ROpt
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
int olen = rot->len;
|
561
|
+
static ROpt create_opt(ROptTable rot, VALUE clas) {
|
562
|
+
ROpt ro;
|
563
|
+
NamedFunc nf;
|
564
|
+
const char *classname = rb_class2name(clas);
|
565
|
+
int olen = rot->len;
|
583
566
|
|
584
567
|
rot->len++;
|
585
568
|
if (NULL == rot->table) {
|
586
|
-
|
587
|
-
|
588
|
-
|
569
|
+
rot->alen = 256;
|
570
|
+
rot->table = OJ_R_ALLOC_N(struct _rOpt, rot->alen);
|
571
|
+
memset(rot->table, 0, sizeof(struct _rOpt) * rot->alen);
|
589
572
|
} else if (rot->alen <= rot->len) {
|
590
|
-
|
591
|
-
|
592
|
-
|
573
|
+
rot->alen *= 2;
|
574
|
+
OJ_R_REALLOC_N(rot->table, struct _rOpt, rot->alen);
|
575
|
+
memset(rot->table + olen, 0, sizeof(struct _rOpt) * olen);
|
593
576
|
}
|
594
577
|
if (0 == olen) {
|
595
|
-
|
578
|
+
ro = rot->table;
|
596
579
|
} else if (rot->table[olen - 1].clas < clas) {
|
597
|
-
|
580
|
+
ro = &rot->table[olen];
|
598
581
|
} else {
|
599
|
-
|
582
|
+
int i;
|
600
583
|
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
584
|
+
for (i = 0, ro = rot->table; i < olen; i++, ro++) {
|
585
|
+
if (clas < ro->clas) {
|
586
|
+
memmove(ro + 1, ro, sizeof(struct _rOpt) * (olen - i));
|
587
|
+
break;
|
588
|
+
}
|
589
|
+
}
|
607
590
|
}
|
608
591
|
ro->clas = clas;
|
609
|
-
ro->on
|
592
|
+
ro->on = true;
|
610
593
|
ro->dump = dump_obj_attrs;
|
611
594
|
for (nf = dump_map; NULL != nf->name; nf++) {
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
595
|
+
if (0 == strcmp(nf->name, classname)) {
|
596
|
+
ro->dump = nf->func;
|
597
|
+
break;
|
598
|
+
}
|
616
599
|
}
|
617
600
|
if (ro->dump == dump_obj_attrs) {
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
601
|
+
if (Qundef == activerecord_base) {
|
602
|
+
// If not defined let an exception be raised.
|
603
|
+
VALUE ar = rb_const_get_at(rb_cObject, rb_intern("ActiveRecord"));
|
604
|
+
|
605
|
+
if (Qundef != ar) {
|
606
|
+
activerecord_base = rb_const_get_at(ar, rb_intern("Base"));
|
607
|
+
}
|
608
|
+
}
|
609
|
+
if (Qundef != activerecord_base && Qtrue == rb_class_inherited_p(clas, activerecord_base)) {
|
610
|
+
ro->dump = dump_activerecord;
|
611
|
+
} else if (Qtrue == rb_class_inherited_p(clas, rb_cStruct)) { // check before enumerable
|
612
|
+
ro->dump = dump_struct;
|
613
|
+
} else if (Qtrue == rb_class_inherited_p(clas, rb_mEnumerable)) {
|
614
|
+
ro->dump = dump_enumerable;
|
615
|
+
} else if (Qtrue == rb_class_inherited_p(clas, rb_eException)) {
|
616
|
+
ro->dump = dump_to_s;
|
617
|
+
}
|
635
618
|
}
|
636
619
|
return ro;
|
637
620
|
}
|
638
621
|
|
639
|
-
static void
|
640
|
-
encoder_free(void *ptr) {
|
622
|
+
static void encoder_free(void *ptr) {
|
641
623
|
if (NULL != ptr) {
|
642
|
-
|
624
|
+
Encoder e = (Encoder)ptr;
|
643
625
|
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
626
|
+
if (NULL != e->ropts.table) {
|
627
|
+
OJ_R_FREE(e->ropts.table);
|
628
|
+
}
|
629
|
+
OJ_R_FREE(ptr);
|
648
630
|
}
|
649
631
|
}
|
650
632
|
|
651
|
-
static void
|
652
|
-
encoder_mark(void *ptr) {
|
633
|
+
static void encoder_mark(void *ptr) {
|
653
634
|
if (NULL != ptr) {
|
654
|
-
|
635
|
+
Encoder e = (Encoder)ptr;
|
655
636
|
|
656
|
-
|
657
|
-
|
658
|
-
|
637
|
+
if (Qnil != e->arg) {
|
638
|
+
rb_gc_mark(e->arg);
|
639
|
+
}
|
659
640
|
}
|
660
641
|
}
|
661
642
|
|
643
|
+
static const rb_data_type_t oj_encoder_type = {
|
644
|
+
"Oj/encoder",
|
645
|
+
{
|
646
|
+
encoder_mark,
|
647
|
+
encoder_free,
|
648
|
+
NULL,
|
649
|
+
},
|
650
|
+
0,
|
651
|
+
0,
|
652
|
+
};
|
653
|
+
|
662
654
|
/* Document-method: new
|
663
655
|
* call-seq: new(options=nil)
|
664
656
|
*
|
665
657
|
* Creates a new Encoder.
|
666
658
|
* - *options* [_Hash_] formatting options
|
667
659
|
*/
|
668
|
-
static VALUE
|
669
|
-
|
670
|
-
Encoder e = ALLOC(struct _encoder);
|
660
|
+
static VALUE encoder_new(int argc, VALUE *argv, VALUE self) {
|
661
|
+
Encoder e = OJ_R_ALLOC(struct _encoder);
|
671
662
|
|
672
663
|
e->opts = oj_default_options;
|
673
|
-
e->arg
|
664
|
+
e->arg = Qnil;
|
674
665
|
copy_opts(&ropts, &e->ropts);
|
675
666
|
|
676
667
|
if (1 <= argc && Qnil != *argv) {
|
677
|
-
|
678
|
-
|
668
|
+
oj_parse_options(*argv, &e->opts);
|
669
|
+
e->arg = *argv;
|
679
670
|
}
|
680
|
-
return
|
671
|
+
return TypedData_Wrap_Struct(encoder_class, &oj_encoder_type, e);
|
681
672
|
}
|
682
673
|
|
683
|
-
static VALUE
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
char
|
688
|
-
char
|
689
|
-
|
690
|
-
ID cid;
|
674
|
+
static VALUE resolve_classpath(const char *name) {
|
675
|
+
char class_name[1024];
|
676
|
+
VALUE clas;
|
677
|
+
char *end = class_name + sizeof(class_name) - 1;
|
678
|
+
char *s;
|
679
|
+
const char *n = name;
|
680
|
+
ID cid;
|
691
681
|
|
692
682
|
clas = rb_cObject;
|
693
683
|
for (s = class_name; '\0' != *n; n++) {
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
}
|
712
|
-
*s
|
684
|
+
if (':' == *n) {
|
685
|
+
*s = '\0';
|
686
|
+
n++;
|
687
|
+
if (':' != *n) {
|
688
|
+
return Qnil;
|
689
|
+
}
|
690
|
+
cid = rb_intern(class_name);
|
691
|
+
if (!rb_const_defined_at(clas, cid)) {
|
692
|
+
return Qnil;
|
693
|
+
}
|
694
|
+
clas = rb_const_get_at(clas, cid);
|
695
|
+
s = class_name;
|
696
|
+
} else if (end <= s) {
|
697
|
+
return Qnil;
|
698
|
+
} else {
|
699
|
+
*s++ = *n;
|
700
|
+
}
|
701
|
+
}
|
702
|
+
*s = '\0';
|
713
703
|
cid = rb_intern(class_name);
|
714
704
|
if (!rb_const_defined_at(clas, cid)) {
|
715
|
-
|
705
|
+
return Qnil;
|
716
706
|
}
|
717
707
|
clas = rb_const_get_at(clas, cid);
|
718
708
|
|
719
709
|
return clas;
|
720
710
|
}
|
721
711
|
|
722
|
-
static void
|
723
|
-
|
724
|
-
ROpt ro;
|
712
|
+
static void optimize(int argc, VALUE *argv, ROptTable rot, bool on) {
|
713
|
+
ROpt ro;
|
725
714
|
|
726
715
|
if (0 == argc) {
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
716
|
+
int i;
|
717
|
+
NamedFunc nf;
|
718
|
+
VALUE clas;
|
719
|
+
|
720
|
+
oj_rails_hash_opt = on;
|
721
|
+
oj_rails_array_opt = on;
|
722
|
+
oj_rails_float_opt = on;
|
723
|
+
|
724
|
+
for (nf = dump_map; NULL != nf->name; nf++) {
|
725
|
+
if (Qnil != (clas = resolve_classpath(nf->name))) {
|
726
|
+
if (NULL == oj_rails_get_opt(rot, clas)) {
|
727
|
+
create_opt(rot, clas);
|
728
|
+
}
|
729
|
+
}
|
730
|
+
}
|
731
|
+
for (i = 0; i < rot->len; i++) {
|
732
|
+
rot->table[i].on = on;
|
733
|
+
}
|
745
734
|
}
|
746
735
|
for (; 0 < argc; argc--, argv++) {
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
}
|
736
|
+
if (rb_cHash == *argv) {
|
737
|
+
oj_rails_hash_opt = on;
|
738
|
+
} else if (rb_cArray == *argv) {
|
739
|
+
oj_rails_array_opt = on;
|
740
|
+
} else if (rb_cFloat == *argv) {
|
741
|
+
oj_rails_float_opt = on;
|
742
|
+
} else if (oj_string_writer_class == *argv) {
|
743
|
+
string_writer_optimized = on;
|
744
|
+
} else if (NULL != (ro = oj_rails_get_opt(rot, *argv)) || NULL != (ro = create_opt(rot, *argv))) {
|
745
|
+
ro->on = on;
|
746
|
+
}
|
759
747
|
}
|
760
748
|
}
|
761
749
|
|
@@ -771,9 +759,9 @@ optimize(int argc, VALUE *argv, ROptTable rot, bool on) {
|
|
771
759
|
*
|
772
760
|
* - *classes* [_Class_] a list of classes to optimize
|
773
761
|
*/
|
774
|
-
static VALUE
|
775
|
-
|
776
|
-
|
762
|
+
static VALUE encoder_optimize(int argc, VALUE *argv, VALUE self) {
|
763
|
+
Encoder e;
|
764
|
+
TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
|
777
765
|
|
778
766
|
optimize(argc, argv, &e->ropts, true);
|
779
767
|
|
@@ -792,8 +780,7 @@ encoder_optimize(int argc, VALUE *argv, VALUE self) {
|
|
792
780
|
*
|
793
781
|
* - *classes* [_Class_] a list of classes to optimize
|
794
782
|
*/
|
795
|
-
static VALUE
|
796
|
-
rails_optimize(int argc, VALUE *argv, VALUE self) {
|
783
|
+
static VALUE rails_optimize(int argc, VALUE *argv, VALUE self) {
|
797
784
|
optimize(argc, argv, &ropts, true);
|
798
785
|
string_writer_optimized = true;
|
799
786
|
|
@@ -808,15 +795,16 @@ rails_optimize(int argc, VALUE *argv, VALUE self) {
|
|
808
795
|
*/
|
809
796
|
VALUE
|
810
797
|
rails_mimic_json(VALUE self) {
|
811
|
-
VALUE
|
798
|
+
VALUE json;
|
812
799
|
|
813
800
|
if (rb_const_defined_at(rb_cObject, rb_intern("JSON"))) {
|
814
|
-
|
801
|
+
json = rb_const_get_at(rb_cObject, rb_intern("JSON"));
|
815
802
|
} else {
|
816
|
-
|
803
|
+
json = rb_define_module("JSON");
|
817
804
|
}
|
818
805
|
oj_mimic_json_methods(json);
|
819
|
-
//
|
806
|
+
// Setting the default mode breaks the prmoise in the docs not to.
|
807
|
+
// oj_default_options.mode = RailsMode;
|
820
808
|
|
821
809
|
return Qnil;
|
822
810
|
}
|
@@ -828,9 +816,9 @@ rails_mimic_json(VALUE self) {
|
|
828
816
|
*
|
829
817
|
* - *classes* [_Class_] a list of classes to deoptimize
|
830
818
|
*/
|
831
|
-
static VALUE
|
832
|
-
|
833
|
-
|
819
|
+
static VALUE encoder_deoptimize(int argc, VALUE *argv, VALUE self) {
|
820
|
+
Encoder e;
|
821
|
+
TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
|
834
822
|
|
835
823
|
optimize(argc, argv, &e->ropts, false);
|
836
824
|
|
@@ -844,8 +832,7 @@ encoder_deoptimize(int argc, VALUE *argv, VALUE self) {
|
|
844
832
|
*
|
845
833
|
* - *classes* [_Class_] a list of classes to deoptimize
|
846
834
|
*/
|
847
|
-
static VALUE
|
848
|
-
rails_deoptimize(int argc, VALUE *argv, VALUE self) {
|
835
|
+
static VALUE rails_deoptimize(int argc, VALUE *argv, VALUE self) {
|
849
836
|
optimize(argc, argv, &ropts, false);
|
850
837
|
string_writer_optimized = false;
|
851
838
|
|
@@ -859,13 +846,15 @@ rails_deoptimize(int argc, VALUE *argv, VALUE self) {
|
|
859
846
|
*
|
860
847
|
* @return true if the class is being optimized for rails and false otherwise
|
861
848
|
*/
|
862
|
-
static VALUE
|
863
|
-
|
864
|
-
|
865
|
-
|
849
|
+
static VALUE encoder_optimized(VALUE self, VALUE clas) {
|
850
|
+
Encoder e;
|
851
|
+
ROpt ro;
|
852
|
+
|
853
|
+
TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
|
854
|
+
ro = oj_rails_get_opt(&e->ropts, clas);
|
866
855
|
|
867
856
|
if (NULL == ro) {
|
868
|
-
|
857
|
+
return Qfalse;
|
869
858
|
}
|
870
859
|
return (ro->on) ? Qtrue : Qfalse;
|
871
860
|
}
|
@@ -875,95 +864,86 @@ encoder_optimized(VALUE self, VALUE clas) {
|
|
875
864
|
*
|
876
865
|
* Returns true if the specified Class is being optimized.
|
877
866
|
*/
|
878
|
-
static VALUE
|
879
|
-
|
880
|
-
ROpt ro = oj_rails_get_opt(&ropts, clas);
|
867
|
+
static VALUE rails_optimized(VALUE self, VALUE clas) {
|
868
|
+
ROpt ro = oj_rails_get_opt(&ropts, clas);
|
881
869
|
|
882
870
|
if (NULL == ro) {
|
883
|
-
|
871
|
+
return Qfalse;
|
884
872
|
}
|
885
873
|
return (ro->on) ? Qtrue : Qfalse;
|
886
874
|
}
|
887
875
|
|
888
876
|
typedef struct _oo {
|
889
|
-
Out
|
890
|
-
VALUE
|
877
|
+
Out out;
|
878
|
+
VALUE obj;
|
891
879
|
} *OO;
|
892
880
|
|
893
|
-
static VALUE
|
894
|
-
|
895
|
-
OO oo = (OO)ov;
|
881
|
+
static VALUE protect_dump(VALUE ov) {
|
882
|
+
OO oo = (OO)ov;
|
896
883
|
|
897
884
|
dump_rails_val(oo->obj, 0, oo->out, true);
|
898
885
|
|
899
886
|
return Qnil;
|
900
887
|
}
|
901
888
|
|
902
|
-
static VALUE
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
struct
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
oo.out = &out;
|
912
|
-
oo.obj = obj;
|
889
|
+
static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *argv) {
|
890
|
+
struct _out out;
|
891
|
+
struct _options copts = *opts;
|
892
|
+
volatile VALUE rstr = Qnil;
|
893
|
+
struct _oo oo;
|
894
|
+
int line = 0;
|
895
|
+
|
896
|
+
oo.out = &out;
|
897
|
+
oo.obj = obj;
|
913
898
|
copts.str_rx.head = NULL;
|
914
899
|
copts.str_rx.tail = NULL;
|
915
|
-
copts.mode
|
900
|
+
copts.mode = RailsMode;
|
916
901
|
if (escape_html) {
|
917
|
-
|
902
|
+
copts.escape_mode = RailsXEsc;
|
918
903
|
} else {
|
919
|
-
|
904
|
+
copts.escape_mode = RailsEsc;
|
920
905
|
}
|
921
|
-
|
922
|
-
out
|
923
|
-
|
906
|
+
|
907
|
+
oj_out_init(&out);
|
908
|
+
|
924
909
|
out.omit_nil = copts.dump_opts.omit_nil;
|
925
|
-
out.
|
926
|
-
out.cur = out.buf;
|
910
|
+
out.cur = out.buf;
|
927
911
|
out.circ_cnt = 0;
|
928
|
-
out.opts
|
912
|
+
out.opts = &copts;
|
929
913
|
out.hash_cnt = 0;
|
930
|
-
out.indent
|
931
|
-
out.argc
|
932
|
-
out.argv
|
933
|
-
out.ropts
|
914
|
+
out.indent = copts.indent;
|
915
|
+
out.argc = argc;
|
916
|
+
out.argv = argv;
|
917
|
+
out.ropts = ropts;
|
934
918
|
if (Yes == copts.circular) {
|
935
|
-
|
919
|
+
oj_cache8_new(&out.circ_cache);
|
936
920
|
}
|
937
|
-
//dump_rails_val(*argv, 0, &out, true);
|
921
|
+
// dump_rails_val(*argv, 0, &out, true);
|
938
922
|
rb_protect(protect_dump, (VALUE)&oo, &line);
|
939
923
|
|
940
924
|
if (0 == line) {
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
rb_raise(rb_eNoMemError, "Not enough memory.");
|
955
|
-
}
|
956
|
-
rstr = rb_str_new2(out.buf);
|
957
|
-
rstr = oj_encode(rstr);
|
925
|
+
if (0 < out.indent) {
|
926
|
+
switch (*(out.cur - 1)) {
|
927
|
+
case ']':
|
928
|
+
case '}': assure_size(&out, 2); *out.cur++ = '\n';
|
929
|
+
default: break;
|
930
|
+
}
|
931
|
+
}
|
932
|
+
*out.cur = '\0';
|
933
|
+
|
934
|
+
if (0 == out.buf) {
|
935
|
+
rb_raise(rb_eNoMemError, "Not enough memory.");
|
936
|
+
}
|
937
|
+
rstr = rb_utf8_str_new_cstr(out.buf);
|
958
938
|
}
|
959
939
|
if (Yes == copts.circular) {
|
960
|
-
|
961
|
-
}
|
962
|
-
if (out.allocated) {
|
963
|
-
xfree(out.buf);
|
940
|
+
oj_cache8_delete(out.circ_cache);
|
964
941
|
}
|
942
|
+
|
943
|
+
oj_out_free(&out);
|
944
|
+
|
965
945
|
if (0 != line) {
|
966
|
-
|
946
|
+
rb_jump_tag(line);
|
967
947
|
}
|
968
948
|
return rstr;
|
969
949
|
}
|
@@ -975,14 +955,14 @@ encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *argv) {
|
|
975
955
|
*
|
976
956
|
* Returns encoded object as a JSON string.
|
977
957
|
*/
|
978
|
-
static VALUE
|
979
|
-
|
980
|
-
|
958
|
+
static VALUE encoder_encode(VALUE self, VALUE obj) {
|
959
|
+
Encoder e;
|
960
|
+
TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
|
981
961
|
|
982
962
|
if (Qnil != e->arg) {
|
983
|
-
|
963
|
+
VALUE argv[1] = {e->arg};
|
984
964
|
|
985
|
-
|
965
|
+
return encode(obj, &e->ropts, &e->opts, 1, argv);
|
986
966
|
}
|
987
967
|
return encode(obj, &e->ropts, &e->opts, 0, NULL);
|
988
968
|
}
|
@@ -997,25 +977,24 @@ encoder_encode(VALUE self, VALUE obj) {
|
|
997
977
|
*
|
998
978
|
* Returns [_String_]
|
999
979
|
*/
|
1000
|
-
static VALUE
|
1001
|
-
rails_encode(int argc, VALUE *argv, VALUE self) {
|
980
|
+
static VALUE rails_encode(int argc, VALUE *argv, VALUE self) {
|
1002
981
|
if (1 > argc) {
|
1003
|
-
|
982
|
+
rb_raise(rb_eArgError, "wrong number of arguments (0 for 1).");
|
1004
983
|
}
|
1005
984
|
if (1 == argc) {
|
1006
|
-
|
985
|
+
return encode(*argv, NULL, &oj_default_options, 0, NULL);
|
1007
986
|
} else {
|
1008
|
-
|
987
|
+
return encode(*argv, NULL, &oj_default_options, argc - 1, argv + 1);
|
1009
988
|
}
|
1010
989
|
}
|
1011
990
|
|
1012
|
-
static VALUE
|
1013
|
-
rails_use_standard_json_time_format(VALUE self, VALUE state) {
|
991
|
+
static VALUE rails_use_standard_json_time_format(VALUE self, VALUE state) {
|
1014
992
|
if (Qtrue == state || Qfalse == state) {
|
993
|
+
// no change needed
|
1015
994
|
} else if (Qnil == state) {
|
1016
|
-
|
995
|
+
state = Qfalse;
|
1017
996
|
} else {
|
1018
|
-
|
997
|
+
state = Qtrue;
|
1019
998
|
}
|
1020
999
|
rb_iv_set(self, "@use_standard_json_time_format", state);
|
1021
1000
|
xml_time = Qtrue == state;
|
@@ -1023,18 +1002,25 @@ rails_use_standard_json_time_format(VALUE self, VALUE state) {
|
|
1023
1002
|
return state;
|
1024
1003
|
}
|
1025
1004
|
|
1026
|
-
static VALUE
|
1027
|
-
|
1005
|
+
static VALUE rails_use_standard_json_time_format_get(VALUE self) {
|
1006
|
+
return xml_time ? Qtrue : Qfalse;
|
1007
|
+
}
|
1008
|
+
|
1009
|
+
static VALUE rails_escape_html_entities_in_json(VALUE self, VALUE state) {
|
1028
1010
|
rb_iv_set(self, "@escape_html_entities_in_json", state);
|
1029
1011
|
escape_html = Qtrue == state;
|
1030
1012
|
|
1031
1013
|
return state;
|
1032
1014
|
}
|
1033
1015
|
|
1034
|
-
static VALUE
|
1035
|
-
|
1016
|
+
static VALUE rails_escape_html_entities_in_json_get(VALUE self) {
|
1017
|
+
return escape_html ? Qtrue : Qfalse;
|
1018
|
+
}
|
1019
|
+
|
1020
|
+
static VALUE rails_time_precision(VALUE self, VALUE prec) {
|
1036
1021
|
rb_iv_set(self, "@time_precision", prec);
|
1037
|
-
oj_default_options.sec_prec
|
1022
|
+
oj_default_options.sec_prec = NUM2INT(prec);
|
1023
|
+
oj_default_options.sec_prec_set = true;
|
1038
1024
|
|
1039
1025
|
return prec;
|
1040
1026
|
}
|
@@ -1046,22 +1032,26 @@ rails_time_precision(VALUE self, VALUE prec) {
|
|
1046
1032
|
* formatting globals used by ActiveSupport to allow the use of those globals
|
1047
1033
|
* in the Oj::Rails optimizations.
|
1048
1034
|
*/
|
1049
|
-
static VALUE
|
1050
|
-
|
1051
|
-
VALUE
|
1052
|
-
VALUE
|
1053
|
-
VALUE
|
1054
|
-
VALUE
|
1055
|
-
VALUE
|
1056
|
-
|
1035
|
+
static VALUE rails_set_encoder(VALUE self) {
|
1036
|
+
VALUE active;
|
1037
|
+
VALUE json;
|
1038
|
+
VALUE encoding;
|
1039
|
+
VALUE pv;
|
1040
|
+
VALUE verbose;
|
1041
|
+
VALUE enc = resolve_classpath("ActiveSupport::JSON::Encoding");
|
1042
|
+
|
1043
|
+
if (Qnil != enc) {
|
1044
|
+
escape_html = Qtrue == rb_iv_get(self, "@escape_html_entities_in_json");
|
1045
|
+
xml_time = Qtrue == rb_iv_get(enc, "@use_standard_json_time_format");
|
1046
|
+
}
|
1057
1047
|
if (rb_const_defined_at(rb_cObject, rb_intern("ActiveSupport"))) {
|
1058
|
-
|
1048
|
+
active = rb_const_get_at(rb_cObject, rb_intern("ActiveSupport"));
|
1059
1049
|
} else {
|
1060
|
-
|
1050
|
+
rb_raise(rb_eStandardError, "ActiveSupport not loaded.");
|
1061
1051
|
}
|
1062
1052
|
rb_funcall(active, rb_intern("json_encoder="), 1, encoder_class);
|
1063
1053
|
|
1064
|
-
json
|
1054
|
+
json = rb_const_get_at(active, rb_intern("JSON"));
|
1065
1055
|
encoding = rb_const_get_at(json, rb_intern("Encoding"));
|
1066
1056
|
|
1067
1057
|
// rb_undef_method doesn't work for modules or maybe sometimes
|
@@ -1070,14 +1060,19 @@ rails_set_encoder(VALUE self) {
|
|
1070
1060
|
rb_gv_set("$VERBOSE", Qfalse);
|
1071
1061
|
rb_undef_method(encoding, "use_standard_json_time_format=");
|
1072
1062
|
rb_define_module_function(encoding, "use_standard_json_time_format=", rails_use_standard_json_time_format, 1);
|
1063
|
+
rb_undef_method(encoding, "use_standard_json_time_format");
|
1064
|
+
rb_define_module_function(encoding, "use_standard_json_time_format", rails_use_standard_json_time_format_get, 0);
|
1073
1065
|
|
1074
|
-
pv
|
1066
|
+
pv = rb_iv_get(encoding, "@escape_html_entities_in_json");
|
1075
1067
|
escape_html = Qtrue == pv;
|
1076
1068
|
rb_undef_method(encoding, "escape_html_entities_in_json=");
|
1077
1069
|
rb_define_module_function(encoding, "escape_html_entities_in_json=", rails_escape_html_entities_in_json, 1);
|
1070
|
+
rb_undef_method(encoding, "escape_html_entities_in_json");
|
1071
|
+
rb_define_module_function(encoding, "escape_html_entities_in_json", rails_escape_html_entities_in_json_get, 0);
|
1078
1072
|
|
1079
|
-
pv
|
1080
|
-
oj_default_options.sec_prec
|
1073
|
+
pv = rb_iv_get(encoding, "@time_precision");
|
1074
|
+
oj_default_options.sec_prec = NUM2INT(pv);
|
1075
|
+
oj_default_options.sec_prec_set = true;
|
1081
1076
|
rb_undef_method(encoding, "time_precision=");
|
1082
1077
|
rb_define_module_function(encoding, "time_precision=", rails_time_precision, 1);
|
1083
1078
|
rb_gv_set("$VERBOSE", verbose);
|
@@ -1091,26 +1086,27 @@ rails_set_encoder(VALUE self) {
|
|
1091
1086
|
* Sets the JSON.parse function to be the Oj::parse function which is json gem
|
1092
1087
|
* compatible.
|
1093
1088
|
*/
|
1094
|
-
static VALUE
|
1095
|
-
|
1096
|
-
VALUE
|
1097
|
-
VALUE
|
1098
|
-
VALUE verbose;
|
1089
|
+
static VALUE rails_set_decoder(VALUE self) {
|
1090
|
+
VALUE json;
|
1091
|
+
VALUE json_error;
|
1092
|
+
VALUE verbose;
|
1099
1093
|
|
1100
1094
|
if (rb_const_defined_at(rb_cObject, rb_intern("JSON"))) {
|
1101
|
-
|
1095
|
+
json = rb_const_get_at(rb_cObject, rb_intern("JSON"));
|
1102
1096
|
} else {
|
1103
|
-
|
1097
|
+
json = rb_define_module("JSON");
|
1104
1098
|
}
|
1105
1099
|
if (rb_const_defined_at(json, rb_intern("JSONError"))) {
|
1106
1100
|
json_error = rb_const_get(json, rb_intern("JSONError"));
|
1107
1101
|
} else {
|
1108
1102
|
json_error = rb_define_class_under(json, "JSONError", rb_eStandardError);
|
1109
1103
|
}
|
1104
|
+
|
1105
|
+
rb_global_variable(&oj_json_parser_error_class);
|
1110
1106
|
if (rb_const_defined_at(json, rb_intern("ParserError"))) {
|
1111
1107
|
oj_json_parser_error_class = rb_const_get(json, rb_intern("ParserError"));
|
1112
1108
|
} else {
|
1113
|
-
|
1109
|
+
oj_json_parser_error_class = rb_define_class_under(json, "ParserError", json_error);
|
1114
1110
|
}
|
1115
1111
|
// rb_undef_method doesn't work for modules or maybe sometimes
|
1116
1112
|
// doesn't. Anyway setting verbose should hide the warning.
|
@@ -1146,13 +1142,15 @@ oj_optimize_rails(VALUE self) {
|
|
1146
1142
|
*
|
1147
1143
|
* The Oj ActiveSupport compliant encoder.
|
1148
1144
|
*/
|
1149
|
-
void
|
1150
|
-
|
1151
|
-
VALUE rails = rb_define_module_under(Oj, "Rails");
|
1145
|
+
void oj_mimic_rails_init(void) {
|
1146
|
+
VALUE rails = rb_define_module_under(Oj, "Rails");
|
1152
1147
|
|
1153
1148
|
rb_define_module_function(rails, "encode", rails_encode, -1);
|
1154
1149
|
|
1155
1150
|
encoder_class = rb_define_class_under(rails, "Encoder", rb_cObject);
|
1151
|
+
rb_gc_register_address(&encoder_class);
|
1152
|
+
rb_undef_alloc_func(encoder_class);
|
1153
|
+
|
1156
1154
|
rb_define_module_function(encoder_class, "new", encoder_new, -1);
|
1157
1155
|
rb_define_module_function(rails, "optimize", rails_optimize, -1);
|
1158
1156
|
rb_define_module_function(rails, "deoptimize", rails_deoptimize, -1);
|
@@ -1168,328 +1166,313 @@ oj_mimic_rails_init() {
|
|
1168
1166
|
rb_define_method(encoder_class, "optimized?", encoder_optimized, 1);
|
1169
1167
|
}
|
1170
1168
|
|
1171
|
-
static void
|
1172
|
-
dump_to_hash(VALUE obj, int depth, Out out) {
|
1169
|
+
static void dump_to_hash(VALUE obj, int depth, Out out) {
|
1173
1170
|
dump_rails_val(rb_funcall(obj, oj_to_hash_id, 0), depth, out, true);
|
1174
1171
|
}
|
1175
1172
|
|
1176
|
-
static void
|
1177
|
-
|
1178
|
-
char
|
1179
|
-
|
1180
|
-
|
1181
|
-
int cnt = 0;
|
1173
|
+
static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
1174
|
+
char buf[64];
|
1175
|
+
char *b;
|
1176
|
+
double d = rb_num2dbl(obj);
|
1177
|
+
size_t cnt = 0;
|
1182
1178
|
|
1183
1179
|
if (0.0 == d) {
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1180
|
+
b = buf;
|
1181
|
+
*b++ = '0';
|
1182
|
+
*b++ = '.';
|
1183
|
+
*b++ = '0';
|
1184
|
+
*b++ = '\0';
|
1185
|
+
cnt = 3;
|
1190
1186
|
} else {
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1199
|
-
|
1200
|
-
|
1201
|
-
|
1202
|
-
|
1203
|
-
|
1187
|
+
if (isnan(d) || OJ_INFINITY == d || -OJ_INFINITY == d) {
|
1188
|
+
strcpy(buf, "null");
|
1189
|
+
cnt = 4;
|
1190
|
+
} else if (d == (double)(long long int)d) {
|
1191
|
+
cnt = snprintf(buf, sizeof(buf), "%.1f", d);
|
1192
|
+
} else if (oj_rails_float_opt) {
|
1193
|
+
cnt = oj_dump_float_printf(buf, sizeof(buf), obj, d, "%0.16g");
|
1194
|
+
} else {
|
1195
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
1196
|
+
|
1197
|
+
strcpy(buf, RSTRING_PTR(rstr));
|
1198
|
+
cnt = RSTRING_LEN(rstr);
|
1199
|
+
}
|
1204
1200
|
}
|
1205
1201
|
assure_size(out, cnt);
|
1206
1202
|
for (b = buf; '\0' != *b; b++) {
|
1207
|
-
|
1203
|
+
*out->cur++ = *b;
|
1208
1204
|
}
|
1209
1205
|
*out->cur = '\0';
|
1210
1206
|
}
|
1211
1207
|
|
1212
|
-
static void
|
1213
|
-
|
1214
|
-
size_t
|
1215
|
-
|
1216
|
-
int
|
1208
|
+
static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
1209
|
+
size_t size;
|
1210
|
+
size_t i;
|
1211
|
+
size_t cnt;
|
1212
|
+
int d2 = depth + 1;
|
1217
1213
|
|
1218
1214
|
if (Yes == out->opts->circular) {
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1215
|
+
if (0 > oj_check_circular(a, out)) {
|
1216
|
+
oj_dump_nil(Qnil, 0, out, false);
|
1217
|
+
return;
|
1218
|
+
}
|
1223
1219
|
}
|
1224
|
-
//if (!oj_rails_array_opt && as_ok && 0 < out->argc && rb_respond_to(a, oj_as_json_id)) {
|
1220
|
+
// if (!oj_rails_array_opt && as_ok && 0 < out->argc && rb_respond_to(a, oj_as_json_id)) {
|
1225
1221
|
if (as_ok && 0 < out->argc && rb_respond_to(a, oj_as_json_id)) {
|
1226
|
-
|
1227
|
-
|
1222
|
+
dump_as_json(a, depth, out, false);
|
1223
|
+
return;
|
1228
1224
|
}
|
1229
|
-
cnt
|
1225
|
+
cnt = RARRAY_LEN(a);
|
1230
1226
|
*out->cur++ = '[';
|
1231
|
-
size
|
1227
|
+
size = 2;
|
1232
1228
|
assure_size(out, size);
|
1233
1229
|
if (0 == cnt) {
|
1234
|
-
|
1230
|
+
*out->cur++ = ']';
|
1235
1231
|
} else {
|
1236
|
-
|
1237
|
-
|
1238
|
-
|
1239
|
-
|
1240
|
-
|
1241
|
-
|
1242
|
-
|
1243
|
-
|
1244
|
-
|
1245
|
-
|
1246
|
-
|
1247
|
-
|
1248
|
-
|
1249
|
-
|
1250
|
-
|
1251
|
-
|
1252
|
-
|
1253
|
-
|
1254
|
-
|
1255
|
-
|
1256
|
-
|
1257
|
-
|
1258
|
-
|
1259
|
-
|
1260
|
-
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1266
|
-
|
1267
|
-
|
1268
|
-
|
1269
|
-
|
1270
|
-
|
1271
|
-
|
1272
|
-
|
1273
|
-
|
1274
|
-
|
1275
|
-
|
1276
|
-
|
1277
|
-
|
1278
|
-
|
1279
|
-
} else {
|
1280
|
-
fill_indent(out, depth);
|
1281
|
-
}
|
1282
|
-
*out->cur++ = ']';
|
1232
|
+
if (out->opts->dump_opts.use) {
|
1233
|
+
size = d2 * out->opts->dump_opts.indent_size + out->opts->dump_opts.array_size + 1;
|
1234
|
+
} else {
|
1235
|
+
size = d2 * out->indent + 2;
|
1236
|
+
}
|
1237
|
+
assure_size(out, size * cnt);
|
1238
|
+
cnt--;
|
1239
|
+
for (i = 0; i <= cnt; i++) {
|
1240
|
+
if (out->opts->dump_opts.use) {
|
1241
|
+
if (0 < out->opts->dump_opts.array_size) {
|
1242
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
1243
|
+
}
|
1244
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
1245
|
+
int i;
|
1246
|
+
for (i = d2; 0 < i; i--) {
|
1247
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
1248
|
+
}
|
1249
|
+
}
|
1250
|
+
} else {
|
1251
|
+
fill_indent(out, d2);
|
1252
|
+
}
|
1253
|
+
dump_rails_val(RARRAY_AREF(a, i), d2, out, true);
|
1254
|
+
if (i < cnt) {
|
1255
|
+
*out->cur++ = ',';
|
1256
|
+
}
|
1257
|
+
}
|
1258
|
+
size = depth * out->indent + 1;
|
1259
|
+
assure_size(out, size);
|
1260
|
+
if (out->opts->dump_opts.use) {
|
1261
|
+
if (0 < out->opts->dump_opts.array_size) {
|
1262
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
1263
|
+
}
|
1264
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
1265
|
+
int i;
|
1266
|
+
|
1267
|
+
for (i = depth; 0 < i; i--) {
|
1268
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
1269
|
+
}
|
1270
|
+
}
|
1271
|
+
} else {
|
1272
|
+
fill_indent(out, depth);
|
1273
|
+
}
|
1274
|
+
*out->cur++ = ']';
|
1283
1275
|
}
|
1284
1276
|
*out->cur = '\0';
|
1285
1277
|
}
|
1286
1278
|
|
1287
|
-
static int
|
1288
|
-
|
1289
|
-
int
|
1290
|
-
long
|
1291
|
-
int
|
1279
|
+
static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
1280
|
+
Out out = (Out)ov;
|
1281
|
+
int depth = out->depth;
|
1282
|
+
long size;
|
1283
|
+
int rtype = rb_type(key);
|
1292
1284
|
|
1293
1285
|
if (out->omit_nil && Qnil == value) {
|
1294
|
-
|
1286
|
+
return ST_CONTINUE;
|
1295
1287
|
}
|
1296
1288
|
if (rtype != T_STRING && rtype != T_SYMBOL) {
|
1297
|
-
|
1298
|
-
|
1289
|
+
key = oj_safe_string_convert(key);
|
1290
|
+
rtype = rb_type(key);
|
1299
1291
|
}
|
1300
1292
|
if (!out->opts->dump_opts.use) {
|
1301
|
-
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
1305
|
-
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
1293
|
+
size = depth * out->indent + 1;
|
1294
|
+
assure_size(out, size);
|
1295
|
+
fill_indent(out, depth);
|
1296
|
+
if (rtype == T_STRING) {
|
1297
|
+
oj_dump_str(key, 0, out, false);
|
1298
|
+
} else {
|
1299
|
+
oj_dump_sym(key, 0, out, false);
|
1300
|
+
}
|
1301
|
+
*out->cur++ = ':';
|
1310
1302
|
} else {
|
1311
|
-
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1321
|
-
|
1322
|
-
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
1329
|
-
|
1330
|
-
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
if (0 < out->opts->dump_opts.after_size) {
|
1337
|
-
strcpy(out->cur, out->opts->dump_opts.after_sep);
|
1338
|
-
out->cur += out->opts->dump_opts.after_size;
|
1339
|
-
}
|
1303
|
+
size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
|
1304
|
+
assure_size(out, size);
|
1305
|
+
if (0 < out->opts->dump_opts.hash_size) {
|
1306
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
|
1307
|
+
}
|
1308
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
1309
|
+
int i;
|
1310
|
+
for (i = depth; 0 < i; i--) {
|
1311
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
1312
|
+
}
|
1313
|
+
}
|
1314
|
+
if (rtype == T_STRING) {
|
1315
|
+
oj_dump_str(key, 0, out, false);
|
1316
|
+
} else {
|
1317
|
+
oj_dump_sym(key, 0, out, false);
|
1318
|
+
}
|
1319
|
+
size = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
|
1320
|
+
assure_size(out, size);
|
1321
|
+
if (0 < out->opts->dump_opts.before_size) {
|
1322
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
|
1323
|
+
}
|
1324
|
+
*out->cur++ = ':';
|
1325
|
+
if (0 < out->opts->dump_opts.after_size) {
|
1326
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
|
1327
|
+
}
|
1340
1328
|
}
|
1341
1329
|
dump_rails_val(value, depth, out, true);
|
1342
|
-
out->depth
|
1330
|
+
out->depth = depth;
|
1343
1331
|
*out->cur++ = ',';
|
1344
1332
|
|
1345
1333
|
return ST_CONTINUE;
|
1346
1334
|
}
|
1347
1335
|
|
1348
|
-
static void
|
1349
|
-
|
1350
|
-
|
1351
|
-
size_t size;
|
1336
|
+
static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
|
1337
|
+
int cnt;
|
1338
|
+
size_t size;
|
1352
1339
|
|
1353
1340
|
if (Yes == out->opts->circular) {
|
1354
|
-
|
1355
|
-
|
1356
|
-
|
1357
|
-
|
1341
|
+
if (0 > oj_check_circular(obj, out)) {
|
1342
|
+
oj_dump_nil(Qnil, 0, out, false);
|
1343
|
+
return;
|
1344
|
+
}
|
1358
1345
|
}
|
1359
1346
|
if ((!oj_rails_hash_opt || 0 < out->argc) && as_ok && rb_respond_to(obj, oj_as_json_id)) {
|
1360
|
-
|
1361
|
-
|
1347
|
+
dump_as_json(obj, depth, out, false);
|
1348
|
+
return;
|
1362
1349
|
}
|
1363
|
-
cnt
|
1350
|
+
cnt = (int)RHASH_SIZE(obj);
|
1364
1351
|
size = depth * out->indent + 2;
|
1365
1352
|
assure_size(out, 2);
|
1366
1353
|
*out->cur++ = '{';
|
1367
1354
|
if (0 == cnt) {
|
1368
|
-
|
1355
|
+
*out->cur++ = '}';
|
1369
1356
|
} else {
|
1370
|
-
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
|
1391
|
-
|
1392
|
-
|
1393
|
-
}
|
1394
|
-
*out->cur++ = '}';
|
1357
|
+
out->depth = depth + 1;
|
1358
|
+
rb_hash_foreach(obj, hash_cb, (VALUE)out);
|
1359
|
+
if (',' == *(out->cur - 1)) {
|
1360
|
+
out->cur--; // backup to overwrite last comma
|
1361
|
+
}
|
1362
|
+
if (!out->opts->dump_opts.use) {
|
1363
|
+
assure_size(out, size);
|
1364
|
+
fill_indent(out, depth);
|
1365
|
+
} else {
|
1366
|
+
size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
|
1367
|
+
assure_size(out, size);
|
1368
|
+
if (0 < out->opts->dump_opts.hash_size) {
|
1369
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
|
1370
|
+
}
|
1371
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
1372
|
+
int i;
|
1373
|
+
|
1374
|
+
for (i = depth; 0 < i; i--) {
|
1375
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
1376
|
+
}
|
1377
|
+
}
|
1378
|
+
}
|
1379
|
+
*out->cur++ = '}';
|
1395
1380
|
}
|
1396
1381
|
*out->cur = '\0';
|
1397
1382
|
}
|
1398
1383
|
|
1399
|
-
static void
|
1400
|
-
|
1384
|
+
static void dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
|
1385
|
+
VALUE clas;
|
1386
|
+
|
1401
1387
|
if (oj_code_dump(oj_compat_codes, obj, depth, out)) {
|
1402
|
-
|
1403
|
-
|
1388
|
+
out->argc = 0;
|
1389
|
+
return;
|
1404
1390
|
}
|
1391
|
+
clas = rb_obj_class(obj);
|
1405
1392
|
if (as_ok) {
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1417
|
-
|
1418
|
-
|
1393
|
+
ROpt ro;
|
1394
|
+
|
1395
|
+
if (NULL != (ro = oj_rails_get_opt(out->ropts, clas)) && ro->on) {
|
1396
|
+
ro->dump(obj, depth, out, as_ok);
|
1397
|
+
} else if (Yes == out->opts->raw_json && rb_respond_to(obj, oj_raw_json_id)) {
|
1398
|
+
oj_dump_raw_json(obj, depth, out);
|
1399
|
+
} else if (rb_respond_to(obj, oj_as_json_id)) {
|
1400
|
+
dump_as_json(obj, depth, out, true);
|
1401
|
+
} else if (rb_respond_to(obj, oj_to_hash_id)) {
|
1402
|
+
dump_to_hash(obj, depth, out);
|
1403
|
+
} else if (oj_bigdecimal_class == clas) {
|
1404
|
+
dump_bigdecimal(obj, depth, out, false);
|
1405
|
+
} else {
|
1406
|
+
oj_dump_obj_to_s(obj, out);
|
1407
|
+
}
|
1419
1408
|
} else if (Yes == out->opts->raw_json && rb_respond_to(obj, oj_raw_json_id)) {
|
1420
|
-
|
1409
|
+
oj_dump_raw_json(obj, depth, out);
|
1421
1410
|
} else if (rb_respond_to(obj, oj_to_hash_id)) {
|
1422
|
-
|
1423
|
-
|
1411
|
+
// Always attempt to_hash.
|
1412
|
+
dump_to_hash(obj, depth, out);
|
1413
|
+
} else if (oj_bigdecimal_class == clas) {
|
1414
|
+
dump_bigdecimal(obj, depth, out, false);
|
1424
1415
|
} else {
|
1425
|
-
|
1416
|
+
oj_dump_obj_to_s(obj, out);
|
1426
1417
|
}
|
1427
1418
|
}
|
1428
1419
|
|
1429
|
-
static DumpFunc
|
1430
|
-
NULL,
|
1431
|
-
dump_obj,
|
1432
|
-
oj_dump_class,
|
1433
|
-
oj_dump_class,
|
1434
|
-
dump_float,
|
1435
|
-
oj_dump_str,
|
1436
|
-
dump_regexp,
|
1437
|
-
//dump_as_string, // RUBY_T_REGEXP = 0x06,
|
1438
|
-
dump_array,
|
1439
|
-
dump_hash,
|
1440
|
-
dump_obj,
|
1441
|
-
oj_dump_bignum,
|
1442
|
-
|
1443
|
-
dump_obj,
|
1444
|
-
NULL,
|
1420
|
+
static DumpFunc rails_funcs[] = {
|
1421
|
+
NULL, // RUBY_T_NONE = 0x00,
|
1422
|
+
dump_obj, // RUBY_T_OBJECT = 0x01,
|
1423
|
+
oj_dump_class, // RUBY_T_CLASS = 0x02,
|
1424
|
+
oj_dump_class, // RUBY_T_MODULE = 0x03,
|
1425
|
+
dump_float, // RUBY_T_FLOAT = 0x04,
|
1426
|
+
oj_dump_str, // RUBY_T_STRING = 0x05,
|
1427
|
+
dump_regexp, // RUBY_T_REGEXP = 0x06,
|
1428
|
+
// dump_as_string, // RUBY_T_REGEXP = 0x06,
|
1429
|
+
dump_array, // RUBY_T_ARRAY = 0x07,
|
1430
|
+
dump_hash, // RUBY_T_HASH = 0x08,
|
1431
|
+
dump_obj, // RUBY_T_STRUCT = 0x09,
|
1432
|
+
oj_dump_bignum, // RUBY_T_BIGNUM = 0x0a,
|
1433
|
+
dump_as_string, // RUBY_T_FILE = 0x0b,
|
1434
|
+
dump_obj, // RUBY_T_DATA = 0x0c,
|
1435
|
+
NULL, // RUBY_T_MATCH = 0x0d,
|
1445
1436
|
// Rails raises a stack error on Complex and Rational. It also corrupts
|
1446
1437
|
// something which causes a segfault on the next call. Oj will not mimic
|
1447
1438
|
// that behavior.
|
1448
|
-
dump_as_string,
|
1449
|
-
dump_as_string,
|
1450
|
-
NULL,
|
1451
|
-
oj_dump_nil,
|
1452
|
-
oj_dump_true,
|
1453
|
-
oj_dump_false,
|
1454
|
-
oj_dump_sym,
|
1455
|
-
oj_dump_fixnum,
|
1439
|
+
dump_as_string, // RUBY_T_COMPLEX = 0x0e,
|
1440
|
+
dump_as_string, // RUBY_T_RATIONAL = 0x0f,
|
1441
|
+
NULL, // 0x10
|
1442
|
+
oj_dump_nil, // RUBY_T_NIL = 0x11,
|
1443
|
+
oj_dump_true, // RUBY_T_TRUE = 0x12,
|
1444
|
+
oj_dump_false, // RUBY_T_FALSE = 0x13,
|
1445
|
+
oj_dump_sym, // RUBY_T_SYMBOL = 0x14,
|
1446
|
+
oj_dump_fixnum, // RUBY_T_FIXNUM = 0x15,
|
1456
1447
|
};
|
1457
1448
|
|
1458
|
-
static void
|
1459
|
-
|
1460
|
-
int type = rb_type(obj);
|
1449
|
+
static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok) {
|
1450
|
+
int type = rb_type(obj);
|
1461
1451
|
|
1462
|
-
|
1463
|
-
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
1464
|
-
}
|
1452
|
+
TRACE(out->opts->trace, "dump", obj, depth, TraceIn);
|
1465
1453
|
if (MAX_DEPTH < depth) {
|
1466
|
-
|
1454
|
+
rb_raise(rb_eNoMemError, "Too deeply nested.\n");
|
1467
1455
|
}
|
1468
1456
|
if (0 < type && type <= RUBY_T_FIXNUM) {
|
1469
|
-
|
1457
|
+
DumpFunc f = rails_funcs[type];
|
1470
1458
|
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
return;
|
1477
|
-
}
|
1459
|
+
if (NULL != f) {
|
1460
|
+
f(obj, depth, out, as_ok);
|
1461
|
+
TRACE(out->opts->trace, "dump", obj, depth, TraceOut);
|
1462
|
+
return;
|
1463
|
+
}
|
1478
1464
|
}
|
1479
1465
|
oj_dump_nil(Qnil, depth, out, false);
|
1480
|
-
|
1481
|
-
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
1482
|
-
}
|
1466
|
+
TRACE(out->opts->trace, "dump", Qnil, depth, TraceOut);
|
1483
1467
|
}
|
1484
1468
|
|
1485
|
-
void
|
1486
|
-
oj_dump_rails_val(VALUE obj, int depth, Out out) {
|
1469
|
+
void oj_dump_rails_val(VALUE obj, int depth, Out out) {
|
1487
1470
|
out->opts->str_rx.head = NULL;
|
1488
1471
|
out->opts->str_rx.tail = NULL;
|
1489
1472
|
if (escape_html) {
|
1490
|
-
|
1473
|
+
out->opts->escape_mode = RailsXEsc;
|
1491
1474
|
} else {
|
1492
|
-
|
1475
|
+
out->opts->escape_mode = RailsEsc;
|
1493
1476
|
}
|
1494
1477
|
dump_rails_val(obj, depth, out, true);
|
1495
1478
|
}
|