Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Time fix #810

Merged
merged 3 commits into from
Aug 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 21 additions & 40 deletions ext/oj/custom.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ static void dump_obj_str(VALUE obj, int depth, Out out) {

static void dump_obj_as_str(VALUE obj, int depth, Out out) {
volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
const char * str = RSTRING_PTR(rstr);
const char *str = RSTRING_PTR(rstr);

oj_dump_cstr(str, RSTRING_LEN(rstr), 0, 0, out);
}

static void bigdecimal_dump(VALUE obj, int depth, Out out) {
volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
const char * str = RSTRING_PTR(rstr);
const char *str = RSTRING_PTR(rstr);
int len = (int)RSTRING_LEN(rstr);

if (0 == strcasecmp("Infinity", str)) {
Expand Down Expand Up @@ -82,8 +82,7 @@ static VALUE complex_load(VALUE clas, VALUE args) {
real_id = rb_intern("real");
imag_id = rb_intern("imag");
}
return rb_complex_new(rb_hash_aref(args, rb_id2str(real_id)),
rb_hash_aref(args, rb_id2str(imag_id)));
return rb_complex_new(rb_hash_aref(args, rb_id2str(real_id)), rb_hash_aref(args, rb_id2str(imag_id)));
}

static void time_dump(VALUE obj, int depth, Out out) {
Expand Down Expand Up @@ -246,8 +245,7 @@ static VALUE rational_load(VALUE clas, VALUE args) {
numerator_id = rb_intern("numerator");
denominator_id = rb_intern("denominator");
}
return rb_rational_new(rb_hash_aref(args, rb_id2str(numerator_id)),
rb_hash_aref(args, rb_id2str(denominator_id)));
return rb_rational_new(rb_hash_aref(args, rb_id2str(numerator_id)), rb_hash_aref(args, rb_id2str(denominator_id)));
}

static VALUE regexp_load(VALUE clas, VALUE args) {
Expand Down Expand Up @@ -292,8 +290,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
assure_size(out, depth * out->indent + 1);
fill_indent(out, depth);
} else {
assure_size(out,
depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
assure_size(out, depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
if (0 < out->opts->dump_opts.hash_size) {
APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
}
Expand Down Expand Up @@ -352,9 +349,7 @@ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
assure_size(out, depth * out->indent + 2);
fill_indent(out, depth);
} else {
assure_size(
out,
depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
assure_size(out, depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
if (0 < out->opts->dump_opts.hash_size) {
APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
}
Expand All @@ -372,10 +367,10 @@ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
}

static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
ID * idp;
AttrGetFunc * fp;
ID *idp;
AttrGetFunc *fp;
volatile VALUE v;
const char * name;
const char *name;
size_t size;
int d2 = depth + 1;

Expand All @@ -384,7 +379,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
if (NULL != out->opts->create_id && Yes == out->opts->create_ok) {
const char *classname = rb_class2name(clas);
int clen = (int)strlen(classname);
size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;

size = d2 * out->indent + 10 + clen + out->opts->create_id_len + sep_len;
assure_size(out, size);
Expand Down Expand Up @@ -481,7 +476,7 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
oj_dump_raw_json(obj, depth, out);
} else if (Yes == out->opts->to_json && rb_respond_to(obj, oj_to_json_id)) {
volatile VALUE rs;
const char * s;
const char *s;
int len;

if (RB_UNLIKELY(Yes == out->opts->trace)) {
Expand Down Expand Up @@ -521,11 +516,7 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
if (aj == obj) {
volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);

oj_dump_cstr(RSTRING_PTR(rstr),
(int)RSTRING_LEN(rstr),
false,
false,
out);
oj_dump_cstr(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), false, false, out);
} else {
oj_dump_custom_val(aj, depth, out, true);
}
Expand Down Expand Up @@ -609,7 +600,7 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
assure_size(out, 2);
*out->cur++ = '{';
if (Qundef != clas && NULL != out->opts->create_id && Yes == out->opts->create_ok) {
size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
const char *classname = rb_obj_classname(obj);
size_t len = strlen(classname);

Expand Down Expand Up @@ -911,7 +902,7 @@ void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok) {
///// load functions /////

static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
const char * key = kval->key;
const char *key = kval->key;
int klen = kval->klen;
Val parent = stack_peek(&pi->stack);
volatile VALUE rkey = kval->key_val;
Expand All @@ -928,14 +919,14 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
}
}
} else {
volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
//volatile VALUE rstr = rb_utf8_str_new(str, len);
volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
// volatile VALUE rstr = rb_utf8_str_new(str, len);

if (Qundef == rkey) {
if (Yes == pi->options.sym_key) {
rkey = ID2SYM(rb_intern3(key, klen, oj_utf8_encoding));
} else {
rkey = rb_utf8_str_new(key, klen);
rkey = rb_utf8_str_new(key, klen);
}
}
if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
Expand Down Expand Up @@ -1008,20 +999,10 @@ static void hash_set_num(struct _parseInfo *pi, Val kval, NumInfo ni) {
// match the expected value.
parent->val = rb_funcall2(parent->val, oj_utc_id, 0, 0);
} else if (ni->has_exp) {
int64_t t = (int64_t)(ni->i + ni->exp);
struct _timeInfo ti;
VALUE args[8];

sec_as_time(t, &ti);

args[0] = LONG2NUM(ti.year);
args[1] = LONG2NUM(ti.mon);
args[2] = LONG2NUM(ti.day);
args[3] = LONG2NUM(ti.hour);
args[4] = LONG2NUM(ti.min);
args[5] = rb_float_new((double)ti.sec + ((double)nsec + 0.5) / 1000000000.0);
args[6] = LONG2NUM(ni->exp);
parent->val = rb_funcall2(rb_cTime, oj_new_id, 7, args);
struct timespec ts;
ts.tv_sec = ni->i;
ts.tv_nsec = nsec;
parent->val = rb_time_timespec_new(&ts, ni->exp);
} else {
parent->val = rb_time_nano_new(ni->i, (long)nsec);
}
Expand Down
17 changes: 4 additions & 13 deletions ext/oj/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,19 +269,10 @@ static int hat_num(ParseInfo pi, Val parent, Val kval, NumInfo ni) {
// match the expected value.
parent->val = rb_funcall2(parent->val, oj_utc_id, 0, 0);
} else if (ni->has_exp) {
int64_t t = (int64_t)(ni->i + ni->exp);
struct _timeInfo ti;
VALUE args[8];

sec_as_time(t, &ti);
args[0] = LONG2NUM((long)(ti.year));
args[1] = LONG2NUM(ti.mon);
args[2] = LONG2NUM(ti.day);
args[3] = LONG2NUM(ti.hour);
args[4] = LONG2NUM(ti.min);
args[5] = rb_float_new((double)ti.sec + ((double)nsec + 0.5) / 1000000000.0);
args[6] = LONG2NUM(ni->exp);
parent->val = rb_funcall2(rb_cTime, oj_new_id, 7, args);
struct timespec ts;
ts.tv_sec = ni->i;
ts.tv_nsec = nsec;
parent->val = rb_time_timespec_new(&ts, ni->exp);
} else {
parent->val = rb_time_nano_new(ni->i, (long)nsec);
}
Expand Down
8 changes: 8 additions & 0 deletions ext/oj/oj.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ ID oj_array_append_id;
ID oj_array_end_id;
ID oj_array_start_id;
ID oj_as_json_id;
ID oj_at_id;
ID oj_begin_id;
ID oj_bigdecimal_id;
ID oj_end_id;
Expand Down Expand Up @@ -89,7 +90,9 @@ VALUE oj_array_class_sym;
VALUE oj_create_additions_sym;
VALUE oj_decimal_class_sym;
VALUE oj_hash_class_sym;
VALUE oj_in_sym;
VALUE oj_indent_sym;
VALUE oj_nanosecond_sym;
VALUE oj_object_class_sym;
VALUE oj_quirks_mode_sym;
VALUE oj_safe_sym;
Expand Down Expand Up @@ -1814,6 +1817,7 @@ void Init_oj(void) {
oj_array_end_id = rb_intern("array_end");
oj_array_start_id = rb_intern("array_start");
oj_as_json_id = rb_intern("as_json");
oj_at_id = rb_intern("at");
oj_begin_id = rb_intern("begin");
oj_bigdecimal_id = rb_intern("BigDecimal");
oj_end_id = rb_intern("end");
Expand Down Expand Up @@ -1961,10 +1965,14 @@ void Init_oj(void) {
rb_gc_register_address(&oj_decimal_class_sym);
oj_hash_class_sym = ID2SYM(rb_intern("hash_class"));
rb_gc_register_address(&oj_hash_class_sym);
oj_in_sym = ID2SYM(rb_intern("in"));
rb_gc_register_address(&oj_in_sym);
oj_indent_sym = ID2SYM(rb_intern("indent"));
rb_gc_register_address(&oj_indent_sym);
oj_max_nesting_sym = ID2SYM(rb_intern("max_nesting"));
rb_gc_register_address(&oj_max_nesting_sym);
oj_nanosecond_sym = ID2SYM(rb_intern("nanosecond"));
rb_gc_register_address(&oj_nanosecond_sym);
oj_object_class_sym = ID2SYM(rb_intern("object_class"));
rb_gc_register_address(&oj_object_class_sym);
oj_object_nl_sym = ID2SYM(rb_intern("object_nl"));
Expand Down
3 changes: 3 additions & 0 deletions ext/oj/oj.h
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,9 @@ extern VALUE oj_ascii_only_sym;
extern VALUE oj_create_additions_sym;
extern VALUE oj_decimal_class_sym;
extern VALUE oj_hash_class_sym;
extern VALUE oj_in_sym;
extern VALUE oj_indent_sym;
extern VALUE oj_nanosecond_sym;
extern VALUE oj_max_nesting_sym;
extern VALUE oj_object_class_sym;
extern VALUE oj_object_nl_sym;
Expand All @@ -334,6 +336,7 @@ extern ID oj_array_append_id;
extern ID oj_array_end_id;
extern ID oj_array_start_id;
extern ID oj_as_json_id;
extern ID oj_at_id;
extern ID oj_begin_id;
extern ID oj_bigdecimal_id;
extern ID oj_end_id;
Expand Down
11 changes: 9 additions & 2 deletions test/test_custom.rb
Original file line number Diff line number Diff line change
Expand Up @@ -493,8 +493,15 @@ def test_time
skip 'TruffleRuby fails this spec' if RUBY_ENGINE == 'truffleruby'

obj = Time.now()
dump_load_dump(obj, false, :time_format => :unix, :create_id => "^o", :create_additions => true)
dump_load_dump(obj, false, :time_format => :unix_zone, :create_id => "^o", :create_additions => true)
# These two forms should be able to recreate the time precisely,
# so we check they can load a dumped version and recreate the
# original object correctly.
dump_and_load(obj, false, :time_format => :unix, :create_id => "^o", :create_additions => true)
dump_and_load(obj, false, :time_format => :unix_zone, :create_id => "^o", :create_additions => true)
# These two forms will lose precision while dumping as they don't
# preserve full precision. We check that a dumped version is equal
# to that version loaded and dumped a second time, but don't check
# that the loaded Ruby objects is still the same as the original.
dump_load_dump(obj, false, :time_format => :xmlschema, :create_id => "^o", :create_additions => true)
dump_load_dump(obj, false, :time_format => :ruby, :create_id => "^o", :create_additions => true)
end
Expand Down