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/dump_object.c CHANGED
@@ -24,12 +24,7 @@ static void dump_data(VALUE obj, int depth, Out out, bool as_ok) {
24
24
 
25
25
  if (rb_cTime == clas) {
26
26
  assure_size(out, 6);
27
- *out->cur++ = '{';
28
- *out->cur++ = '"';
29
- *out->cur++ = '^';
30
- *out->cur++ = 't';
31
- *out->cur++ = '"';
32
- *out->cur++ = ':';
27
+ APPEND_CHARS(out->cur, "{\"^t\":", 6);
33
28
  dump_time(obj, out);
34
29
  *out->cur++ = '}';
35
30
  *out->cur = '\0';
@@ -91,12 +86,7 @@ static void dump_class(VALUE obj, int depth, Out out, bool as_ok) {
91
86
  size_t len = strlen(s);
92
87
 
93
88
  assure_size(out, 6);
94
- *out->cur++ = '{';
95
- *out->cur++ = '"';
96
- *out->cur++ = '^';
97
- *out->cur++ = 'c';
98
- *out->cur++ = '"';
99
- *out->cur++ = ':';
89
+ APPEND_CHARS(out->cur, "{\"^c\":", 6);
100
90
  oj_dump_cstr(s, len, 0, 0, out);
101
91
  *out->cur++ = '}';
102
92
  *out->cur = '\0';
@@ -120,9 +110,7 @@ static void dump_array_class(VALUE a, VALUE clas, int depth, Out out) {
120
110
  if (0 < id) {
121
111
  assure_size(out, d2 * out->indent + 16);
122
112
  fill_indent(out, d2);
123
- *out->cur++ = '"';
124
- *out->cur++ = '^';
125
- *out->cur++ = 'i';
113
+ APPEND_CHARS(out->cur, "\"^i", 3);
126
114
  dump_ulong(id, out);
127
115
  *out->cur++ = '"';
128
116
  }
@@ -139,25 +127,23 @@ static void dump_array_class(VALUE a, VALUE clas, int depth, Out out) {
139
127
  } else {
140
128
  size = d2 * out->indent + 2;
141
129
  }
130
+ assure_size(out, size * cnt);
142
131
  cnt--;
143
132
  for (i = 0; i <= cnt; i++) {
144
- assure_size(out, size);
145
133
  if (out->opts->dump_opts.use) {
146
134
  if (0 < out->opts->dump_opts.array_size) {
147
- strcpy(out->cur, out->opts->dump_opts.array_nl);
148
- out->cur += out->opts->dump_opts.array_size;
135
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
149
136
  }
150
137
  if (0 < out->opts->dump_opts.indent_size) {
151
138
  int i;
152
139
  for (i = d2; 0 < i; i--) {
153
- strcpy(out->cur, out->opts->dump_opts.indent_str);
154
- out->cur += out->opts->dump_opts.indent_size;
140
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
155
141
  }
156
142
  }
157
143
  } else {
158
144
  fill_indent(out, d2);
159
145
  }
160
- oj_dump_obj_val(rb_ary_entry(a, i), d2, out);
146
+ oj_dump_obj_val(RARRAY_AREF(a, i), d2, out);
161
147
  if (i < cnt) {
162
148
  *out->cur++ = ',';
163
149
  }
@@ -168,15 +154,13 @@ static void dump_array_class(VALUE a, VALUE clas, int depth, Out out) {
168
154
  // printf("*** d2: %u indent: %u '%s'\n", d2, out->opts->dump_opts->indent_size,
169
155
  // out->opts->dump_opts->indent);
170
156
  if (0 < out->opts->dump_opts.array_size) {
171
- strcpy(out->cur, out->opts->dump_opts.array_nl);
172
- out->cur += out->opts->dump_opts.array_size;
157
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
173
158
  }
174
159
  if (0 < out->opts->dump_opts.indent_size) {
175
160
  int i;
176
161
 
177
162
  for (i = depth; 0 < i; i--) {
178
- strcpy(out->cur, out->opts->dump_opts.indent_str);
179
- out->cur += out->opts->dump_opts.indent_size;
163
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
180
164
  }
181
165
  }
182
166
  } else {
@@ -218,7 +202,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
218
202
  int depth = out->depth;
219
203
  long size = depth * out->indent + 1;
220
204
 
221
- if (oj_dump_ignore(out->opts, value)) {
205
+ if (dump_ignore(out->opts, value)) {
222
206
  return ST_CONTINUE;
223
207
  }
224
208
  if (out->omit_nil && Qnil == value) {
@@ -226,47 +210,50 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
226
210
  }
227
211
  assure_size(out, size);
228
212
  fill_indent(out, depth);
229
- if (rb_type(key) == T_STRING) {
213
+ switch (rb_type(key)) {
214
+ case T_STRING:
230
215
  dump_str_class(key, Qundef, depth, out);
231
216
  *out->cur++ = ':';
232
217
  oj_dump_obj_val(value, depth, out);
233
- } else if (rb_type(key) == T_SYMBOL) {
218
+ break;
219
+
220
+ case T_SYMBOL:
234
221
  dump_sym(key, 0, out, false);
235
222
  *out->cur++ = ':';
236
223
  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;
224
+ break;
243
225
 
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];
226
+ default:
227
+ {
228
+ int d2 = depth + 1;
229
+ long s2 = size + out->indent + 1;
230
+ int i;
231
+ int started = 0;
232
+ uint8_t b;
233
+
234
+ assure_size(out, s2 + 15);
235
+ APPEND_CHARS(out->cur, "\"^#", 3);
236
+ out->hash_cnt++;
237
+ for (i = 28; 0 <= i; i -= 4) {
238
+ b = (uint8_t)((out->hash_cnt >> i) & 0x0000000F);
239
+ if ('\0' != b) {
240
+ started = 1;
241
+ }
242
+ if (started) {
243
+ *out->cur++ = hex_chars[b];
244
+ }
256
245
  }
246
+ APPEND_CHARS(out->cur, "\":[", 3);
247
+ fill_indent(out, d2);
248
+ oj_dump_obj_val(key, d2, out);
249
+ assure_size(out, s2);
250
+ *out->cur++ = ',';
251
+ fill_indent(out, d2);
252
+ oj_dump_obj_val(value, d2, out);
253
+ assure_size(out, size);
254
+ fill_indent(out, depth);
255
+ *out->cur++ = ']';
257
256
  }
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
257
  }
271
258
  out->depth = depth;
272
259
  *out->cur++ = ',';
@@ -286,8 +273,7 @@ static void dump_hash_class(VALUE obj, VALUE clas, int depth, Out out) {
286
273
  size = depth * out->indent + 2;
287
274
  assure_size(out, 2);
288
275
  if (0 == cnt) {
289
- *out->cur++ = '{';
290
- *out->cur++ = '}';
276
+ APPEND_CHARS(out->cur, "{}", 2);
291
277
  } else {
292
278
  long id = oj_check_circular(obj, out);
293
279
 
@@ -298,11 +284,7 @@ static void dump_hash_class(VALUE obj, VALUE clas, int depth, Out out) {
298
284
  if (0 < id) {
299
285
  assure_size(out, size + 16);
300
286
  fill_indent(out, depth + 1);
301
- *out->cur++ = '"';
302
- *out->cur++ = '^';
303
- *out->cur++ = 'i';
304
- *out->cur++ = '"';
305
- *out->cur++ = ':';
287
+ APPEND_CHARS(out->cur, "\"^i\":", 5);
306
288
  dump_ulong(id, out);
307
289
  *out->cur++ = ',';
308
290
  }
@@ -318,15 +300,13 @@ static void dump_hash_class(VALUE obj, VALUE clas, int depth, Out out) {
318
300
  size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
319
301
  assure_size(out, size);
320
302
  if (0 < out->opts->dump_opts.hash_size) {
321
- strcpy(out->cur, out->opts->dump_opts.hash_nl);
322
- out->cur += out->opts->dump_opts.hash_size;
303
+ APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
323
304
  }
324
305
  if (0 < out->opts->dump_opts.indent_size) {
325
306
  int i;
326
307
 
327
308
  for (i = depth; 0 < i; i--) {
328
- strcpy(out->cur, out->opts->dump_opts.indent_str);
329
- out->cur += out->opts->dump_opts.indent_size;
309
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
330
310
  }
331
311
  }
332
312
  }
@@ -335,14 +315,13 @@ static void dump_hash_class(VALUE obj, VALUE clas, int depth, Out out) {
335
315
  *out->cur = '\0';
336
316
  }
337
317
 
338
- #ifdef HAVE_RB_IVAR_FOREACH
339
318
  static int dump_attr_cb(ID key, VALUE value, VALUE ov) {
340
319
  Out out = (Out)ov;
341
320
  int depth = out->depth;
342
321
  size_t size = depth * out->indent + 1;
343
322
  const char *attr = rb_id2name(key);
344
323
 
345
- if (oj_dump_ignore(out->opts, value)) {
324
+ if (dump_ignore(out->opts, value)) {
346
325
  return ST_CONTINUE;
347
326
  }
348
327
  if (out->omit_nil && Qnil == value) {
@@ -378,7 +357,6 @@ static int dump_attr_cb(ID key, VALUE value, VALUE ov) {
378
357
 
379
358
  return ST_CONTINUE;
380
359
  }
381
- #endif
382
360
 
383
361
  static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
384
362
  dump_hash_class(obj, rb_obj_class(obj), depth, out);
@@ -401,11 +379,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
401
379
  size = d2 * out->indent + clen + 10;
402
380
  assure_size(out, size);
403
381
  fill_indent(out, d2);
404
- *out->cur++ = '"';
405
- *out->cur++ = '^';
406
- *out->cur++ = 'O';
407
- *out->cur++ = '"';
408
- *out->cur++ = ':';
382
+ APPEND_CHARS(out->cur, "\"^O\":", 5);
409
383
  oj_dump_cstr(class_name, clen, 0, 0, out);
410
384
  *out->cur++ = ',';
411
385
  }
@@ -423,12 +397,9 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
423
397
  assure_size(out, size);
424
398
  fill_indent(out, d2);
425
399
  *out->cur++ = '"';
426
- memcpy(out->cur, name, nlen);
427
- out->cur += nlen;
428
- *out->cur++ = '"';
429
- *out->cur++ = ':';
430
- memcpy(out->cur, s, len);
431
- out->cur += len;
400
+ APPEND_CHARS(out->cur, name, nlen);
401
+ APPEND_CHARS(out->cur, "\":", 2);
402
+ APPEND_CHARS(out->cur, s, len);
432
403
  *out->cur = '\0';
433
404
  }
434
405
  } else {
@@ -439,7 +410,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
439
410
  assure_size(out, size);
440
411
  name = rb_id2name(*idp);
441
412
  nlen = strlen(name);
442
- if (0 != *fp) {
413
+ if (NULL != *fp) {
443
414
  v = (*fp)(obj);
444
415
  } else if (0 == strchr(name, '.')) {
445
416
  v = rb_funcall(obj, *idp, 0);
@@ -502,22 +473,14 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
502
473
 
503
474
  assure_size(out, d2 * out->indent + clen + 10);
504
475
  fill_indent(out, d2);
505
- *out->cur++ = '"';
506
- *out->cur++ = '^';
507
- *out->cur++ = 'o';
508
- *out->cur++ = '"';
509
- *out->cur++ = ':';
476
+ APPEND_CHARS(out->cur, "\"^o\":", 5);
510
477
  oj_dump_cstr(class_name, clen, 0, 0, out);
511
478
  }
512
479
  if (0 < id) {
513
480
  assure_size(out, d2 * out->indent + 16);
514
481
  *out->cur++ = ',';
515
482
  fill_indent(out, d2);
516
- *out->cur++ = '"';
517
- *out->cur++ = '^';
518
- *out->cur++ = 'i';
519
- *out->cur++ = '"';
520
- *out->cur++ = ':';
483
+ APPEND_CHARS(out->cur, "\"^i\":", 5);
521
484
  dump_ulong(id, out);
522
485
  }
523
486
  switch (type) {
@@ -525,57 +488,28 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
525
488
  assure_size(out, d2 * out->indent + 14);
526
489
  *out->cur++ = ',';
527
490
  fill_indent(out, d2);
528
- *out->cur++ = '"';
529
- *out->cur++ = 's';
530
- *out->cur++ = 'e';
531
- *out->cur++ = 'l';
532
- *out->cur++ = 'f';
533
- *out->cur++ = '"';
534
- *out->cur++ = ':';
491
+ APPEND_CHARS(out->cur, "\"self\":", 7);
535
492
  oj_dump_cstr(RSTRING_PTR(obj), (int)RSTRING_LEN(obj), 0, 0, out);
536
493
  break;
537
494
  case T_ARRAY:
538
495
  assure_size(out, d2 * out->indent + 14);
539
496
  *out->cur++ = ',';
540
497
  fill_indent(out, d2);
541
- *out->cur++ = '"';
542
- *out->cur++ = 's';
543
- *out->cur++ = 'e';
544
- *out->cur++ = 'l';
545
- *out->cur++ = 'f';
546
- *out->cur++ = '"';
547
- *out->cur++ = ':';
498
+ APPEND_CHARS(out->cur, "\"self\":", 7);
548
499
  dump_array_class(obj, Qundef, depth + 1, out);
549
500
  break;
550
501
  case T_HASH:
551
502
  assure_size(out, d2 * out->indent + 14);
552
503
  *out->cur++ = ',';
553
504
  fill_indent(out, d2);
554
- *out->cur++ = '"';
555
- *out->cur++ = 's';
556
- *out->cur++ = 'e';
557
- *out->cur++ = 'l';
558
- *out->cur++ = 'f';
559
- *out->cur++ = '"';
560
- *out->cur++ = ':';
505
+ APPEND_CHARS(out->cur, "\"self\":", 7);
561
506
  dump_hash_class(obj, Qundef, depth + 1, out);
562
507
  break;
563
508
  default: break;
564
509
  }
565
510
  {
566
- int cnt;
567
- #ifdef HAVE_RB_IVAR_COUNT
568
- cnt = (int)rb_ivar_count(obj);
569
- #else
570
- volatile VALUE vars = rb_funcall2(obj, oj_instance_variables_id, 0, 0);
571
- VALUE * np = RARRAY_PTR(vars);
572
- ID vid;
573
- const char * attr;
574
- int i;
575
- int first = 1;
576
-
577
- cnt = (int)RARRAY_LEN(vars);
578
- #endif
511
+ int cnt = (int)rb_ivar_count(obj);
512
+
579
513
  if (Qundef != clas && 0 < cnt) {
580
514
  *out->cur++ = ',';
581
515
  }
@@ -588,52 +522,10 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
588
522
  }
589
523
  }
590
524
  out->depth = depth + 1;
591
- #ifdef HAVE_RB_IVAR_FOREACH
592
525
  rb_ivar_foreach(obj, dump_attr_cb, (VALUE)out);
593
526
  if (',' == *(out->cur - 1)) {
594
527
  out->cur--; // backup to overwrite last comma
595
528
  }
596
- #else
597
- size = d2 * out->indent + 1;
598
- for (i = cnt; 0 < i; i--, np++) {
599
- VALUE value;
600
-
601
- vid = rb_to_id(*np);
602
- attr = rb_id2name(vid);
603
- if (Yes == out->opts->ignore_under && '@' == *attr && '_' == attr[1]) {
604
- continue;
605
- }
606
- value = rb_ivar_get(obj, vid);
607
-
608
- if (oj_dump_ignore(out->opts, value)) {
609
- continue;
610
- }
611
- if (out->omit_nil && Qnil == value) {
612
- continue;
613
- }
614
- if (first) {
615
- first = 0;
616
- } else {
617
- *out->cur++ = ',';
618
- }
619
- assure_size(out, size);
620
- fill_indent(out, d2);
621
- if ('@' == *attr) {
622
- attr++;
623
- oj_dump_cstr(attr, strlen(attr), 0, 0, out);
624
- } else {
625
- char buf[32];
626
-
627
- *buf = '~';
628
- strncpy(buf + 1, attr, sizeof(buf) - 2);
629
- buf[sizeof(buf) - 1] = '\0';
630
- oj_dump_cstr(buf, strlen(attr) + 1, 0, 0, out);
631
- }
632
- *out->cur++ = ':';
633
- oj_dump_obj_val(value, d2, out);
634
- assure_size(out, 2);
635
- }
636
- #endif
637
529
  if (rb_obj_is_kind_of(obj, rb_eException)) {
638
530
  volatile VALUE rv;
639
531
 
@@ -681,12 +573,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
681
573
  assure_size(out, size);
682
574
  *out->cur++ = '{';
683
575
  fill_indent(out, d2);
684
- *out->cur++ = '"';
685
- *out->cur++ = '^';
686
- *out->cur++ = 'u';
687
- *out->cur++ = '"';
688
- *out->cur++ = ':';
689
- *out->cur++ = '[';
576
+ APPEND_CHARS(out->cur, "\"^u\":[", 6);
690
577
  if ('#' == *class_name) {
691
578
  VALUE ma = rb_struct_s_members(clas);
692
579
  const char *name;
@@ -694,7 +581,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
694
581
 
695
582
  *out->cur++ = '[';
696
583
  for (i = 0; i < cnt; i++) {
697
- volatile VALUE s = rb_sym2str(rb_ary_entry(ma, i));
584
+ volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
698
585
 
699
586
  name = RSTRING_PTR(s);
700
587
  len = (int)RSTRING_LEN(s);
@@ -704,16 +591,14 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
704
591
  *out->cur++ = ',';
705
592
  }
706
593
  *out->cur++ = '"';
707
- memcpy(out->cur, name, len);
708
- out->cur += len;
594
+ APPEND_CHARS(out->cur, name, len);
709
595
  *out->cur++ = '"';
710
596
  }
711
597
  *out->cur++ = ']';
712
598
  } else {
713
599
  fill_indent(out, d3);
714
600
  *out->cur++ = '"';
715
- memcpy(out->cur, class_name, len);
716
- out->cur += len;
601
+ APPEND_CHARS(out->cur, class_name, len);
717
602
  *out->cur++ = '"';
718
603
  }
719
604
  *out->cur++ = ',';
@@ -730,7 +615,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
730
615
 
731
616
  for (i = 0; i < cnt; i++) {
732
617
  v = RSTRUCT_GET(obj, i);
733
- if (oj_dump_ignore(out->opts, v)) {
618
+ if (dump_ignore(out->opts, v)) {
734
619
  v = Qnil;
735
620
  }
736
621
  assure_size(out, size);
@@ -748,7 +633,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
748
633
  for (i = 0; i < slen; i++) {
749
634
  assure_size(out, size);
750
635
  fill_indent(out, d3);
751
- if (oj_dump_ignore(out->opts, v)) {
636
+ if (dump_ignore(out->opts, v)) {
752
637
  v = Qnil;
753
638
  }
754
639
  oj_dump_obj_val(rb_struct_aref(obj, INT2FIX(i)), d3, out, 0, 0, true);
@@ -757,8 +642,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
757
642
  }
758
643
  #endif
759
644
  out->cur--;
760
- *out->cur++ = ']';
761
- *out->cur++ = '}';
645
+ APPEND_CHARS(out->cur, "]}", 2);
762
646
  *out->cur = '\0';
763
647
  }
764
648
 
@@ -798,7 +682,7 @@ static DumpFunc obj_funcs[] = {
798
682
  void oj_dump_obj_val(VALUE obj, int depth, Out out) {
799
683
  int type = rb_type(obj);
800
684
 
801
- if (Yes == out->opts->trace) {
685
+ if (RB_UNLIKELY(Yes == out->opts->trace)) {
802
686
  oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
803
687
  }
804
688
  if (MAX_DEPTH < depth) {
@@ -809,14 +693,14 @@ void oj_dump_obj_val(VALUE obj, int depth, Out out) {
809
693
 
810
694
  if (NULL != f) {
811
695
  f(obj, depth, out, false);
812
- if (Yes == out->opts->trace) {
696
+ if (RB_UNLIKELY(Yes == out->opts->trace)) {
813
697
  oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
814
698
  }
815
699
  return;
816
700
  }
817
701
  }
818
702
  oj_dump_nil(Qnil, depth, out, false);
819
- if (Yes == out->opts->trace) {
703
+ if (RB_UNLIKELY(Yes == out->opts->trace)) {
820
704
  oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
821
705
  }
822
706
  }
data/ext/oj/dump_strict.c CHANGED
@@ -105,9 +105,7 @@ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
105
105
  }
106
106
  }
107
107
  assure_size(out, cnt);
108
- for (b = buf; '\0' != *b; b++) {
109
- *out->cur++ = *b;
110
- }
108
+ APPEND_CHARS(out->cur, buf, cnt);
111
109
  *out->cur = '\0';
112
110
  }
113
111
 
@@ -134,28 +132,26 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
134
132
  } else {
135
133
  size = d2 * out->indent + 2;
136
134
  }
135
+ assure_size(out, size * cnt);
137
136
  cnt--;
138
137
  for (i = 0; i <= cnt; i++) {
139
- assure_size(out, size);
140
138
  if (out->opts->dump_opts.use) {
141
139
  if (0 < out->opts->dump_opts.array_size) {
142
- strcpy(out->cur, out->opts->dump_opts.array_nl);
143
- out->cur += out->opts->dump_opts.array_size;
140
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
144
141
  }
145
142
  if (0 < out->opts->dump_opts.indent_size) {
146
143
  int i;
147
144
  for (i = d2; 0 < i; i--) {
148
- strcpy(out->cur, out->opts->dump_opts.indent_str);
149
- out->cur += out->opts->dump_opts.indent_size;
145
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
150
146
  }
151
147
  }
152
148
  } else {
153
149
  fill_indent(out, d2);
154
150
  }
155
151
  if (NullMode == out->opts->mode) {
156
- oj_dump_null_val(rb_ary_entry(a, i), d2, out);
152
+ oj_dump_null_val(RARRAY_AREF(a, i), d2, out);
157
153
  } else {
158
- oj_dump_strict_val(rb_ary_entry(a, i), d2, out);
154
+ oj_dump_strict_val(RARRAY_AREF(a, i), d2, out);
159
155
  }
160
156
  if (i < cnt) {
161
157
  *out->cur++ = ',';
@@ -167,15 +163,13 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
167
163
  // printf("*** d2: %u indent: %u '%s'\n", d2, out->opts->dump_opts->indent_size,
168
164
  // out->opts->dump_opts->indent);
169
165
  if (0 < out->opts->dump_opts.array_size) {
170
- strcpy(out->cur, out->opts->dump_opts.array_nl);
171
- out->cur += out->opts->dump_opts.array_size;
166
+ APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
172
167
  }
173
168
  if (0 < out->opts->dump_opts.indent_size) {
174
169
  int i;
175
170
 
176
171
  for (i = depth; 0 < i; i--) {
177
- strcpy(out->cur, out->opts->dump_opts.indent_str);
178
- out->cur += out->opts->dump_opts.indent_size;
172
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
179
173
  }
180
174
  }
181
175
  } else {
@@ -214,14 +208,12 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
214
208
  size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
215
209
  assure_size(out, size);
216
210
  if (0 < out->opts->dump_opts.hash_size) {
217
- strcpy(out->cur, out->opts->dump_opts.hash_nl);
218
- out->cur += out->opts->dump_opts.hash_size;
211
+ APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
219
212
  }
220
213
  if (0 < out->opts->dump_opts.indent_size) {
221
214
  int i;
222
215
  for (i = depth; 0 < i; i--) {
223
- strcpy(out->cur, out->opts->dump_opts.indent_str);
224
- out->cur += out->opts->dump_opts.indent_size;
216
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
225
217
  }
226
218
  }
227
219
  if (rtype == T_STRING) {
@@ -232,13 +224,11 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
232
224
  size = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
233
225
  assure_size(out, size);
234
226
  if (0 < out->opts->dump_opts.before_size) {
235
- strcpy(out->cur, out->opts->dump_opts.before_sep);
236
- out->cur += out->opts->dump_opts.before_size;
227
+ APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
237
228
  }
238
229
  *out->cur++ = ':';
239
230
  if (0 < out->opts->dump_opts.after_size) {
240
- strcpy(out->cur, out->opts->dump_opts.after_sep);
241
- out->cur += out->opts->dump_opts.after_size;
231
+ APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
242
232
  }
243
233
  }
244
234
  if (NullMode == out->opts->mode) {
@@ -281,15 +271,13 @@ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
281
271
  size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
282
272
  assure_size(out, size);
283
273
  if (0 < out->opts->dump_opts.hash_size) {
284
- strcpy(out->cur, out->opts->dump_opts.hash_nl);
285
- out->cur += out->opts->dump_opts.hash_size;
274
+ APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
286
275
  }
287
276
  if (0 < out->opts->dump_opts.indent_size) {
288
277
  int i;
289
278
 
290
279
  for (i = depth; 0 < i; i--) {
291
- strcpy(out->cur, out->opts->dump_opts.indent_str);
292
- out->cur += out->opts->dump_opts.indent_size;
280
+ APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
293
281
  }
294
282
  }
295
283
  }
@@ -350,7 +338,7 @@ static DumpFunc strict_funcs[] = {
350
338
  void oj_dump_strict_val(VALUE obj, int depth, Out out) {
351
339
  int type = rb_type(obj);
352
340
 
353
- if (Yes == out->opts->trace) {
341
+ if (RB_UNLIKELY(Yes == out->opts->trace)) {
354
342
  oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
355
343
  }
356
344
  if (MAX_DEPTH < depth) {
@@ -361,7 +349,7 @@ void oj_dump_strict_val(VALUE obj, int depth, Out out) {
361
349
 
362
350
  if (NULL != f) {
363
351
  f(obj, depth, out, false);
364
- if (Yes == out->opts->trace) {
352
+ if (RB_UNLIKELY(Yes == out->opts->trace)) {
365
353
  oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
366
354
  }
367
355
  return;
@@ -398,7 +386,7 @@ static DumpFunc null_funcs[] = {
398
386
  void oj_dump_null_val(VALUE obj, int depth, Out out) {
399
387
  int type = rb_type(obj);
400
388
 
401
- if (Yes == out->opts->trace) {
389
+ if (RB_UNLIKELY(Yes == out->opts->trace)) {
402
390
  oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
403
391
  }
404
392
  if (MAX_DEPTH < depth) {
@@ -409,14 +397,14 @@ void oj_dump_null_val(VALUE obj, int depth, Out out) {
409
397
 
410
398
  if (NULL != f) {
411
399
  f(obj, depth, out, false);
412
- if (Yes == out->opts->trace) {
400
+ if (RB_UNLIKELY(Yes == out->opts->trace)) {
413
401
  oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
414
402
  }
415
403
  return;
416
404
  }
417
405
  }
418
406
  oj_dump_nil(Qnil, depth, out, false);
419
- if (Yes == out->opts->trace) {
407
+ if (RB_UNLIKELY(Yes == out->opts->trace)) {
420
408
  oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
421
409
  }
422
410
  }