oj 3.8.1 → 3.10.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/ext/oj/compat.c +5 -5
- data/ext/oj/custom.c +65 -38
- data/ext/oj/dump.c +9 -12
- data/ext/oj/dump_compat.c +8 -10
- data/ext/oj/dump_object.c +18 -11
- data/ext/oj/dump_strict.c +6 -5
- data/ext/oj/extconf.rb +6 -0
- data/ext/oj/mimic_json.c +15 -3
- data/ext/oj/object.c +8 -5
- data/ext/oj/oj.c +50 -31
- data/ext/oj/oj.h +6 -4
- data/ext/oj/parse.c +16 -3
- data/ext/oj/parse.h +1 -0
- data/ext/oj/rails.c +40 -4
- data/ext/oj/resolve.c +3 -3
- data/ext/oj/sparse.c +5 -0
- data/ext/oj/util.c +5 -5
- data/ext/oj/val_stack.c +9 -9
- data/ext/oj/val_stack.h +9 -9
- data/ext/oj/wab.c +9 -9
- data/lib/oj/version.rb +1 -1
- data/pages/Options.md +4 -0
- data/pages/Rails.md +21 -21
- data/test/activesupport5/abstract_unit.rb +45 -0
- data/test/activesupport5/decoding_test.rb +68 -60
- data/test/activesupport5/encoding_test.rb +111 -96
- data/test/activesupport5/encoding_test_cases.rb +33 -25
- data/test/activesupport5/test_helper.rb +43 -21
- data/test/activesupport5/time_zone_test_helpers.rb +18 -3
- data/test/activesupport6/abstract_unit.rb +44 -0
- data/test/activesupport6/decoding_test.rb +133 -0
- data/test/activesupport6/encoding_test.rb +507 -0
- data/test/activesupport6/encoding_test_cases.rb +98 -0
- data/test/activesupport6/test_common.rb +17 -0
- data/test/activesupport6/test_helper.rb +163 -0
- data/test/activesupport6/time_zone_test_helpers.rb +39 -0
- data/test/bar.rb +8 -11
- data/test/baz.rb +16 -0
- data/test/foo.rb +42 -157
- data/test/test_compat.rb +0 -7
- data/test/test_custom.rb +25 -6
- data/test/test_integer_range.rb +1 -2
- data/test/test_object.rb +4 -3
- data/test/test_rails.rb +26 -0
- data/test/test_strict.rb +24 -1
- data/test/test_various.rb +41 -62
- data/test/tests.rb +1 -0
- metadata +22 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3dd1cae4ccf720f35b777913213b66466c7d9752055c60d828cdf681956731a3
|
4
|
+
data.tar.gz: e913c57a4619bfbea97144f6f4783219aca294e598c8c6449ddfc6cb997b46f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc0b7bd0e9ea90e69eda6a6205c09540e2217f9ccdcb3c6e937fb82e4b979fada30a028b64559ac5dfddc22afb9d4302669de35315bb5c5392ad100a373bb472
|
7
|
+
data.tar.gz: 8d8ad9eeb68fb2d058c3f499ad51fc8c50d3349b36a237769f996a43de58449fbae36d3bff82c6be6a16828331f12aa19df6a1ef90b5bdff78ecdf732450a268
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# [![{}j](http://www.ohler.com/dev/images/oj_comet_64.svg)](http://www.ohler.com/oj) gem
|
2
2
|
|
3
|
-
[![Build Status](https://img.shields.io/travis/ohler55/oj/master.svg)](http://travis-ci.org/ohler55/oj?branch=master) [![AppVeyor](https://img.shields.io/appveyor/ci/ohler55/oj/master.svg)](https://ci.appveyor.com/project/ohler55/oj) ![Gem](https://img.shields.io/gem/v/oj.svg) ![Gem](https://img.shields.io/gem/dt/oj.svg) [![SemVer compatibility](https://api.dependabot.com/badges/compatibility_score?dependency-name=oj&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=oj&package-manager=bundler&version-scheme=semver) [![TideLift](https://tidelift.com/badges/github/ohler55/oj)](https://tidelift.com/subscription/pkg/rubygems-oj?utm_source=rubygems-oj&utm_medium=referral&utm_campaign=readme)
|
3
|
+
[![Build Status](https://img.shields.io/travis/ohler55/oj/master.svg?logo=travis)](http://travis-ci.org/ohler55/oj?branch=master) [![AppVeyor](https://img.shields.io/appveyor/ci/ohler55/oj/master.svg?logo=appveyor)](https://ci.appveyor.com/project/ohler55/oj) ![Gem](https://img.shields.io/gem/v/oj.svg) ![Gem](https://img.shields.io/gem/dt/oj.svg) [![SemVer compatibility](https://api.dependabot.com/badges/compatibility_score?dependency-name=oj&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=oj&package-manager=bundler&version-scheme=semver) [![TideLift](https://tidelift.com/badges/github/ohler55/oj)](https://tidelift.com/subscription/pkg/rubygems-oj?utm_source=rubygems-oj&utm_medium=referral&utm_campaign=readme)
|
4
4
|
|
5
5
|
A *fast* JSON parser and Object marshaller as a Ruby gem.
|
6
6
|
|
@@ -42,7 +42,7 @@ gem 'oj'
|
|
42
42
|
|
43
43
|
## Support
|
44
44
|
|
45
|
-
[Get supported Oj with a Tidelift Subscription.](https://tidelift.com/subscription/pkg/rubygems-oj?utm_source=rubygems-oj&utm_medium=referral&utm_campaign=readme)
|
45
|
+
[Get supported Oj with a Tidelift Subscription.](https://tidelift.com/subscription/pkg/rubygems-oj?utm_source=rubygems-oj&utm_medium=referral&utm_campaign=readme) Security updates are [supported](https://tidelift.com/security).
|
46
46
|
|
47
47
|
## Further Reading
|
48
48
|
|
data/ext/oj/compat.c
CHANGED
@@ -65,7 +65,7 @@ hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *o
|
|
65
65
|
static VALUE
|
66
66
|
start_hash(ParseInfo pi) {
|
67
67
|
volatile VALUE h;
|
68
|
-
|
68
|
+
|
69
69
|
if (Qnil != pi->options.hash_class) {
|
70
70
|
h = rb_class_new_instance(0, NULL, pi->options.hash_class);
|
71
71
|
} else {
|
@@ -87,7 +87,7 @@ end_hash(struct _parseInfo *pi) {
|
|
87
87
|
clas = oj_name2class(pi, parent->classname, parent->clen, 0, rb_eArgError);
|
88
88
|
if (Qundef != clas) { // else an error
|
89
89
|
ID creatable = rb_intern("json_creatable?");
|
90
|
-
|
90
|
+
|
91
91
|
if (!rb_respond_to(clas, creatable) || Qtrue == rb_funcall(clas, creatable, 0)) {
|
92
92
|
parent->val = rb_funcall(clas, oj_json_create_id, 1, parent->val);
|
93
93
|
}
|
@@ -146,7 +146,7 @@ add_num(ParseInfo pi, NumInfo ni) {
|
|
146
146
|
static void
|
147
147
|
hash_set_num(struct _parseInfo *pi, Val parent, NumInfo ni) {
|
148
148
|
volatile VALUE rval = oj_num_as_value(ni);
|
149
|
-
|
149
|
+
|
150
150
|
if (!oj_use_hash_alt && rb_cHash != rb_obj_class(parent->val)) {
|
151
151
|
// The rb_hash_set would still work but the unit tests for the
|
152
152
|
// json gem require the less efficient []= method be called to set
|
@@ -192,7 +192,7 @@ static void
|
|
192
192
|
array_append_num(ParseInfo pi, NumInfo ni) {
|
193
193
|
Val parent = stack_peek(&pi->stack);
|
194
194
|
volatile VALUE rval = oj_num_as_value(ni);
|
195
|
-
|
195
|
+
|
196
196
|
if (!oj_use_array_alt && rb_cArray != rb_obj_class(parent->val)) {
|
197
197
|
// The rb_ary_push would still work but the unit tests for the json
|
198
198
|
// gem require the less efficient << method be called to push the
|
@@ -274,7 +274,7 @@ oj_compat_load(int argc, VALUE *argv, VALUE self) {
|
|
274
274
|
pi.options.nilnil = Yes;
|
275
275
|
pi.options.empty_string = Yes;
|
276
276
|
oj_set_compat_callbacks(&pi);
|
277
|
-
|
277
|
+
|
278
278
|
if (T_STRING == rb_type(*argv)) {
|
279
279
|
return oj_pi_parse(argc, argv, &pi, 0, 0, false);
|
280
280
|
} else {
|
data/ext/oj/custom.c
CHANGED
@@ -32,6 +32,13 @@ dump_obj_str(VALUE obj, int depth, Out out) {
|
|
32
32
|
oj_code_attrs(obj, attrs, depth, out, Yes == out->opts->create_ok);
|
33
33
|
}
|
34
34
|
|
35
|
+
static void
|
36
|
+
dump_obj_as_str(VALUE obj, int depth, Out out) {
|
37
|
+
volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
|
38
|
+
const char *str = rb_string_value_ptr((VALUE*)&rstr);
|
39
|
+
|
40
|
+
oj_dump_cstr(str, RSTRING_LEN(rstr), 0, 0, out);
|
41
|
+
}
|
35
42
|
|
36
43
|
static void
|
37
44
|
bigdecimal_dump(VALUE obj, int depth, Out out) {
|
@@ -57,19 +64,23 @@ static ID imag_id = 0;
|
|
57
64
|
|
58
65
|
static void
|
59
66
|
complex_dump(VALUE obj, int depth, Out out) {
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
67
|
+
if (NULL != out->opts->create_id) {
|
68
|
+
struct _attr attrs[] = {
|
69
|
+
{ "real", 4, Qnil },
|
70
|
+
{ "imag", 4, Qnil },
|
71
|
+
{ NULL, 0, Qnil },
|
72
|
+
};
|
73
|
+
if (0 == real_id) {
|
74
|
+
real_id = rb_intern("real");
|
75
|
+
imag_id = rb_intern("imag");
|
76
|
+
}
|
77
|
+
attrs[0].value = rb_funcall(obj, real_id, 0);
|
78
|
+
attrs[1].value = rb_funcall(obj, imag_id, 0);
|
71
79
|
|
72
|
-
|
80
|
+
oj_code_attrs(obj, attrs, depth, out, Yes == out->opts->create_ok);
|
81
|
+
} else {
|
82
|
+
dump_obj_as_str(obj, depth, out);
|
83
|
+
}
|
73
84
|
}
|
74
85
|
|
75
86
|
static VALUE
|
@@ -193,17 +204,21 @@ openstruct_load(VALUE clas, VALUE args) {
|
|
193
204
|
|
194
205
|
static void
|
195
206
|
range_dump(VALUE obj, int depth, Out out) {
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
207
|
+
if (NULL != out->opts->create_id) {
|
208
|
+
struct _attr attrs[] = {
|
209
|
+
{ "begin", 5, Qnil },
|
210
|
+
{ "end", 3, Qnil },
|
211
|
+
{ "exclude", 7, Qnil },
|
212
|
+
{ NULL, 0, Qnil },
|
213
|
+
};
|
214
|
+
attrs[0].value = rb_funcall(obj, oj_begin_id, 0);
|
215
|
+
attrs[1].value = rb_funcall(obj, oj_end_id, 0);
|
216
|
+
attrs[2].value = rb_funcall(obj, oj_exclude_end_id, 0);
|
205
217
|
|
206
|
-
|
218
|
+
oj_code_attrs(obj, attrs, depth, out, Yes == out->opts->create_ok);
|
219
|
+
} else {
|
220
|
+
dump_obj_as_str(obj, depth, out);
|
221
|
+
}
|
207
222
|
}
|
208
223
|
|
209
224
|
static VALUE
|
@@ -222,19 +237,23 @@ static ID denominator_id = 0;
|
|
222
237
|
|
223
238
|
static void
|
224
239
|
rational_dump(VALUE obj, int depth, Out out) {
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
240
|
+
if (NULL != out->opts->create_id) {
|
241
|
+
struct _attr attrs[] = {
|
242
|
+
{ "numerator", 9, Qnil },
|
243
|
+
{ "denominator", 11, Qnil },
|
244
|
+
{ NULL, 0, Qnil },
|
245
|
+
};
|
246
|
+
if (0 == numerator_id) {
|
247
|
+
numerator_id = rb_intern("numerator");
|
248
|
+
denominator_id = rb_intern("denominator");
|
249
|
+
}
|
250
|
+
attrs[0].value = rb_funcall(obj, numerator_id, 0);
|
251
|
+
attrs[1].value = rb_funcall(obj, denominator_id, 0);
|
236
252
|
|
237
|
-
|
253
|
+
oj_code_attrs(obj, attrs, depth, out, Yes == out->opts->create_ok);
|
254
|
+
} else {
|
255
|
+
dump_obj_as_str(obj, depth, out);
|
256
|
+
}
|
238
257
|
}
|
239
258
|
|
240
259
|
static VALUE
|
@@ -278,7 +297,8 @@ static struct _code codes[] = {
|
|
278
297
|
};
|
279
298
|
|
280
299
|
static int
|
281
|
-
hash_cb(VALUE key, VALUE value,
|
300
|
+
hash_cb(VALUE key, VALUE value, VALUE ov) {
|
301
|
+
Out out = (Out)ov;
|
282
302
|
int depth = out->depth;
|
283
303
|
|
284
304
|
if (oj_dump_ignore(out->opts, value)) {
|
@@ -573,7 +593,8 @@ dump_common(VALUE obj, int depth, Out out) {
|
|
573
593
|
}
|
574
594
|
|
575
595
|
static int
|
576
|
-
dump_attr_cb(ID key, VALUE value,
|
596
|
+
dump_attr_cb(ID key, VALUE value, VALUE ov) {
|
597
|
+
Out out = (Out)ov;
|
577
598
|
int depth = out->depth;
|
578
599
|
size_t size;
|
579
600
|
const char *attr;
|
@@ -590,6 +611,8 @@ dump_attr_cb(ID key, VALUE value, Out out) {
|
|
590
611
|
// the key name is NULL. Not an empty string but NULL.
|
591
612
|
if (NULL == attr) {
|
592
613
|
attr = "";
|
614
|
+
} else if (Yes == out->opts->ignore_under && '@' == *attr && '_' == attr[1]) {
|
615
|
+
return ST_CONTINUE;
|
593
616
|
}
|
594
617
|
if (0 == strcmp("bt", attr) || 0 == strcmp("mesg", attr)) {
|
595
618
|
return ST_CONTINUE;
|
@@ -874,7 +897,11 @@ dump_data(VALUE obj, int depth, Out out, bool as_ok) {
|
|
874
897
|
|
875
898
|
static void
|
876
899
|
dump_regexp(VALUE obj, int depth, Out out, bool as_ok) {
|
877
|
-
|
900
|
+
if (NULL != out->opts->create_id) {
|
901
|
+
dump_obj_str(obj, depth, out);
|
902
|
+
} else {
|
903
|
+
dump_obj_as_str(obj, depth, out);
|
904
|
+
}
|
878
905
|
}
|
879
906
|
|
880
907
|
static void
|
@@ -1046,7 +1073,7 @@ hash_set_num(struct _parseInfo *pi, Val kval, NumInfo ni) {
|
|
1046
1073
|
oj_set_obj_ivar(parent, kval, rval);
|
1047
1074
|
break;
|
1048
1075
|
case T_HASH:
|
1049
|
-
if (4 == parent->klen && NULL != parent->key && rb_cTime == parent->clas && 0 == strncmp("time", parent->key, 4)) {
|
1076
|
+
if (4 == parent->klen && NULL != parent->key && rb_cTime == parent->clas && 0 != ni->div && 0 == strncmp("time", parent->key, 4)) {
|
1050
1077
|
int64_t nsec = ni->num * 1000000000LL / ni->div;
|
1051
1078
|
|
1052
1079
|
if (ni->neg) {
|
data/ext/oj/dump.c
CHANGED
@@ -548,7 +548,7 @@ oj_dump_xml_time(VALUE obj, Out out) {
|
|
548
548
|
tzhour = (int)(tzsecs / 3600);
|
549
549
|
tzmin = (int)(tzsecs / 60) - (tzhour * 60);
|
550
550
|
}
|
551
|
-
if (0 == nsec || 0 == out->opts->sec_prec) {
|
551
|
+
if ((0 == nsec && !out->opts->sec_prec_set) || 0 == out->opts->sec_prec) {
|
552
552
|
if (0 == tzsecs && rb_funcall2(obj, oj_utcq_id, 0, 0)) {
|
553
553
|
sprintf(buf, "%04d-%02d-%02dT%02d:%02d:%02dZ", ti.year, ti.mon, ti.day, ti.hour, ti.min, ti.sec);
|
554
554
|
oj_dump_cstr(buf, 20, 0, 0, out);
|
@@ -1023,8 +1023,8 @@ oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1023
1023
|
int neg = 0;
|
1024
1024
|
bool dump_as_string = false;
|
1025
1025
|
|
1026
|
-
if (out->opts->
|
1027
|
-
(out->opts->
|
1026
|
+
if (out->opts->int_range_max != 0 && out->opts->int_range_min != 0 &&
|
1027
|
+
(out->opts->int_range_max < num || out->opts->int_range_min > num)) {
|
1028
1028
|
dump_as_string = true;
|
1029
1029
|
}
|
1030
1030
|
if (0 > num) {
|
@@ -1062,23 +1062,20 @@ void
|
|
1062
1062
|
oj_dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
|
1063
1063
|
volatile VALUE rs = rb_big2str(obj, 10);
|
1064
1064
|
int cnt = (int)RSTRING_LEN(rs);
|
1065
|
-
|
1065
|
+
bool dump_as_string = false;
|
1066
1066
|
|
1067
|
-
|
1067
|
+
if (out->opts->int_range_max != 0 || out->opts->int_range_min != 0) { // Bignum cannot be inside of Fixnum range
|
1068
1068
|
dump_as_string = true;
|
1069
1069
|
assure_size(out, cnt + 2);
|
1070
1070
|
*out->cur++ = '"';
|
1071
|
-
|
1071
|
+
} else {
|
1072
1072
|
assure_size(out, cnt);
|
1073
|
-
|
1074
|
-
|
1073
|
+
}
|
1075
1074
|
memcpy(out->cur, rb_string_value_ptr((VALUE*)&rs), cnt);
|
1076
1075
|
out->cur += cnt;
|
1077
|
-
|
1078
|
-
if(dump_as_string) {
|
1076
|
+
if (dump_as_string) {
|
1079
1077
|
*out->cur++ = '"';
|
1080
|
-
|
1081
|
-
|
1078
|
+
}
|
1082
1079
|
*out->cur = '\0';
|
1083
1080
|
}
|
1084
1081
|
|
data/ext/oj/dump_compat.c
CHANGED
@@ -648,7 +648,8 @@ dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
|
648
648
|
}
|
649
649
|
|
650
650
|
static int
|
651
|
-
hash_cb(VALUE key, VALUE value,
|
651
|
+
hash_cb(VALUE key, VALUE value, VALUE ov) {
|
652
|
+
Out out = (Out)ov;
|
652
653
|
int depth = out->depth;
|
653
654
|
|
654
655
|
if (out->omit_nil && Qnil == value) {
|
@@ -870,7 +871,7 @@ dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
|
|
870
871
|
// this must use to_s to pass the json gem unit tests.
|
871
872
|
volatile VALUE rs;
|
872
873
|
int cnt;
|
873
|
-
|
874
|
+
bool dump_as_string = false;
|
874
875
|
|
875
876
|
if (use_bignum_alt) {
|
876
877
|
rs = rb_big2str(obj, 10);
|
@@ -880,21 +881,18 @@ dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
|
|
880
881
|
rb_check_type(rs, T_STRING);
|
881
882
|
cnt = (int)RSTRING_LEN(rs);
|
882
883
|
|
883
|
-
|
884
|
+
if (out->opts->int_range_min != 0 || out->opts->int_range_max != 0) {
|
884
885
|
dump_as_string = true; // Bignum cannot be inside of Fixnum range
|
885
886
|
assure_size(out, cnt + 2);
|
886
887
|
*out->cur++ = '"';
|
887
|
-
|
888
|
+
} else {
|
888
889
|
assure_size(out, cnt);
|
889
|
-
|
890
|
-
|
890
|
+
}
|
891
891
|
memcpy(out->cur, rb_string_value_ptr((VALUE*)&rs), cnt);
|
892
892
|
out->cur += cnt;
|
893
|
-
|
894
|
-
if(dump_as_string) {
|
893
|
+
if (dump_as_string) {
|
895
894
|
*out->cur++ = '"';
|
896
|
-
|
897
|
-
|
895
|
+
}
|
898
896
|
*out->cur = '\0';
|
899
897
|
}
|
900
898
|
|
data/ext/oj/dump_object.c
CHANGED
@@ -56,7 +56,7 @@ dump_data(VALUE obj, int depth, Out out, bool as_ok) {
|
|
56
56
|
}
|
57
57
|
} else {
|
58
58
|
long id = oj_check_circular(obj, out);
|
59
|
-
|
59
|
+
|
60
60
|
if (0 <= id) {
|
61
61
|
dump_obj_attrs(obj, clas, id, depth, out);
|
62
62
|
}
|
@@ -72,7 +72,7 @@ dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
|
|
72
72
|
volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
|
73
73
|
const char *str = rb_string_value_ptr((VALUE*)&rstr);
|
74
74
|
int len = (int)RSTRING_LEN(rstr);
|
75
|
-
|
75
|
+
|
76
76
|
if (0 == strcasecmp("Infinity", str)) {
|
77
77
|
str = oj_nan_str(obj, out->opts->dump_opts.nan_dump, out->opts->mode, true, &len);
|
78
78
|
oj_dump_raw(str, len, out);
|
@@ -224,7 +224,8 @@ dump_sym(VALUE obj, int depth, Out out, bool as_ok) {
|
|
224
224
|
}
|
225
225
|
|
226
226
|
static int
|
227
|
-
hash_cb(VALUE key, VALUE value,
|
227
|
+
hash_cb(VALUE key, VALUE value, VALUE ov) {
|
228
|
+
Out out = (Out)ov;
|
228
229
|
int depth = out->depth;
|
229
230
|
long size = depth * out->indent + 1;
|
230
231
|
|
@@ -280,7 +281,7 @@ hash_cb(VALUE key, VALUE value, Out out) {
|
|
280
281
|
}
|
281
282
|
out->depth = depth;
|
282
283
|
*out->cur++ = ',';
|
283
|
-
|
284
|
+
|
284
285
|
return ST_CONTINUE;
|
285
286
|
}
|
286
287
|
|
@@ -348,7 +349,8 @@ dump_hash_class(VALUE obj, VALUE clas, int depth, Out out) {
|
|
348
349
|
|
349
350
|
#ifdef HAVE_RB_IVAR_FOREACH
|
350
351
|
static int
|
351
|
-
dump_attr_cb(ID key, VALUE value,
|
352
|
+
dump_attr_cb(ID key, VALUE value, VALUE ov) {
|
353
|
+
Out out = (Out)ov;
|
352
354
|
int depth = out->depth;
|
353
355
|
size_t size = depth * out->indent + 1;
|
354
356
|
const char *attr = rb_id2name(key);
|
@@ -363,6 +365,8 @@ dump_attr_cb(ID key, VALUE value, Out out) {
|
|
363
365
|
// the key name is NULL. Not an empty string but NULL.
|
364
366
|
if (NULL == attr) {
|
365
367
|
attr = "";
|
368
|
+
} else if (Yes == out->opts->ignore_under && '@' == *attr && '_' == attr[1]) {
|
369
|
+
return ST_CONTINUE;
|
366
370
|
}
|
367
371
|
if (0 == strcmp("bt", attr) || 0 == strcmp("mesg", attr)) {
|
368
372
|
return ST_CONTINUE;
|
@@ -384,7 +388,7 @@ dump_attr_cb(ID key, VALUE value, Out out) {
|
|
384
388
|
oj_dump_obj_val(value, depth, out);
|
385
389
|
out->depth = depth;
|
386
390
|
*out->cur++ = ',';
|
387
|
-
|
391
|
+
|
388
392
|
return ST_CONTINUE;
|
389
393
|
}
|
390
394
|
#endif
|
@@ -424,7 +428,7 @@ dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
|
|
424
428
|
v = rb_funcall(obj, *odd->attrs, 0);
|
425
429
|
if (Qundef == v || T_STRING != rb_type(v)) {
|
426
430
|
rb_raise(rb_eEncodingError, "Invalid type for raw JSON.");
|
427
|
-
} else {
|
431
|
+
} else {
|
428
432
|
const char *s = rb_string_value_ptr((VALUE*)&v);
|
429
433
|
int len = (int)RSTRING_LEN(v);
|
430
434
|
const char *name = rb_id2name(*odd->attrs);
|
@@ -460,7 +464,7 @@ dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
|
|
460
464
|
char *n;
|
461
465
|
char *end;
|
462
466
|
ID i;
|
463
|
-
|
467
|
+
|
464
468
|
if (sizeof(nbuf) <= nlen) {
|
465
469
|
if (NULL == (n2 = strdup(name))) {
|
466
470
|
rb_raise(rb_eNoMemError, "for attribute name.");
|
@@ -610,9 +614,12 @@ dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out) {
|
|
610
614
|
size = d2 * out->indent + 1;
|
611
615
|
for (i = cnt; 0 < i; i--, np++) {
|
612
616
|
VALUE value;
|
613
|
-
|
617
|
+
|
614
618
|
vid = rb_to_id(*np);
|
615
619
|
attr = rb_id2name(vid);
|
620
|
+
if (Yes == out->opts->ignore_under && '@' == *attr && '_' == attr[1]) {
|
621
|
+
return ST_CONTINUE;
|
622
|
+
}
|
616
623
|
value = rb_ivar_get(obj, vid);
|
617
624
|
|
618
625
|
if (oj_dump_ignore(out->opts, value)) {
|
@@ -739,7 +746,7 @@ dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
739
746
|
#else // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
740
747
|
cnt = (int)RSTRUCT_LEN(obj);
|
741
748
|
#endif // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
742
|
-
|
749
|
+
|
743
750
|
for (i = 0; i < cnt; i++) {
|
744
751
|
v = RSTRUCT_GET(obj, i);
|
745
752
|
if (oj_dump_ignore(out->opts, v)) {
|
@@ -812,7 +819,7 @@ static DumpFunc obj_funcs[] = {
|
|
812
819
|
void
|
813
820
|
oj_dump_obj_val(VALUE obj, int depth, Out out) {
|
814
821
|
int type = rb_type(obj);
|
815
|
-
|
822
|
+
|
816
823
|
if (Yes == out->opts->trace) {
|
817
824
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
818
825
|
}
|
data/ext/oj/dump_strict.c
CHANGED
@@ -45,7 +45,7 @@ dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
|
45
45
|
cnt = 3;
|
46
46
|
} else {
|
47
47
|
NanDump nd = out->opts->dump_opts.nan_dump;
|
48
|
-
|
48
|
+
|
49
49
|
if (AutoNan == nd) {
|
50
50
|
nd = RaiseNan;
|
51
51
|
}
|
@@ -195,11 +195,12 @@ dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
|
195
195
|
}
|
196
196
|
|
197
197
|
static int
|
198
|
-
hash_cb(VALUE key, VALUE value,
|
198
|
+
hash_cb(VALUE key, VALUE value, VALUE ov) {
|
199
|
+
Out out = (Out)ov;
|
199
200
|
int depth = out->depth;
|
200
201
|
long size;
|
201
202
|
int rtype = rb_type(key);
|
202
|
-
|
203
|
+
|
203
204
|
if (rtype != T_STRING && rtype != T_SYMBOL) {
|
204
205
|
rb_raise(rb_eTypeError, "In :strict and :null mode all Hash keys must be Strings or Symbols, not %s.\n", rb_class2name(rb_obj_class(key)));
|
205
206
|
}
|
@@ -359,7 +360,7 @@ static DumpFunc strict_funcs[] = {
|
|
359
360
|
void
|
360
361
|
oj_dump_strict_val(VALUE obj, int depth, Out out) {
|
361
362
|
int type = rb_type(obj);
|
362
|
-
|
363
|
+
|
363
364
|
if (Yes == out->opts->trace) {
|
364
365
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
365
366
|
}
|
@@ -408,7 +409,7 @@ static DumpFunc null_funcs[] = {
|
|
408
409
|
void
|
409
410
|
oj_dump_null_val(VALUE obj, int depth, Out out) {
|
410
411
|
int type = rb_type(obj);
|
411
|
-
|
412
|
+
|
412
413
|
if (Yes == out->opts->trace) {
|
413
414
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
414
415
|
}
|