oj 3.0.2 → 3.0.3
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/ext/oj/code.h +2 -0
- data/ext/oj/dump.c +1 -1
- data/ext/oj/dump.h +1 -1
- data/ext/oj/dump_compat.c +7 -8
- data/ext/oj/dump_object.c +1 -1
- data/ext/oj/oj.c +1 -1
- data/ext/oj/{mimic_rails.c → rails.c} +363 -9
- data/ext/oj/{mimic_rails.h → rails.h} +4 -4
- data/lib/oj/version.rb +1 -1
- data/pages/Rails.md +5 -2
- data/test/activesupport4/decoding_test.rb +5 -2
- data/test/activesupport4/encoding_test.rb +1 -1
- metadata +4 -5
- data/ext/oj/dump_rails.c +0 -329
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c5c4e44c052cf9e204ada5c41bc6b868b04ec56
|
4
|
+
data.tar.gz: d2a0352206bb10de6743c8be87d22120f122c7ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f4e47a2c590b33dff4fd7057c9874d1ab95f9c0057cc7f22a30617604865d8999b2dab758c47d89ee6445de033eeb07ac3b32077db52080f08a62bf57af3b9e2
|
7
|
+
data.tar.gz: 56ea00a656fc87fbc072a240ddcb58223627f4a28874d8b9fe37d1044757bd6e2cab993cadfc711be04adfae11cd2557c084a66e80c853132b6ff40adbef8913
|
data/ext/oj/code.h
CHANGED
data/ext/oj/dump.c
CHANGED
@@ -538,7 +538,7 @@ oj_dump_obj_to_json_using_params(VALUE obj, Options copts, Out out, int argc, VA
|
|
538
538
|
case NullMode: oj_dump_null_val(obj, 0, out); break;
|
539
539
|
case ObjectMode: oj_dump_obj_val(obj, 0, out); break;
|
540
540
|
case CompatMode: oj_dump_compat_val(obj, 0, out, Yes == copts->to_json); break;
|
541
|
-
case RailsMode: oj_dump_rails_val(obj, 0, out
|
541
|
+
case RailsMode: oj_dump_rails_val(obj, 0, out); break;
|
542
542
|
case CustomMode: oj_dump_custom_val(obj, 0, out, true); break;
|
543
543
|
default: oj_dump_custom_val(obj, 0, out, true); break;
|
544
544
|
}
|
data/ext/oj/dump.h
CHANGED
@@ -41,7 +41,7 @@ extern void oj_dump_strict_val(VALUE obj, int depth, Out out);
|
|
41
41
|
extern void oj_dump_null_val(VALUE obj, int depth, Out out);
|
42
42
|
extern void oj_dump_obj_val(VALUE obj, int depth, Out out);
|
43
43
|
extern void oj_dump_compat_val(VALUE obj, int depth, Out out, bool as_ok);
|
44
|
-
extern void oj_dump_rails_val(VALUE obj, int depth, Out out
|
44
|
+
extern void oj_dump_rails_val(VALUE obj, int depth, Out out);
|
45
45
|
extern void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok);
|
46
46
|
|
47
47
|
extern VALUE oj_add_to_json(int argc, VALUE *argv, VALUE self);
|
data/ext/oj/dump_compat.c
CHANGED
@@ -462,7 +462,7 @@ time_alt(VALUE obj, int depth, Out out) {
|
|
462
462
|
oj_code_attrs(obj, attrs, depth, out);
|
463
463
|
}
|
464
464
|
|
465
|
-
|
465
|
+
struct _Code oj_compat_codes[] = {
|
466
466
|
{ "BigDecimal", Qnil, bigdecimal_alt, NULL, false },
|
467
467
|
{ "Complex", Qnil, complex_alt, NULL, false },
|
468
468
|
{ "Date", Qnil, date_alt, false },
|
@@ -481,7 +481,7 @@ oj_add_to_json(int argc, VALUE *argv, VALUE self) {
|
|
481
481
|
Code a;
|
482
482
|
|
483
483
|
if (0 == argc) {
|
484
|
-
for (a =
|
484
|
+
for (a = oj_compat_codes; NULL != a->name; a++) {
|
485
485
|
if (Qnil == a->clas || Qundef == a->clas) {
|
486
486
|
a->clas = rb_const_get_at(rb_cObject, rb_intern(a->name));
|
487
487
|
}
|
@@ -514,7 +514,7 @@ oj_add_to_json(int argc, VALUE *argv, VALUE self) {
|
|
514
514
|
oj_use_array_alt = true;
|
515
515
|
continue;
|
516
516
|
}
|
517
|
-
for (a =
|
517
|
+
for (a = oj_compat_codes; NULL != a->name; a++) {
|
518
518
|
if (Qnil == a->clas || Qundef == a->clas) {
|
519
519
|
a->clas = rb_const_get_at(rb_cObject, rb_intern(a->name));
|
520
520
|
}
|
@@ -531,7 +531,7 @@ oj_add_to_json(int argc, VALUE *argv, VALUE self) {
|
|
531
531
|
VALUE
|
532
532
|
oj_remove_to_json(int argc, VALUE *argv, VALUE self) {
|
533
533
|
if (0 == argc) {
|
534
|
-
oj_code_set_active(
|
534
|
+
oj_code_set_active(oj_compat_codes, Qnil, false);
|
535
535
|
use_struct_alt = false;
|
536
536
|
use_exception_alt = false;
|
537
537
|
use_bignum_alt = false;
|
@@ -559,7 +559,7 @@ oj_remove_to_json(int argc, VALUE *argv, VALUE self) {
|
|
559
559
|
oj_use_array_alt = false;
|
560
560
|
continue;
|
561
561
|
}
|
562
|
-
oj_code_set_active(
|
562
|
+
oj_code_set_active(oj_compat_codes, *argv, false);
|
563
563
|
}
|
564
564
|
}
|
565
565
|
return Qnil;
|
@@ -723,7 +723,7 @@ dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
|
|
723
723
|
// called.
|
724
724
|
static void
|
725
725
|
dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
|
726
|
-
if (oj_code_dump(
|
726
|
+
if (oj_code_dump(oj_compat_codes, obj, depth, out)) {
|
727
727
|
return;
|
728
728
|
}
|
729
729
|
if (use_exception_alt && rb_obj_is_kind_of(obj, rb_eException)) {
|
@@ -754,7 +754,7 @@ static void
|
|
754
754
|
dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
755
755
|
VALUE clas = rb_obj_class(obj);
|
756
756
|
|
757
|
-
if (oj_code_dump(
|
757
|
+
if (oj_code_dump(oj_compat_codes, obj, depth, out)) {
|
758
758
|
return;
|
759
759
|
}
|
760
760
|
if (rb_cRange == clas) {
|
@@ -866,7 +866,6 @@ dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
|
|
866
866
|
*out->cur = '\0';
|
867
867
|
}
|
868
868
|
|
869
|
-
|
870
869
|
static DumpFunc compat_funcs[] = {
|
871
870
|
NULL, // RUBY_T_NONE = 0x00,
|
872
871
|
dump_obj, // RUBY_T_OBJECT = 0x01,
|
data/ext/oj/dump_object.c
CHANGED
@@ -624,7 +624,7 @@ dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out) {
|
|
624
624
|
oj_dump_cstr(buf, strlen(attr) + 1, 0, 0, out);
|
625
625
|
}
|
626
626
|
*out->cur++ = ':';
|
627
|
-
oj_dump_obj_val(value, d2, out,
|
627
|
+
oj_dump_obj_val(value, d2, out, true);
|
628
628
|
assure_size(out, 2);
|
629
629
|
}
|
630
630
|
#endif
|
data/ext/oj/oj.c
CHANGED
@@ -1,11 +1,14 @@
|
|
1
|
-
/*
|
1
|
+
/* rails.c
|
2
2
|
* Copyright (c) 2017, Peter Ohler
|
3
3
|
* All rights reserved.
|
4
4
|
*/
|
5
5
|
|
6
|
-
#include "
|
7
|
-
#include "mimic_rails.h"
|
6
|
+
#include "rails.h"
|
8
7
|
#include "encode.h"
|
8
|
+
#include "code.h"
|
9
|
+
#include "encode.h"
|
10
|
+
|
11
|
+
#define OJ_INFINITY (1.0/0.0)
|
9
12
|
|
10
13
|
// TBD keep static array of strings and functions to help with rails optimization
|
11
14
|
typedef struct _Encoder {
|
@@ -14,6 +17,11 @@ typedef struct _Encoder {
|
|
14
17
|
VALUE arg;
|
15
18
|
} *Encoder;
|
16
19
|
|
20
|
+
bool oj_rails_hash_opt = false;
|
21
|
+
bool oj_rails_array_opt = false;
|
22
|
+
|
23
|
+
static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok);
|
24
|
+
|
17
25
|
extern VALUE Oj;
|
18
26
|
|
19
27
|
static struct _ROptTable ropts = { 0, 0, NULL };
|
@@ -98,7 +106,7 @@ dump_attr_cb(ID key, VALUE value, Out out) {
|
|
98
106
|
oj_dump_cstr(buf, strlen(buf), 0, 0, out);
|
99
107
|
}
|
100
108
|
*out->cur++ = ':';
|
101
|
-
|
109
|
+
dump_rails_val(value, depth, out, true);
|
102
110
|
out->depth = depth;
|
103
111
|
*out->cur++ = ',';
|
104
112
|
|
@@ -172,7 +180,7 @@ dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
172
180
|
#else
|
173
181
|
v = rb_struct_aref(obj, INT2FIX(i));
|
174
182
|
#endif
|
175
|
-
|
183
|
+
dump_rails_val(v, d3, out, true);
|
176
184
|
}
|
177
185
|
fill_indent(out, depth);
|
178
186
|
*out->cur++ = '}';
|
@@ -187,7 +195,7 @@ dump_enumerable(VALUE obj, int depth, Out out, bool as_ok) {
|
|
187
195
|
if (0 == to_a_id) {
|
188
196
|
to_a_id = rb_intern("to_a");
|
189
197
|
}
|
190
|
-
|
198
|
+
dump_rails_val(rb_funcall(obj, to_a_id, 0), depth, out, false);
|
191
199
|
}
|
192
200
|
|
193
201
|
static void
|
@@ -556,7 +564,7 @@ static VALUE
|
|
556
564
|
protect_dump(VALUE ov) {
|
557
565
|
OO oo = (OO)ov;
|
558
566
|
|
559
|
-
|
567
|
+
dump_rails_val(oo->obj, 0, oo->out, true);
|
560
568
|
|
561
569
|
return Qnil;
|
562
570
|
}
|
@@ -596,7 +604,7 @@ encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *argv) {
|
|
596
604
|
if (Yes == copts.circular) {
|
597
605
|
oj_cache8_new(&out.circ_cache);
|
598
606
|
}
|
599
|
-
//
|
607
|
+
//dump_rails_val(*argv, 0, &out, true);
|
600
608
|
rb_protect(protect_dump, (VALUE)&oo, &line);
|
601
609
|
|
602
610
|
if (0 == line) {
|
@@ -719,6 +727,7 @@ rails_set_encoder(VALUE self) {
|
|
719
727
|
VALUE json;
|
720
728
|
VALUE encoding;
|
721
729
|
VALUE pv;
|
730
|
+
VALUE verbose;
|
722
731
|
|
723
732
|
if (rb_const_defined_at(rb_cObject, rb_intern("ActiveSupport"))) {
|
724
733
|
active = rb_const_get_at(rb_cObject, rb_intern("ActiveSupport"));
|
@@ -730,7 +739,11 @@ rails_set_encoder(VALUE self) {
|
|
730
739
|
json = rb_const_get_at(active, rb_intern("JSON"));
|
731
740
|
encoding = rb_const_get_at(json, rb_intern("Encoding"));
|
732
741
|
|
733
|
-
rb_undef_method
|
742
|
+
// rb_undef_method doesn't work for modules or maybe sometimes
|
743
|
+
// doesn't. Anyway setting verbose should hide the warning.
|
744
|
+
verbose = rb_gv_get("$VERBOSE");
|
745
|
+
rb_gv_set("$VERBOSE", Qfalse);
|
746
|
+
rb_undef_method(encoding, "use_standard_json_time_format=");
|
734
747
|
rb_define_module_function(encoding, "use_standard_json_time_format=", rails_use_standard_json_time_format, 1);
|
735
748
|
|
736
749
|
rb_undef_method(encoding, "escape_html_entities_in_json=");
|
@@ -740,6 +753,7 @@ rails_set_encoder(VALUE self) {
|
|
740
753
|
oj_default_options.sec_prec = NUM2INT(pv);
|
741
754
|
rb_undef_method(encoding, "time_precision=");
|
742
755
|
rb_define_module_function(encoding, "time_precision=", rails_time_precision, 1);
|
756
|
+
rb_gv_set("$VERBOSE", verbose);
|
743
757
|
|
744
758
|
return Qnil;
|
745
759
|
}
|
@@ -754,6 +768,7 @@ static VALUE
|
|
754
768
|
rails_set_decoder(VALUE self) {
|
755
769
|
VALUE json;
|
756
770
|
VALUE json_error;
|
771
|
+
VALUE verbose;
|
757
772
|
|
758
773
|
if (rb_const_defined_at(rb_cObject, rb_intern("JSON"))) {
|
759
774
|
json = rb_const_get_at(rb_cObject, rb_intern("JSON"));
|
@@ -770,8 +785,13 @@ rails_set_decoder(VALUE self) {
|
|
770
785
|
} else {
|
771
786
|
oj_json_parser_error_class = rb_define_class_under(json, "ParserError", json_error);
|
772
787
|
}
|
788
|
+
// rb_undef_method doesn't work for modules or maybe sometimes
|
789
|
+
// doesn't. Anyway setting verbose should hide the warning.
|
790
|
+
verbose = rb_gv_get("$VERBOSE");
|
791
|
+
rb_gv_set("$VERBOSE", Qfalse);
|
773
792
|
rb_undef_method(json, "parse");
|
774
793
|
rb_define_module_function(json, "parse", oj_mimic_parse, -1);
|
794
|
+
rb_gv_set("$VERBOSE", verbose);
|
775
795
|
|
776
796
|
return Qnil;
|
777
797
|
}
|
@@ -804,3 +824,337 @@ oj_mimic_rails_init() {
|
|
804
824
|
rb_define_method(encoder_class, "deoptimize", encoder_deoptimize, -1);
|
805
825
|
rb_define_method(encoder_class, "optimized?", encoder_optimized, 1);
|
806
826
|
}
|
827
|
+
|
828
|
+
static void
|
829
|
+
dump_as_json(VALUE obj, int depth, Out out, bool as_ok) {
|
830
|
+
volatile VALUE ja;
|
831
|
+
|
832
|
+
if (0 < out->argc) {
|
833
|
+
ja = rb_funcall2(obj, oj_as_json_id, out->argc, out->argv);
|
834
|
+
} else {
|
835
|
+
ja = rb_funcall(obj, oj_as_json_id, 0);
|
836
|
+
}
|
837
|
+
if (ja == obj || !as_ok) {
|
838
|
+
// Once as_json is call it should never be called again on the same
|
839
|
+
// object with as_ok.
|
840
|
+
dump_rails_val(ja, depth, out, false);
|
841
|
+
} else {
|
842
|
+
int type = rb_type(ja);
|
843
|
+
|
844
|
+
if (T_HASH == type || T_ARRAY == type) {
|
845
|
+
dump_rails_val(ja, depth, out, false);
|
846
|
+
} else {
|
847
|
+
dump_rails_val(ja, depth, out, true);
|
848
|
+
}
|
849
|
+
}
|
850
|
+
}
|
851
|
+
|
852
|
+
static void
|
853
|
+
dump_to_hash(VALUE obj, int depth, Out out) {
|
854
|
+
dump_rails_val(rb_funcall(obj, oj_to_hash_id, 0), depth, out, false);
|
855
|
+
}
|
856
|
+
|
857
|
+
static void
|
858
|
+
dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
859
|
+
char buf[64];
|
860
|
+
char *b;
|
861
|
+
double d = rb_num2dbl(obj);
|
862
|
+
int cnt = 0;
|
863
|
+
|
864
|
+
if (0.0 == d) {
|
865
|
+
b = buf;
|
866
|
+
*b++ = '0';
|
867
|
+
*b++ = '.';
|
868
|
+
*b++ = '0';
|
869
|
+
*b++ = '\0';
|
870
|
+
cnt = 3;
|
871
|
+
} else {
|
872
|
+
if (isnan(d) || OJ_INFINITY == d || -OJ_INFINITY == d) {
|
873
|
+
strcpy(buf, "null");
|
874
|
+
cnt = 4;
|
875
|
+
} else if (d == (double)(long long int)d) {
|
876
|
+
cnt = snprintf(buf, sizeof(buf), "%.1f", d);
|
877
|
+
} else {
|
878
|
+
cnt = snprintf(buf, sizeof(buf), "%0.16g", d);
|
879
|
+
}
|
880
|
+
}
|
881
|
+
assure_size(out, cnt);
|
882
|
+
for (b = buf; '\0' != *b; b++) {
|
883
|
+
*out->cur++ = *b;
|
884
|
+
}
|
885
|
+
*out->cur = '\0';
|
886
|
+
}
|
887
|
+
|
888
|
+
static void
|
889
|
+
dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
890
|
+
size_t size;
|
891
|
+
int i, cnt;
|
892
|
+
int d2 = depth + 1;
|
893
|
+
|
894
|
+
if (Yes == out->opts->circular) {
|
895
|
+
if (0 > oj_check_circular(a, out)) {
|
896
|
+
oj_dump_nil(Qnil, 0, out, false);
|
897
|
+
return;
|
898
|
+
}
|
899
|
+
}
|
900
|
+
if (as_ok && !oj_rails_array_opt && rb_respond_to(a, oj_as_json_id)) {
|
901
|
+
dump_as_json(a, depth, out, false);
|
902
|
+
return;
|
903
|
+
}
|
904
|
+
cnt = (int)RARRAY_LEN(a);
|
905
|
+
*out->cur++ = '[';
|
906
|
+
size = 2;
|
907
|
+
assure_size(out, size);
|
908
|
+
if (0 == cnt) {
|
909
|
+
*out->cur++ = ']';
|
910
|
+
} else {
|
911
|
+
if (out->opts->dump_opts.use) {
|
912
|
+
size = d2 * out->opts->dump_opts.indent_size + out->opts->dump_opts.array_size + 1;
|
913
|
+
} else {
|
914
|
+
size = d2 * out->indent + 2;
|
915
|
+
}
|
916
|
+
cnt--;
|
917
|
+
for (i = 0; i <= cnt; i++) {
|
918
|
+
assure_size(out, size);
|
919
|
+
if (out->opts->dump_opts.use) {
|
920
|
+
if (0 < out->opts->dump_opts.array_size) {
|
921
|
+
strcpy(out->cur, out->opts->dump_opts.array_nl);
|
922
|
+
out->cur += out->opts->dump_opts.array_size;
|
923
|
+
}
|
924
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
925
|
+
int i;
|
926
|
+
for (i = d2; 0 < i; i--) {
|
927
|
+
strcpy(out->cur, out->opts->dump_opts.indent_str);
|
928
|
+
out->cur += out->opts->dump_opts.indent_size;
|
929
|
+
}
|
930
|
+
}
|
931
|
+
} else {
|
932
|
+
fill_indent(out, d2);
|
933
|
+
}
|
934
|
+
dump_rails_val(rb_ary_entry(a, i), d2, out, as_ok);
|
935
|
+
if (i < cnt) {
|
936
|
+
*out->cur++ = ',';
|
937
|
+
}
|
938
|
+
}
|
939
|
+
size = depth * out->indent + 1;
|
940
|
+
assure_size(out, size);
|
941
|
+
if (out->opts->dump_opts.use) {
|
942
|
+
if (0 < out->opts->dump_opts.array_size) {
|
943
|
+
strcpy(out->cur, out->opts->dump_opts.array_nl);
|
944
|
+
out->cur += out->opts->dump_opts.array_size;
|
945
|
+
}
|
946
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
947
|
+
int i;
|
948
|
+
|
949
|
+
for (i = depth; 0 < i; i--) {
|
950
|
+
strcpy(out->cur, out->opts->dump_opts.indent_str);
|
951
|
+
out->cur += out->opts->dump_opts.indent_size;
|
952
|
+
}
|
953
|
+
}
|
954
|
+
} else {
|
955
|
+
fill_indent(out, depth);
|
956
|
+
}
|
957
|
+
*out->cur++ = ']';
|
958
|
+
}
|
959
|
+
*out->cur = '\0';
|
960
|
+
}
|
961
|
+
|
962
|
+
static int
|
963
|
+
hash_cb(VALUE key, VALUE value, Out out) {
|
964
|
+
int depth = out->depth;
|
965
|
+
long size;
|
966
|
+
int rtype = rb_type(key);
|
967
|
+
|
968
|
+
if (rtype != T_STRING && rtype != T_SYMBOL) {
|
969
|
+
key = rb_funcall(key, oj_to_s_id, 0);
|
970
|
+
rtype = rb_type(key);
|
971
|
+
}
|
972
|
+
if (!out->opts->dump_opts.use) {
|
973
|
+
size = depth * out->indent + 1;
|
974
|
+
assure_size(out, size);
|
975
|
+
fill_indent(out, depth);
|
976
|
+
if (rtype == T_STRING) {
|
977
|
+
oj_dump_str(key, 0, out, false);
|
978
|
+
} else {
|
979
|
+
oj_dump_sym(key, 0, out, false);
|
980
|
+
}
|
981
|
+
*out->cur++ = ':';
|
982
|
+
} else {
|
983
|
+
size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
|
984
|
+
assure_size(out, size);
|
985
|
+
if (0 < out->opts->dump_opts.hash_size) {
|
986
|
+
strcpy(out->cur, out->opts->dump_opts.hash_nl);
|
987
|
+
out->cur += out->opts->dump_opts.hash_size;
|
988
|
+
}
|
989
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
990
|
+
int i;
|
991
|
+
for (i = depth; 0 < i; i--) {
|
992
|
+
strcpy(out->cur, out->opts->dump_opts.indent_str);
|
993
|
+
out->cur += out->opts->dump_opts.indent_size;
|
994
|
+
}
|
995
|
+
}
|
996
|
+
if (rtype == T_STRING) {
|
997
|
+
oj_dump_str(key, 0, out, false);
|
998
|
+
} else {
|
999
|
+
oj_dump_sym(key, 0, out, false);
|
1000
|
+
}
|
1001
|
+
size = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
|
1002
|
+
assure_size(out, size);
|
1003
|
+
if (0 < out->opts->dump_opts.before_size) {
|
1004
|
+
strcpy(out->cur, out->opts->dump_opts.before_sep);
|
1005
|
+
out->cur += out->opts->dump_opts.before_size;
|
1006
|
+
}
|
1007
|
+
*out->cur++ = ':';
|
1008
|
+
if (0 < out->opts->dump_opts.after_size) {
|
1009
|
+
strcpy(out->cur, out->opts->dump_opts.after_sep);
|
1010
|
+
out->cur += out->opts->dump_opts.after_size;
|
1011
|
+
}
|
1012
|
+
}
|
1013
|
+
dump_rails_val(value, depth, out, false);
|
1014
|
+
out->depth = depth;
|
1015
|
+
*out->cur++ = ',';
|
1016
|
+
|
1017
|
+
return ST_CONTINUE;
|
1018
|
+
}
|
1019
|
+
|
1020
|
+
static void
|
1021
|
+
dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
|
1022
|
+
int cnt;
|
1023
|
+
size_t size;
|
1024
|
+
|
1025
|
+
if (Yes == out->opts->circular) {
|
1026
|
+
if (0 > oj_check_circular(obj, out)) {
|
1027
|
+
oj_dump_nil(Qnil, 0, out, false);
|
1028
|
+
return;
|
1029
|
+
}
|
1030
|
+
}
|
1031
|
+
if (as_ok && !oj_rails_hash_opt && rb_respond_to(obj, oj_as_json_id)) {
|
1032
|
+
dump_as_json(obj, depth, out, false);
|
1033
|
+
return;
|
1034
|
+
}
|
1035
|
+
cnt = (int)RHASH_SIZE(obj);
|
1036
|
+
size = depth * out->indent + 2;
|
1037
|
+
assure_size(out, 2);
|
1038
|
+
*out->cur++ = '{';
|
1039
|
+
if (0 == cnt) {
|
1040
|
+
*out->cur++ = '}';
|
1041
|
+
} else {
|
1042
|
+
out->depth = depth + 1;
|
1043
|
+
rb_hash_foreach(obj, hash_cb, (VALUE)out);
|
1044
|
+
if (',' == *(out->cur - 1)) {
|
1045
|
+
out->cur--; // backup to overwrite last comma
|
1046
|
+
}
|
1047
|
+
if (!out->opts->dump_opts.use) {
|
1048
|
+
assure_size(out, size);
|
1049
|
+
fill_indent(out, depth);
|
1050
|
+
} else {
|
1051
|
+
size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
|
1052
|
+
assure_size(out, size);
|
1053
|
+
if (0 < out->opts->dump_opts.hash_size) {
|
1054
|
+
strcpy(out->cur, out->opts->dump_opts.hash_nl);
|
1055
|
+
out->cur += out->opts->dump_opts.hash_size;
|
1056
|
+
}
|
1057
|
+
if (0 < out->opts->dump_opts.indent_size) {
|
1058
|
+
int i;
|
1059
|
+
|
1060
|
+
for (i = depth; 0 < i; i--) {
|
1061
|
+
strcpy(out->cur, out->opts->dump_opts.indent_str);
|
1062
|
+
out->cur += out->opts->dump_opts.indent_size;
|
1063
|
+
}
|
1064
|
+
}
|
1065
|
+
}
|
1066
|
+
*out->cur++ = '}';
|
1067
|
+
}
|
1068
|
+
*out->cur = '\0';
|
1069
|
+
}
|
1070
|
+
|
1071
|
+
static void
|
1072
|
+
dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
|
1073
|
+
if (oj_code_dump(oj_compat_codes, obj, depth, out)) {
|
1074
|
+
return;
|
1075
|
+
}
|
1076
|
+
if (as_ok) {
|
1077
|
+
ROpt ro;
|
1078
|
+
|
1079
|
+
if (NULL != (ro = oj_rails_get_opt(out->ropts, rb_obj_class(obj))) && ro->on) {
|
1080
|
+
ro->dump(obj, depth, out, as_ok);
|
1081
|
+
} else if (rb_respond_to(obj, oj_as_json_id)) {
|
1082
|
+
dump_as_json(obj, depth, out, true);
|
1083
|
+
} else if (rb_respond_to(obj, oj_to_hash_id)) {
|
1084
|
+
dump_to_hash(obj, depth, out);
|
1085
|
+
} else {
|
1086
|
+
oj_dump_obj_to_s(obj, out);
|
1087
|
+
}
|
1088
|
+
} else if (rb_respond_to(obj, oj_to_hash_id)) {
|
1089
|
+
// Always attempt to_hash.
|
1090
|
+
dump_to_hash(obj, depth, out);
|
1091
|
+
} else {
|
1092
|
+
oj_dump_obj_to_s(obj, out);
|
1093
|
+
}
|
1094
|
+
}
|
1095
|
+
|
1096
|
+
static void
|
1097
|
+
dump_as_string(VALUE obj, int depth, Out out, bool as_ok) {
|
1098
|
+
if (oj_code_dump(oj_compat_codes, obj, depth, out)) {
|
1099
|
+
return;
|
1100
|
+
}
|
1101
|
+
oj_dump_obj_to_s(obj, out);
|
1102
|
+
}
|
1103
|
+
|
1104
|
+
static DumpFunc rails_funcs[] = {
|
1105
|
+
NULL, // RUBY_T_NONE = 0x00,
|
1106
|
+
dump_obj, // RUBY_T_OBJECT = 0x01,
|
1107
|
+
oj_dump_class, // RUBY_T_CLASS = 0x02,
|
1108
|
+
oj_dump_class, // RUBY_T_MODULE = 0x03,
|
1109
|
+
dump_float, // RUBY_T_FLOAT = 0x04,
|
1110
|
+
oj_dump_str, // RUBY_T_STRING = 0x05,
|
1111
|
+
dump_as_string, // RUBY_T_REGEXP = 0x06,
|
1112
|
+
dump_array, // RUBY_T_ARRAY = 0x07,
|
1113
|
+
dump_hash, // RUBY_T_HASH = 0x08,
|
1114
|
+
dump_obj, // RUBY_T_STRUCT = 0x09,
|
1115
|
+
oj_dump_bignum, // RUBY_T_BIGNUM = 0x0a,
|
1116
|
+
NULL, // RUBY_T_FILE = 0x0b,
|
1117
|
+
dump_obj, // RUBY_T_DATA = 0x0c,
|
1118
|
+
NULL, // RUBY_T_MATCH = 0x0d,
|
1119
|
+
// Rails raises a stack error on Complex and Rational. It also corrupts
|
1120
|
+
// something whic causes a segfault on the next call. Oj will not mimic
|
1121
|
+
// that behavior.
|
1122
|
+
dump_as_string, // RUBY_T_COMPLEX = 0x0e,
|
1123
|
+
dump_as_string, // RUBY_T_RATIONAL = 0x0f,
|
1124
|
+
NULL, // 0x10
|
1125
|
+
oj_dump_nil, // RUBY_T_NIL = 0x11,
|
1126
|
+
oj_dump_true, // RUBY_T_TRUE = 0x12,
|
1127
|
+
oj_dump_false, // RUBY_T_FALSE = 0x13,
|
1128
|
+
oj_dump_sym, // RUBY_T_SYMBOL = 0x14,
|
1129
|
+
oj_dump_fixnum, // RUBY_T_FIXNUM = 0x15,
|
1130
|
+
};
|
1131
|
+
|
1132
|
+
static void
|
1133
|
+
dump_rails_val(VALUE obj, int depth, Out out, bool as_ok) {
|
1134
|
+
int type = rb_type(obj);
|
1135
|
+
|
1136
|
+
if (MAX_DEPTH < depth) {
|
1137
|
+
rb_raise(rb_eNoMemError, "Too deeply nested.\n");
|
1138
|
+
}
|
1139
|
+
if (0 < type && type <= RUBY_T_FIXNUM) {
|
1140
|
+
DumpFunc f = rails_funcs[type];
|
1141
|
+
|
1142
|
+
if (NULL != f) {
|
1143
|
+
f(obj, depth, out, as_ok);
|
1144
|
+
return;
|
1145
|
+
}
|
1146
|
+
}
|
1147
|
+
oj_dump_nil(Qnil, depth, out, false);
|
1148
|
+
}
|
1149
|
+
|
1150
|
+
void
|
1151
|
+
oj_dump_rails_val(VALUE obj, int depth, Out out) {
|
1152
|
+
out->opts->str_rx.head = NULL;
|
1153
|
+
out->opts->str_rx.tail = NULL;
|
1154
|
+
if (escape_html) {
|
1155
|
+
out->opts->escape_mode = JXEsc;
|
1156
|
+
} else {
|
1157
|
+
out->opts->escape_mode = RailsEsc;
|
1158
|
+
}
|
1159
|
+
dump_rails_val(obj, depth, out, true);
|
1160
|
+
}
|
@@ -1,10 +1,10 @@
|
|
1
|
-
/*
|
1
|
+
/* rails.h
|
2
2
|
* Copyright (c) 2017, Peter Ohler
|
3
3
|
* All rights reserved.
|
4
4
|
*/
|
5
5
|
|
6
|
-
#ifndef
|
7
|
-
#define
|
6
|
+
#ifndef __OJ_RAILS_H__
|
7
|
+
#define __OJ_RAILS_H__
|
8
8
|
|
9
9
|
#include "dump.h"
|
10
10
|
|
@@ -14,4 +14,4 @@ extern ROpt oj_rails_get_opt(ROptTable rot, VALUE clas);
|
|
14
14
|
extern bool oj_rails_hash_opt;
|
15
15
|
extern bool oj_rails_array_opt;
|
16
16
|
|
17
|
-
#endif /*
|
17
|
+
#endif /* __OJ_RAILS_H__ */
|
data/lib/oj/version.rb
CHANGED
data/pages/Rails.md
CHANGED
@@ -40,12 +40,15 @@ specific to Oj such as the :circular option which it used to detect circular
|
|
40
40
|
references while encoding.
|
41
41
|
|
42
42
|
By default Oj acts like the ActiveSupport encoder and honors any changes in
|
43
|
-
the as_json() methods. There are
|
43
|
+
the as_json() methods. There are some optimized Oj encoders for some
|
44
44
|
classes. When the optimized encoder it toggled the as_json() methods will not
|
45
45
|
be called for that class but instead the optimized version will be called. The
|
46
46
|
optimized version is the same as the ActiveSupport default encoding for a
|
47
47
|
given class. The optimized versions are toggled with the optimize() and
|
48
|
-
deoptimize() methods.
|
48
|
+
deoptimize() methods. There is a default optimized version for every class
|
49
|
+
that takes the visible attributes and encodes them but that may not be the
|
50
|
+
same as what Rails uses. Trial an error is the best approach for classes not
|
51
|
+
listed here.
|
49
52
|
|
50
53
|
The classes that can be put in optimized mode are:
|
51
54
|
|
@@ -76,8 +76,11 @@ class TestJSONDecoding < ActiveSupport::TestCase
|
|
76
76
|
prev = ActiveSupport.parse_json_times
|
77
77
|
ActiveSupport.parse_json_times = true
|
78
78
|
silence_warnings do
|
79
|
-
|
80
|
-
|
79
|
+
if expected.nil?
|
80
|
+
assert_nil ActiveSupport::JSON.decode(json), "JSON decoding failed for #{json}"
|
81
|
+
else
|
82
|
+
assert_equal expected, ActiveSupport::JSON.decode(json), "JSON decoding failed for #{json}"
|
83
|
+
end
|
81
84
|
end
|
82
85
|
ActiveSupport.parse_json_times = prev
|
83
86
|
end
|
@@ -421,7 +421,7 @@ class TestJSONEncoding < ActiveSupport::TestCase
|
|
421
421
|
end
|
422
422
|
|
423
423
|
def test_nil_true_and_false_represented_as_themselves
|
424
|
-
|
424
|
+
assert_nil(nil.as_json)
|
425
425
|
assert_equal true, true.as_json
|
426
426
|
assert_equal false, false.as_json
|
427
427
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oj
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Ohler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-04-
|
11
|
+
date: 2017-04-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -85,7 +85,6 @@ files:
|
|
85
85
|
- ext/oj/dump_compat.c
|
86
86
|
- ext/oj/dump_leaf.c
|
87
87
|
- ext/oj/dump_object.c
|
88
|
-
- ext/oj/dump_rails.c
|
89
88
|
- ext/oj/dump_strict.c
|
90
89
|
- ext/oj/encode.h
|
91
90
|
- ext/oj/err.c
|
@@ -96,8 +95,6 @@ files:
|
|
96
95
|
- ext/oj/hash.h
|
97
96
|
- ext/oj/hash_test.c
|
98
97
|
- ext/oj/mimic_json.c
|
99
|
-
- ext/oj/mimic_rails.c
|
100
|
-
- ext/oj/mimic_rails.h
|
101
98
|
- ext/oj/object.c
|
102
99
|
- ext/oj/odd.c
|
103
100
|
- ext/oj/odd.h
|
@@ -105,6 +102,8 @@ files:
|
|
105
102
|
- ext/oj/oj.h
|
106
103
|
- ext/oj/parse.c
|
107
104
|
- ext/oj/parse.h
|
105
|
+
- ext/oj/rails.c
|
106
|
+
- ext/oj/rails.h
|
108
107
|
- ext/oj/reader.c
|
109
108
|
- ext/oj/reader.h
|
110
109
|
- ext/oj/resolve.c
|
data/ext/oj/dump_rails.c
DELETED
@@ -1,329 +0,0 @@
|
|
1
|
-
/* dump_object.c
|
2
|
-
* Copyright (c) 2012, 2017, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
5
|
-
|
6
|
-
#include "dump.h"
|
7
|
-
#include "encode.h"
|
8
|
-
#include "mimic_rails.h"
|
9
|
-
|
10
|
-
#define OJ_INFINITY (1.0/0.0)
|
11
|
-
|
12
|
-
bool oj_rails_hash_opt = false;
|
13
|
-
bool oj_rails_array_opt = false;
|
14
|
-
|
15
|
-
static void
|
16
|
-
dump_as_json(VALUE obj, int depth, Out out, bool as_ok) {
|
17
|
-
volatile VALUE ja;
|
18
|
-
|
19
|
-
if (0 < out->argc) {
|
20
|
-
ja = rb_funcall2(obj, oj_as_json_id, out->argc, out->argv);
|
21
|
-
} else {
|
22
|
-
ja = rb_funcall(obj, oj_as_json_id, 0);
|
23
|
-
}
|
24
|
-
if (ja == obj || !as_ok) {
|
25
|
-
// Once as_json is call it should never be called again on the same
|
26
|
-
// object with as_ok.
|
27
|
-
oj_dump_rails_val(ja, depth, out, false);
|
28
|
-
} else {
|
29
|
-
int type = rb_type(ja);
|
30
|
-
|
31
|
-
if (T_HASH == type || T_ARRAY == type) {
|
32
|
-
oj_dump_rails_val(ja, depth, out, false);
|
33
|
-
} else {
|
34
|
-
oj_dump_rails_val(ja, depth, out, true);
|
35
|
-
}
|
36
|
-
}
|
37
|
-
}
|
38
|
-
|
39
|
-
static void
|
40
|
-
dump_to_hash(VALUE obj, int depth, Out out) {
|
41
|
-
oj_dump_rails_val(rb_funcall(obj, oj_to_hash_id, 0), depth, out, false);
|
42
|
-
}
|
43
|
-
|
44
|
-
static void
|
45
|
-
dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
46
|
-
char buf[64];
|
47
|
-
char *b;
|
48
|
-
double d = rb_num2dbl(obj);
|
49
|
-
int cnt = 0;
|
50
|
-
|
51
|
-
if (0.0 == d) {
|
52
|
-
b = buf;
|
53
|
-
*b++ = '0';
|
54
|
-
*b++ = '.';
|
55
|
-
*b++ = '0';
|
56
|
-
*b++ = '\0';
|
57
|
-
cnt = 3;
|
58
|
-
} else {
|
59
|
-
if (isnan(d) || OJ_INFINITY == d || -OJ_INFINITY == d) {
|
60
|
-
strcpy(buf, "null");
|
61
|
-
cnt = 4;
|
62
|
-
} else if (d == (double)(long long int)d) {
|
63
|
-
cnt = snprintf(buf, sizeof(buf), "%.1f", d);
|
64
|
-
} else {
|
65
|
-
cnt = snprintf(buf, sizeof(buf), "%0.16g", d);
|
66
|
-
}
|
67
|
-
}
|
68
|
-
assure_size(out, cnt);
|
69
|
-
for (b = buf; '\0' != *b; b++) {
|
70
|
-
*out->cur++ = *b;
|
71
|
-
}
|
72
|
-
*out->cur = '\0';
|
73
|
-
}
|
74
|
-
|
75
|
-
static void
|
76
|
-
dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
77
|
-
size_t size;
|
78
|
-
int i, cnt;
|
79
|
-
int d2 = depth + 1;
|
80
|
-
|
81
|
-
if (Yes == out->opts->circular) {
|
82
|
-
if (0 > oj_check_circular(a, out)) {
|
83
|
-
oj_dump_nil(Qnil, 0, out, false);
|
84
|
-
return;
|
85
|
-
}
|
86
|
-
}
|
87
|
-
if (as_ok && !oj_rails_array_opt && rb_respond_to(a, oj_as_json_id)) {
|
88
|
-
dump_as_json(a, depth, out, false);
|
89
|
-
return;
|
90
|
-
}
|
91
|
-
cnt = (int)RARRAY_LEN(a);
|
92
|
-
*out->cur++ = '[';
|
93
|
-
size = 2;
|
94
|
-
assure_size(out, size);
|
95
|
-
if (0 == cnt) {
|
96
|
-
*out->cur++ = ']';
|
97
|
-
} else {
|
98
|
-
if (out->opts->dump_opts.use) {
|
99
|
-
size = d2 * out->opts->dump_opts.indent_size + out->opts->dump_opts.array_size + 1;
|
100
|
-
} else {
|
101
|
-
size = d2 * out->indent + 2;
|
102
|
-
}
|
103
|
-
cnt--;
|
104
|
-
for (i = 0; i <= cnt; i++) {
|
105
|
-
assure_size(out, size);
|
106
|
-
if (out->opts->dump_opts.use) {
|
107
|
-
if (0 < out->opts->dump_opts.array_size) {
|
108
|
-
strcpy(out->cur, out->opts->dump_opts.array_nl);
|
109
|
-
out->cur += out->opts->dump_opts.array_size;
|
110
|
-
}
|
111
|
-
if (0 < out->opts->dump_opts.indent_size) {
|
112
|
-
int i;
|
113
|
-
for (i = d2; 0 < i; i--) {
|
114
|
-
strcpy(out->cur, out->opts->dump_opts.indent_str);
|
115
|
-
out->cur += out->opts->dump_opts.indent_size;
|
116
|
-
}
|
117
|
-
}
|
118
|
-
} else {
|
119
|
-
fill_indent(out, d2);
|
120
|
-
}
|
121
|
-
oj_dump_rails_val(rb_ary_entry(a, i), d2, out, as_ok);
|
122
|
-
if (i < cnt) {
|
123
|
-
*out->cur++ = ',';
|
124
|
-
}
|
125
|
-
}
|
126
|
-
size = depth * out->indent + 1;
|
127
|
-
assure_size(out, size);
|
128
|
-
if (out->opts->dump_opts.use) {
|
129
|
-
if (0 < out->opts->dump_opts.array_size) {
|
130
|
-
strcpy(out->cur, out->opts->dump_opts.array_nl);
|
131
|
-
out->cur += out->opts->dump_opts.array_size;
|
132
|
-
}
|
133
|
-
if (0 < out->opts->dump_opts.indent_size) {
|
134
|
-
int i;
|
135
|
-
|
136
|
-
for (i = depth; 0 < i; i--) {
|
137
|
-
strcpy(out->cur, out->opts->dump_opts.indent_str);
|
138
|
-
out->cur += out->opts->dump_opts.indent_size;
|
139
|
-
}
|
140
|
-
}
|
141
|
-
} else {
|
142
|
-
fill_indent(out, depth);
|
143
|
-
}
|
144
|
-
*out->cur++ = ']';
|
145
|
-
}
|
146
|
-
*out->cur = '\0';
|
147
|
-
}
|
148
|
-
|
149
|
-
static int
|
150
|
-
hash_cb(VALUE key, VALUE value, Out out) {
|
151
|
-
int depth = out->depth;
|
152
|
-
long size;
|
153
|
-
int rtype = rb_type(key);
|
154
|
-
|
155
|
-
if (rtype != T_STRING && rtype != T_SYMBOL) {
|
156
|
-
key = rb_funcall(key, oj_to_s_id, 0);
|
157
|
-
rtype = rb_type(key);
|
158
|
-
}
|
159
|
-
if (!out->opts->dump_opts.use) {
|
160
|
-
size = depth * out->indent + 1;
|
161
|
-
assure_size(out, size);
|
162
|
-
fill_indent(out, depth);
|
163
|
-
if (rtype == T_STRING) {
|
164
|
-
oj_dump_str(key, 0, out, false);
|
165
|
-
} else {
|
166
|
-
oj_dump_sym(key, 0, out, false);
|
167
|
-
}
|
168
|
-
*out->cur++ = ':';
|
169
|
-
} else {
|
170
|
-
size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
|
171
|
-
assure_size(out, size);
|
172
|
-
if (0 < out->opts->dump_opts.hash_size) {
|
173
|
-
strcpy(out->cur, out->opts->dump_opts.hash_nl);
|
174
|
-
out->cur += out->opts->dump_opts.hash_size;
|
175
|
-
}
|
176
|
-
if (0 < out->opts->dump_opts.indent_size) {
|
177
|
-
int i;
|
178
|
-
for (i = depth; 0 < i; i--) {
|
179
|
-
strcpy(out->cur, out->opts->dump_opts.indent_str);
|
180
|
-
out->cur += out->opts->dump_opts.indent_size;
|
181
|
-
}
|
182
|
-
}
|
183
|
-
if (rtype == T_STRING) {
|
184
|
-
oj_dump_str(key, 0, out, false);
|
185
|
-
} else {
|
186
|
-
oj_dump_sym(key, 0, out, false);
|
187
|
-
}
|
188
|
-
size = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
|
189
|
-
assure_size(out, size);
|
190
|
-
if (0 < out->opts->dump_opts.before_size) {
|
191
|
-
strcpy(out->cur, out->opts->dump_opts.before_sep);
|
192
|
-
out->cur += out->opts->dump_opts.before_size;
|
193
|
-
}
|
194
|
-
*out->cur++ = ':';
|
195
|
-
if (0 < out->opts->dump_opts.after_size) {
|
196
|
-
strcpy(out->cur, out->opts->dump_opts.after_sep);
|
197
|
-
out->cur += out->opts->dump_opts.after_size;
|
198
|
-
}
|
199
|
-
}
|
200
|
-
oj_dump_rails_val(value, depth, out, false);
|
201
|
-
out->depth = depth;
|
202
|
-
*out->cur++ = ',';
|
203
|
-
|
204
|
-
return ST_CONTINUE;
|
205
|
-
}
|
206
|
-
|
207
|
-
static void
|
208
|
-
dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
|
209
|
-
int cnt;
|
210
|
-
size_t size;
|
211
|
-
|
212
|
-
if (Yes == out->opts->circular) {
|
213
|
-
if (0 > oj_check_circular(obj, out)) {
|
214
|
-
oj_dump_nil(Qnil, 0, out, false);
|
215
|
-
return;
|
216
|
-
}
|
217
|
-
}
|
218
|
-
if (as_ok && !oj_rails_hash_opt && rb_respond_to(obj, oj_as_json_id)) {
|
219
|
-
dump_as_json(obj, depth, out, false);
|
220
|
-
return;
|
221
|
-
}
|
222
|
-
cnt = (int)RHASH_SIZE(obj);
|
223
|
-
size = depth * out->indent + 2;
|
224
|
-
assure_size(out, 2);
|
225
|
-
*out->cur++ = '{';
|
226
|
-
if (0 == cnt) {
|
227
|
-
*out->cur++ = '}';
|
228
|
-
} else {
|
229
|
-
out->depth = depth + 1;
|
230
|
-
rb_hash_foreach(obj, hash_cb, (VALUE)out);
|
231
|
-
if (',' == *(out->cur - 1)) {
|
232
|
-
out->cur--; // backup to overwrite last comma
|
233
|
-
}
|
234
|
-
if (!out->opts->dump_opts.use) {
|
235
|
-
assure_size(out, size);
|
236
|
-
fill_indent(out, depth);
|
237
|
-
} else {
|
238
|
-
size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
|
239
|
-
assure_size(out, size);
|
240
|
-
if (0 < out->opts->dump_opts.hash_size) {
|
241
|
-
strcpy(out->cur, out->opts->dump_opts.hash_nl);
|
242
|
-
out->cur += out->opts->dump_opts.hash_size;
|
243
|
-
}
|
244
|
-
if (0 < out->opts->dump_opts.indent_size) {
|
245
|
-
int i;
|
246
|
-
|
247
|
-
for (i = depth; 0 < i; i--) {
|
248
|
-
strcpy(out->cur, out->opts->dump_opts.indent_str);
|
249
|
-
out->cur += out->opts->dump_opts.indent_size;
|
250
|
-
}
|
251
|
-
}
|
252
|
-
}
|
253
|
-
*out->cur++ = '}';
|
254
|
-
}
|
255
|
-
*out->cur = '\0';
|
256
|
-
}
|
257
|
-
|
258
|
-
static void
|
259
|
-
dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
|
260
|
-
if (as_ok) {
|
261
|
-
ROpt ro;
|
262
|
-
|
263
|
-
if (NULL != (ro = oj_rails_get_opt(out->ropts, rb_obj_class(obj))) && ro->on) {
|
264
|
-
ro->dump(obj, depth, out, as_ok);
|
265
|
-
} else if (rb_respond_to(obj, oj_as_json_id)) {
|
266
|
-
dump_as_json(obj, depth, out, true);
|
267
|
-
} else if (rb_respond_to(obj, oj_to_hash_id)) {
|
268
|
-
dump_to_hash(obj, depth, out);
|
269
|
-
} else {
|
270
|
-
oj_dump_obj_to_s(obj, out);
|
271
|
-
}
|
272
|
-
} else if (rb_respond_to(obj, oj_to_hash_id)) {
|
273
|
-
// Always attempt to_hash.
|
274
|
-
dump_to_hash(obj, depth, out);
|
275
|
-
} else {
|
276
|
-
oj_dump_obj_to_s(obj, out);
|
277
|
-
}
|
278
|
-
}
|
279
|
-
|
280
|
-
static void
|
281
|
-
dump_as_string(VALUE obj, int depth, Out out, bool as_ok) {
|
282
|
-
oj_dump_obj_to_s(obj, out);
|
283
|
-
}
|
284
|
-
|
285
|
-
static DumpFunc rails_funcs[] = {
|
286
|
-
NULL, // RUBY_T_NONE = 0x00,
|
287
|
-
dump_obj, // RUBY_T_OBJECT = 0x01,
|
288
|
-
oj_dump_class, // RUBY_T_CLASS = 0x02,
|
289
|
-
oj_dump_class, // RUBY_T_MODULE = 0x03,
|
290
|
-
dump_float, // RUBY_T_FLOAT = 0x04,
|
291
|
-
oj_dump_str, // RUBY_T_STRING = 0x05,
|
292
|
-
dump_as_string, // RUBY_T_REGEXP = 0x06,
|
293
|
-
dump_array, // RUBY_T_ARRAY = 0x07,
|
294
|
-
dump_hash, // RUBY_T_HASH = 0x08,
|
295
|
-
dump_obj, // RUBY_T_STRUCT = 0x09,
|
296
|
-
oj_dump_bignum, // RUBY_T_BIGNUM = 0x0a,
|
297
|
-
NULL, // RUBY_T_FILE = 0x0b,
|
298
|
-
dump_obj, // RUBY_T_DATA = 0x0c,
|
299
|
-
NULL, // RUBY_T_MATCH = 0x0d,
|
300
|
-
// Rails raises a stack error on Complex and Rational. It also corrupts
|
301
|
-
// something whic causes a segfault on the next call. Oj will not mimic
|
302
|
-
// that behavior.
|
303
|
-
dump_as_string, // RUBY_T_COMPLEX = 0x0e,
|
304
|
-
dump_as_string, // RUBY_T_RATIONAL = 0x0f,
|
305
|
-
NULL, // 0x10
|
306
|
-
oj_dump_nil, // RUBY_T_NIL = 0x11,
|
307
|
-
oj_dump_true, // RUBY_T_TRUE = 0x12,
|
308
|
-
oj_dump_false, // RUBY_T_FALSE = 0x13,
|
309
|
-
oj_dump_sym, // RUBY_T_SYMBOL = 0x14,
|
310
|
-
oj_dump_fixnum, // RUBY_T_FIXNUM = 0x15,
|
311
|
-
};
|
312
|
-
|
313
|
-
void
|
314
|
-
oj_dump_rails_val(VALUE obj, int depth, Out out, bool as_ok) {
|
315
|
-
int type = rb_type(obj);
|
316
|
-
|
317
|
-
if (MAX_DEPTH < depth) {
|
318
|
-
rb_raise(rb_eNoMemError, "Too deeply nested.\n");
|
319
|
-
}
|
320
|
-
if (0 < type && type <= RUBY_T_FIXNUM) {
|
321
|
-
DumpFunc f = rails_funcs[type];
|
322
|
-
|
323
|
-
if (NULL != f) {
|
324
|
-
f(obj, depth, out, as_ok);
|
325
|
-
return;
|
326
|
-
}
|
327
|
-
}
|
328
|
-
oj_dump_nil(Qnil, depth, out, false);
|
329
|
-
}
|