oj 3.13.7 → 3.13.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +75 -0
  3. data/README.md +11 -0
  4. data/ext/oj/buf.h +4 -0
  5. data/ext/oj/circarray.c +1 -1
  6. data/ext/oj/code.c +15 -22
  7. data/ext/oj/compat.c +10 -10
  8. data/ext/oj/custom.c +66 -112
  9. data/ext/oj/dump.c +147 -184
  10. data/ext/oj/dump.h +25 -8
  11. data/ext/oj/dump_compat.c +47 -89
  12. data/ext/oj/dump_leaf.c +14 -58
  13. data/ext/oj/dump_object.c +72 -188
  14. data/ext/oj/dump_strict.c +19 -31
  15. data/ext/oj/encoder.c +43 -0
  16. data/ext/oj/extconf.rb +5 -4
  17. data/ext/oj/fast.c +36 -24
  18. data/ext/oj/intern.c +22 -12
  19. data/ext/oj/intern.h +1 -1
  20. data/ext/oj/mimic_json.c +74 -73
  21. data/ext/oj/object.c +54 -72
  22. data/ext/oj/odd.c +83 -63
  23. data/ext/oj/odd.h +13 -13
  24. data/ext/oj/oj.c +166 -175
  25. data/ext/oj/oj.h +25 -3
  26. data/ext/oj/parse.c +123 -79
  27. data/ext/oj/parse.h +2 -0
  28. data/ext/oj/parser.c +77 -21
  29. data/ext/oj/parser.h +12 -0
  30. data/ext/oj/rails.c +46 -70
  31. data/ext/oj/rails.h +1 -1
  32. data/ext/oj/reader.c +2 -0
  33. data/ext/oj/saj.c +11 -23
  34. data/ext/oj/saj2.c +333 -85
  35. data/ext/oj/saj2.h +23 -0
  36. data/ext/oj/sparse.c +4 -0
  37. data/ext/oj/stream_writer.c +3 -1
  38. data/ext/oj/strict.c +13 -13
  39. data/ext/oj/string_writer.c +12 -5
  40. data/ext/oj/usual.c +86 -131
  41. data/ext/oj/usual.h +68 -0
  42. data/ext/oj/val_stack.c +1 -1
  43. data/ext/oj/validate.c +21 -26
  44. data/ext/oj/wab.c +22 -27
  45. data/lib/oj/saj.rb +20 -6
  46. data/lib/oj/state.rb +1 -1
  47. data/lib/oj/version.rb +1 -1
  48. data/pages/Compatibility.md +1 -1
  49. data/pages/JsonGem.md +15 -0
  50. data/pages/Modes.md +6 -3
  51. data/pages/Options.md +6 -0
  52. data/pages/Rails.md +12 -0
  53. data/test/activesupport7/abstract_unit.rb +49 -0
  54. data/test/activesupport7/decoding_test.rb +125 -0
  55. data/test/activesupport7/encoding_test.rb +486 -0
  56. data/test/activesupport7/encoding_test_cases.rb +104 -0
  57. data/test/activesupport7/time_zone_test_helpers.rb +47 -0
  58. data/test/bar.rb +3 -8
  59. data/test/bug.rb +16 -0
  60. data/test/foo.rb +71 -7
  61. data/test/helper.rb +8 -2
  62. data/test/json_gem/json_generator_test.rb +5 -4
  63. data/test/json_gem/json_parser_test.rb +8 -1
  64. data/test/json_gem/test_helper.rb +7 -3
  65. data/test/perf_dump.rb +50 -0
  66. data/test/test_compat.rb +25 -0
  67. data/test/test_custom.rb +13 -2
  68. data/test/test_fast.rb +37 -7
  69. data/test/test_file.rb +23 -7
  70. data/test/test_gc.rb +11 -0
  71. data/test/test_object.rb +8 -10
  72. data/test/test_parser.rb +3 -19
  73. data/test/test_parser_debug.rb +27 -0
  74. data/test/test_parser_saj.rb +92 -2
  75. data/test/test_saj.rb +1 -1
  76. data/test/test_scp.rb +2 -4
  77. data/test/test_strict.rb +2 -0
  78. data/test/test_various.rb +32 -2
  79. data/test/test_wab.rb +2 -0
  80. data/test/tests.rb +9 -1
  81. data/test/tests_mimic.rb +9 -0
  82. data/test/tests_mimic_addition.rb +9 -0
  83. metadata +15 -115
