oj 3.10.6 → 3.10.11
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/mimic_json.c +4 -3
- data/ext/oj/object.c +1 -1
- data/ext/oj/oj.c +6 -1
- data/ext/oj/oj.h +3 -1
- data/ext/oj/parse.c +105 -37
- 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 +6 -0
- 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 +25 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47283e200dc64657f1847aede3e919be687893f79283f4c84d04202a7039c27a
|
4
|
+
data.tar.gz: 7572d238ef551ba6278e0687f322eee9f4c719170076012e553816d8a51ca1a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d30cd67a79dd62acb4f3795993d3b41fd261c3672d1e22b932f4de5e5ff51131b4310be5f8fbd34de5a1259d22c5ea591213e74aedec0d870234da96d3f9bafd
|
7
|
+
data.tar.gz: 917c44023d012a3020e53f5487409a4d72d3149c3e0e8f47a41580a53f169af740ddc0842f23ac4fcbed85eec33fa87197d913c0f84b1aa0c6a17af29f849bc8
|
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/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 {
|
@@ -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,40 +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
|
-
// All these machinations are to get rounding to work better.
|
859
|
+
} else if (FastDec == ni->bigdec_load) {
|
798
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
|
-
if ((long double)INT64_MAX > ld && (int64_t)ld != (ni->i * ni->div + ni->num)) {
|
805
|
-
volatile VALUE bd = rb_str_new(ni->str, ni->len);
|
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
|
-
double d;
|
813
|
-
|
814
|
-
ld = roundl(ld);
|
815
|
-
// You would expect that staying with a long double would be
|
816
|
-
// more accurate but it fails to match what Ruby generates so
|
817
|
-
// drop down to a double.
|
818
|
-
if (0 < x) {
|
819
|
-
d = (double)ld * pow(10.0, x);
|
820
|
-
} else if (0 > x) {
|
821
|
-
d = (double)ld / pow(10.0, -x);
|
863
|
+
if (0 < x) {
|
864
|
+
if (x < (int)(sizeof(exp_plus) / sizeof(*exp_plus))) {
|
865
|
+
ld *= exp_plus[x];
|
822
866
|
} else {
|
823
|
-
|
867
|
+
ld *= powl(10.0, x);
|
824
868
|
}
|
825
|
-
|
826
|
-
|
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);
|
827
874
|
}
|
828
|
-
rnum = rb_float_new(d);
|
829
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);
|
830
892
|
}
|
831
893
|
}
|
832
894
|
return rnum;
|
@@ -848,6 +910,12 @@ oj_set_error_at(ParseInfo pi, VALUE err_clas, const char* file, int line, const
|
|
848
910
|
if (p + 3 < end) {
|
849
911
|
*p++ = ' ';
|
850
912
|
*p++ = '(';
|
913
|
+
*p++ = 'a';
|
914
|
+
*p++ = 'f';
|
915
|
+
*p++ = 't';
|
916
|
+
*p++ = 'e';
|
917
|
+
*p++ = 'r';
|
918
|
+
*p++ = ' ';
|
851
919
|
start = p;
|
852
920
|
for (vp = pi->stack.head; vp < pi->stack.tail; vp++) {
|
853
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.
|
@@ -23,8 +23,14 @@ class JSONCommonInterfaceTest < Test::Unit::TestCase
|
|
23
23
|
'h' => 1000.0,
|
24
24
|
'i' => 0.001
|
25
25
|
}
|
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
|
+
|
26
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,35 @@
|
|
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.11
|
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-20 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: '1.0'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '3'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.0'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '3'
|
13
33
|
- !ruby/object:Gem::Dependency
|
14
34
|
name: rake-compiler
|
15
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -219,6 +239,7 @@ files:
|
|
219
239
|
- test/perf_simple.rb
|
220
240
|
- test/perf_strict.rb
|
221
241
|
- test/perf_wab.rb
|
242
|
+
- test/prec.rb
|
222
243
|
- test/sample.rb
|
223
244
|
- test/sample/change.rb
|
224
245
|
- test/sample/dir.rb
|
@@ -276,7 +297,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
276
297
|
requirements:
|
277
298
|
- - ">="
|
278
299
|
- !ruby/object:Gem::Version
|
279
|
-
version: '2.
|
300
|
+
version: '2.4'
|
280
301
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
281
302
|
requirements:
|
282
303
|
- - ">="
|
@@ -289,6 +310,7 @@ specification_version: 4
|
|
289
310
|
summary: A fast JSON parser and serializer.
|
290
311
|
test_files:
|
291
312
|
- test/foo.rb
|
313
|
+
- test/prec.rb
|
292
314
|
- test/test_integer_range.rb
|
293
315
|
- test/test_strict.rb
|
294
316
|
- test/perf_strict.rb
|