oj 3.13.9 → 3.13.10

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: 646e1253e68f33e284b1efa4ec5f6c3ad9de2e52a1f4ddfbb37435ceb5e23bd0
4
- data.tar.gz: 775d9f0169d77a6f06990cf0d1f0e1904a530567d0939471f326e7ec5ee24c37
3
+ metadata.gz: e4f2c04b24ed0dc8c781036c17371378649d1aad9b927b402b2b0f3d67f9f94b
4
+ data.tar.gz: 65b50beb64e09569e7bcdcff9675a60b146de5ed78027b90de5def8eb6b57aa8
5
5
  SHA512:
6
- metadata.gz: f15a8a5dabfece0fb92ebfd2be99d567890441a2774c361646fc0ab03eba1de0070106cdc0addcc6fa75cf797dcd568b2f0129954c5debbe9ffa334ea8aa7fc4
7
- data.tar.gz: 9d3d0d399610c5209a6819df7583368c14250311249ff3f42a67c868057b96fb8f89c12657aeaf36f1ef545793038aece84f8a7524f40f77ed8636fe6d9e09f5
6
+ metadata.gz: 62a4e36ea67596152899cf389502a69f4f19b354dc5980c66b31ad5163b932245030bfd338ad582ec101572b56fd280c0e784b1d20567f830933627274506503
7
+ data.tar.gz: 671d6a7066b4f74c164ce4af83acbab38fcb0743c97c13985ad4f8e7f1431f67288d1bb80f74b7e55d90d6c5e727e01dc72b138b7dfda3220cbc55ae3ebf2856
data/CHANGELOG.md CHANGED
@@ -1,6 +1,11 @@
1
1
  # CHANGELOG
2
2
 
3
3
 
4
+ ## 3.13.10 - 2021-12-12
5
+
6
+ - Fixed Oj::Doc re-entrant issue with each_child.
7
+ - Fixed each_child on empty Oj::Doc.
8
+
4
9
  ## 3.13.9 - 2021-10-06
5
10
 
6
11
  - Fix mimic JSON load so that it honors the `:symbolize_names` option.
data/README.md CHANGED
@@ -43,6 +43,15 @@ or in Bundler:
43
43
  gem 'oj'