data/ext/oj/custom.c CHANGED
@@ -31,14 +31,14 @@ static void dump_obj_str(VALUE obj, int depth, Out out) {
31
31
 
32
32
  static void dump_obj_as_str(VALUE obj, int depth, Out out) {
33
33
  volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
34
- const char * str = RSTRING_PTR(rstr);
34
+ const char *str = RSTRING_PTR(rstr);
35
35
 
36
36
  oj_dump_cstr(str, RSTRING_LEN(rstr), 0, 0, out);
37
37
  }
38
38
 
39
39
  static void bigdecimal_dump(VALUE obj, int depth, Out out) {
40
40
  volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
41
- const char * str = RSTRING_PTR(rstr);
41
+ const char *str = RSTRING_PTR(rstr);
42
42
  int len = (int)RSTRING_LEN(rstr);
43
43
 
44
44
  if (0 == strcasecmp("Infinity", str)) {
@@ -82,8 +82,7 @@ static VALUE complex_load(VALUE clas, VALUE args) {
82
82
  real_id = rb_intern("real");
83
83
  imag_id = rb_intern("imag");
84
84
  }
85
- return rb_complex_new(rb_hash_aref(args, rb_id2str(real_id)),
86
- rb_hash_aref(args, rb_id2str(imag_id)));
85
+ return rb_complex_new(rb_hash_aref(args, rb_id2str(real_id)), rb_hash_aref(args, rb_id2str(imag_id)));
87
86
  }
88
87
 
89
88
  static void time_dump(VALUE obj, int depth, Out out) {
@@ -246,8 +245,7 @@ static VALUE rational_load(VALUE clas, VALUE args) {
246
245
  numerator_id = rb_intern("numerator");
247
246
  denominator_id = rb_intern("denominator");
248
247
  }
249
- return rb_rational_new(rb_hash_aref(args, rb_id2str(numerator_id)),
250
- rb_hash_aref(args, rb_id2str(denominator_id)));
248
+ return rb_rational_new(rb_hash_aref(args, rb_id2str(numerator_id)), rb_hash_aref(args, rb_id2str(denominator_id)));
251
249
  }
252
250
 
253
251
  static VALUE regexp_load(VALUE clas, VALUE args) {
@@ -282,7 +280,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
282
280
  Out out = (Out)ov;
283
281
  int depth = out->depth;
284
282
 
285
- if (oj_dump_ignore(out->opts, value)) {
283
+ if (dump_ignore(out->opts, value)) {
286
284
  return ST_CONTINUE;
287
285
  }
288
286
  if (out->omit_nil && Qnil == value) {
@@ -292,18 +290,15 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
292
290
  assure_size(out, depth * out->indent + 1);
293
291
  fill_indent(out, depth);
294
292
  } else {
295
- assure_size(out,
296
- depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
293
+ assure_size(out, depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
297
294
  if (0 < out->opts->dump_opts.hash_size) {
298
- strcpy(out->cur, out->opts->dump_opts.hash_nl);
299
- out->cur += out->opts->dump_opts.hash_size;
295
+ APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
300
296
  }
301
297
  if (0 < out->opts->dump_opts.indent_size) {
302
298
  int i;
303
299
 
304
300
  for (i = depth; 0 < i; i--) {
305
- strcpy(out->cur, out->opts->dump_opts.indent_str);
306
- out->cur += out->opts->dump_opts.indent_size;
301
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
307
302
  }
308
303
  }
309
304
  }
@@ -317,13 +312,11 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
317
312
  } else {
318
313
  assure_size(out, out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2);
319
314
  if (0 < out->opts->dump_opts.before_size) {
320
- strcpy(out->cur, out->opts->dump_opts.before_sep);
321
- out->cur += out->opts->dump_opts.before_size;
315
+ APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
322
316
  }
323
317
  *out->cur++ = ':';
324
318
  if (0 < out->opts->dump_opts.after_size) {
325
- strcpy(out->cur, out->opts->dump_opts.after_sep);
326
- out->cur += out->opts->dump_opts.after_size;
319
+ APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
327
320
  }
328
321
  }
329
322
  oj_dump_custom_val(value, depth, out, true);
@@ -344,8 +337,7 @@ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
344
337
  cnt = (int)RHASH_SIZE(obj);
345
338
  assure_size(out, 2);
346
339
  if (0 == cnt) {
347
- *out->cur++ = '{';
348
- *out->cur++ = '}';
340
+ APPEND_CHARS(out->cur, "{}", 2);
349
341
  } else {
350
342
  *out->cur++ = '{';
351
343
  out->depth = depth + 1;
@@ -357,19 +349,15 @@ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
357
349
  assure_size(out, depth * out->indent + 2);
358
350
  fill_indent(out, depth);
359
351
  } else {
360
- assure_size(
361
- out,
362
- depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
352
+ assure_size(out, depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
363
353
  if (0 < out->opts->dump_opts.hash_size) {
364
- strcpy(out->cur, out->opts->dump_opts.hash_nl);
365
- out->cur += out->opts->dump_opts.hash_size;
354
+ APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
366
355
  }
367
356
  if (0 < out->opts->dump_opts.indent_size) {
368
357
  int i;
369
358
 
370
359
  for (i = depth; 0 < i; i--) {
371
- strcpy(out->cur, out->opts->dump_opts.indent_str);
372
- out->cur += out->opts->dump_opts.indent_size;
360
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
373
361
  }
374
362
  }
375
363
  }
@@ -379,10 +367,10 @@ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
379
367
  }
380
368
 
381
369
  static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
382
- ID * idp;
383
- AttrGetFunc * fp;
370
+ ID *idp;
371
+ AttrGetFunc *fp;
384
372
  volatile VALUE v;
385
- const char * name;
373
+ const char *name;
386
374
  size_t size;
387
375
  int d2 = depth + 1;
388
376
 
@@ -391,29 +379,24 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
391
379
  if (NULL != out->opts->create_id && Yes == out->opts->create_ok) {
392
380
  const char *classname = rb_class2name(clas);
393
381
  int clen = (int)strlen(classname);
394
- size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
382
+ size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
395
383
 
396
384
  size = d2 * out->indent + 10 + clen + out->opts->create_id_len + sep_len;
397
385
  assure_size(out, size);
398
386
  fill_indent(out, d2);
399
387
  *out->cur++ = '"';
400
- memcpy(out->cur, out->opts->create_id, out->opts->create_id_len);
401
- out->cur += out->opts->create_id_len;
388
+ APPEND_CHARS(out->cur, out->opts->create_id, out->opts->create_id_len);
402
389
  *out->cur++ = '"';
403
390
  if (0 < out->opts->dump_opts.before_size) {
404
- strcpy(out->cur, out->opts->dump_opts.before_sep);
405
- out->cur += out->opts->dump_opts.before_size;
391
+ APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
406
392
  }
407
393
  *out->cur++ = ':';
408
394
  if (0 < out->opts->dump_opts.after_size) {
409
- strcpy(out->cur, out->opts->dump_opts.after_sep);
410
- out->cur += out->opts->dump_opts.after_size;
395
+ APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
411
396
  }
412
397
  *out->cur++ = '"';
413
- memcpy(out->cur, classname, clen);
414
- out->cur += clen;
415
- *out->cur++ = '"';
416
- *out->cur++ = ',';
398
+ APPEND_CHARS(out->cur, classname, clen);
399
+ APPEND_CHARS(out->cur, "\",", 2);
417
400
  }
418
401
  if (odd->raw) {
419
402
  v = rb_funcall(obj, *odd->attrs, 0);
@@ -429,12 +412,9 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
429
412
  assure_size(out, size);
430
413
  fill_indent(out, d2);
431
414
  *out->cur++ = '"';
432
- memcpy(out->cur, name, nlen);
433
- out->cur += nlen;
434
- *out->cur++ = '"';
435
- *out->cur++ = ':';
436
- memcpy(out->cur, s, len);
437
- out->cur += len;
415
+ APPEND_CHARS(out->cur, name, nlen);
416
+ APPEND_CHARS(out->cur, "\":", 2);
417
+ APPEND_CHARS(out->cur, s, len);
438
418
  *out->cur = '\0';
439
419
  }
440
420
  } else {
@@ -496,10 +476,10 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
496
476
  oj_dump_raw_json(obj, depth, out);
497
477
  } else if (Yes == out->opts->to_json && rb_respond_to(obj, oj_to_json_id)) {
498
478
  volatile VALUE rs;
499
- const char * s;
479
+ const char *s;
500
480
  int len;
501
481
 
502
- if (Yes == out->opts->trace) {
482
+ if (RB_UNLIKELY(Yes == out->opts->trace)) {
503
483
  oj_trace("to_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
504
484
  }
505
485
  if (0 == rb_obj_method_arity(obj, oj_to_json_id)) {
@@ -507,20 +487,19 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
507
487
  } else {
508
488
  rs = rb_funcall2(obj, oj_to_json_id, out->argc, out->argv);
509
489
  }
510
- if (Yes == out->opts->trace) {
490
+ if (RB_UNLIKELY(Yes == out->opts->trace)) {
511
491
  oj_trace("to_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
512
492
  }
513
493
  s = RSTRING_PTR(rs);
514
494
  len = (int)RSTRING_LEN(rs);
515
495
 
516
496
  assure_size(out, len + 1);
517
- memcpy(out->cur, s, len);
518
- out->cur += len;
497
+ APPEND_CHARS(out->cur, s, len);
519
498
  *out->cur = '\0';
520
499
  } else if (Yes == out->opts->as_json && rb_respond_to(obj, oj_as_json_id)) {
521
500
  volatile VALUE aj;
522
501
 
523
- if (Yes == out->opts->trace) {
502
+ if (RB_UNLIKELY(Yes == out->opts->trace)) {
524
503
  oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
525
504
  }
526
505
  // Some classes elect to not take an options argument so check the arity
@@ -530,18 +509,14 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
530
509
  } else {
531
510
  aj = rb_funcall2(obj, oj_as_json_id, out->argc, out->argv);
532
511
  }
533
- if (Yes == out->opts->trace) {
512
+ if (RB_UNLIKELY(Yes == out->opts->trace)) {
534
513
  oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
535
514
  }
536
515
  // Catch the obvious brain damaged recursive dumping.
537
516
  if (aj == obj) {
538
517
  volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
539
518
 
540
- oj_dump_cstr(RSTRING_PTR(rstr),
541
- (int)RSTRING_LEN(rstr),
542
- false,
543
- false,
544
- out);
519
+ oj_dump_cstr(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), false, false, out);
545
520
  } else {
546
521
  oj_dump_custom_val(aj, depth, out, true);
547
522
  }
@@ -577,7 +552,7 @@ static int dump_attr_cb(ID key, VALUE value, VALUE ov) {
577
552
  size_t size;
578
553
  const char *attr;
579
554
 
580
- if (oj_dump_ignore(out->opts, value)) {
555
+ if (dump_ignore(out->opts, value)) {
581
556
  return ST_CONTINUE;
582
557
  }
583
558
  if (out->omit_nil && Qnil == value) {
@@ -625,7 +600,7 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
625
600
  assure_size(out, 2);
626
601
  *out->cur++ = '{';
627
602
  if (Qundef != clas && NULL != out->opts->create_id && Yes == out->opts->create_ok) {
628
- size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
603
+ size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
629
604
  const char *classname = rb_obj_classname(obj);
630
605
  size_t len = strlen(classname);
631
606
 
@@ -633,21 +608,17 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
633
608
  assure_size(out, size);
634
609
  fill_indent(out, d2);
635
610
  *out->cur++ = '"';
636
- memcpy(out->cur, out->opts->create_id, out->opts->create_id_len);
637
- out->cur += out->opts->create_id_len;
611
+ APPEND_CHARS(out->cur, out->opts->create_id, out->opts->create_id_len);
638
612
  *out->cur++ = '"';
639
613
  if (0 < out->opts->dump_opts.before_size) {
640
- strcpy(out->cur, out->opts->dump_opts.before_sep);
641
- out->cur += out->opts->dump_opts.before_size;
614
+ APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
642
615
  }
643
616
  *out->cur++ = ':';
644
617
  if (0 < out->opts->dump_opts.after_size) {
645
- strcpy(out->cur, out->opts->dump_opts.after_sep);
646
- out->cur += out->opts->dump_opts.after_size;
618
+ APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
647
619
  }
648
620
  *out->cur++ = '"';
649
- memcpy(out->cur, classname, len);
650
- out->cur += len;
621
+ APPEND_CHARS(out->cur, classname, len);
651
622
  *out->cur++ = '"';
652
623
  class_written = true;
653
624
  }
@@ -731,25 +702,23 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
731
702
  } else {
732
703
  size = d2 * out->indent + 2;
733
704
  }
705
+ assure_size(out, size * cnt);
734
706
  cnt--;
735
707
  for (i = 0; i <= cnt; i++) {
736
- assure_size(out, size);
737
708
  if (out->opts->dump_opts.use) {
738
709
  if (0 < out->opts->dump_opts.array_size) {
739
- strcpy(out->cur, out->opts->dump_opts.array_nl);
740
- out->cur += out->opts->dump_opts.array_size;
710
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
741
711
  }
742
712
  if (0 < out->opts->dump_opts.indent_size) {
743
713
  int i;
744
714
  for (i = d2; 0 < i; i--) {
745
- strcpy(out->cur, out->opts->dump_opts.indent_str);
746
- out->cur += out->opts->dump_opts.indent_size;
715
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
747
716
  }
748
717
  }
749
718
  } else {
750
719
  fill_indent(out, d2);
751
720
  }
752
- oj_dump_custom_val(rb_ary_entry(a, i), d2, out, true);
721
+ oj_dump_custom_val(RARRAY_AREF(a, i), d2, out, true);
753
722
  if (i < cnt) {
754
723
  *out->cur++ = ',';
755
724
  }
@@ -758,15 +727,13 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
758
727
  assure_size(out, size);
759
728
  if (out->opts->dump_opts.use) {
760
729
  if (0 < out->opts->dump_opts.array_size) {
761
- strcpy(out->cur, out->opts->dump_opts.array_nl);
762
- out->cur += out->opts->dump_opts.array_size;
730
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
763
731
  }
764
732
  if (0 < out->opts->dump_opts.indent_size) {
765
733
  int i;
766
734
 
767
735
  for (i = depth; 0 < i; i--) {
768
- strcpy(out->cur, out->opts->dump_opts.indent_str);
769
- out->cur += out->opts->dump_opts.indent_size;
736
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
770
737
  }
771
738
  }
772
739
  } else {
@@ -800,8 +767,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
800
767
  *out->cur++ = '"';
801
768
  oj_dump_custom_val(rb_funcall(obj, oj_begin_id, 0), d3, out, false);
802
769
  assure_size(out, 3);
803
- *out->cur++ = '.';
804
- *out->cur++ = '.';
770
+ APPEND_CHARS(out->cur, "..", 2);
805
771
  if (Qtrue == rb_funcall(obj, oj_exclude_end_id, 0)) {
806
772
  *out->cur++ = '.';
807
773
  }
@@ -833,7 +799,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
833
799
  v = rb_struct_aref(obj, INT2FIX(i));
834
800
  #endif
835
801
  if (ma != Qnil) {
836
- volatile VALUE s = rb_sym2str(rb_ary_entry(ma, i));
802
+ volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
837
803
 
838
804
  name = RSTRING_PTR(s);
839
805
  len = (int)RSTRING_LEN(s);
@@ -844,10 +810,8 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
844
810
  assure_size(out, size + len + 3);
845
811
  fill_indent(out, d3);
846
812
  *out->cur++ = '"';
847
- memcpy(out->cur, name, len);
848
- out->cur += len;
849
- *out->cur++ = '"';
850
- *out->cur++ = ':';
813
+ APPEND_CHARS(out->cur, name, len);
814
+ APPEND_CHARS(out->cur, "\":", 2);
851
815
  oj_dump_custom_val(v, d3, out, true);
852
816
  *out->cur++ = ',';
853
817
  }
@@ -912,7 +876,7 @@ static DumpFunc custom_funcs[] = {
912
876
  void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok) {
913
877
  int type = rb_type(obj);
914
878
 
915
- if (Yes == out->opts->trace) {
879
+ if (RB_UNLIKELY(Yes == out->opts->trace)) {
916
880
  oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
917
881
  }
918
882
  if (MAX_DEPTH < depth) {
@@ -923,14 +887,14 @@ void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok) {
923
887
 
924
888
  if (NULL != f) {
925
889
  f(obj, depth, out, true);
926
- if (Yes == out->opts->trace) {
890
+ if (RB_UNLIKELY(Yes == out->opts->trace)) {
927
891
  oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
928
892
  }
929
893
  return;
930
894
  }
931
895
  }
932
896
  oj_dump_nil(Qnil, depth, out, false);
933
- if (Yes == out->opts->trace) {
897
+ if (RB_UNLIKELY(Yes == out->opts->trace)) {
934
898
  oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
935
899
  }
936
900
  }
@@ -938,7 +902,7 @@ void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok) {
938
902
  ///// load functions /////
939
903
 
940
904
  static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
941
- const char * key = kval->key;
905
+ const char *key = kval->key;
942
906
  int klen = kval->klen;
943
907
  Val parent = stack_peek(&pi->stack);
944
908
  volatile VALUE rkey = kval->key_val;
@@ -955,14 +919,14 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
955
919
  }
956
920
  }
957
921
  } else {
958
- volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
959
- //volatile VALUE rstr = rb_utf8_str_new(str, len);
922
+ volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
923
+ // volatile VALUE rstr = rb_utf8_str_new(str, len);
960
924
 
961
925
  if (Qundef == rkey) {
962
926
  if (Yes == pi->options.sym_key) {
963
927
  rkey = ID2SYM(rb_intern3(key, klen, oj_utf8_encoding));
964
928
  } else {
965
- rkey = rb_utf8_str_new(key, klen);
929
+ rkey = rb_utf8_str_new(key, klen);
966
930
  }
967
931
  }
968
932
  if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
@@ -986,7 +950,7 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
986
950
  break;
987
951
  default: break;
988
952
  }
989
- if (Yes == pi->options.trace) {
953
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
990
954
  oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rstr);
991
955
  }
992
956
  }
@@ -1005,7 +969,7 @@ static void end_hash(struct _parseInfo *pi) {
1005
969
  }
1006
970
  parent->clas = Qundef;
1007
971
  }
1008
- if (Yes == pi->options.trace) {
972
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
1009
973
  oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
1010
974
  }
1011
975
  }
@@ -1035,20 +999,10 @@ static void hash_set_num(struct _parseInfo *pi, Val kval, NumInfo ni) {
1035
999
  // match the expected value.
1036
1000
  parent->val = rb_funcall2(parent->val, oj_utc_id, 0, 0);
1037
1001
  } else if (ni->has_exp) {
1038
- int64_t t = (int64_t)(ni->i + ni->exp);
1039
- struct _timeInfo ti;
1040
- VALUE args[8];
1041
-
1042
- sec_as_time(t, &ti);
1043
-
1044
- args[0] = LONG2NUM(ti.year);
1045
- args[1] = LONG2NUM(ti.mon);
1046
- args[2] = LONG2NUM(ti.day);
1047
- args[3] = LONG2NUM(ti.hour);
1048
- args[4] = LONG2NUM(ti.min);
1049
- args[5] = rb_float_new((double)ti.sec + ((double)nsec + 0.5) / 1000000000.0);
1050
- args[6] = LONG2NUM(ni->exp);
1051
- parent->val = rb_funcall2(rb_cTime, oj_new_id, 7, args);
1002
+ struct timespec ts;
1003
+ ts.tv_sec = ni->i;
1004
+ ts.tv_nsec = nsec;
1005
+ parent->val = rb_time_timespec_new(&ts, (int)ni->exp);
1052
1006
  } else {
1053
1007
  parent->val = rb_time_nano_new(ni->i, (long)nsec);
1054
1008
  }
@@ -1059,7 +1013,7 @@ static void hash_set_num(struct _parseInfo *pi, Val kval, NumInfo ni) {
1059
1013
  break;
1060
1014
  default: break;
1061
1015
  }
1062
- if (Yes == pi->options.trace) {
1016
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
1063
1017
  oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rval);
1064
1018
  }
1065
1019
  }
@@ -1072,7 +1026,7 @@ static void hash_set_value(ParseInfo pi, Val kval, VALUE value) {
1072
1026
  case T_HASH: rb_hash_aset(parent->val, oj_calc_hash_key(pi, kval), value); break;
1073
1027
  default: break;
1074
1028
  }
1075
- if (Yes == pi->options.trace) {
1029
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
1076
1030
  oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
1077
1031
  }
1078
1032
  }
@@ -1082,7 +1036,7 @@ static void array_append_num(ParseInfo pi, NumInfo ni) {
1082
1036
  volatile VALUE rval = oj_num_as_value(ni);
1083
1037
 
1084
1038
  rb_ary_push(parent->val, rval);
1085
- if (Yes == pi->options.trace) {
1039
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
1086
1040
  oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
1087
1041
  }
1088
1042
  }
@@ -1099,7 +1053,7 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
1099
1053
  }
1100
1054
  }
1101
1055
  rb_ary_push(stack_peek(&pi->stack)->val, rstr);
1102
- if (Yes == pi->options.trace) {
1056
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
1103
1057
  oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rstr);
1104
1058
  }
1105
1059
  }