oj 3.0.2 → 3.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
}
|