44
44
  ```
45
45
 
46
+ ## Rails and json quickstart
47
+
48
+ See the Quickstart sections of the [Rails](pages/Rails.md) and [json](pages/JsonGem.md) docs.
49
+
50
+ ## multi_json
51
+
52
+ Code which uses [multi_json](https://github.com/intridea/multi_json)
53
+ will automatically prefer Oj if it is installed.
54
+
46
55
  ## Support
47
56
 
48
57
  [Get supported Oj with a Tidelift Subscription.](https://tidelift.com/subscription/pkg/rubygems-oj?utm_source=rubygems-oj&utm_medium=referral&utm_campaign=readme) Security updates are [supported](https://tidelift.com/security).
data/ext/oj/custom.c CHANGED
@@ -282,7 +282,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
282
282
  Out out = (Out)ov;
283
283
  int depth = out->depth;
284
284
 
285
- if (oj_dump_ignore(out->opts, value)) {
285
+ if (dump_ignore(out->opts, value)) {
286
286
  return ST_CONTINUE;
287
287
  }
288
288
  if (out->omit_nil && Qnil == value) {
@@ -577,7 +577,7 @@ static int dump_attr_cb(ID key, VALUE value, VALUE ov) {
577
577
  size_t size;
578
578
  const char *attr;
579
579
 
580
- if (oj_dump_ignore(out->opts, value)) {
580
+ if (dump_ignore(out->opts, value)) {
581
581
  return ST_CONTINUE;
582
582
  }
583
583
  if (out->omit_nil && Qnil == value) {
@@ -749,7 +749,7 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
749
749
  } else {
750
750
  fill_indent(out, d2);
751
751
  }
752
- oj_dump_custom_val(rb_ary_entry(a, i), d2, out, true);
752
+ oj_dump_custom_val(RARRAY_AREF(a, i), d2, out, true);
753
753
  if (i < cnt) {
754
754
  *out->cur++ = ',';
755
755
  }
@@ -833,7 +833,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
833
833
  v = rb_struct_aref(obj, INT2FIX(i));
834
834
  #endif
835
835
  if (ma != Qnil) {
836
- volatile VALUE s = rb_sym2str(rb_ary_entry(ma, i));
836
+ volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
837
837
 
838
838
  name = RSTRING_PTR(s);
839
839
  len = (int)RSTRING_LEN(s);
data/ext/oj/dump.c CHANGED
@@ -1225,17 +1225,3 @@ int oj_dump_float_printf(char *buf, size_t blen, VALUE obj, double d, const char
1225
1225
  }
1226
1226
  return cnt;
1227
1227
  }
1228
-
1229
- bool oj_dump_ignore(Options opts, VALUE obj) {
1230
- if (NULL != opts->ignore && (ObjectMode == opts->mode || CustomMode == opts->mode)) {
1231
- VALUE *vp = opts->ignore;
1232
- VALUE clas = rb_obj_class(obj);
1233
-
1234
- for (; Qnil != *vp; vp++) {
1235
- if (clas == *vp) {
1236
- return true;
1237
- }
1238
- }
1239
- }
1240
- return false;
1241
- }
data/ext/oj/dump.h CHANGED
@@ -50,7 +50,6 @@ extern VALUE oj_remove_to_json(int argc, VALUE *argv, VALUE self);
50
50
 
51
51
  extern int oj_dump_float_printf(char *buf, size_t blen, VALUE obj, double d, const char *format);
52
52
 
53
- extern bool oj_dump_ignore(Options opts, VALUE obj);
54
53
  extern time_t oj_sec_from_time_hard_way(VALUE obj);
55
54
 
56
55
  inline static void assure_size(Out out, size_t len) {
@@ -69,6 +68,20 @@ inline static void fill_indent(Out out, int cnt) {
69
68
  }
70
69
  }
71
70
 
71
+ inline static bool dump_ignore(Options opts, VALUE obj) {
72
+ if (NULL != opts->ignore && (ObjectMode == opts->mode || CustomMode == opts->mode)) {
73
+ VALUE *vp = opts->ignore;
74
+ VALUE clas = rb_obj_class(obj);
75
+
76
+ for (; Qnil != *vp; vp++) {
77
+ if (clas == *vp) {
78
+ return true;
79
+ }
80
+ }
81
+ }
82
+ return false;
83
+ }
84
+
72
85
  inline static void dump_ulong(unsigned long num, Out out) {
73
86
  char buf[32];
74
87
  char *b = buf + sizeof(buf) - 1;
data/ext/oj/dump_compat.c CHANGED
@@ -182,7 +182,7 @@ dump_array(VALUE a, int depth, Out out, bool as_ok) {
182
182
  } else {
183
183
  fill_indent(out, d2);
184
184
  }
185
- oj_dump_compat_val(rb_ary_entry(a, i), d2, out, true);
185
+ oj_dump_compat_val(RARRAY_AREF(a, i), d2, out, true);
186
186
  if (i < cnt) {
187
187
  *out->cur++ = ',';
188
188
  }
data/ext/oj/dump_object.c CHANGED
@@ -157,7 +157,7 @@ static void dump_array_class(VALUE a, VALUE clas, int depth, Out out) {
157
157
  } else {
158
158
  fill_indent(out, d2);
159
159
  }
160
- oj_dump_obj_val(rb_ary_entry(a, i), d2, out);
160
+ oj_dump_obj_val(RARRAY_AREF(a, i), d2, out);
161
161
  if (i < cnt) {
162
162
  *out->cur++ = ',';
163
163
  }
@@ -218,7 +218,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
218
218
  int depth = out->depth;
219
219
  long size = depth * out->indent + 1;
220
220
 
221
- if (oj_dump_ignore(out->opts, value)) {
221
+ if (dump_ignore(out->opts, value)) {
222
222
  return ST_CONTINUE;
223
223
  }
224
224
  if (out->omit_nil && Qnil == value) {
@@ -226,47 +226,54 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
226
226
  }
227
227
  assure_size(out, size);
228
228
  fill_indent(out, depth);
229
- if (rb_type(key) == T_STRING) {
229
+ switch (rb_type(key)) {
230
+ case T_STRING:
230
231
  dump_str_class(key, Qundef, depth, out);
231
232
  *out->cur++ = ':';
232
233
  oj_dump_obj_val(value, depth, out);
233
- } else if (rb_type(key) == T_SYMBOL) {
234
+ break;
235
+
236
+ case T_SYMBOL:
234
237
  dump_sym(key, 0, out, false);
235
238
  *out->cur++ = ':';
236
239
  oj_dump_obj_val(value, depth, out);
237
- } else {
238
- int d2 = depth + 1;
239
- long s2 = size + out->indent + 1;
240
- int i;
241
- int started = 0;
242
- uint8_t b;
240
+ break;
243
241
 
244
- assure_size(out, s2 + 15);
245
- *out->cur++ = '"';
246
- *out->cur++ = '^';
247
- *out->cur++ = '#';
248
- out->hash_cnt++;
249
- for (i = 28; 0 <= i; i -= 4) {
250
- b = (uint8_t)((out->hash_cnt >> i) & 0x0000000F);
251
- if ('\0' != b) {
252
- started = 1;
253
- }
254
- if (started) {
255
- *out->cur++ = hex_chars[b];
242
+ default:
243
+ {
244
+ int d2 = depth + 1;
245
+ long s2 = size + out->indent + 1;
246
+ int i;
247
+ int started = 0;
248
+ uint8_t b;
249
+
250
+ assure_size(out, s2 + 15);
251
+ *out->cur++ = '"';
252
+ *out->cur++ = '^';
253
+ *out->cur++ = '#';
254
+ out->hash_cnt++;
255
+ for (i = 28; 0 <= i; i -= 4) {
256
+ b = (uint8_t)((out->hash_cnt >> i) & 0x0000000F);
257
+ if ('\0' != b) {
258
+ started = 1;
259
+ }
260
+ if (started) {
261
+ *out->cur++ = hex_chars[b];
262
+ }
256
263
  }
264
+ *out->cur++ = '"';
265
+ *out->cur++ = ':';
266
+ *out->cur++ = '[';
267
+ fill_indent(out, d2);
268
+ oj_dump_obj_val(key, d2, out);
269
+ assure_size(out, s2);
270
+ *out->cur++ = ',';
271
+ fill_indent(out, d2);
272
+ oj_dump_obj_val(value, d2, out);
273
+ assure_size(out, size);
274
+ fill_indent(out, depth);
275
+ *out->cur++ = ']';
257
276
  }
258
- *out->cur++ = '"';
259
- *out->cur++ = ':';
260
- *out->cur++ = '[';
261
- fill_indent(out, d2);
262
- oj_dump_obj_val(key, d2, out);
263
- assure_size(out, s2);
264
- *out->cur++ = ',';
265
- fill_indent(out, d2);
266
- oj_dump_obj_val(value, d2, out);
267
- assure_size(out, size);
268
- fill_indent(out, depth);
269
- *out->cur++ = ']';
270
277
  }
271
278
  out->depth = depth;
272
279
  *out->cur++ = ',';
@@ -342,7 +349,7 @@ static int dump_attr_cb(ID key, VALUE value, VALUE ov) {
342
349
  size_t size = depth * out->indent + 1;
343
350
  const char *attr = rb_id2name(key);
344
351
 
345
- if (oj_dump_ignore(out->opts, value)) {
352
+ if (dump_ignore(out->opts, value)) {
346
353
  return ST_CONTINUE;
347
354
  }
348
355
  if (out->omit_nil && Qnil == value) {
@@ -605,7 +612,7 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
605
612
  }
606
613
  value = rb_ivar_get(obj, vid);
607
614
 
608
- if (oj_dump_ignore(out->opts, value)) {
615
+ if (dump_ignore(out->opts, value)) {
609
616
  continue;
610
617
  }
611
618
  if (out->omit_nil && Qnil == value) {
@@ -694,7 +701,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
694
701
 
695
702
  *out->cur++ = '[';
696
703
  for (i = 0; i < cnt; i++) {
697
- volatile VALUE s = rb_sym2str(rb_ary_entry(ma, i));
704
+ volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
698
705
 
699
706
  name = RSTRING_PTR(s);
700
707
  len = (int)RSTRING_LEN(s);
@@ -730,7 +737,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
730
737
 
731
738
  for (i = 0; i < cnt; i++) {
732
739
  v = RSTRUCT_GET(obj, i);
733
- if (oj_dump_ignore(out->opts, v)) {
740
+ if (dump_ignore(out->opts, v)) {
734
741
  v = Qnil;
735
742
  }
736
743
  assure_size(out, size);
@@ -748,7 +755,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
748
755
  for (i = 0; i < slen; i++) {
749
756
  assure_size(out, size);
750
757
  fill_indent(out, d3);
751
- if (oj_dump_ignore(out->opts, v)) {
758
+ if (dump_ignore(out->opts, v)) {
752
759
  v = Qnil;
753
760
  }
754
761
  oj_dump_obj_val(rb_struct_aref(obj, INT2FIX(i)), d3, out, 0, 0, true);
data/ext/oj/dump_strict.c CHANGED
@@ -153,9 +153,9 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
153
153
  fill_indent(out, d2);
154
154
  }
155
155
  if (NullMode == out->opts->mode) {
156
- oj_dump_null_val(rb_ary_entry(a, i), d2, out);
156
+ oj_dump_null_val(RARRAY_AREF(a, i), d2, out);
157
157
  } else {
158
- oj_dump_strict_val(rb_ary_entry(a, i), d2, out);
158
+ oj_dump_strict_val(RARRAY_AREF(a, i), d2, out);
159
159
  }
160
160
  if (i < cnt) {
161
161
  *out->cur++ = ',';
data/ext/oj/fast.c CHANGED
@@ -771,7 +771,7 @@ static VALUE parse_json(VALUE clas, char *json, bool given, bool allocated) {
771
771
  pi.doc = doc;
772
772
  #if IS_WINDOWS
773
773
  // assume a 1M stack and give half to ruby
774
- pi.stack_min = (void*)((char*)&pi - (512 * 1024));
774
+ pi.stack_min = (void *)((char *)&pi - (512 * 1024));
775
775
  #else
776
776
  {
777
777
  struct rlimit lim;
@@ -1492,6 +1492,7 @@ static VALUE doc_each_child(int argc, VALUE *argv, VALUE self) {
1492
1492
  Doc doc = self_doc(self);
1493
1493
  const char *path = 0;
1494
1494
  size_t wlen;
1495
+ Leaf * where_orig = doc->where;
1495
1496
 
1496
1497
  wlen = doc->where - doc->where_path;
1497
1498
  if (0 < wlen) {
@@ -1508,9 +1509,13 @@ static VALUE doc_each_child(int argc, VALUE *argv, VALUE self) {
1508
1509
  if (0 < wlen) {
1509
1510
  memcpy(doc->where_path, save_path, sizeof(Leaf) * (wlen + 1));
1510
1511
  }
1512
+ doc->where = where_orig;
1511
1513
  return Qnil;
1512
1514
  }
1513
1515
  }
1516
+ if (NULL == doc->where || NULL == *doc->where) {
1517
+ return Qnil;
1518
+ }
1514
1519
  if (COL_VAL == (*doc->where)->value_type && 0 != (*doc->where)->elements) {
1515
1520
  Leaf first = (*doc->where)->elements->next;
1516
1521
  Leaf e = first;
@@ -1525,6 +1530,7 @@ static VALUE doc_each_child(int argc, VALUE *argv, VALUE self) {
1525
1530
  if (0 < wlen) {
1526
1531
  memcpy(doc->where_path, save_path, sizeof(Leaf) * (wlen + 1));
1527
1532
  }
1533
+ doc->where = where_orig;
1528
1534
  }
1529
1535
  return Qnil;
1530
1536
  }
data/ext/oj/mimic_json.c CHANGED
@@ -272,7 +272,7 @@ static int mimic_walk(VALUE key, VALUE obj, VALUE proc) {
272
272
  size_t i;
273
273
 
274
274
  for (i = 0; i < cnt; i++) {
275
- mimic_walk(Qnil, rb_ary_entry(obj, i), proc);
275
+ mimic_walk(Qnil, RARRAY_AREF(obj, i), proc);
276
276
  }
277
277
  break;
278
278
  }
@@ -499,6 +499,52 @@ oj_mimic_pretty_generate(int argc, VALUE *argv, VALUE self) {
499
499
  return mimic_generate_core(2, rargs, &copts);
500
500
  }
501
501
 
502
+ static int parse_options_cb(VALUE k, VALUE v, VALUE info) {
503
+ struct _parseInfo *pi = (struct _parseInfo *)info;
504
+
505
+ if (oj_symbolize_names_sym == k) {
506
+ pi->options.sym_key = (Qtrue == v) ? Yes : No;
507
+ } else if (oj_quirks_mode_sym == k) {
508
+ pi->options.quirks_mode = (Qtrue == v) ? Yes : No;
509
+ } else if (oj_create_additions_sym == k) {
510
+ pi->options.create_ok = (Qtrue == v) ? Yes : No;
511
+ } else if (oj_allow_nan_sym == k) {
512
+ pi->options.allow_nan = (Qtrue == v) ? Yes : No;
513
+ } else if (oj_hash_class_sym == k) {
514
+ if (Qnil == v) {
515
+ pi->options.hash_class = Qnil;
516
+ } else {
517
+ rb_check_type(v, T_CLASS);
518
+ pi->options.hash_class = v;
519
+ }
520
+ } else if (oj_object_class_sym == k) {
521
+ if (Qnil == v) {
522
+ pi->options.hash_class = Qnil;
523
+ } else {
524
+ rb_check_type(v, T_CLASS);
525
+ pi->options.hash_class = v;
526
+ }
527
+ } else if (oj_array_class_sym == k) {
528
+ if (Qnil == v) {
529
+ pi->options.array_class = Qnil;
530
+ } else {
531
+ rb_check_type(v, T_CLASS);
532
+ pi->options.array_class = v;
533
+ }
534
+ } else if (oj_decimal_class_sym == k) {
535
+ pi->options.compat_bigdec = (oj_bigdecimal_class == v);
536
+ } else if (oj_max_nesting_sym == k) {
537
+ if (Qtrue == v) {
538
+ pi->max_depth = 100;
539
+ } else if (Qfalse == v || Qnil == v) {
540
+ pi->max_depth = 0;
541
+ } else if (T_FIXNUM == rb_type(v)) {
542
+ pi->max_depth = NUM2INT(v);
543
+ }
544
+ }
545
+ return ST_CONTINUE;
546
+ }
547
+
502
548
  static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
503
549
  struct _parseInfo pi;
504
550
  VALUE ropts;
@@ -524,59 +570,11 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
524
570
  pi.max_depth = 100;
525
571
 
526
572
  if (Qnil != ropts) {
527
- VALUE v;
528
-
529
573
  if (T_HASH != rb_type(ropts)) {
530
574
  rb_raise(rb_eArgError, "options must be a hash.");
531
575
  }
532
- if (Qnil != (v = rb_hash_lookup(ropts, oj_symbolize_names_sym))) {
533
- pi.options.sym_key = (Qtrue == v) ? Yes : No;
534
- }
535
- if (Qnil != (v = rb_hash_lookup(ropts, oj_quirks_mode_sym))) {
536
- pi.options.quirks_mode = (Qtrue == v) ? Yes : No;
537
- }
538
- if (Qnil != (v = rb_hash_lookup(ropts, oj_create_additions_sym))) {
539
- pi.options.create_ok = (Qtrue == v) ? Yes : No;
540
- }
541
- if (Qnil != (v = rb_hash_lookup(ropts, oj_allow_nan_sym))) {
542
- pi.options.allow_nan = (Qtrue == v) ? Yes : No;
543
- }
544
576
 
545
- if (oj_hash_has_key(ropts, oj_hash_class_sym)) {
546
- if (Qnil == (v = rb_hash_lookup(ropts, oj_hash_class_sym))) {
547
- pi.options.hash_class = Qnil;
548
- } else {
549
- rb_check_type(v, T_CLASS);
550
- pi.options.hash_class = v;
551
- }
552
- }
553
- if (oj_hash_has_key(ropts, oj_object_class_sym)) {
554
- if (Qnil == (v = rb_hash_lookup(ropts, oj_object_class_sym))) {
555
- pi.options.hash_class = Qnil;
556
- } else {
557
- rb_check_type(v, T_CLASS);
558
- pi.options.hash_class = v;
559
- }
560
- }
561
- if (oj_hash_has_key(ropts, oj_array_class_sym)) {
562
- if (Qnil == (v = rb_hash_lookup(ropts, oj_array_class_sym))) {
563
- pi.options.array_class = Qnil;
564
- } else {
565
- rb_check_type(v, T_CLASS);
566
- pi.options.array_class = v;
567
- }
568
- }
569
- if (oj_hash_has_key(ropts, oj_decimal_class_sym)) {
570
- pi.options.compat_bigdec = (oj_bigdecimal_class == rb_hash_lookup(ropts, oj_decimal_class_sym));
571
- }
572
- v = rb_hash_lookup(ropts, oj_max_nesting_sym);
573
- if (Qtrue == v) {
574
- pi.max_depth = 100;
575
- } else if (Qfalse == v || Qnil == v) {
576
- pi.max_depth = 0;
577
- } else if (T_FIXNUM == rb_type(v)) {
578
- pi.max_depth = NUM2INT(v);
579
- }
577
+ rb_hash_foreach(ropts, parse_options_cb, (VALUE)&pi);
580
578
  oj_parse_opt_match_string(&pi.options.str_rx, ropts);
581
579
  if (Yes == pi.options.create_ok && Yes == pi.options.sym_key) {
582
580
  rb_raise(rb_eArgError, ":symbolize_names and :create_additions can not both be true.");
data/ext/oj/object.c CHANGED
@@ -325,7 +325,7 @@ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, vol
325
325
  int i, cnt = (int)RARRAY_LEN(e1);
326
326
 
327
327
  for (i = 0; i < cnt; i++) {
328
- rstr = rb_ary_entry(e1, i);
328
+ rstr = RARRAY_AREF(e1, i);
329
329
  args[i] = rb_funcall(rstr, oj_to_sym_id, 0);
330
330
  }
331
331
  sc = rb_funcall2(rb_cStruct, oj_new_id, cnt, args);
data/ext/oj/oj.c CHANGED
@@ -916,7 +916,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
916
916
 
917
917
  copts->ignore = ALLOC_N(VALUE, cnt + 1);
918
918
  for (i = 0; i < cnt; i++) {
919
- copts->ignore[i] = rb_ary_entry(v, i);
919
+ copts->ignore[i] = RARRAY_AREF(v, i);
920
920
  }
921
921
  copts->ignore[i] = Qnil;
922
922
  }
data/ext/oj/rails.c CHANGED
@@ -157,7 +157,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
157
157
  assure_size(out, 2);
158
158
  *out->cur++ = '{';
159
159
  for (i = 0; i < cnt; i++) {
160
- volatile VALUE s = rb_sym2str(rb_ary_entry(ma, i));
160
+ volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
161
161
 
162
162
  name = RSTRING_PTR(s);
163
163
  len = (int)RSTRING_LEN(s);
@@ -383,7 +383,7 @@ static StrLen columns_array(VALUE rcols, int *ccnt) {
383
383
  *ccnt = cnt;
384
384
  cols = ALLOC_N(struct _strLen, cnt);
385
385
  for (i = 0, cp = cols; i < cnt; i++, cp++) {
386
- v = rb_ary_entry(rcols, i);
386
+ v = RARRAY_AREF(rcols, i);
387
387
  if (T_STRING != rb_type(v)) {
388
388
  v = rb_funcall(v, oj_to_s_id, 0);
389
389
  }
@@ -420,7 +420,7 @@ static void dump_row(VALUE row, StrLen cols, int ccnt, int depth, Out out) {
420
420
  }
421
421
  oj_dump_cstr(cols->str, cols->len, 0, 0, out);
422
422
  *out->cur++ = ':';
423
- dump_rails_val(rb_ary_entry(row, i), depth, out, true);
423
+ dump_rails_val(RARRAY_AREF(row, i), depth, out, true);
424
424
  if (i < ccnt - 1) {
425
425
  *out->cur++ = ',';
426
426
  }
@@ -490,7 +490,7 @@ static void dump_activerecord_result(VALUE obj, int depth, Out out, bool as_ok)
490
490
  } else {
491
491
  fill_indent(out, d2);
492
492
  }
493
- dump_row(rb_ary_entry(rows, i), cols, ccnt, d2, out);
493
+ dump_row(RARRAY_AREF(rows, i), cols, ccnt, d2, out);
494
494
  if (i < rcnt - 1) {
495
495
  *out->cur++ = ',';
496
496
  }
@@ -1281,7 +1281,7 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
1281
1281
  } else {
1282
1282
  fill_indent(out, d2);
1283
1283
  }
1284
- dump_rails_val(rb_ary_entry(a, i), d2, out, true);
1284
+ dump_rails_val(RARRAY_AREF(a, i), d2, out, true);
1285
1285
  if (i < cnt) {
1286
1286
  *out->cur++ = ',';
1287
1287
  }
data/ext/oj/wab.c CHANGED
@@ -128,7 +128,7 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
128
128
  for (i = 0; i <= cnt; i++) {
129
129
  assure_size(out, size);
130
130
  fill_indent(out, d2);
131
- oj_dump_wab_val(rb_ary_entry(a, i), d2, out);
131
+ oj_dump_wab_val(RARRAY_AREF(a, i), d2, out);
132
132
  if (i < cnt) {
133
133
  *out->cur++ = ',';
134
134
  }
data/lib/oj/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
2
  module Oj
3
3
  # Current version of the module.
4
- VERSION = '3.13.9'
4
+ VERSION = '3.13.10'
5
5
  end
data/pages/JsonGem.md CHANGED
@@ -1,3 +1,18 @@
1
+ # JSON Quickstart
2
+
3
+ To have Oj universally "take over" many methods on the JSON constant (`load`, `parse`, etc.) with
4
+ their faster Oj counterparts, in a mode that is compatible with the json gem:
5
+
6
+ ```ruby
7
+ Oj.mimic_JSON()
8
+ ```
9
+
10
+ If the project does not already use the json gem, `JSON` will become available.
11
+ If the project does require the json gem, `Oj.mimic_JSON()` should be invoked after the
12
+ json gem has been required.
13
+
14
+ For more details and options, read on...
15
+
1
16
  # Oj JSON Gem Compatibility
2
17
 
3
18
  The `:compat` mode mimics the json gem. The json gem is built around the use
data/pages/Modes.md CHANGED
@@ -39,7 +39,8 @@ if a non-native type is encountered instead of raising an Exception.
39
39
  The `:compat` mode mimics the json gem. The json gem is built around the use
40
40
  of the `to_json(*)` method defined for a class. Oj attempts to provide the
41
41
  same functionality by being a drop in replacement with a few
42
- exceptions. [{file:JsonGem.md}](JsonGem.md) includes more details on
42
+ exceptions. To universally replace many `JSON` methods with their faster Oj counterparts,
43
+ simply run `Oj.mimic_json`. [{file:JsonGem.md}](JsonGem.md) includes more details on
43
44
  compatibility and use.
44
45
 
45
46
  ## :rails Mode
@@ -108,11 +109,11 @@ information.
108
109
  | :float_precision | Fixnum | x | x | | | | x | |
109
110
  | :hash_class | Class | | | x | x | | x | |
110
111
  | :ignore | Array | | | | | x | x | |
111
- | :indent | Integer | x | x | 3 | 4 | x | x | x |
112
+ | :indent | Integer | x | x | 4 | 4 | x | x | x |
112
113
  | :indent_str | String | | | x | x | | x | |
113
114
  | :integer_range | Range | x | x | x | x | x | x | x |
114
115
  | :match_string | Hash | | | x | x | | x | |
115
- | :max_nesting | Fixnum | 4 | 4 | x | | 5 | 4 | |
116
+ | :max_nesting | Fixnum | 5 | 5 | x | | 5 | 5 | |
116
117
  | :mode | Symbol | - | - | - | - | - | - | |
117
118
  | :nan | Symbol | | | | | | x | |
118
119
  | :nilnil | Boolean | | | | | | x | |
@@ -140,6 +141,8 @@ information.
140
141
  3. By default the bigdecimal_as decimal is not set and the default encoding
141
142
  for Rails is as a string. Setting the value to true will encode a
142
143
  BigDecimal as a number which breaks compatibility.
144
+ Note: after version 3.11.3 both `Oj.generate` and `JSON.generate`
145
+ will not honour this option in Rails Mode, detais on https://github.com/ohler55/oj/pull/716.
143
146
 
144
147
  4. The integer indent value in the default options will be honored by since
145
148
  the json gem expects a String type the indent in calls to 'to_json()',
data/pages/Rails.md CHANGED
@@ -1,3 +1,15 @@
1
+ # Rails Quickstart
2
+
3
+ To universally replace Rails' use of the json gem with Oj, and also
4
+ have Oj "take over" many methods on the JSON constant (`load`, `parse`, etc.) with
5
+ their faster Oj counterparts, add this to an initializer:
6
+
7
+ ```ruby
8
+ Oj.optimize_rails()
9
+ ```
10
+
11
+ For more details and options, read on...
12
+
1
13
  # Oj Rails Compatibility
2
14
 
3
15
  The `:rails` mode mimics the ActiveSupport version 5 encoder. Rails and
data/test/foo.rb CHANGED
@@ -4,17 +4,32 @@ $: << '.'
4
4
  $: << File.join(File.dirname(__FILE__), "../lib")
5
5
  $: << File.join(File.dirname(__FILE__), "../ext")
6
6
 
7
- # require 'json'
7
+ require 'rails'
8
8
  require 'oj'
9
- Oj.mimic_JSON
10
-
11
- source = %( {"a": 1, "b": 2} )
12
- puts "JSON.load, no symbolize => OK"
13
- pp JSON.load( source )
14
- puts "JSON.load, do symbolize => KO: keys are not symbols"
15
- #pp JSON.load( source, nil, symbolize_names: true, create_additions: false )
16
- pp JSON.load( source, nil, symbolize_names: true, create_additions: false )
17
- puts "JSON.parse, no symbolize => OK"
18
- pp JSON.parse( source )
19
- puts "JSON.parse, do symbolize => OK"
20
- pp JSON.parse( source, symbolize_names: true )
9
+
10
+ $data = {:ticker=>"ASAI3", :price=>18.7, :rate=>-0.8.to_d}
11
+
12
+ def encode
13
+ p "JSON.generate: #{JSON.generate($data)}"
14
+ p "Oj.generate: #{Oj.generate($data)}"
15
+ p "Oj.dump: #{Oj.dump($data)}"
16
+ p "to_json: #{$data.to_json}"
17
+ p "ActiveSupport::JSON.encode: #{ActiveSupport::JSON.encode($data)}"
18
+ end
19
+
20
+ puts "With Oj version (#{Oj::VERSION})"
21
+
22
+ puts
23
+ puts "Before optimizing"
24
+ encode
25
+
26
+ Oj.optimize_rails
27
+ Oj.default_options = {
28
+ mode: :rails,
29
+ bigdecimal_as_decimal: true,
30
+ bigdecimal_load: true
31
+ }
32
+
33
+ puts
34
+ puts "After optimizing"
35
+ encode
data/test/test_fast.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # coding: utf-8
2
3
  # frozen_string_literal: true
3
4
 
4
5
  $: << File.dirname(__FILE__)
@@ -395,6 +396,19 @@ class DocTest < Minitest::Test
395
396
  end
396
397
  end
397
398
 
399
+ def test_nested_each_child
400
+ h = {}
401
+ Oj::Doc.open('{"a":1,"c":[2],"d":3}') do |doc|
402
+ doc.each_child('/') do |child|
403
+ h[child.path] = child.fetch
404
+ child.each_child do |grandchild|
405
+ h[grandchild.path] = grandchild.fetch
406
+ end
407
+ end
408
+ end
409
+ assert_equal({"/a"=>1, "/c"=>[2], "/c/1"=>2, "/d"=>3}, h)
410
+ end
411
+
398
412
  def test_size
399
413
  Oj::Doc.open('[1,2,3]') do |doc|
400
414
  assert_equal(4, doc.size)
@@ -491,6 +505,11 @@ class DocTest < Minitest::Test
491
505
  assert_equal({'/a/x' => 2, '/b/y' => 4}, results)
492
506
  end
493
507
 
508
+ def test_doc_empty
509
+ result = Oj::Doc.open("") { |doc| doc.each_child {} }
510
+ assert_nil(result)
511
+ end
512
+
494
513
  def test_comment
495
514
  json = %{{
496
515
  "x"/*one*/:/*two*/true,//three
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.13.9
4
+ version: 3.13.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Ohler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-06 00:00:00.000000000 Z
11
+ date: 2021-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler