oj 3.10.0 → 3.10.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 62a52be7754c5ef34c3006fb28fa918cb18f23c26ffa94e8daedf05396bbe0fb
4
- data.tar.gz: 9cf9cfab00cf1e28f8b42c6d3e88ee6a2a785093cc024c558eeceb25eaf39cd1
3
+ metadata.gz: e6c2164398794345431cbf21fe2598c7a68498dc21a49868103f9227470c5cdc
4
+ data.tar.gz: 81ddcee2018723c2ca4a9c668d78043d60647a83ab99057cdce3bd92ebad56fd
5
5
  SHA512:
6
- metadata.gz: 931cf30643fc1be050ec4f3c0c69f85b643b073e7bd5d16c5c8a5431c8d3701ae73fc5b68311246f2db993fa1c3e40b6169978f10b377a947cc937a7d26afd6e
7
- data.tar.gz: 779d173d00513d830f825cc9e0f51a5a066beece8fe9289d1face779c34210d6f7506e8e8af380fc5f2d3c2dd727b46f14cc985d4a2867e3a71fb1de4217361a
6
+ metadata.gz: 546bcdf0ee93a8b170970ac0a9e26497ee4b903f606f1fc2640e77093765ea9d63d58501c4472fb742d810ac1adddbb31caaaa19b2cf984af1b0345b529a4aa3
7
+ data.tar.gz: 51745a18bc008d4ba5bac4a459ec2231997998efdf56de1e56b3bdd2b5e972733ed12a43be7ff10f54827825ae7e9a5c3532629c044f4c71ebe0934a05e2d334
@@ -65,7 +65,7 @@ hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *o
65
65
  static VALUE
66
66
  start_hash(ParseInfo pi) {
67
67
  volatile VALUE h;
68
-
68
+
69
69
  if (Qnil != pi->options.hash_class) {
70
70
  h = rb_class_new_instance(0, NULL, pi->options.hash_class);
71
71
  } else {
@@ -87,7 +87,7 @@ end_hash(struct _parseInfo *pi) {
87
87
  clas = oj_name2class(pi, parent->classname, parent->clen, 0, rb_eArgError);
88
88
  if (Qundef != clas) { // else an error
89
89
  ID creatable = rb_intern("json_creatable?");
90
-
90
+
91
91
  if (!rb_respond_to(clas, creatable) || Qtrue == rb_funcall(clas, creatable, 0)) {
92
92
  parent->val = rb_funcall(clas, oj_json_create_id, 1, parent->val);
93
93
  }
@@ -146,7 +146,7 @@ add_num(ParseInfo pi, NumInfo ni) {
146
146
  static void
147
147
  hash_set_num(struct _parseInfo *pi, Val parent, NumInfo ni) {
148
148
  volatile VALUE rval = oj_num_as_value(ni);
149
-
149
+
150
150
  if (!oj_use_hash_alt && rb_cHash != rb_obj_class(parent->val)) {
151
151
  // The rb_hash_set would still work but the unit tests for the
152
152
  // json gem require the less efficient []= method be called to set
@@ -192,7 +192,7 @@ static void
192
192
  array_append_num(ParseInfo pi, NumInfo ni) {
193
193
  Val parent = stack_peek(&pi->stack);
194
194
  volatile VALUE rval = oj_num_as_value(ni);
195
-
195
+
196
196
  if (!oj_use_array_alt && rb_cArray != rb_obj_class(parent->val)) {
197
197
  // The rb_ary_push would still work but the unit tests for the json
198
198
  // gem require the less efficient << method be called to push the
@@ -274,7 +274,7 @@ oj_compat_load(int argc, VALUE *argv, VALUE self) {
274
274
  pi.options.nilnil = Yes;
275
275
  pi.options.empty_string = Yes;
276
276
  oj_set_compat_callbacks(&pi);
277
-
277
+
278
278
  if (T_STRING == rb_type(*argv)) {
279
279
  return oj_pi_parse(argc, argv, &pi, 0, 0, false);
280
280
  } else {
@@ -297,7 +297,8 @@ static struct _code codes[] = {
297
297
  };
298
298
 
299
299
  static int
300
- hash_cb(VALUE key, VALUE value, Out out) {
300
+ hash_cb(VALUE key, VALUE value, VALUE ov) {
301
+ Out out = (Out)ov;
301
302
  int depth = out->depth;
302
303
 
303
304
  if (oj_dump_ignore(out->opts, value)) {
@@ -592,7 +593,8 @@ dump_common(VALUE obj, int depth, Out out) {
592
593
  }
593
594
 
594
595
  static int
595
- dump_attr_cb(ID key, VALUE value, Out out) {
596
+ dump_attr_cb(ID key, VALUE value, VALUE ov) {
597
+ Out out = (Out)ov;
596
598
  int depth = out->depth;
597
599
  size_t size;
598
600
  const char *attr;
@@ -111,7 +111,7 @@ static char rails_friendly_chars[256] = "\
111
111
  11111111111111111111111111111111\
112
112
  11111111111111111111111111111111\
113
113
  11111111111111111111111111111111\
114
- 11611111111111111111111111111111";
114
+ 11111111111111111111111111111111";
115
115
 
116
116
  static void
117
117
  raise_strict(VALUE obj) {
@@ -648,7 +648,8 @@ dump_float(VALUE obj, int depth, Out out, bool as_ok) {
648
648
  }
649
649
 
650
650
  static int
651
- hash_cb(VALUE key, VALUE value, Out out) {
651
+ hash_cb(VALUE key, VALUE value, VALUE ov) {
652
+ Out out = (Out)ov;
652
653
  int depth = out->depth;
653
654
 
654
655
  if (out->omit_nil && Qnil == value) {
@@ -224,7 +224,8 @@ dump_sym(VALUE obj, int depth, Out out, bool as_ok) {
224
224
  }
225
225
 
226
226
  static int
227
- hash_cb(VALUE key, VALUE value, Out out) {
227
+ hash_cb(VALUE key, VALUE value, VALUE ov) {
228
+ Out out = (Out)ov;
228
229
  int depth = out->depth;
229
230
  long size = depth * out->indent + 1;
230
231
 
@@ -348,7 +349,8 @@ dump_hash_class(VALUE obj, VALUE clas, int depth, Out out) {
348
349
 
349
350
  #ifdef HAVE_RB_IVAR_FOREACH
350
351
  static int
351
- dump_attr_cb(ID key, VALUE value, Out out) {
352
+ dump_attr_cb(ID key, VALUE value, VALUE ov) {
353
+ Out out = (Out)ov;
352
354
  int depth = out->depth;
353
355
  size_t size = depth * out->indent + 1;
354
356
  const char *attr = rb_id2name(key);
@@ -616,7 +618,7 @@ dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out) {
616
618
  vid = rb_to_id(*np);
617
619
  attr = rb_id2name(vid);
618
620
  if (Yes == out->opts->ignore_under && '@' == *attr && '_' == attr[1]) {
619
- return ST_CONTINUE;
621
+ continue;
620
622
  }
621
623
  value = rb_ivar_get(obj, vid);
622
624
 
@@ -45,7 +45,7 @@ dump_float(VALUE obj, int depth, Out out, bool as_ok) {
45
45
  cnt = 3;
46
46
  } else {
47
47
  NanDump nd = out->opts->dump_opts.nan_dump;
48
-
48
+
49
49
  if (AutoNan == nd) {
50
50
  nd = RaiseNan;
51
51
  }
@@ -195,11 +195,12 @@ dump_array(VALUE a, int depth, Out out, bool as_ok) {
195
195
  }
196
196
 
197
197
  static int
198
- hash_cb(VALUE key, VALUE value, Out out) {
198
+ hash_cb(VALUE key, VALUE value, VALUE ov) {
199
+ Out out = (Out)ov;
199
200
  int depth = out->depth;
200
201
  long size;
201
202
  int rtype = rb_type(key);
202
-
203
+
203
204
  if (rtype != T_STRING && rtype != T_SYMBOL) {
204
205
  rb_raise(rb_eTypeError, "In :strict and :null mode all Hash keys must be Strings or Symbols, not %s.\n", rb_class2name(rb_obj_class(key)));
205
206
  }
@@ -359,7 +360,7 @@ static DumpFunc strict_funcs[] = {
359
360
  void
360
361
  oj_dump_strict_val(VALUE obj, int depth, Out out) {
361
362
  int type = rb_type(obj);
362
-
363
+
363
364
  if (Yes == out->opts->trace) {
364
365
  oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
365
366
  }
@@ -408,7 +409,7 @@ static DumpFunc null_funcs[] = {
408
409
  void
409
410
  oj_dump_null_val(VALUE obj, int depth, Out out) {
410
411
  int type = rb_type(obj);
411
-
412
+
412
413
  if (Yes == out->opts->trace) {
413
414
  oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
414
415
  }
@@ -42,6 +42,11 @@ end
42
42
 
43
43
  $CPPFLAGS += ' -Wall'
44
44
  #puts "*** $CPPFLAGS: #{$CPPFLAGS}"
45
+ # Adding the __attribute__ flag only works with gcc compilers and even then it
46
+ # does not work to check args with varargs so just remove the check.
47
+ CONFIG['warnflags'].slice!(/ -Wsuggest-attribute=format/)
48
+ CONFIG['warnflags'].slice!(/ -Wdeclaration-after-statement/)
49
+ CONFIG['warnflags'].slice!(/ -Wmissing-noreturn/)
45
50
 
46
51
  create_makefile(File.join(extension_name, extension_name))
47
52
 
@@ -199,6 +199,7 @@ mimic_dump(int argc, VALUE *argv, VALUE self) {
199
199
  struct _out out;
200
200
  struct _options copts = oj_default_options;
201
201
  VALUE rstr;
202
+ VALUE active_hack[1];
202
203
 
203
204
  copts.str_rx.head = NULL;
204
205
  copts.str_rx.tail = NULL;
@@ -216,6 +217,7 @@ mimic_dump(int argc, VALUE *argv, VALUE self) {
216
217
  */
217
218
  copts.dump_opts.max_depth = MAX_DEPTH; // when using dump there is no limit
218
219
  out.omit_nil = copts.dump_opts.omit_nil;
220
+
219
221
  if (2 <= argc) {
220
222
  int limit;
221
223
 
@@ -230,7 +232,15 @@ mimic_dump(int argc, VALUE *argv, VALUE self) {
230
232
  copts.dump_opts.max_depth = limit;
231
233
  }
232
234
  }
233
- oj_dump_obj_to_json(*argv, &copts, &out);
235
+ // ActiveSupport in active_support/core_ext/object/json.rb check the
236
+ // optional argument type to to_json and it the argument is a
237
+ // ::JSON::State it calls the JSON gem code otherwise it calls the active
238
+ // support encoder code. To make sure the desired branch is called a
239
+ // default ::JSON::State argument is passed in. Basically a hack to get
240
+ // around the active support hack so two wrongs make a right this time.
241
+ active_hack[0] = rb_funcall(state_class, oj_new_id, 0);
242
+ oj_dump_obj_to_json_using_params(*argv, &copts, &out, 1, active_hack);
243
+
234
244
  if (0 == out.buf) {
235
245
  rb_raise(rb_eNoMemError, "Not enough memory.");
236
246
  }
@@ -669,7 +669,8 @@ static void
669
669
  array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
670
670
  volatile VALUE rval = Qnil;
671
671
 
672
- if (3 <= len && 0 != pi->circ_array) {
672
+ // orig lets us know whether the string was ^r1 or \u005er1
673
+ if (3 <= len && 0 != pi->circ_array && '^' == orig[0] && 0 == rb_array_len(stack_peek(&pi->stack)->val)) {
673
674
  if ('i' == str[1]) {
674
675
  long i = read_long(str + 2, len - 2);
675
676
 
@@ -766,7 +766,9 @@ oj_parse_options(VALUE ropts, Options copts) {
766
766
  }
767
767
 
768
768
  static int
769
- match_string_cb(VALUE key, VALUE value, RxClass rc) {
769
+ match_string_cb(VALUE key, VALUE value, VALUE rx) {
770
+ RxClass rc = (RxClass)rx;
771
+
770
772
  if (T_CLASS != rb_type(value)) {
771
773
  rb_raise(rb_eArgError, "for :match_string, the hash values must be a Class.");
772
774
  }
@@ -801,7 +803,7 @@ oj_parse_opt_match_string(RxClass rc, VALUE ropts) {
801
803
  }
802
804
 
803
805
  /* Document-method: load
804
- * call-seq: load(json, options) { _|_obj, start, len_|_ }
806
+ * call-seq: load(json, options={}) { _|_obj, start, len_|_ }
805
807
  *
806
808
  * Parses a JSON document String into a Object, Hash, Array, String, Fixnum,
807
809
  * Float, true, false, or nil according to the default mode or the mode
@@ -885,7 +887,7 @@ load(int argc, VALUE *argv, VALUE self) {
885
887
  }
886
888
 
887
889
  /* Document-method: load_file
888
- * call-seq: load_file(path, options) { _|_obj, start, len_|_ }
890
+ * call-seq: load_file(path, options={}) { _|_obj, start, len_|_ }
889
891
  *
890
892
  * Parses a JSON document String into a Object, Hash, Array, String, Fixnum,
891
893
  * Float, true, false, or nil according to the default mode or the mode
@@ -1043,7 +1045,7 @@ safe_load(VALUE self, VALUE doc) {
1043
1045
  */
1044
1046
 
1045
1047
  /* Document-method: dump
1046
- * call-seq: dump(obj, options)
1048
+ * call-seq: dump(obj, options={})
1047
1049
  *
1048
1050
  * Dumps an Object (obj) to a string.
1049
1051
  * - *obj* [_Object_] Object to serialize as an JSON document String
@@ -1141,7 +1143,7 @@ to_json(int argc, VALUE *argv, VALUE self) {
1141
1143
  }
1142
1144
 
1143
1145
  /* Document-method: to_file
1144
- * call-seq: to_file(file_path, obj, options)
1146
+ * call-seq: to_file(file_path, obj, options={})
1145
1147
  *
1146
1148
  * Dumps an Object to the specified file.
1147
1149
  * - *file* [_String_] _path file path to write the JSON document to
@@ -1164,7 +1166,7 @@ to_file(int argc, VALUE *argv, VALUE self) {
1164
1166
  }
1165
1167
 
1166
1168
  /* Document-method: to_stream
1167
- * call-seq: to_stream(io, obj, options)
1169
+ * call-seq: to_stream(io, obj, options={})
1168
1170
  *
1169
1171
  * Dumps an Object to the specified IO stream.
1170
1172
  * - *io* [_IO_] IO stream to write the JSON document to
@@ -740,7 +740,7 @@ oj_parse2(ParseInfo pi) {
740
740
  }
741
741
 
742
742
  static VALUE
743
- rescue_big_decimal(VALUE str) {
743
+ rescue_big_decimal(VALUE str, VALUE ignore) {
744
744
  rb_raise(oj_parse_error_class, "Invalid value for BigDecimal()");
745
745
  return Qnil;
746
746
  }
@@ -795,13 +795,13 @@ oj_num_as_value(NumInfo ni) {
795
795
  }
796
796
  } else {
797
797
  // All these machinations are to get rounding to work better.
798
- long double d = (long double)ni->i * (long double)ni->div + (long double)ni->num;
798
+ long double ld = (long double)ni->i * (long double)ni->div + (long double)ni->num;
799
799
  int x = (int)((int64_t)ni->exp - ni->di);
800
800
 
801
801
  // Rounding sometimes cuts off the last digit even if there are only
802
802
  // 15 digits. This attempts to fix those few cases where this
803
803
  // occurs.
804
- if ((long double)INT64_MAX > d && (int64_t)d != (ni->i * ni->div + ni->num)) {
804
+ if ((long double)INT64_MAX > ld && (int64_t)ld != (ni->i * ni->div + ni->num)) {
805
805
  volatile VALUE bd = rb_str_new(ni->str, ni->len);
806
806
 
807
807
  rnum = rb_rescue2(parse_big_decimal, bd, rescue_big_decimal, bd, rb_eException, 0);
@@ -809,16 +809,23 @@ oj_num_as_value(NumInfo ni) {
809
809
  rnum = rb_funcall(rnum, rb_intern("to_f"), 0);
810
810
  }
811
811
  } else {
812
- d = roundl(d);
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.
813
818
  if (0 < x) {
814
- d *= powl(10.0L, x);
819
+ d = (double)ld * pow(10.0, x);
815
820
  } else if (0 > x) {
816
- d /= powl(10.0L, -x);
821
+ d = (double)ld / pow(10.0, -x);
822
+ } else {
823
+ d = (double)ld;
817
824
  }
818
825
  if (ni->neg) {
819
826
  d = -d;
820
827
  }
821
- rnum = rb_float_new((double)d);
828
+ rnum = rb_float_new(d);
822
829
  }
823
830
  }
824
831
  }
@@ -87,7 +87,8 @@ copy_opts(ROptTable src, ROptTable dest) {
87
87
  }
88
88
 
89
89
  static int
90
- dump_attr_cb(ID key, VALUE value, Out out) {
90
+ dump_attr_cb(ID key, VALUE value, VALUE ov) {
91
+ Out out = (Out)ov;
91
92
  int depth = out->depth;
92
93
  size_t size = depth * out->indent + 1;
93
94
  const char *attr = rb_id2name(key);
@@ -1014,6 +1015,7 @@ rails_encode(int argc, VALUE *argv, VALUE self) {
1014
1015
  static VALUE
1015
1016
  rails_use_standard_json_time_format(VALUE self, VALUE state) {
1016
1017
  if (Qtrue == state || Qfalse == state) {
1018
+ // no change needed
1017
1019
  } else if (Qnil == state) {
1018
1020
  state = Qfalse;
1019
1021
  } else {
@@ -1025,6 +1027,11 @@ rails_use_standard_json_time_format(VALUE self, VALUE state) {
1025
1027
  return state;
1026
1028
  }
1027
1029
 
1030
+ static VALUE
1031
+ rails_use_standard_json_time_format_get(VALUE self) {
1032
+ return xml_time ? Qtrue : Qfalse;
1033
+ }
1034
+
1028
1035
  static VALUE
1029
1036
  rails_escape_html_entities_in_json(VALUE self, VALUE state) {
1030
1037
  rb_iv_set(self, "@escape_html_entities_in_json", state);
@@ -1033,6 +1040,11 @@ rails_escape_html_entities_in_json(VALUE self, VALUE state) {
1033
1040
  return state;
1034
1041
  }
1035
1042
 
1043
+ static VALUE
1044
+ rails_escape_html_entities_in_json_get(VALUE self) {
1045
+ return escape_html ? Qtrue : Qfalse;
1046
+ }
1047
+
1036
1048
  static VALUE
1037
1049
  rails_time_precision(VALUE self, VALUE prec) {
1038
1050
  rb_iv_set(self, "@time_precision", prec);
@@ -1056,7 +1068,12 @@ rails_set_encoder(VALUE self) {
1056
1068
  VALUE encoding;
1057
1069
  VALUE pv;
1058
1070
  VALUE verbose;
1071
+ VALUE enc = resolve_classpath("ActiveSupport::JSON::Encoding");
1059
1072
 
1073
+ if (Qnil != enc) {
1074
+ escape_html = Qtrue == rb_iv_get(self, "@escape_html_entities_in_json");
1075
+ xml_time = Qtrue == rb_iv_get(enc, "@use_standard_json_time_format");
1076
+ }
1060
1077
  if (rb_const_defined_at(rb_cObject, rb_intern("ActiveSupport"))) {
1061
1078
  active = rb_const_get_at(rb_cObject, rb_intern("ActiveSupport"));
1062
1079
  } else {
@@ -1073,11 +1090,15 @@ rails_set_encoder(VALUE self) {
1073
1090
  rb_gv_set("$VERBOSE", Qfalse);
1074
1091
  rb_undef_method(encoding, "use_standard_json_time_format=");
1075
1092
  rb_define_module_function(encoding, "use_standard_json_time_format=", rails_use_standard_json_time_format, 1);
1093
+ rb_undef_method(encoding, "use_standard_json_time_format");
1094
+ rb_define_module_function(encoding, "use_standard_json_time_format", rails_use_standard_json_time_format_get, 0);
1076
1095
 
1077
1096
  pv = rb_iv_get(encoding, "@escape_html_entities_in_json");
1078
1097
  escape_html = Qtrue == pv;
1079
1098
  rb_undef_method(encoding, "escape_html_entities_in_json=");
1080
1099
  rb_define_module_function(encoding, "escape_html_entities_in_json=", rails_escape_html_entities_in_json, 1);
1100
+ rb_undef_method(encoding, "escape_html_entities_in_json");
1101
+ rb_define_module_function(encoding, "escape_html_entities_in_json", rails_escape_html_entities_in_json_get, 0);
1081
1102
 
1082
1103
  pv = rb_iv_get(encoding, "@time_precision");
1083
1104
  oj_default_options.sec_prec = NUM2INT(pv);
@@ -1289,7 +1310,8 @@ dump_array(VALUE a, int depth, Out out, bool as_ok) {
1289
1310
  }
1290
1311
 
1291
1312
  static int
1292
- hash_cb(VALUE key, VALUE value, Out out) {
1313
+ hash_cb(VALUE key, VALUE value, VALUE ov) {
1314
+ Out out = (Out)ov;
1293
1315
  int depth = out->depth;
1294
1316
  long size;
1295
1317
  int rtype = rb_type(key);
@@ -1402,14 +1424,17 @@ dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
1402
1424
 
1403
1425
  static void
1404
1426
  dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
1427
+ VALUE clas;
1428
+
1405
1429
  if (oj_code_dump(oj_compat_codes, obj, depth, out)) {
1406
1430
  out->argc = 0;
1407
1431
  return;
1408
1432
  }
1433
+ clas = rb_obj_class(obj);
1409
1434
  if (as_ok) {
1410
1435
  ROpt ro;
1411
1436
 
1412
- if (NULL != (ro = oj_rails_get_opt(out->ropts, rb_obj_class(obj))) && ro->on) {
1437
+ if (NULL != (ro = oj_rails_get_opt(out->ropts, clas)) && ro->on) {
1413
1438
  ro->dump(obj, depth, out, as_ok);
1414
1439
  } else if (Yes == out->opts->raw_json && rb_respond_to(obj, oj_raw_json_id)) {
1415
1440
  oj_dump_raw_json(obj, depth, out);
@@ -1417,6 +1442,8 @@ dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
1417
1442
  dump_as_json(obj, depth, out, true);
1418
1443
  } else if (rb_respond_to(obj, oj_to_hash_id)) {
1419
1444
  dump_to_hash(obj, depth, out);
1445
+ } else if (oj_bigdecimal_class == clas) {
1446
+ dump_bigdecimal(obj, depth, out, false);
1420
1447
  } else {
1421
1448
  oj_dump_obj_to_s(obj, out);
1422
1449
  }
@@ -1425,6 +1452,8 @@ dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
1425
1452
  } else if (rb_respond_to(obj, oj_to_hash_id)) {
1426
1453
  // Always attempt to_hash.
1427
1454
  dump_to_hash(obj, depth, out);
1455
+ } else if (oj_bigdecimal_class == clas) {
1456
+ dump_bigdecimal(obj, depth, out, false);
1428
1457
  } else {
1429
1458
  oj_dump_obj_to_s(obj, out);
1430
1459
  }
@@ -1442,8 +1471,7 @@ static DumpFunc rails_funcs[] = {
1442
1471
  dump_array, // RUBY_T_ARRAY = 0x07,
1443
1472
  dump_hash, // RUBY_T_HASH = 0x08,
1444
1473
  dump_obj, // RUBY_T_STRUCT = 0x09,
1445
- dump_bigdecimal, // RUBY_T_BIGNUM = 0x0a,
1446
- //oj_dump_bignum, // RUBY_T_BIGNUM = 0x0a,
1474
+ oj_dump_bignum, // RUBY_T_BIGNUM = 0x0a,
1447
1475
  dump_as_string, // RUBY_T_FILE = 0x0b,
1448
1476
  dump_obj, // RUBY_T_DATA = 0x0c,
1449
1477
  NULL, // RUBY_T_MATCH = 0x0d,
@@ -773,6 +773,7 @@ oj_sparse2(ParseInfo pi) {
773
773
  first = 0;
774
774
  }
775
775
  start = pi->rd.pos;
776
+ // TBD break if option set to allow that
776
777
  }
777
778
  }
778
779
  }
@@ -148,11 +148,12 @@ dump_array(VALUE a, int depth, Out out, bool as_ok) {
148
148
  }
149
149
 
150
150
  static int
151
- hash_cb(VALUE key, VALUE value, Out out) {
151
+ hash_cb(VALUE key, VALUE value, VALUE ov) {
152
+ Out out = (Out)ov;
152
153
  int depth = out->depth;
153
154
  long size;
154
155
  int rtype = rb_type(key);
155
-
156
+
156
157
  if (rtype != T_SYMBOL) {
157
158
  rb_raise(rb_eTypeError, "In :wab mode all Hash keys must be Symbols, not %s.\n", rb_class2name(rb_obj_class(key)));
158
159
  }
@@ -270,7 +271,7 @@ static DumpFunc wab_funcs[] = {
270
271
  void
271
272
  oj_dump_wab_val(VALUE obj, int depth, Out out) {
272
273
  int type = rb_type(obj);
273
-
274
+
274
275
  if (Yes == out->opts->trace) {
275
276
  oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
276
277
  }
@@ -324,7 +325,7 @@ add_value(ParseInfo pi, VALUE val) {
324
325
  static bool
325
326
  uuid_check(const char *str, int len) {
326
327
  int i;
327
-
328
+
328
329
  for (i = 0; i < 8; i++, str++) {
329
330
  if ('x' != hex_chars[*(uint8_t*)str]) {
330
331
  return false;
@@ -380,7 +381,7 @@ time_parse(const char *s, int len) {
380
381
  long nsecs = 0;
381
382
  int i;
382
383
  time_t secs;
383
-
384
+
384
385
  memset(&tm, 0, sizeof(tm));
385
386
  if ('-' == *s) {
386
387
  s++;
@@ -444,7 +445,7 @@ protect_uri(VALUE rstr) {
444
445
  static VALUE
445
446
  cstr_to_rstr(const char *str, size_t len) {
446
447
  volatile VALUE v = Qnil;
447
-
448
+
448
449
  if (30 == len && '-' == str[4] && '-' == str[7] && 'T' == str[10] && ':' == str[13] && ':' == str[16] && '.' == str[19] && 'Z' == str[29]) {
449
450
  if (Qnil != (v = time_parse(str, (int)len))) {
450
451
  return v;
@@ -521,7 +522,7 @@ hash_set_cstr(ParseInfo pi, Val parent, const char *str, size_t len, const char
521
522
  static void
522
523
  hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
523
524
  volatile VALUE rval = Qnil;
524
-
525
+
525
526
  if (ni->infinity || ni->nan) {
526
527
  oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
527
528
  }
@@ -551,7 +552,7 @@ start_array(ParseInfo pi) {
551
552
  static void
552
553
  array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
553
554
  volatile VALUE rval = cstr_to_rstr(str, len);
554
-
555
+
555
556
  rb_ary_push(stack_peek(&pi->stack)->val, rval);
556
557
  if (Yes == pi->options.trace) {
557
558
  oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, rval);
@@ -628,4 +629,3 @@ oj_wab_parse_cstr(int argc, VALUE *argv, char *json, size_t len) {
628
629
 
629
630
  return oj_pi_parse(argc, argv, &pi, json, len, true);
630
631
  }
631
-
@@ -1,5 +1,5 @@
1
1
 
2
2
  module Oj
3
3
  # Current version of the module.
4
- VERSION = '3.10.0'
4
+ VERSION = '3.10.6'
5
5
  end
@@ -80,6 +80,45 @@ The classes that can be put in optimized mode and are optimized when
80
80
  The ActiveSupport decoder is the `JSON.parse()` method. Calling the
81
81
  `Oj::Rails.set_decoder()` method replaces that method with the Oj equivalent.
82
82
 
83
+ ### Usage in Rails 3
84
+
85
+ To support Rails 3 you can create a new module mixin to prepend to controllers:
86
+
87
+ ```ruby
88
+ require 'oj'
89
+
90
+ module OjJsonEncoder
91
+ def render(options = nil, extra_options = {}, &block)
92
+ if options && options.is_a?(Hash) && options[:json]
93
+ obj = options.delete(:json)
94
+ obj = Oj.dump(obj, :mode => :rails) unless obj.is_a?(String)
95
+ options[:text] = obj
96
+ response.content_type ||= Mime::JSON
97
+ end
98
+ super
99
+ end
100
+ end
101
+ ```
102
+
103
+ Usage:
104
+
105
+ ```ruby
106
+ class MyController < ApplicationController
107
+ prepend OjJsonEncoder
108
+ def index
109
+ render :json => { :hello => 'world' }
110
+ end
111
+ end
112
+ ```
113
+
114
+ ### Older Ruby Version Support (Pre 2.3.0)
115
+
116
+ If you are using an older version of Ruby, you can pin `oj` to an earlier version in your Gemfile:
117
+
118
+ ```ruby
119
+ gem 'oj', '3.7.12'
120
+ ```
121
+
83
122
  ### Notes:
84
123
 
85
124
  1. Optimized Floats set the significant digits to 16. This is different than
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- # encoding: UTF-8
3
2
 
4
3
  $: << File.dirname(__FILE__)
5
4
  $oj_dir = File.dirname(File.expand_path(File.dirname(__FILE__)))
@@ -7,16 +6,30 @@ $oj_dir = File.dirname(File.expand_path(File.dirname(__FILE__)))
7
6
  $: << File.join($oj_dir, dir)
8
7
  end
9
8
 
10
- require 'rails'
11
9
  require 'active_support'
12
- require 'active_support/json'
10
+ require "active_support/json"
13
11
 
14
- require 'oj'
12
+ $s = "\u2014 & \n \u{1F618}"
13
+
14
+ =begin
15
+ def check(label)
16
+ puts "\n--- #{label} --------------------"
17
+
18
+ ActiveSupport::JSON::Encoding.use_standard_json_time_format = true
19
+ puts "with standard_json == true: t.to_json - #{$t.to_json}"
20
+ ActiveSupport::JSON::Encoding.use_standard_json_time_format = false
21
+ puts "with standard_json == false: t.to_json - #{$t.to_json}"
22
+ end
23
+
24
+ check('Before Oj')
25
+ =end
15
26
 
16
- puts Rails::VERSION::STRING
27
+ require 'oj'
17
28
 
18
- #Oj.optimize_rails
29
+ ActiveSupport::JSON::Encoding.escape_html_entities_in_json = false
30
+ puts "ActiveSupport.encode(s) - #{ActiveSupport::JSON.encode($s)}"
19
31
 
20
- h = {foo: "bar"}
32
+ Oj.optimize_rails
33
+ Oj.default_options = { mode: :rails }
21
34
 
22
- puts Oj.dump(h, mode: :rails)
35
+ puts "Oj.dump(s) - #{Oj.dump($s)}"
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- # encoding: UTF-8
3
2
 
4
3
  $: << File.dirname(__FILE__)
5
4
  $oj_dir = File.dirname(File.expand_path(File.dirname(__FILE__)))
@@ -7,161 +6,47 @@ $oj_dir = File.dirname(File.expand_path(File.dirname(__FILE__)))
7
6
  $: << File.join($oj_dir, dir)
8
7
  end
9
8
 
10
- #require 'json'
9
+ require 'json'
10
+
11
+ t = [Time.now.utc]
12
+
13
+ puts "t.to_json - #{t.to_json}"
14
+
15
+ puts "--- active support"
16
+
17
+ require 'active_support'
18
+ require "active_support/json"
19
+
20
+ ActiveSupport::JSON::Encoding.use_standard_json_time_format = false
21
+
22
+ puts "t.as_json - #{t.as_json}"
23
+ puts "t.to_json - #{t.to_json}"
24
+
11
25
  require 'oj'
12
26
 
13
- Oj.mimic_JSON
14
-
15
- obj = {
16
- ab: {
17
- cbbb: {
18
- tilbeb: [
19
- {
20
- coob: {
21
- uijwts: [
22
- {
23
- prrrrr: {
24
- yakj: "pvebbx",
25
- lbhqy: {
26
- uhyw: {
27
- uijwts: [
28
- {
29
- jangi: {
30
- ubentg7haineued8atnr8w: {
31
- abc: "uejdncbncnamnasdasdasdasd",
32
- cde: "skfjskdfjskdfjsdkfjsdkfjs"
33
- }
34
- }
35
- }
36
- ]
37
- }
38
- }
39
- }
40
- },
41
- {
42
- kdncg: {
43
- lvbnt8b9ounv: {
44
- qk: 9
45
- }
46
- }
47
- }
48
- ],
49
- jenfjbhe: {}
50
- }
51
- }
52
- ]
53
- }
54
- },
55
- ijbh: {
56
- jsnbrpbnunt: {
57
- b88dibalbvp: {
58
- mnbvd: "9uhbqlpiev"
59
- }
60
- },
61
- ncnwkl: {
62
- ksdfsf: {
63
- mjln: "mnklkn"
64
- },
65
- kbrh: {
66
- sdfn83nnalbmgnansdd: {
67
- uijwts: {
68
- ibha: {
69
- uijwts: [
70
- {
71
- lnrbf: {
72
- nbvtmqbhap9ebeb7btnnaw: {
73
- ksb: "sdfksdfjsdfsb39242dnasddd",
74
- mnm: "1293dsfnsdmfnsdfsd,fmnsd,"
75
- }
76
- }
77
- }
78
- ]
79
- }
80
- },
81
- kbrh: {
82
- bo8libts: {
83
- nag40n: {
84
- kyen: "sdfasnc92nsn"
85
- },
86
- kbrh: {
87
- nbwyu26snfcbajsdkj8: {
88
- uijwts: {
89
- mdfnkjsdd: {}
90
- },
91
- kbrh: {
92
- kneahce: {
93
- uijwts: {
94
- kwnb: {
95
- uijwts: [
96
- {
97
- fhfd: {
98
- sfasdnfmasndfamsdnfajsmdf: false
99
- }
100
- }
101
- ],
102
- asdfsdff: [
103
- {
104
- cwdf: {
105
- sddlkfajsdkfjabskdfjalsdkfjansdkfjf: ""
106
- }
107
- },
108
- {
109
- bsdj: {
110
- sdfsjdlfkasy8kljsfsdf83jlkjfals: true
111
- }
112
- }
113
- ]
114
- }
115
- },
116
- kbrh: {
117
- sdfsdfsddfk: {
118
- uijwts: {
119
- sdfsd: {
120
- sdfsadf89mnlrrrqurqwvdnff: {
121
- "kj": 8
122
- }
123
- }
124
- },
125
- kbrh: {
126
- dkdjd: {
127
- dfeteu: {
128
- sdfd: "sdfasdfjlkjslrsdbb"
129
- },
130
- kbrh: {
131
- sdfskjdfldk: {
132
- buqpen: {
133
- kjlkj: {
134
- sdflskdjfalsdkrjalwkjfsrlfjasdf: {
135
- sd: 0
136
- }
137
- }
138
- },
139
- kbrh: {
140
- sdfksljdlfksdfl: {
141
- sdfsdkfjssd: {
142
- ksdjf: "sdflsdkfjasdkaufs;ldkfjsdlf",
143
- sdfsdfsl: [5]
144
- }
145
- }
146
- }
147
- }
148
- }
149
- }
150
- }
151
- }
152
- }
153
- }
154
- }
155
- }
156
- }
157
- }
158
- }
159
- }
160
- }
161
- }
162
- }
163
- }
164
-
165
- #Oj.dump(obj)
166
- JSON.pretty_generate(obj)
167
- #JSON.generate(obj)
27
+ t = [Time.now.utc]
28
+
29
+ puts "-----------------------"
30
+
31
+ #puts "t.as_json - #{t.as_json}"
32
+ puts "t.to_json - #{t.to_json}"
33
+
34
+ #Oj.mimic_JSON
35
+
36
+ #puts "Oj - t.as_json - #{t.as_json}"
37
+
38
+ puts "--- active support"
39
+
40
+ require 'active_support'
41
+ require "active_support/json"
42
+
43
+ ActiveSupport::JSON::Encoding.use_standard_json_time_format = false
44
+
45
+ puts "t.as_json - #{t.as_json}"
46
+ puts "t.to_json - #{t.to_json}"
47
+
48
+ puts "--- optimize"
49
+ Oj.optimize_rails
50
+
51
+ puts "t.as_json - #{t.as_json}"
52
+ puts "t.to_json - #{t.to_json}"
@@ -15,7 +15,7 @@ class JSONCommonInterfaceTest < Test::Unit::TestCase
15
15
  def setup
16
16
  @hash = {
17
17
  'a' => 2,
18
- 'b' => 3.141,
18
+ 'b' => 5.23683071,
19
19
  'c' => 'c',
20
20
  'd' => [ 1, "b", 3.14 ],
21
21
  'e' => { 'foo' => 'bar' },
@@ -23,7 +23,7 @@ class JSONCommonInterfaceTest < Test::Unit::TestCase
23
23
  'h' => 1000.0,
24
24
  'i' => 0.001
25
25
  }
26
- @json = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},'\
26
+ @json = '{"a":2,"b":5.23683071,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},'\
27
27
  '"g":"\\"\\u0000\\u001f","h":1000.0,"i":0.001}'
28
28
  end
29
29
 
@@ -470,10 +470,10 @@ class CustomJuice < Minitest::Test
470
470
 
471
471
  def test_time
472
472
  obj = Time.now()
473
- dump_and_load(obj, false, :time_format => :unix, :create_id => "^o", :create_additions => true)
474
- dump_and_load_inspect(obj, false, :time_format => :unix_zone, :create_id => "^o", :create_additions => true)
475
- dump_and_load_inspect(obj, false, :time_format => :xmlschema, :create_id => "^o", :create_additions => true)
476
- dump_and_load_inspect(obj, false, :time_format => :ruby, :create_id => "^o", :create_additions => true)
473
+ dump_load_dump(obj, false, :time_format => :unix, :create_id => "^o", :create_additions => true)
474
+ dump_load_dump(obj, false, :time_format => :unix_zone, :create_id => "^o", :create_additions => true)
475
+ dump_load_dump(obj, false, :time_format => :xmlschema, :create_id => "^o", :create_additions => true)
476
+ dump_load_dump(obj, false, :time_format => :ruby, :create_id => "^o", :create_additions => true)
477
477
  end
478
478
 
479
479
  def dump_and_load(obj, trace=false, options={})
@@ -504,4 +504,19 @@ class CustomJuice < Minitest::Test
504
504
  loaded
505
505
  end
506
506
 
507
+ def dump_load_dump(obj, trace=false, options={})
508
+ options = options.merge(:indent => 2, :mode => :custom)
509
+ json = Oj.dump(obj, options)
510
+ puts json if trace
511
+
512
+ loaded = Oj.load(json, options);
513
+ if obj.nil?
514
+ assert_nil(loaded)
515
+ else
516
+ json2 = Oj.dump(loaded, options)
517
+ assert_equal(json, json2)
518
+ end
519
+ loaded
520
+ end
521
+
507
522
  end
@@ -869,6 +869,14 @@ class ObjectJuice < Minitest::Test
869
869
  assert_equal(a2[1].__id__, a2.__id__)
870
870
  end
871
871
 
872
+ def test_circular_array3
873
+ a = ['^r1']
874
+ json = Oj.dump(a, mode: :object, circular: true)
875
+ assert_equal(%{["^i1","\\u005er1"]}, json)
876
+ a2 = Oj.load(json, mode: :object, circular: true)
877
+ assert_equal(a, a2)
878
+ end
879
+
872
880
  def test_circular_hash2
873
881
  h = { 'a' => 7 }
874
882
  h['b'] = h
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ $: << File.dirname(__FILE__)
5
+
6
+ require 'helper'
7
+
8
+ class RailsJuice < Minitest::Test
9
+
10
+ def test_bigdecimal_dump
11
+ orig = Oj.default_options
12
+ Oj.default_options = { mode: :rails, bigdecimal_as_decimal: true }
13
+ bd = BigDecimal('123')
14
+ json = Oj.dump(bd)
15
+ Oj.default_options = orig
16
+
17
+ assert_equal('0.123e3', json.downcase)
18
+
19
+ json = Oj.dump(bd, mode: :rails, bigdecimal_as_decimal: false)
20
+ assert_equal('"0.123e3"', json.downcase)
21
+
22
+ json = Oj.dump(bd, mode: :rails, bigdecimal_as_decimal: true)
23
+ assert_equal('0.123e3', json.downcase)
24
+ end
25
+
26
+ end
@@ -19,6 +19,7 @@ require 'test_saj'
19
19
  require 'test_scp'
20
20
  require 'test_strict'
21
21
  require 'test_various'
22
+ require 'test_rails'
22
23
  require 'test_wab'
23
24
  require 'test_writer'
24
25
  require 'test_integer_range'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oj
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.10.0
4
+ version: 3.10.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Ohler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-28 00:00:00.000000000 Z
11
+ date: 2020-04-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler
@@ -243,6 +243,7 @@ files:
243
243
  - test/test_integer_range.rb
244
244
  - test/test_null.rb
245
245
  - test/test_object.rb
246
+ - test/test_rails.rb
246
247
  - test/test_saj.rb
247
248
  - test/test_scp.rb
248
249
  - test/test_strict.rb
@@ -282,7 +283,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
282
283
  - !ruby/object:Gem::Version
283
284
  version: '0'
284
285
  requirements: []
285
- rubygems_version: 3.0.3
286
+ rubygems_version: 3.1.2
286
287
  signing_key:
287
288
  specification_version: 4
288
289
  summary: A fast JSON parser and serializer.
@@ -354,6 +355,7 @@ test_files:
354
355
  - test/baz.rb
355
356
  - test/tests_mimic_addition.rb
356
357
  - test/test_writer.rb
358
+ - test/test_rails.rb
357
359
  - test/perf.rb
358
360
  - test/isolated/test_mimic_define.rb
359
361
  - test/isolated/test_mimic_after.rb