oj 3.13.11 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +50 -0
- data/README.md +2 -0
- data/ext/oj/buf.h +4 -0
- data/ext/oj/circarray.c +1 -1
- data/ext/oj/code.c +15 -22
- data/ext/oj/compat.c +10 -10
- data/ext/oj/custom.c +62 -108
- data/ext/oj/dump.c +85 -97
- data/ext/oj/dump.h +12 -8
- data/ext/oj/dump_compat.c +46 -88
- data/ext/oj/dump_leaf.c +14 -58
- data/ext/oj/dump_object.c +33 -156
- data/ext/oj/dump_strict.c +17 -29
- data/ext/oj/extconf.rb +5 -4
- data/ext/oj/fast.c +24 -22
- data/ext/oj/intern.c +15 -11
- data/ext/oj/intern.h +1 -1
- data/ext/oj/mimic_json.c +44 -32
- data/ext/oj/object.c +42 -41
- data/ext/oj/odd.c +83 -63
- data/ext/oj/odd.h +13 -13
- data/ext/oj/oj.c +57 -22
- data/ext/oj/oj.h +24 -3
- data/ext/oj/parse.c +114 -78
- data/ext/oj/parse.h +2 -0
- data/ext/oj/parser.c +77 -21
- data/ext/oj/parser.h +12 -0
- data/ext/oj/rails.c +41 -65
- data/ext/oj/rails.h +1 -1
- data/ext/oj/reader.c +2 -0
- data/ext/oj/saj.c +11 -23
- data/ext/oj/saj2.c +333 -85
- data/ext/oj/saj2.h +23 -0
- data/ext/oj/sparse.c +4 -0
- data/ext/oj/stream_writer.c +3 -1
- data/ext/oj/strict.c +13 -13
- data/ext/oj/string_writer.c +12 -5
- data/ext/oj/usual.c +82 -129
- data/ext/oj/usual.h +68 -0
- data/ext/oj/val_stack.c +1 -1
- data/ext/oj/validate.c +21 -26
- data/ext/oj/wab.c +21 -26
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/state.rb +1 -1
- data/lib/oj/version.rb +1 -1
- data/pages/Compatibility.md +1 -1
- data/pages/Options.md +6 -0
- data/test/activesupport7/abstract_unit.rb +49 -0
- data/test/activesupport7/decoding_test.rb +125 -0
- data/test/activesupport7/encoding_test.rb +486 -0
- data/test/activesupport7/encoding_test_cases.rb +104 -0
- data/test/activesupport7/time_zone_test_helpers.rb +47 -0
- data/test/bar.rb +3 -8
- data/test/foo.rb +3 -3
- data/test/helper.rb +8 -2
- data/test/json_gem/json_generator_test.rb +5 -4
- data/test/json_gem/json_parser_test.rb +8 -1
- data/test/json_gem/test_helper.rb +7 -3
- data/test/perf_dump.rb +50 -0
- data/test/test_compat.rb +25 -0
- data/test/test_custom.rb +13 -2
- data/test/test_file.rb +23 -7
- data/test/test_gc.rb +11 -0
- data/test/test_object.rb +8 -10
- data/test/test_parser.rb +3 -19
- data/test/test_parser_debug.rb +27 -0
- data/test/test_parser_saj.rb +92 -2
- data/test/test_scp.rb +2 -4
- data/test/test_strict.rb +2 -0
- data/test/test_various.rb +8 -3
- data/test/test_wab.rb +2 -0
- data/test/tests.rb +9 -0
- data/test/tests_mimic.rb +9 -0
- data/test/tests_mimic_addition.rb +9 -0
- metadata +13 -116
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
|
-
|
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
|
-
|
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
|
-
|
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,19 +127,17 @@ 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
|
-
|
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
|
-
|
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 {
|
@@ -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
|
-
|
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
|
-
|
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 {
|
@@ -248,9 +232,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
248
232
|
uint8_t b;
|
249
233
|
|
250
234
|
assure_size(out, s2 + 15);
|
251
|
-
|
252
|
-
*out->cur++ = '^';
|
253
|
-
*out->cur++ = '#';
|
235
|
+
APPEND_CHARS(out->cur, "\"^#", 3);
|
254
236
|
out->hash_cnt++;
|
255
237
|
for (i = 28; 0 <= i; i -= 4) {
|
256
238
|
b = (uint8_t)((out->hash_cnt >> i) & 0x0000000F);
|
@@ -261,9 +243,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
261
243
|
*out->cur++ = hex_chars[b];
|
262
244
|
}
|
263
245
|
}
|
264
|
-
|
265
|
-
*out->cur++ = ':';
|
266
|
-
*out->cur++ = '[';
|
246
|
+
APPEND_CHARS(out->cur, "\":[", 3);
|
267
247
|
fill_indent(out, d2);
|
268
248
|
oj_dump_obj_val(key, d2, out);
|
269
249
|
assure_size(out, s2);
|
@@ -293,8 +273,7 @@ static void dump_hash_class(VALUE obj, VALUE clas, int depth, Out out) {
|
|
293
273
|
size = depth * out->indent + 2;
|
294
274
|
assure_size(out, 2);
|
295
275
|
if (0 == cnt) {
|
296
|
-
|
297
|
-
*out->cur++ = '}';
|
276
|
+
APPEND_CHARS(out->cur, "{}", 2);
|
298
277
|
} else {
|
299
278
|
long id = oj_check_circular(obj, out);
|
300
279
|
|
@@ -305,11 +284,7 @@ static void dump_hash_class(VALUE obj, VALUE clas, int depth, Out out) {
|
|
305
284
|
if (0 < id) {
|
306
285
|
assure_size(out, size + 16);
|
307
286
|
fill_indent(out, depth + 1);
|
308
|
-
|
309
|
-
*out->cur++ = '^';
|
310
|
-
*out->cur++ = 'i';
|
311
|
-
*out->cur++ = '"';
|
312
|
-
*out->cur++ = ':';
|
287
|
+
APPEND_CHARS(out->cur, "\"^i\":", 5);
|
313
288
|
dump_ulong(id, out);
|
314
289
|
*out->cur++ = ',';
|
315
290
|
}
|
@@ -325,15 +300,13 @@ static void dump_hash_class(VALUE obj, VALUE clas, int depth, Out out) {
|
|
325
300
|
size = depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1;
|
326
301
|
assure_size(out, size);
|
327
302
|
if (0 < out->opts->dump_opts.hash_size) {
|
328
|
-
|
329
|
-
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);
|
330
304
|
}
|
331
305
|
if (0 < out->opts->dump_opts.indent_size) {
|
332
306
|
int i;
|
333
307
|
|
334
308
|
for (i = depth; 0 < i; i--) {
|
335
|
-
|
336
|
-
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);
|
337
310
|
}
|
338
311
|
}
|
339
312
|
}
|
@@ -342,7 +315,6 @@ static void dump_hash_class(VALUE obj, VALUE clas, int depth, Out out) {
|
|
342
315
|
*out->cur = '\0';
|
343
316
|
}
|
344
317
|
|
345
|
-
#ifdef HAVE_RB_IVAR_FOREACH
|
346
318
|
static int dump_attr_cb(ID key, VALUE value, VALUE ov) {
|
347
319
|
Out out = (Out)ov;
|
348
320
|
int depth = out->depth;
|
@@ -385,7 +357,6 @@ static int dump_attr_cb(ID key, VALUE value, VALUE ov) {
|
|
385
357
|
|
386
358
|
return ST_CONTINUE;
|
387
359
|
}
|
388
|
-
#endif
|
389
360
|
|
390
361
|
static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
|
391
362
|
dump_hash_class(obj, rb_obj_class(obj), depth, out);
|
@@ -408,11 +379,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
|
|
408
379
|
size = d2 * out->indent + clen + 10;
|
409
380
|
assure_size(out, size);
|
410
381
|
fill_indent(out, d2);
|
411
|
-
|
412
|
-
*out->cur++ = '^';
|
413
|
-
*out->cur++ = 'O';
|
414
|
-
*out->cur++ = '"';
|
415
|
-
*out->cur++ = ':';
|
382
|
+
APPEND_CHARS(out->cur, "\"^O\":", 5);
|
416
383
|
oj_dump_cstr(class_name, clen, 0, 0, out);
|
417
384
|
*out->cur++ = ',';
|
418
385
|
}
|
@@ -430,12 +397,9 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
|
|
430
397
|
assure_size(out, size);
|
431
398
|
fill_indent(out, d2);
|
432
399
|
*out->cur++ = '"';
|
433
|
-
|
434
|
-
out->cur
|
435
|
-
|
436
|
-
*out->cur++ = ':';
|
437
|
-
memcpy(out->cur, s, len);
|
438
|
-
out->cur += len;
|
400
|
+
APPEND_CHARS(out->cur, name, nlen);
|
401
|
+
APPEND_CHARS(out->cur, "\":", 2);
|
402
|
+
APPEND_CHARS(out->cur, s, len);
|
439
403
|
*out->cur = '\0';
|
440
404
|
}
|
441
405
|
} else {
|
@@ -446,7 +410,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
|
|
446
410
|
assure_size(out, size);
|
447
411
|
name = rb_id2name(*idp);
|
448
412
|
nlen = strlen(name);
|
449
|
-
if (
|
413
|
+
if (NULL != *fp) {
|
450
414
|
v = (*fp)(obj);
|
451
415
|
} else if (0 == strchr(name, '.')) {
|
452
416
|
v = rb_funcall(obj, *idp, 0);
|
@@ -509,22 +473,14 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
|
|
509
473
|
|
510
474
|
assure_size(out, d2 * out->indent + clen + 10);
|
511
475
|
fill_indent(out, d2);
|
512
|
-
|
513
|
-
*out->cur++ = '^';
|
514
|
-
*out->cur++ = 'o';
|
515
|
-
*out->cur++ = '"';
|
516
|
-
*out->cur++ = ':';
|
476
|
+
APPEND_CHARS(out->cur, "\"^o\":", 5);
|
517
477
|
oj_dump_cstr(class_name, clen, 0, 0, out);
|
518
478
|
}
|
519
479
|
if (0 < id) {
|
520
480
|
assure_size(out, d2 * out->indent + 16);
|
521
481
|
*out->cur++ = ',';
|
522
482
|
fill_indent(out, d2);
|
523
|
-
|
524
|
-
*out->cur++ = '^';
|
525
|
-
*out->cur++ = 'i';
|
526
|
-
*out->cur++ = '"';
|
527
|
-
*out->cur++ = ':';
|
483
|
+
APPEND_CHARS(out->cur, "\"^i\":", 5);
|
528
484
|
dump_ulong(id, out);
|
529
485
|
}
|
530
486
|
switch (type) {
|
@@ -532,57 +488,28 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
|
|
532
488
|
assure_size(out, d2 * out->indent + 14);
|
533
489
|
*out->cur++ = ',';
|
534
490
|
fill_indent(out, d2);
|
535
|
-
|
536
|
-
*out->cur++ = 's';
|
537
|
-
*out->cur++ = 'e';
|
538
|
-
*out->cur++ = 'l';
|
539
|
-
*out->cur++ = 'f';
|
540
|
-
*out->cur++ = '"';
|
541
|
-
*out->cur++ = ':';
|
491
|
+
APPEND_CHARS(out->cur, "\"self\":", 7);
|
542
492
|
oj_dump_cstr(RSTRING_PTR(obj), (int)RSTRING_LEN(obj), 0, 0, out);
|
543
493
|
break;
|
544
494
|
case T_ARRAY:
|
545
495
|
assure_size(out, d2 * out->indent + 14);
|
546
496
|
*out->cur++ = ',';
|
547
497
|
fill_indent(out, d2);
|
548
|
-
|
549
|
-
*out->cur++ = 's';
|
550
|
-
*out->cur++ = 'e';
|
551
|
-
*out->cur++ = 'l';
|
552
|
-
*out->cur++ = 'f';
|
553
|
-
*out->cur++ = '"';
|
554
|
-
*out->cur++ = ':';
|
498
|
+
APPEND_CHARS(out->cur, "\"self\":", 7);
|
555
499
|
dump_array_class(obj, Qundef, depth + 1, out);
|
556
500
|
break;
|
557
501
|
case T_HASH:
|
558
502
|
assure_size(out, d2 * out->indent + 14);
|
559
503
|
*out->cur++ = ',';
|
560
504
|
fill_indent(out, d2);
|
561
|
-
|
562
|
-
*out->cur++ = 's';
|
563
|
-
*out->cur++ = 'e';
|
564
|
-
*out->cur++ = 'l';
|
565
|
-
*out->cur++ = 'f';
|
566
|
-
*out->cur++ = '"';
|
567
|
-
*out->cur++ = ':';
|
505
|
+
APPEND_CHARS(out->cur, "\"self\":", 7);
|
568
506
|
dump_hash_class(obj, Qundef, depth + 1, out);
|
569
507
|
break;
|
570
508
|
default: break;
|
571
509
|
}
|
572
510
|
{
|
573
|
-
int cnt;
|
574
|
-
|
575
|
-
cnt = (int)rb_ivar_count(obj);
|
576
|
-
#else
|
577
|
-
volatile VALUE vars = rb_funcall2(obj, oj_instance_variables_id, 0, 0);
|
578
|
-
VALUE * np = RARRAY_PTR(vars);
|
579
|
-
ID vid;
|
580
|
-
const char * attr;
|
581
|
-
int i;
|
582
|
-
int first = 1;
|
583
|
-
|
584
|
-
cnt = (int)RARRAY_LEN(vars);
|
585
|
-
#endif
|
511
|
+
int cnt = (int)rb_ivar_count(obj);
|
512
|
+
|
586
513
|
if (Qundef != clas && 0 < cnt) {
|
587
514
|
*out->cur++ = ',';
|
588
515
|
}
|
@@ -595,52 +522,10 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
|
|
595
522
|
}
|
596
523
|
}
|
597
524
|
out->depth = depth + 1;
|
598
|
-
#ifdef HAVE_RB_IVAR_FOREACH
|
599
525
|
rb_ivar_foreach(obj, dump_attr_cb, (VALUE)out);
|
600
526
|
if (',' == *(out->cur - 1)) {
|
601
527
|
out->cur--; // backup to overwrite last comma
|
602
528
|
}
|
603
|
-
#else
|
604
|
-
size = d2 * out->indent + 1;
|
605
|
-
for (i = cnt; 0 < i; i--, np++) {
|
606
|
-
VALUE value;
|
607
|
-
|
608
|
-
vid = rb_to_id(*np);
|
609
|
-
attr = rb_id2name(vid);
|
610
|
-
if (Yes == out->opts->ignore_under && '@' == *attr && '_' == attr[1]) {
|
611
|
-
continue;
|
612
|
-
}
|
613
|
-
value = rb_ivar_get(obj, vid);
|
614
|
-
|
615
|
-
if (dump_ignore(out->opts, value)) {
|
616
|
-
continue;
|
617
|
-
}
|
618
|
-
if (out->omit_nil && Qnil == value) {
|
619
|
-
continue;
|
620
|
-
}
|
621
|
-
if (first) {
|
622
|
-
first = 0;
|
623
|
-
} else {
|
624
|
-
*out->cur++ = ',';
|
625
|
-
}
|
626
|
-
assure_size(out, size);
|
627
|
-
fill_indent(out, d2);
|
628
|
-
if ('@' == *attr) {
|
629
|
-
attr++;
|
630
|
-
oj_dump_cstr(attr, strlen(attr), 0, 0, out);
|
631
|
-
} else {
|
632
|
-
char buf[32];
|
633
|
-
|
634
|
-
*buf = '~';
|
635
|
-
strncpy(buf + 1, attr, sizeof(buf) - 2);
|
636
|
-
buf[sizeof(buf) - 1] = '\0';
|
637
|
-
oj_dump_cstr(buf, strlen(attr) + 1, 0, 0, out);
|
638
|
-
}
|
639
|
-
*out->cur++ = ':';
|
640
|
-
oj_dump_obj_val(value, d2, out);
|
641
|
-
assure_size(out, 2);
|
642
|
-
}
|
643
|
-
#endif
|
644
529
|
if (rb_obj_is_kind_of(obj, rb_eException)) {
|
645
530
|
volatile VALUE rv;
|
646
531
|
|
@@ -688,12 +573,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
688
573
|
assure_size(out, size);
|
689
574
|
*out->cur++ = '{';
|
690
575
|
fill_indent(out, d2);
|
691
|
-
|
692
|
-
*out->cur++ = '^';
|
693
|
-
*out->cur++ = 'u';
|
694
|
-
*out->cur++ = '"';
|
695
|
-
*out->cur++ = ':';
|
696
|
-
*out->cur++ = '[';
|
576
|
+
APPEND_CHARS(out->cur, "\"^u\":[", 6);
|
697
577
|
if ('#' == *class_name) {
|
698
578
|
VALUE ma = rb_struct_s_members(clas);
|
699
579
|
const char *name;
|
@@ -711,16 +591,14 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
711
591
|
*out->cur++ = ',';
|
712
592
|
}
|
713
593
|
*out->cur++ = '"';
|
714
|
-
|
715
|
-
out->cur += len;
|
594
|
+
APPEND_CHARS(out->cur, name, len);
|
716
595
|
*out->cur++ = '"';
|
717
596
|
}
|
718
597
|
*out->cur++ = ']';
|
719
598
|
} else {
|
720
599
|
fill_indent(out, d3);
|
721
600
|
*out->cur++ = '"';
|
722
|
-
|
723
|
-
out->cur += len;
|
601
|
+
APPEND_CHARS(out->cur, class_name, len);
|
724
602
|
*out->cur++ = '"';
|
725
603
|
}
|
726
604
|
*out->cur++ = ',';
|
@@ -764,8 +642,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
764
642
|
}
|
765
643
|
#endif
|
766
644
|
out->cur--;
|
767
|
-
|
768
|
-
*out->cur++ = '}';
|
645
|
+
APPEND_CHARS(out->cur, "]}", 2);
|
769
646
|
*out->cur = '\0';
|
770
647
|
}
|
771
648
|
|
@@ -805,7 +682,7 @@ static DumpFunc obj_funcs[] = {
|
|
805
682
|
void oj_dump_obj_val(VALUE obj, int depth, Out out) {
|
806
683
|
int type = rb_type(obj);
|
807
684
|
|
808
|
-
if (Yes == out->opts->trace) {
|
685
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
809
686
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
810
687
|
}
|
811
688
|
if (MAX_DEPTH < depth) {
|
@@ -816,14 +693,14 @@ void oj_dump_obj_val(VALUE obj, int depth, Out out) {
|
|
816
693
|
|
817
694
|
if (NULL != f) {
|
818
695
|
f(obj, depth, out, false);
|
819
|
-
if (Yes == out->opts->trace) {
|
696
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
820
697
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
821
698
|
}
|
822
699
|
return;
|
823
700
|
}
|
824
701
|
}
|
825
702
|
oj_dump_nil(Qnil, depth, out, false);
|
826
|
-
if (Yes == out->opts->trace) {
|
703
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
827
704
|
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
828
705
|
}
|
829
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
|
-
|
109
|
-
*out->cur++ = *b;
|
110
|
-
}
|
108
|
+
APPEND_CHARS(out->cur, buf, cnt);
|
111
109
|
*out->cur = '\0';
|
112
110
|
}
|
113
111
|
|
@@ -134,19 +132,17 @@ 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
|
-
|
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
|
-
|
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 {
|
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
}
|
data/ext/oj/extconf.rb
CHANGED
@@ -23,14 +23,10 @@ dflags = {
|
|
23
23
|
'RSTRUCT_LEN_RETURNS_INTEGER_OBJECT' => ('ruby' == type && '2' == version[0] && '4' == version[1] && '1' >= version[2]) ? 1 : 0,
|
24
24
|
}
|
25
25
|
|
26
|
-
have_func('rb_time_timespec')
|
27
|
-
have_func('rb_ivar_count')
|
28
|
-
have_func('rb_ivar_foreach')
|
29
26
|
# Support for compaction.
|
30
27
|
have_func('rb_gc_mark_movable')
|
31
28
|
have_func('stpcpy')
|
32
29
|
have_func('pthread_mutex_init')
|
33
|
-
have_func('rb_enc_associate')
|
34
30
|
have_func('rb_enc_interned_str')
|
35
31
|
have_func('rb_ext_ractor_safe', 'ruby.h')
|
36
32
|
# rb_hash_bulk_insert is deep down in a header not included in normal build and that seems to fool have_func.
|
@@ -38,6 +34,11 @@ have_func('rb_hash_bulk_insert', 'ruby.h') unless '2' == version[0] && '6' == ve
|
|
38
34
|
|
39
35
|
dflags['OJ_DEBUG'] = true unless ENV['OJ_DEBUG'].nil?
|
40
36
|
|
37
|
+
if with_config('--with-sse42')
|
38
|
+
$CPPFLAGS += ' -msse4.2'
|
39
|
+
dflags['OJ_USE_SSE4_2'] = 1
|
40
|
+
end
|
41
|
+
|
41
42
|
dflags.each do |k,v|
|
42
43
|
if v.nil?
|
43
44
|
$CPPFLAGS += " -D#{k}"
|
data/ext/oj/fast.c
CHANGED
@@ -13,6 +13,7 @@
|
|
13
13
|
|
14
14
|
#include "encode.h"
|
15
15
|
#include "oj.h"
|
16
|
+
#include "dump.h"
|
16
17
|
|
17
18
|
// maximum to allocate on the stack, arbitrary limit
|
18
19
|
#define SMALL_JSON 65536
|
@@ -676,21 +677,23 @@ static void free_doc_cb(void *x) {
|
|
676
677
|
}
|
677
678
|
|
678
679
|
static void mark_leaf(Leaf leaf) {
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
680
|
+
if (NULL != leaf) {
|
681
|
+
switch (leaf->value_type) {
|
682
|
+
case COL_VAL:
|
683
|
+
if (NULL != leaf->elements) {
|
684
|
+
Leaf first = leaf->elements->next;
|
685
|
+
Leaf e = first;
|
684
686
|
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
687
|
+
do {
|
688
|
+
mark_leaf(e);
|
689
|
+
e = e->next;
|
690
|
+
} while (e != first);
|
691
|
+
}
|
692
|
+
break;
|
693
|
+
case RUBY_VAL: mark(leaf->value); break;
|
692
694
|
|
693
|
-
|
695
|
+
default: break;
|
696
|
+
}
|
694
697
|
}
|
695
698
|
}
|
696
699
|
|
@@ -771,7 +774,7 @@ static VALUE parse_json(VALUE clas, char *json, bool given, bool allocated) {
|
|
771
774
|
pi.doc = doc;
|
772
775
|
#if IS_WINDOWS
|
773
776
|
// assume a 1M stack and give half to ruby
|
774
|
-
pi.stack_min = (void *)((char *)&pi - (
|
777
|
+
pi.stack_min = (void *)((char *)&pi - (512L * 1024L));
|
775
778
|
#else
|
776
779
|
{
|
777
780
|
struct rlimit lim;
|
@@ -1610,18 +1613,15 @@ static VALUE doc_dump(int argc, VALUE *argv, VALUE self) {
|
|
1610
1613
|
volatile VALUE rjson;
|
1611
1614
|
|
1612
1615
|
if (0 == filename) {
|
1613
|
-
char buf[4096];
|
1614
1616
|
struct _out out;
|
1615
1617
|
|
1616
|
-
out
|
1617
|
-
|
1618
|
-
out.allocated = false;
|
1618
|
+
oj_out_init(&out);
|
1619
|
+
|
1619
1620
|
out.omit_nil = oj_default_options.dump_opts.omit_nil;
|
1620
1621
|
oj_dump_leaf_to_json(leaf, &oj_default_options, &out);
|
1621
1622
|
rjson = rb_str_new2(out.buf);
|
1622
|
-
|
1623
|
-
|
1624
|
-
}
|
1623
|
+
|
1624
|
+
oj_out_free(&out);
|
1625
1625
|
} else {
|
1626
1626
|
oj_write_leaf_to_file(leaf, filename, &oj_default_options);
|
1627
1627
|
rjson = Qnil;
|
@@ -1717,8 +1717,10 @@ static VALUE doc_not_implemented(VALUE self) {
|
|
1717
1717
|
* # Now try again using a path to Oj::Doc.fetch() directly and not using a
|
1718
1718
|
* block. doc = Oj::Doc.open(json) doc.fetch('/2/three') #=> 3 doc.close()
|
1719
1719
|
*/
|
1720
|
-
void oj_init_doc() {
|
1720
|
+
void oj_init_doc(void) {
|
1721
1721
|
oj_doc_class = rb_define_class_under(Oj, "Doc", rb_cObject);
|
1722
|
+
rb_gc_register_address(&oj_doc_class);
|
1723
|
+
rb_undef_alloc_func(oj_doc_class);
|
1722
1724
|
rb_define_singleton_method(oj_doc_class, "open", doc_open, 1);
|
1723
1725
|
rb_define_singleton_method(oj_doc_class, "open_file", doc_open_file, 1);
|
1724
1726
|
rb_define_singleton_method(oj_doc_class, "parse", doc_open, 1);
|