Class: Oj::Rails::Encoder
- Inherits:
-
Object
- Object
- Oj::Rails::Encoder
- Defined in:
- ext/oj/rails.c,
ext/oj/rails.c
Overview
The Oj ActiveSupport compliant encoder.
Class Method Summary collapse
Instance Method Summary collapse
- #deoptimize(*args) ⇒ Object
- #encode(obj) ⇒ Object
- #optimize(*args) ⇒ Object
- #optimized?(clas) ⇒ Object
Class Method Details
.new(*args) ⇒ Object
754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 |
# File 'ext/oj/rails.c', line 754
static VALUE encoder_new(int argc, VALUE *argv, VALUE self) {
Encoder e = OJ_R_ALLOC(struct _encoder);
e->ropts.len = 0;
e->ropts.alen = 0;
e->ropts.table = NULL;
e->own_ropts = false;
if (1 <= argc && Qnil != *argv) {
e->arg = *argv;
} else {
e->arg = rb_hash_new();
}
// An encoder given no options of its own reads oj_default_options at encode
// time rather than copying it here. ActiveSupport keeps such an encoder for
// the life of the process, so a copy taken now would freeze every later
// Oj.default_options and ActiveSupport::JSON::Encoding change out of it -
// including the time_precision that set_encoder itself writes after
// ActiveSupport has already built and cached that encoder.
//
// A hash counts as options only if at least one key names an option Oj
// knows. Non-empty is not enough: ActiveSupport 8.1 caches a second encoder
// built with {escape: false}, a key Oj has never had.
e->own_opts = T_HASH == rb_type(e->arg) && 0 < RHASH_SIZE(e->arg);
if (e->own_opts) {
e->opts = oj_default_options;
// Detach from the match_string regexps owned by the defaults before the
// options are parsed so that a :match_string option builds a chain of
// its own that is freed with the encoder.
e->opts.str_rx.head = NULL;
e->opts.str_rx.tail = NULL;
e->own_opts = oj_parse_options_consumed(e->arg, &e->opts);
}
if (e->own_opts) {
oj_options_take_ownership(&e->opts);
} else {
// Nothing to free: every option that allocates is reached through a
// recognized key, and ownership is not taken until after that check.
memset(&e->opts, 0, sizeof(e->opts));
}
return TypedData_Wrap_Struct(encoder_class, &oj_encoder_type, e);
}
|
Instance Method Details
#deoptimize(*args) ⇒ Object
943 944 945 946 947 948 949 950 |
# File 'ext/oj/rails.c', line 943
static VALUE encoder_deoptimize(int argc, VALUE *argv, VALUE self) {
Encoder e;
TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
optimize(argc, argv, encoder_own_ropts(e), false);
return Qnil;
}
|
#encode(obj) ⇒ Object
1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 |
# File 'ext/oj/rails.c', line 1082
static VALUE encoder_encode(VALUE self, VALUE obj) {
Encoder e;
TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
if (Qnil != e->arg) {
// as_json is allowed to write into the options hash it is handed, and
// the ActiveSupport suite has a test that does exactly that. Handing
// out the encoder's own hash lets one such call poison every later
// encode by the same encoder, which on ActiveSupport 8.1 is every
// option-less to_json in the process because json_encoder= caches one
// encoder and keeps it. Rails never exposes a hash it will reuse:
// JSONGemEncoder#encode passes options.dup, and only when there are
// options at all, so with none as_json writes into its own default.
// The copy is not frozen the way Rails 8.0 and later freeze theirs,
// because Oj hands as_json the hash even when it is empty and that is
// exactly the case Rails leaves writable.
VALUE argv[1] = {T_HASH == rb_type(e->arg) ? rb_hash_dup(e->arg) : e->arg};
return encode(obj, encoder_ropts(e), encoder_opts(e), 1, argv);
}
return encode(obj, encoder_ropts(e), encoder_opts(e), 0, NULL);
}
|
#optimize(*args) ⇒ Object
886 887 888 889 890 891 892 893 |
# File 'ext/oj/rails.c', line 886
static VALUE encoder_optimize(int argc, VALUE *argv, VALUE self) {
Encoder e;
TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
optimize(argc, argv, encoder_own_ropts(e), true);
return Qnil;
}
|
#optimized?(clas) ⇒ Object
973 974 975 976 977 978 979 980 981 982 983 984 |
# File 'ext/oj/rails.c', line 973
static VALUE encoder_optimized(VALUE self, VALUE clas) {
Encoder e;
ROpt ro;
TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
ro = oj_rails_get_opt(encoder_ropts(e), clas);
if (NULL == ro) {
return Qfalse;
}
return (ro->on) ? Qtrue : Qfalse;
}
|