module JSON
A mimic of the json gem module.
Constants
- FAST_STATE_PROTOTYPE
- Infinity
- MinusInfinity
- NaN
- PRETTY_STATE_PROTOTYPE
Taken from the unit test. Note that items like check_circular? are not present.
- Parser
- SAFE_STATE_PROTOTYPE
- State
Public Class Methods
If the obj argument is a String then it is assumed to be a JSON String and parsed otherwise the obj is encoded as a JSON String.
-
obj [String|Hash|Array] object to convert
-
opts [Hash] same options as either generate or parse
Returns [Object]
static VALUE
mimic_dump_load(int argc, VALUE *argv, VALUE self) {
if (1 > argc) {
rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
} else if (T_STRING == rb_type(*argv)) {
return mimic_load(argc, argv, self);
} else {
return mimic_dump(argc, argv, self);
}
return Qnil;
}
Returns [String] the create_id.
static VALUE
mimic_create_id(VALUE self) {
if (NULL != oj_default_options.create_id) {
return oj_encode(rb_str_new_cstr(oj_default_options.create_id));
}
return rb_str_new_cstr(oj_json_class);
}
Sets the ::create_id tag to look for in JSON document. That key triggers the creation of a class with the same name.
-
id [nil|String] new ::create_id
Returns [String] the id.
static VALUE
mimic_set_create_id(VALUE self, VALUE id) {
Check_Type(id, T_STRING);
if (NULL != oj_default_options.create_id) {
if (oj_json_class != oj_default_options.create_id && NULL != oj_default_options.create_id) {
xfree((char*)oj_default_options.create_id);
}
oj_default_options.create_id = NULL;
oj_default_options.create_id_len = 0;
}
if (Qnil != id) {
size_t len = RSTRING_LEN(id) + 1;
oj_default_options.create_id = ALLOC_N(char, len);
strcpy((char*)oj_default_options.create_id, StringValuePtr(id));
oj_default_options.create_id_len = len - 1;
}
return id;
}
Encodes an object as a JSON String.
-
obj [Object] object to convert to encode as JSON
-
anIO [IO] an IO that allows writing
-
limit [Fixnum] ignored
Returns [String] a JSON string.
static VALUE
mimic_dump(int argc, VALUE *argv, VALUE self) {
char buf[4096];
struct _Out out;
struct _Options copts = oj_default_options;
VALUE rstr;
copts.str_rx.head = NULL;
copts.str_rx.tail = NULL;
out.buf = buf;
out.end = buf + sizeof(buf) - 10;
out.allocated = false;
out.caller = CALLER_DUMP;
copts.escape_mode = JXEsc;
copts.mode = CompatMode;
/* seems like this is not correct
if (No == copts.nilnil && Qnil == *argv) {
rb_raise(rb_eTypeError, "nil not allowed.");
}
*/
copts.dump_opts.max_depth = MAX_DEPTH; // when using dump there is no limit
out.omit_nil = copts.dump_opts.omit_nil;
if (2 <= argc) {
int limit;
// The json gem take a more liberal approach to optional
// arguments. Expected are (obj, anIO=nil, limit=nil) yet the io
// argument can be left off completely and the 2nd argument is then
// the limit.
if (0 <= (limit = mimic_limit_arg(argv[1]))) {
copts.dump_opts.max_depth = limit;
}
if (3 <= argc && 0 <= (limit = mimic_limit_arg(argv[2]))) {
copts.dump_opts.max_depth = limit;
}
}
oj_dump_obj_to_json(*argv, &copts, &out);
if (0 == out.buf) {
rb_raise(rb_eNoMemError, "Not enough memory.");
}
rstr = rb_str_new2(out.buf);
rstr = oj_encode(rstr);
if (2 <= argc && Qnil != argv[1] && rb_respond_to(argv[1], oj_write_id)) {
VALUE io = argv[1];
VALUE args[1];
*args = rstr;
rb_funcall2(io, oj_write_id, 1, args);
rstr = io;
}
if (out.allocated) {
xfree(out.buf);
}
return rstr;
}
# File lib/oj/json.rb, line 48 def self.dump_default_options Oj::MimicDumpOption.new end
# File lib/oj/json.rb, line 52 def self.dump_default_options=(h) m = Oj::MimicDumpOption.new h.each do |k,v| m[k] = v end end
VALUE
oj_mimic_generate(int argc, VALUE *argv, VALUE self) {
struct _Options copts = oj_default_options;
copts.str_rx.head = NULL;
copts.str_rx.tail = NULL;
return mimic_generate_core(argc, argv, &copts);
}
Encode obj as a JSON String. The obj argument must be a Hash, Array, or
respond to to_h or to_json. Options
other than those listed such as :allow_nan or
:max_nesting are ignored.
-
opts [Hash] options
-
:indent [String] String to use for indentation.
-
:space [String] String placed after a , or : delimiter
-
:space_before [String] String placed before a : delimiter
-
:ascii_only [Boolean] if not nil or false then use only ascii characters in the output. Note ::generate does support this even if it is not documented.
-
Returns [String] generated JSON.
VALUE
oj_mimic_generate(int argc, VALUE *argv, VALUE self) {
struct _Options copts = oj_default_options;
copts.str_rx.head = NULL;
copts.str_rx.tail = NULL;
return mimic_generate_core(argc, argv, &copts);
}
Encode obj as a JSON String. The obj argument must be a Hash, Array, or
respond to to_h or to_json. Options
other than those listed such as :allow_nan or
:max_nesting are ignored.
-
opts [Hash] options
-
:indent [String] String to use for indentation.
-
:space [String] String placed after a , or : delimiter
-
:space_before [String] String placed before a : delimiter
-
:ascii_only [Boolean] if not nil or false then use only ascii characters in the output. Note ::generate does support this even if it is not documented.
-
Returns [String] generated JSON.
VALUE
oj_mimic_generate(int argc, VALUE *argv, VALUE self) {
struct _Options copts = oj_default_options;
copts.str_rx.head = NULL;
copts.str_rx.tail = NULL;
return mimic_generate_core(argc, argv, &copts);
}
# File lib/oj/json.rb, line 71 def self.generator() @@generator end
# File lib/oj/json.rb, line 67 def self.generator=(g) @@generator = g end
Loads a Ruby Object from a JSON source that can be either a String or an IO. If Proc is given or a block is providedit is called with each nested element of the loaded Object.
-
source [String|IO] JSON source
-
proc [Proc] to yield to on each element or nil
Returns [Object] the decode Object.
static VALUE
mimic_load(int argc, VALUE *argv, VALUE self) {
VALUE obj;
VALUE p = Qnil;
obj = oj_compat_parse(argc, argv, self);
if (2 <= argc) {
if (rb_cProc == rb_obj_class(argv[1])) {
p = argv[1];
} else if (3 <= argc) {
if (rb_cProc == rb_obj_class(argv[2])) {
p = argv[2];
}
}
}
mimic_walk(Qnil, obj, p);
return obj;
}
Parses a JSON String or
IO into a Ruby Object. Options other than those listed such as
:allow_nan or :max_nesting are ignored.
:object_class and :array_object are not
supported.
-
source [String|IO] source to parse
-
opts [Hash] options
Returns [Object] @see ::create_id=
VALUE
oj_mimic_parse(int argc, VALUE *argv, VALUE self) {
return mimic_parse_core(argc, argv, self, false);
}
Same as parse(). @see parse
static VALUE
mimic_parse_bang(int argc, VALUE *argv, VALUE self) {
return mimic_parse_core(argc, argv, self, true);
}
# File lib/oj/json.rb, line 63 def self.parser() @@parser end
# File lib/oj/json.rb, line 59 def self.parser=(p) @@parser = p end
Same as generate() but with different defaults for the spacing options. @see generate
Return [String] the generated JSON.
VALUE
oj_mimic_pretty_generate(int argc, VALUE *argv, VALUE self) {
struct _Options copts = oj_default_options;
VALUE rargs[2];
volatile VALUE h;
// Some (all?) json gem to_json methods need a State instance and not just
// a Hash. I haven't dug deep enough to find out why but using a State
// instance and not a Hash gives the desired behavior.
*rargs = *argv;
if (1 == argc) {
h = rb_hash_new();
} else {
h = argv[1];
}
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_indent_sym)) {
rb_hash_aset(h, oj_indent_sym, rb_str_new2(" "));
}
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_space_before_sym)) {
rb_hash_aset(h, oj_space_before_sym, rb_str_new2(""));
}
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_space_sym)) {
rb_hash_aset(h, oj_space_sym, rb_str_new2(" "));
}
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_object_nl_sym)) {
rb_hash_aset(h, oj_object_nl_sym, rb_str_new2("\n"));
}
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_array_nl_sym)) {
rb_hash_aset(h, oj_array_nl_sym, rb_str_new2("\n"));
}
rargs[1] = rb_funcall(state_class, oj_new_id, 1, h);
copts.str_rx.head = NULL;
copts.str_rx.tail = NULL;
strcpy(copts.dump_opts.indent_str, " ");
copts.dump_opts.indent_size = (uint8_t)strlen(copts.dump_opts.indent_str);
strcpy(copts.dump_opts.before_sep, "");
copts.dump_opts.before_size = (uint8_t)strlen(copts.dump_opts.before_sep);
strcpy(copts.dump_opts.after_sep, " ");
copts.dump_opts.after_size = (uint8_t)strlen(copts.dump_opts.after_sep);
strcpy(copts.dump_opts.hash_nl, "\n");
copts.dump_opts.hash_size = (uint8_t)strlen(copts.dump_opts.hash_nl);
strcpy(copts.dump_opts.array_nl, "\n");
copts.dump_opts.array_size = (uint8_t)strlen(copts.dump_opts.array_nl);
copts.dump_opts.use = true;
return mimic_generate_core(2, rargs, &copts);
}
Same as generate() but with different defaults for the spacing options. @see generate
Return [String] the generated JSON.
VALUE
oj_mimic_pretty_generate(int argc, VALUE *argv, VALUE self) {
struct _Options copts = oj_default_options;
VALUE rargs[2];
volatile VALUE h;
// Some (all?) json gem to_json methods need a State instance and not just
// a Hash. I haven't dug deep enough to find out why but using a State
// instance and not a Hash gives the desired behavior.
*rargs = *argv;
if (1 == argc) {
h = rb_hash_new();
} else {
h = argv[1];
}
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_indent_sym)) {
rb_hash_aset(h, oj_indent_sym, rb_str_new2(" "));
}
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_space_before_sym)) {
rb_hash_aset(h, oj_space_before_sym, rb_str_new2(""));
}
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_space_sym)) {
rb_hash_aset(h, oj_space_sym, rb_str_new2(" "));
}
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_object_nl_sym)) {
rb_hash_aset(h, oj_object_nl_sym, rb_str_new2("\n"));
}
if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_array_nl_sym)) {
rb_hash_aset(h, oj_array_nl_sym, rb_str_new2("\n"));
}
rargs[1] = rb_funcall(state_class, oj_new_id, 1, h);
copts.str_rx.head = NULL;
copts.str_rx.tail = NULL;
strcpy(copts.dump_opts.indent_str, " ");
copts.dump_opts.indent_size = (uint8_t)strlen(copts.dump_opts.indent_str);
strcpy(copts.dump_opts.before_sep, "");
copts.dump_opts.before_size = (uint8_t)strlen(copts.dump_opts.before_sep);
strcpy(copts.dump_opts.after_sep, " ");
copts.dump_opts.after_size = (uint8_t)strlen(copts.dump_opts.after_sep);
strcpy(copts.dump_opts.hash_nl, "\n");
copts.dump_opts.hash_size = (uint8_t)strlen(copts.dump_opts.hash_nl);
strcpy(copts.dump_opts.array_nl, "\n");
copts.dump_opts.array_size = (uint8_t)strlen(copts.dump_opts.array_nl);
copts.dump_opts.use = true;
return mimic_generate_core(2, rargs, &copts);
}
Yields to the proc for every element in the obj recursivly.
-
obj [Hash|Array] object to walk
-
proc [Proc] to yield to on each element
static VALUE
mimic_recurse_proc(VALUE self, VALUE obj) {
rb_need_block();
mimic_walk(Qnil, obj, Qnil);
return Qnil;
}
Loads a Ruby Object from a JSON source that can be either a String or an IO. If Proc is given or a block is providedit is called with each nested element of the loaded Object.
-
source [String|IO] JSON source
-
proc [Proc] to yield to on each element or nil
Returns [Object] the decoded Object.
static VALUE
mimic_load(int argc, VALUE *argv, VALUE self) {
VALUE obj;
VALUE p = Qnil;
obj = oj_compat_parse(argc, argv, self);
if (2 <= argc) {
if (rb_cProc == rb_obj_class(argv[1])) {
p = argv[1];
} else if (3 <= argc) {
if (rb_cProc == rb_obj_class(argv[2])) {
p = argv[2];
}
}
}
mimic_walk(Qnil, obj, p);
return obj;
}
Returns [JSON::State] the JSON::State class.
static VALUE
mimic_state(VALUE self) {
return state_class;
}
Encode obj as a JSON String. The obj argument must be a Hash, Array, or
respond to to_h or to_json. Options
other than those listed such as :allow_nan or
:max_nesting are ignored.
-
opts [Hash] options
-
:indent [String] String to use for indentation.
-
:space [String] String placed after a , or : delimiter
-
:space_before [String] String placed before a : delimiter
-
:ascii_only [Boolean] if not nil or false then use only ascii characters in the output. Note ::generate does support this even if it is not documented.
-
Returns [String] generated JSON.
VALUE
oj_mimic_generate(int argc, VALUE *argv, VALUE self) {
struct _Options copts = oj_default_options;
copts.str_rx.head = NULL;
copts.str_rx.tail = NULL;
return mimic_generate_core(argc, argv, &copts);
}