oj 3.10.3 → 3.10.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/oj/custom.c +1 -1
- data/ext/oj/dump_object.c +1 -1
- data/ext/oj/mimic_json.c +4 -3
- data/ext/oj/object.c +1 -1
- data/ext/oj/oj.c +11 -6
- data/ext/oj/oj.h +3 -1
- data/ext/oj/parse.c +107 -32
- data/ext/oj/parse.h +2 -1
- data/ext/oj/sparse.c +22 -10
- data/lib/oj/version.rb +1 -1
- data/pages/Options.md +11 -11
- data/test/json_gem/json_common_interface_test.rb +8 -2
- data/test/prec.rb +23 -0
- data/test/sample_json.rb +1 -1
- data/test/test_custom.rb +11 -0
- data/test/test_various.rb +1 -2
- metadata +19 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3b5fb7fd1905154e2b5ebd902ec807b12108f7619f59d7c24e47b49e6aaf569f
|
4
|
+
data.tar.gz: c93ce257ece0931ad32d997670ecbc3960d65c0fb722986c7d13d34c9d486ca6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 597ca25a4f92c2c836ee46420f390a6bf4dbbd884deff31148fe03a684603e45b4e6361b928002d1eb16e46c2653b22ede1064ed5f46818cceb44c58440f62f8
|
7
|
+
data.tar.gz: 5972ca3d493979fee3b2dbd14bbc6a2cbb367175b48ef540fe3dab3e92a76dae28b5d1b366b27115f02d6dbfdfef59698ad251849b1598e457397edb0fbfbdb5
|
data/ext/oj/custom.c
CHANGED
@@ -1089,7 +1089,7 @@ hash_set_num(struct _parseInfo *pi, Val kval, NumInfo ni) {
|
|
1089
1089
|
// offset and then a conversion to UTC keeps makes the time
|
1090
1090
|
// match the expected value.
|
1091
1091
|
parent->val = rb_funcall2(parent->val, oj_utc_id, 0, 0);
|
1092
|
-
} else if (ni->
|
1092
|
+
} else if (ni->has_exp) {
|
1093
1093
|
int64_t t = (int64_t)(ni->i + ni->exp);
|
1094
1094
|
struct _timeInfo ti;
|
1095
1095
|
VALUE args[8];
|
data/ext/oj/dump_object.c
CHANGED
@@ -618,7 +618,7 @@ dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out) {
|
|
618
618
|
vid = rb_to_id(*np);
|
619
619
|
attr = rb_id2name(vid);
|
620
620
|
if (Yes == out->opts->ignore_under && '@' == *attr && '_' == attr[1]) {
|
621
|
-
|
621
|
+
continue;
|
622
622
|
}
|
623
623
|
value = rb_ivar_get(obj, vid);
|
624
624
|
|
data/ext/oj/mimic_json.c
CHANGED
@@ -513,7 +513,8 @@ mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
|
|
513
513
|
pi.options.create_ok = No;
|
514
514
|
pi.options.allow_nan = (bang ? Yes : No);
|
515
515
|
pi.options.nilnil = No;
|
516
|
-
pi.options.bigdec_load = FloatDec;
|
516
|
+
//pi.options.bigdec_load = FloatDec;
|
517
|
+
pi.options.bigdec_load = RubyDec;
|
517
518
|
pi.options.mode = CompatMode;
|
518
519
|
pi.max_depth = 100;
|
519
520
|
|
@@ -686,7 +687,7 @@ static struct _options mimic_object_to_json_options = {
|
|
686
687
|
No, // class_cache
|
687
688
|
RubyTime, // time_format
|
688
689
|
No, // bigdec_as_num
|
689
|
-
|
690
|
+
RubyDec, // bigdec_load
|
690
691
|
No, // to_hash
|
691
692
|
No, // to_json
|
692
693
|
No, // as_json
|
@@ -707,7 +708,7 @@ static struct _options mimic_object_to_json_options = {
|
|
707
708
|
oj_json_class,// create_id
|
708
709
|
10, // create_id_len
|
709
710
|
3, // sec_prec
|
710
|
-
|
711
|
+
0, // float_prec
|
711
712
|
"%0.16g", // float_fmt
|
712
713
|
Qnil, // hash_class
|
713
714
|
Qnil, // array_class
|
data/ext/oj/object.c
CHANGED
@@ -295,7 +295,7 @@ hat_num(ParseInfo pi, Val parent, Val kval, NumInfo ni) {
|
|
295
295
|
// offset and then a conversion to UTC keeps makes the time
|
296
296
|
// match the expected value.
|
297
297
|
parent->val = rb_funcall2(parent->val, oj_utc_id, 0, 0);
|
298
|
-
} else if (ni->
|
298
|
+
} else if (ni->has_exp) {
|
299
299
|
int64_t t = (int64_t)(ni->i + ni->exp);
|
300
300
|
struct _timeInfo ti;
|
301
301
|
VALUE args[8];
|
data/ext/oj/oj.c
CHANGED
@@ -115,6 +115,7 @@ static VALUE custom_sym;
|
|
115
115
|
static VALUE empty_string_sym;
|
116
116
|
static VALUE escape_mode_sym;
|
117
117
|
static VALUE integer_range_sym;
|
118
|
+
static VALUE fast_sym;
|
118
119
|
static VALUE float_prec_sym;
|
119
120
|
static VALUE float_sym;
|
120
121
|
static VALUE huge_sym;
|
@@ -230,7 +231,7 @@ struct _options oj_default_options = {
|
|
230
231
|
* - *:mode* [_:object_|_:strict_|_:compat_|_:null_|_:custom_|_:rails_|_:wab_] load and dump modes to use for JSON
|
231
232
|
* - *:time_format* [_:unix_|_:unix_zone_|_:xmlschema_|_:ruby_] time format when dumping
|
232
233
|
* - *:bigdecimal_as_decimal* [_Boolean_|_nil_] dump BigDecimal as a decimal number or as a String
|
233
|
-
* - *:bigdecimal_load* [_:bigdecimal_|_:float_|_:auto_] load decimals as BigDecimal instead of as a Float. :auto pick the most precise for the number of digits.
|
234
|
+
* - *:bigdecimal_load* [_:bigdecimal_|_:float_|_:auto_|_:fast_] load decimals as BigDecimal instead of as a Float. :auto pick the most precise for the number of digits. :float should be the same as ruby. :fast may require rounding but is must faster.
|
234
235
|
* - *:create_id* [_String_|_nil_] create id for json compatible object encoding, default is 'json_class'
|
235
236
|
* - *:create_additions* [_Boolean_|_nil_] if true allow creation of instances using create_id on load.
|
236
237
|
* - *:second_precision* [_Fixnum_|_nil_] number of digits after the decimal when dumping the seconds portion of time
|
@@ -331,6 +332,7 @@ get_def_opts(VALUE self) {
|
|
331
332
|
switch (oj_default_options.bigdec_load) {
|
332
333
|
case BigDec: rb_hash_aset(opts, bigdecimal_load_sym, bigdecimal_sym);break;
|
333
334
|
case FloatDec: rb_hash_aset(opts, bigdecimal_load_sym, float_sym); break;
|
335
|
+
case FastDec: rb_hash_aset(opts, bigdecimal_load_sym, fast_sym); break;
|
334
336
|
case AutoDec:
|
335
337
|
default: rb_hash_aset(opts, bigdecimal_load_sym, auto_sym); break;
|
336
338
|
}
|
@@ -574,6 +576,8 @@ oj_parse_options(VALUE ropts, Options copts) {
|
|
574
576
|
copts->bigdec_load = BigDec;
|
575
577
|
} else if (float_sym == v) {
|
576
578
|
copts->bigdec_load = FloatDec;
|
579
|
+
} else if (fast_sym == v) {
|
580
|
+
copts->bigdec_load = FastDec;
|
577
581
|
} else if (auto_sym == v || Qfalse == v) {
|
578
582
|
copts->bigdec_load = AutoDec;
|
579
583
|
} else {
|
@@ -803,7 +807,7 @@ oj_parse_opt_match_string(RxClass rc, VALUE ropts) {
|
|
803
807
|
}
|
804
808
|
|
805
809
|
/* Document-method: load
|
806
|
-
* call-seq: load(json, options) { _|_obj, start, len_|_ }
|
810
|
+
* call-seq: load(json, options={}) { _|_obj, start, len_|_ }
|
807
811
|
*
|
808
812
|
* Parses a JSON document String into a Object, Hash, Array, String, Fixnum,
|
809
813
|
* Float, true, false, or nil according to the default mode or the mode
|
@@ -887,7 +891,7 @@ load(int argc, VALUE *argv, VALUE self) {
|
|
887
891
|
}
|
888
892
|
|
889
893
|
/* Document-method: load_file
|
890
|
-
* call-seq: load_file(path, options) { _|_obj, start, len_|_ }
|
894
|
+
* call-seq: load_file(path, options={}) { _|_obj, start, len_|_ }
|
891
895
|
*
|
892
896
|
* Parses a JSON document String into a Object, Hash, Array, String, Fixnum,
|
893
897
|
* Float, true, false, or nil according to the default mode or the mode
|
@@ -1045,7 +1049,7 @@ safe_load(VALUE self, VALUE doc) {
|
|
1045
1049
|
*/
|
1046
1050
|
|
1047
1051
|
/* Document-method: dump
|
1048
|
-
* call-seq: dump(obj, options)
|
1052
|
+
* call-seq: dump(obj, options={})
|
1049
1053
|
*
|
1050
1054
|
* Dumps an Object (obj) to a string.
|
1051
1055
|
* - *obj* [_Object_] Object to serialize as an JSON document String
|
@@ -1143,7 +1147,7 @@ to_json(int argc, VALUE *argv, VALUE self) {
|
|
1143
1147
|
}
|
1144
1148
|
|
1145
1149
|
/* Document-method: to_file
|
1146
|
-
* call-seq: to_file(file_path, obj, options)
|
1150
|
+
* call-seq: to_file(file_path, obj, options={})
|
1147
1151
|
*
|
1148
1152
|
* Dumps an Object to the specified file.
|
1149
1153
|
* - *file* [_String_] _path file path to write the JSON document to
|
@@ -1166,7 +1170,7 @@ to_file(int argc, VALUE *argv, VALUE self) {
|
|
1166
1170
|
}
|
1167
1171
|
|
1168
1172
|
/* Document-method: to_stream
|
1169
|
-
* call-seq: to_stream(io, obj, options)
|
1173
|
+
* call-seq: to_stream(io, obj, options={})
|
1170
1174
|
*
|
1171
1175
|
* Dumps an Object to the specified IO stream.
|
1172
1176
|
* - *io* [_IO_] IO stream to write the JSON document to
|
@@ -1654,6 +1658,7 @@ Init_oj() {
|
|
1654
1658
|
empty_string_sym = ID2SYM(rb_intern("empty_string")); rb_gc_register_address(&empty_string_sym);
|
1655
1659
|
escape_mode_sym = ID2SYM(rb_intern("escape_mode")); rb_gc_register_address(&escape_mode_sym);
|
1656
1660
|
integer_range_sym = ID2SYM(rb_intern("integer_range")); rb_gc_register_address(&integer_range_sym);
|
1661
|
+
fast_sym = ID2SYM(rb_intern("fast")); rb_gc_register_address(&fast_sym);
|
1657
1662
|
float_prec_sym = ID2SYM(rb_intern("float_precision")); rb_gc_register_address(&float_prec_sym);
|
1658
1663
|
float_sym = ID2SYM(rb_intern("float")); rb_gc_register_address(&float_sym);
|
1659
1664
|
huge_sym = ID2SYM(rb_intern("huge")); rb_gc_register_address(&huge_sym);
|
data/ext/oj/oj.h
CHANGED
data/ext/oj/parse.c
CHANGED
@@ -393,8 +393,9 @@ read_num(ParseInfo pi) {
|
|
393
393
|
ni.infinity = 0;
|
394
394
|
ni.nan = 0;
|
395
395
|
ni.neg = 0;
|
396
|
-
ni.
|
397
|
-
ni.no_big = (FloatDec == pi->options.bigdec_load);
|
396
|
+
ni.has_exp = 0;
|
397
|
+
ni.no_big = (FloatDec == pi->options.bigdec_load || FastDec == pi->options.bigdec_load || RubyDec == pi->options.bigdec_load);
|
398
|
+
ni.bigdec_load = pi->options.bigdec_load;
|
398
399
|
|
399
400
|
if ('-' == *pi->cur) {
|
400
401
|
pi->cur++;
|
@@ -453,6 +454,7 @@ read_num(ParseInfo pi) {
|
|
453
454
|
// except when mimicing the JSON gem or in strict mode.
|
454
455
|
if (StrictMode == pi->options.mode || CompatMode == pi->options.mode) {
|
455
456
|
int pos = (int)(pi->cur - ni.str);
|
457
|
+
|
456
458
|
if (1 == pos || (2 == pos && ni.neg)) {
|
457
459
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number");
|
458
460
|
return;
|
@@ -468,18 +470,26 @@ read_num(ParseInfo pi) {
|
|
468
470
|
if (0 < ni.num || 0 < ni.i) {
|
469
471
|
dec_cnt++;
|
470
472
|
}
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
473
|
+
if (INT64_MAX <= ni.div) {
|
474
|
+
if (!ni.no_big) {
|
475
|
+
ni.big = true;
|
476
|
+
}
|
477
|
+
} else {
|
478
|
+
ni.num = ni.num * 10 + d;
|
479
|
+
ni.div *= 10;
|
480
|
+
ni.di++;
|
481
|
+
if (INT64_MAX <= ni.div || DEC_MAX < dec_cnt) {
|
482
|
+
if (!ni.no_big) {
|
483
|
+
ni.big = true;
|
484
|
+
}
|
485
|
+
}
|
476
486
|
}
|
477
487
|
}
|
478
488
|
}
|
479
489
|
if ('e' == *pi->cur || 'E' == *pi->cur) {
|
480
490
|
int eneg = 0;
|
481
491
|
|
482
|
-
ni.
|
492
|
+
ni.has_exp = 1;
|
483
493
|
pi->cur++;
|
484
494
|
if ('-' == *pi->cur) {
|
485
495
|
pi->cur++;
|
@@ -490,7 +500,7 @@ read_num(ParseInfo pi) {
|
|
490
500
|
for (; '0' <= *pi->cur && *pi->cur <= '9'; pi->cur++) {
|
491
501
|
ni.exp = ni.exp * 10 + (*pi->cur - '0');
|
492
502
|
if (EXP_MAX <= ni.exp) {
|
493
|
-
ni.big =
|
503
|
+
ni.big = true;
|
494
504
|
}
|
495
505
|
}
|
496
506
|
if (eneg) {
|
@@ -750,6 +760,59 @@ parse_big_decimal(VALUE str) {
|
|
750
760
|
return rb_funcall(rb_cObject, oj_bigdecimal_id, 1, str);
|
751
761
|
}
|
752
762
|
|
763
|
+
static long double exp_plus[] = {
|
764
|
+
1.0,
|
765
|
+
1.0e1,
|
766
|
+
1.0e2,
|
767
|
+
1.0e3,
|
768
|
+
1.0e4,
|
769
|
+
1.0e5,
|
770
|
+
1.0e6,
|
771
|
+
1.0e7,
|
772
|
+
1.0e8,
|
773
|
+
1.0e9,
|
774
|
+
1.0e10,
|
775
|
+
1.0e11,
|
776
|
+
1.0e12,
|
777
|
+
1.0e13,
|
778
|
+
1.0e14,
|
779
|
+
1.0e15,
|
780
|
+
1.0e16,
|
781
|
+
1.0e17,
|
782
|
+
1.0e18,
|
783
|
+
1.0e19,
|
784
|
+
1.0e20,
|
785
|
+
1.0e21,
|
786
|
+
1.0e22,
|
787
|
+
1.0e23,
|
788
|
+
1.0e24,
|
789
|
+
1.0e25,
|
790
|
+
1.0e26,
|
791
|
+
1.0e27,
|
792
|
+
1.0e28,
|
793
|
+
1.0e29,
|
794
|
+
1.0e30,
|
795
|
+
1.0e31,
|
796
|
+
1.0e32,
|
797
|
+
1.0e33,
|
798
|
+
1.0e34,
|
799
|
+
1.0e35,
|
800
|
+
1.0e36,
|
801
|
+
1.0e37,
|
802
|
+
1.0e38,
|
803
|
+
1.0e39,
|
804
|
+
1.0e40,
|
805
|
+
1.0e41,
|
806
|
+
1.0e42,
|
807
|
+
1.0e43,
|
808
|
+
1.0e44,
|
809
|
+
1.0e45,
|
810
|
+
1.0e46,
|
811
|
+
1.0e47,
|
812
|
+
1.0e48,
|
813
|
+
1.0e49,
|
814
|
+
};
|
815
|
+
|
753
816
|
VALUE
|
754
817
|
oj_num_as_value(NumInfo ni) {
|
755
818
|
volatile VALUE rnum = Qnil;
|
@@ -762,7 +825,7 @@ oj_num_as_value(NumInfo ni) {
|
|
762
825
|
}
|
763
826
|
} else if (ni->nan) {
|
764
827
|
rnum = rb_float_new(0.0/0.0);
|
765
|
-
} else if (1 == ni->div && 0 == ni->exp) { // fixnum
|
828
|
+
} else if (1 == ni->div && 0 == ni->exp && !ni->has_exp) { // fixnum
|
766
829
|
if (ni->big) {
|
767
830
|
if (256 > ni->len) {
|
768
831
|
char buf[256];
|
@@ -793,33 +856,39 @@ oj_num_as_value(NumInfo ni) {
|
|
793
856
|
if (ni->no_big) {
|
794
857
|
rnum = rb_funcall(rnum, rb_intern("to_f"), 0);
|
795
858
|
}
|
796
|
-
} else {
|
797
|
-
|
798
|
-
long double d = (long double)ni->i * (long double)ni->div + (long double)ni->num;
|
859
|
+
} else if (FastDec == ni->bigdec_load) {
|
860
|
+
long double ld = (long double)ni->i * (long double)ni->div + (long double)ni->num;
|
799
861
|
int x = (int)((int64_t)ni->exp - ni->di);
|
800
862
|
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
rnum = rb_rescue2(parse_big_decimal, bd, rescue_big_decimal, bd, rb_eException, 0);
|
808
|
-
if (ni->no_big) {
|
809
|
-
rnum = rb_funcall(rnum, rb_intern("to_f"), 0);
|
810
|
-
}
|
811
|
-
} else {
|
812
|
-
d = roundl(d);
|
813
|
-
if (0 < x) {
|
814
|
-
d *= powl(10.0L, x);
|
815
|
-
} else if (0 > x) {
|
816
|
-
d /= powl(10.0L, -x);
|
863
|
+
if (0 < x) {
|
864
|
+
if (x < (int)(sizeof(exp_plus) / sizeof(*exp_plus))) {
|
865
|
+
ld *= exp_plus[x];
|
866
|
+
} else {
|
867
|
+
ld *= powl(10.0, x);
|
817
868
|
}
|
818
|
-
|
819
|
-
|
869
|
+
} else if (x < 0) {
|
870
|
+
if (-x < (int)(sizeof(exp_plus) / sizeof(*exp_plus))) {
|
871
|
+
ld /= exp_plus[-x];
|
872
|
+
} else {
|
873
|
+
ld /= powl(10.0, -x);
|
820
874
|
}
|
821
|
-
rnum = rb_float_new((double)d);
|
822
875
|
}
|
876
|
+
if (ni->neg) {
|
877
|
+
ld = -ld;
|
878
|
+
}
|
879
|
+
rnum = rb_float_new((double)ld);
|
880
|
+
} else if (RubyDec == ni->bigdec_load) {
|
881
|
+
volatile VALUE sv = rb_str_new(ni->str, ni->len);
|
882
|
+
|
883
|
+
rnum = rb_funcall(sv, rb_intern("to_f"), 0);
|
884
|
+
} else {
|
885
|
+
char *end;
|
886
|
+
double d = strtod(ni->str, &end);
|
887
|
+
|
888
|
+
if ((long)ni->len != (long)(end - ni->str)) {
|
889
|
+
rb_raise(oj_parse_error_class, "Invalid float");
|
890
|
+
}
|
891
|
+
rnum = rb_float_new(d);
|
823
892
|
}
|
824
893
|
}
|
825
894
|
return rnum;
|
@@ -841,6 +910,12 @@ oj_set_error_at(ParseInfo pi, VALUE err_clas, const char* file, int line, const
|
|
841
910
|
if (p + 3 < end) {
|
842
911
|
*p++ = ' ';
|
843
912
|
*p++ = '(';
|
913
|
+
*p++ = 'a';
|
914
|
+
*p++ = 'f';
|
915
|
+
*p++ = 't';
|
916
|
+
*p++ = 'e';
|
917
|
+
*p++ = 'r';
|
918
|
+
*p++ = ' ';
|
844
919
|
start = p;
|
845
920
|
for (vp = pi->stack.head; vp < pi->stack.tail; vp++) {
|
846
921
|
if (end <= p + 1 + vp->klen) {
|
data/ext/oj/parse.h
CHANGED
data/ext/oj/sparse.c
CHANGED
@@ -407,8 +407,10 @@ read_num(ParseInfo pi) {
|
|
407
407
|
ni.infinity = 0;
|
408
408
|
ni.nan = 0;
|
409
409
|
ni.neg = 0;
|
410
|
-
ni.
|
411
|
-
ni.no_big = (FloatDec == pi->options.bigdec_load);
|
410
|
+
ni.has_exp = 0;
|
411
|
+
ni.no_big = (FloatDec == pi->options.bigdec_load || FastDec == pi->options.bigdec_load || RubyDec == pi->options.bigdec_load);
|
412
|
+
ni.bigdec_load = pi->options.bigdec_load;
|
413
|
+
|
412
414
|
c = reader_get(&pi->rd);
|
413
415
|
if ('-' == c) {
|
414
416
|
c = reader_get(&pi->rd);
|
@@ -469,18 +471,26 @@ read_num(ParseInfo pi) {
|
|
469
471
|
if (0 < ni.num || 0 < ni.i) {
|
470
472
|
dec_cnt++;
|
471
473
|
}
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
474
|
+
if (INT64_MAX <= ni.div) {
|
475
|
+
if (!ni.no_big) {
|
476
|
+
ni.big = true;
|
477
|
+
}
|
478
|
+
} else {
|
479
|
+
ni.num = ni.num * 10 + d;
|
480
|
+
ni.div *= 10;
|
481
|
+
ni.di++;
|
482
|
+
if (INT64_MAX <= ni.div || DEC_MAX < dec_cnt) {
|
483
|
+
if (!ni.no_big) {
|
484
|
+
ni.big = true;
|
485
|
+
}
|
486
|
+
}
|
477
487
|
}
|
478
488
|
}
|
479
489
|
}
|
480
490
|
if ('e' == c || 'E' == c) {
|
481
491
|
int eneg = 0;
|
482
492
|
|
483
|
-
ni.
|
493
|
+
ni.has_exp = 1;
|
484
494
|
c = reader_get(&pi->rd);
|
485
495
|
if ('-' == c) {
|
486
496
|
c = reader_get(&pi->rd);
|
@@ -539,7 +549,8 @@ read_nan(ParseInfo pi) {
|
|
539
549
|
ni.infinity = 0;
|
540
550
|
ni.nan = 1;
|
541
551
|
ni.neg = 0;
|
542
|
-
ni.no_big = (FloatDec == pi->options.bigdec_load);
|
552
|
+
ni.no_big = (FloatDec == pi->options.bigdec_load || FastDec == pi->options.bigdec_load || RubyDec == pi->options.bigdec_load);
|
553
|
+
ni.bigdec_load = pi->options.bigdec_load;
|
543
554
|
|
544
555
|
if ('a' != reader_get(&pi->rd) ||
|
545
556
|
('N' != (c = reader_get(&pi->rd)) && 'n' != c)) {
|
@@ -736,7 +747,8 @@ oj_sparse2(ParseInfo pi) {
|
|
736
747
|
ni.infinity = 0;
|
737
748
|
ni.nan = 1;
|
738
749
|
ni.neg = 0;
|
739
|
-
ni.no_big = (FloatDec == pi->options.bigdec_load);
|
750
|
+
ni.no_big = (FloatDec == pi->options.bigdec_load || RubyDec == pi->options.bigdec_load || FastDec == pi->options.bigdec_load);
|
751
|
+
ni.bigdec_load = pi->options.bigdec_load;
|
740
752
|
add_num_value(pi, &ni);
|
741
753
|
} else {
|
742
754
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "invalid token");
|
data/lib/oj/version.rb
CHANGED
data/pages/Options.md
CHANGED
@@ -80,16 +80,16 @@ dynamically modifying classes or reloading classes then don't use this.
|
|
80
80
|
|
81
81
|
### :create_additions
|
82
82
|
|
83
|
-
A flag indicating the :create_id key when encountered during parsing
|
84
|
-
|
85
|
-
with the key.
|
83
|
+
A flag indicating that the :create_id key, when encountered during parsing,
|
84
|
+
should create an Object matching the class name specified in the value
|
85
|
+
associated with the key.
|
86
86
|
|
87
87
|
### :create_id [String]
|
88
88
|
|
89
89
|
The :create_id option specifies that key is used for dumping and loading when
|
90
90
|
specifying the class for an encoded object. The default is `json_create`.
|
91
91
|
|
92
|
-
In the `:custom` mode setting the `:create_id` to nil will cause Complex,
|
92
|
+
In the `:custom` mode, setting the `:create_id` to nil will cause Complex,
|
93
93
|
Rational, Range, and Regexp to be output as strings instead of as JSON
|
94
94
|
objects.
|
95
95
|
|
@@ -179,7 +179,7 @@ customization.
|
|
179
179
|
### :nan [Symbol]
|
180
180
|
|
181
181
|
How to dump Infinity, -Infinity, and NaN in :null, :strict, and :compat
|
182
|
-
mode. Default is :auto but is ignored in the :compat and :rails
|
182
|
+
mode. Default is :auto but is ignored in the :compat and :rails modes.
|
183
183
|
|
184
184
|
- `:null` places a null
|
185
185
|
|
@@ -252,7 +252,7 @@ The :time_format when dumping.
|
|
252
252
|
|
253
253
|
- `:unix` time is output as a decimal number in seconds since epoch including fractions of a second.
|
254
254
|
|
255
|
-
- `:unix_zone` similar to the `:unix` format but with the timezone encoded in
|
255
|
+
- `:unix_zone` is similar to the `:unix` format but with the timezone encoded in
|
256
256
|
the exponent of the decimal number of seconds since epoch.
|
257
257
|
|
258
258
|
- `:xmlschema` time is output as a string that follows the XML schema definition.
|
@@ -262,16 +262,16 @@ The :time_format when dumping.
|
|
262
262
|
### :use_as_json [Boolean]
|
263
263
|
|
264
264
|
Call `as_json()` methods on dump, default is false. The option is ignored in
|
265
|
-
the :compat and :rails
|
265
|
+
the :compat and :rails modes.
|
266
266
|
|
267
267
|
|
268
268
|
### :use_raw_json [Boolean]
|
269
269
|
|
270
270
|
Call `raw_json()` methods on dump, default is false. The option is
|
271
|
-
accepted in the :compat and :rails
|
271
|
+
accepted in the :compat and :rails modes even though it is not
|
272
272
|
supported by other JSON gems. It provides a means to optimize dump or
|
273
273
|
generate performance. The `raw_json(depth, indent)` method should be
|
274
|
-
called only by Oj. It is not intended for any other use. This is
|
274
|
+
called only by Oj. It is not intended for any other use. This is meant
|
275
275
|
to replace the abused `to_json` methods. Calling `Oj.dump` inside the
|
276
276
|
`raw_json` with the object itself when `:use_raw_json` is true will
|
277
277
|
result in an infinite loop.
|
@@ -279,9 +279,9 @@ result in an infinite loop.
|
|
279
279
|
### :use_to_hash [Boolean]
|
280
280
|
|
281
281
|
Call `to_hash()` methods on dump, default is false. The option is ignored in
|
282
|
-
the :compat and :rails
|
282
|
+
the :compat and :rails modes.
|
283
283
|
|
284
284
|
### :use_to_json [Boolean]
|
285
285
|
|
286
286
|
Call `to_json()` methods on dump, default is false. The option is ignored in
|
287
|
-
the :compat and :rails
|
287
|
+
the :compat and :rails modes.
|
@@ -15,7 +15,7 @@ class JSONCommonInterfaceTest < Test::Unit::TestCase
|
|
15
15
|
def setup
|
16
16
|
@hash = {
|
17
17
|
'a' => 2,
|
18
|
-
'b' =>
|
18
|
+
'b' => 5.23683071,
|
19
19
|
'c' => 'c',
|
20
20
|
'd' => [ 1, "b", 3.14 ],
|
21
21
|
'e' => { 'foo' => 'bar' },
|
@@ -23,8 +23,14 @@ class JSONCommonInterfaceTest < Test::Unit::TestCase
|
|
23
23
|
'h' => 1000.0,
|
24
24
|
'i' => 0.001
|
25
25
|
}
|
26
|
-
|
26
|
+
# Tired of chasing floating point rounding and precision. Oj not uses the
|
27
|
+
# Ruby float parser in compat mode yet on i386 machines there are issues
|
28
|
+
# with this test when the float is included.
|
29
|
+
|
30
|
+
@json = '{"a":2,"b":5.23683071,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},'\
|
27
31
|
'"g":"\\"\\u0000\\u001f","h":1000.0,"i":0.001}'
|
32
|
+
#@json = '{"a":2,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},'\
|
33
|
+
#p '"g":"\\"\\u0000\\u001f","h":1000.0,"i":0.001}'
|
28
34
|
end
|
29
35
|
|
30
36
|
def test_index
|
data/test/prec.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'oj'
|
4
|
+
|
5
|
+
extras = {"locationLng" => -97.14690769100295}
|
6
|
+
|
7
|
+
Oj.default_options = {float_precision: 17}
|
8
|
+
|
9
|
+
encoded = Oj.dump(extras)
|
10
|
+
puts encoded
|
11
|
+
puts Oj.load(encoded)
|
12
|
+
|
13
|
+
require "active_record"
|
14
|
+
|
15
|
+
Oj::Rails.set_encoder()
|
16
|
+
Oj::Rails.set_decoder()
|
17
|
+
|
18
|
+
Oj.default_options = {float_precision: 17}
|
19
|
+
# Using Oj rails encoder, gets the correct value: {"locationLng":-97.14690769100295}
|
20
|
+
encoded = ActiveSupport::JSON.encode(extras)
|
21
|
+
puts encoded
|
22
|
+
puts ActiveSupport::JSON.decode(encoded)
|
23
|
+
puts Oj.load(encoded)
|
data/test/sample_json.rb
CHANGED
data/test/test_custom.rb
CHANGED
@@ -118,6 +118,17 @@ class CustomJuice < Minitest::Test
|
|
118
118
|
dump_and_load(-2.48e100 * 1.0e10, false)
|
119
119
|
end
|
120
120
|
|
121
|
+
def test_float_parse
|
122
|
+
f = Oj.load("12.123456789012345678", mode: :custom, bigdecimal_load: :float);
|
123
|
+
assert_equal(Float, f.class)
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_float_parse_fast
|
127
|
+
f = Oj.load("12.123456789012345678", mode: :custom, bigdecimal_load: :fast);
|
128
|
+
assert_equal(Float, f.class)
|
129
|
+
assert_equal('12.12345678901235', "%0.14f" % [f]) # only care about 16 digits
|
130
|
+
end
|
131
|
+
|
121
132
|
def test_nan_dump
|
122
133
|
assert_equal('null', Oj.dump(0/0.0, :nan => :null))
|
123
134
|
assert_equal('3.3e14159265358979323846', Oj.dump(0/0.0, :nan => :huge))
|
data/test/test_various.rb
CHANGED
@@ -185,7 +185,6 @@ class Juice < Minitest::Test
|
|
185
185
|
n = Oj.load('-0.000012345678901234567')
|
186
186
|
assert_equal(BigDecimal, n.class)
|
187
187
|
assert_equal('-0.12345678901234567E-4', n.to_s.upcase)
|
188
|
-
|
189
188
|
end
|
190
189
|
|
191
190
|
=begin
|
@@ -671,7 +670,7 @@ class Juice < Minitest::Test
|
|
671
670
|
raise e
|
672
671
|
end
|
673
672
|
}
|
674
|
-
assert_equal('first[2].third', msg.split('(')[1].split(')')[0])
|
673
|
+
assert_equal('after first[2].third', msg.split('(')[1].split(')')[0])
|
675
674
|
end
|
676
675
|
|
677
676
|
def test_bad_bignum
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oj
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.10.
|
4
|
+
version: 3.10.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Ohler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-08-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bigdecimal
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: rake-compiler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -219,6 +233,7 @@ files:
|
|
219
233
|
- test/perf_simple.rb
|
220
234
|
- test/perf_strict.rb
|
221
235
|
- test/perf_wab.rb
|
236
|
+
- test/prec.rb
|
222
237
|
- test/sample.rb
|
223
238
|
- test/sample/change.rb
|
224
239
|
- test/sample/dir.rb
|
@@ -276,7 +291,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
276
291
|
requirements:
|
277
292
|
- - ">="
|
278
293
|
- !ruby/object:Gem::Version
|
279
|
-
version: '2.
|
294
|
+
version: '2.4'
|
280
295
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
281
296
|
requirements:
|
282
297
|
- - ">="
|
@@ -289,6 +304,7 @@ specification_version: 4
|
|
289
304
|
summary: A fast JSON parser and serializer.
|
290
305
|
test_files:
|
291
306
|
- test/foo.rb
|
307
|
+
- test/prec.rb
|
292
308
|
- test/test_integer_range.rb
|
293
309
|
- test/test_strict.rb
|
294
310
|
- test/perf_strict.rb
|