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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +75 -0
- data/README.md +11 -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 +66 -112
- data/ext/oj/dump.c +147 -184
- data/ext/oj/dump.h +25 -8
- data/ext/oj/dump_compat.c +47 -89
- data/ext/oj/dump_leaf.c +14 -58
- data/ext/oj/dump_object.c +72 -188
- data/ext/oj/dump_strict.c +19 -31
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/extconf.rb +5 -4
- data/ext/oj/fast.c +36 -24
- data/ext/oj/intern.c +22 -12
- data/ext/oj/intern.h +1 -1
- data/ext/oj/mimic_json.c +74 -73
- data/ext/oj/object.c +54 -72
- data/ext/oj/odd.c +83 -63
- data/ext/oj/odd.h +13 -13
- data/ext/oj/oj.c +166 -175
- data/ext/oj/oj.h +25 -3
- data/ext/oj/parse.c +123 -79
- 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 +46 -70
- 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 +86 -131
- 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 +22 -27
- 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/JsonGem.md +15 -0
- data/pages/Modes.md +6 -3
- data/pages/Options.md +6 -0
- data/pages/Rails.md +12 -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/bug.rb +16 -0
- data/test/foo.rb +71 -7
- 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_fast.rb +37 -7
- 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_saj.rb +1 -1
- data/test/test_scp.rb +2 -4
- data/test/test_strict.rb +2 -0
- data/test/test_various.rb +32 -2
- data/test/test_wab.rb +2 -0
- data/test/tests.rb +9 -1
- data/test/tests_mimic.rb +9 -0
- data/test/tests_mimic_addition.rb +9 -0
- metadata +15 -115
data/ext/oj/dump.h
CHANGED
@@ -32,6 +32,11 @@ extern void oj_dump_obj_to_s(VALUE obj, Out out);
|
|
32
32
|
|
33
33
|
extern const char *oj_nan_str(VALUE obj, int opt, int mode, bool plus, int *lenp);
|
34
34
|
|
35
|
+
// initialize an out buffer with the provided stack allocated memory
|
36
|
+
extern void oj_out_init(Out out);
|
37
|
+
// clean up the out buffer if it uses heap allocated memory
|
38
|
+
extern void oj_out_free(Out out);
|
39
|
+
|
35
40
|
extern void oj_grow_out(Out out, size_t len);
|
36
41
|
extern long oj_check_circular(VALUE obj, Out out);
|
37
42
|
|
@@ -50,7 +55,6 @@ extern VALUE oj_remove_to_json(int argc, VALUE *argv, VALUE self);
|
|
50
55
|
|
51
56
|
extern int oj_dump_float_printf(char *buf, size_t blen, VALUE obj, double d, const char *format);
|
52
57
|
|
53
|
-
extern bool oj_dump_ignore(Options opts, VALUE obj);
|
54
58
|
extern time_t oj_sec_from_time_hard_way(VALUE obj);
|
55
59
|
|
56
60
|
inline static void assure_size(Out out, size_t len) {
|
@@ -63,15 +67,29 @@ inline static void fill_indent(Out out, int cnt) {
|
|
63
67
|
if (0 < out->indent) {
|
64
68
|
cnt *= out->indent;
|
65
69
|
*out->cur++ = '\n';
|
66
|
-
|
67
|
-
|
70
|
+
memset(out->cur, ' ', cnt);
|
71
|
+
out->cur += cnt;
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
inline static bool dump_ignore(Options opts, VALUE obj) {
|
76
|
+
if (NULL != opts->ignore && (ObjectMode == opts->mode || CustomMode == opts->mode)) {
|
77
|
+
VALUE *vp = opts->ignore;
|
78
|
+
VALUE clas = rb_obj_class(obj);
|
79
|
+
|
80
|
+
for (; Qnil != *vp; vp++) {
|
81
|
+
if (clas == *vp) {
|
82
|
+
return true;
|
83
|
+
}
|
68
84
|
}
|
69
85
|
}
|
86
|
+
return false;
|
70
87
|
}
|
71
88
|
|
72
89
|
inline static void dump_ulong(unsigned long num, Out out) {
|
73
|
-
char
|
74
|
-
char
|
90
|
+
char buf[32];
|
91
|
+
char *b = buf + sizeof(buf) - 1;
|
92
|
+
size_t cnt = 0;
|
75
93
|
|
76
94
|
*b-- = '\0';
|
77
95
|
if (0 < num) {
|
@@ -82,9 +100,8 @@ inline static void dump_ulong(unsigned long num, Out out) {
|
|
82
100
|
} else {
|
83
101
|
*b = '0';
|
84
102
|
}
|
85
|
-
|
86
|
-
|
87
|
-
}
|
103
|
+
cnt = sizeof(buf) - (b - buf) - 1;
|
104
|
+
APPEND_CHARS(out->cur, b, cnt);
|
88
105
|
*out->cur = '\0';
|
89
106
|
}
|
90
107
|
|
data/ext/oj/dump_compat.c
CHANGED
@@ -32,21 +32,17 @@ dump_obj_classname(const char *classname, int depth, Out out) {
|
|
32
32
|
*out->cur++ = '{';
|
33
33
|
fill_indent(out, d2);
|
34
34
|
*out->cur++ = '"';
|
35
|
-
|
36
|
-
out->cur += out->opts->create_id_len;
|
35
|
+
APPEND_CHARS(out->cur, out->opts->create_id, out->opts->create_id_len);
|
37
36
|
*out->cur++ = '"';
|
38
37
|
if (0 < out->opts->dump_opts.before_size) {
|
39
|
-
|
40
|
-
out->cur += out->opts->dump_opts.before_size;
|
38
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
|
41
39
|
}
|
42
40
|
*out->cur++ = ':';
|
43
41
|
if (0 < out->opts->dump_opts.after_size) {
|
44
|
-
|
45
|
-
out->cur += out->opts->dump_opts.after_size;
|
42
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
|
46
43
|
}
|
47
44
|
*out->cur++ = '"';
|
48
|
-
|
49
|
-
out->cur += len;
|
45
|
+
APPEND_CHARS(out->cur, classname, len);
|
50
46
|
*out->cur++ = '"';
|
51
47
|
}
|
52
48
|
|
@@ -71,15 +67,13 @@ dump_values_array(VALUE *values, int depth, Out out) {
|
|
71
67
|
assure_size(out, size);
|
72
68
|
if (out->opts->dump_opts.use) {
|
73
69
|
if (0 < out->opts->dump_opts.array_size) {
|
74
|
-
|
75
|
-
out->cur += out->opts->dump_opts.array_size;
|
70
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
76
71
|
}
|
77
72
|
if (0 < out->opts->dump_opts.indent_size) {
|
78
73
|
int i;
|
79
74
|
|
80
75
|
for (i = d2; 0 < i; i--) {
|
81
|
-
|
82
|
-
out->cur += out->opts->dump_opts.indent_size;
|
76
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
83
77
|
}
|
84
78
|
}
|
85
79
|
} else {
|
@@ -93,15 +87,13 @@ dump_values_array(VALUE *values, int depth, Out out) {
|
|
93
87
|
assure_size(out, size);
|
94
88
|
if (out->opts->dump_opts.use) {
|
95
89
|
if (0 < out->opts->dump_opts.array_size) {
|
96
|
-
|
97
|
-
out->cur += out->opts->dump_opts.array_size;
|
90
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
98
91
|
}
|
99
92
|
if (0 < out->opts->dump_opts.indent_size) {
|
100
93
|
int i;
|
101
94
|
|
102
95
|
for (i = depth; 0 < i; i--) {
|
103
|
-
|
104
|
-
out->cur += out->opts->dump_opts.indent_size;
|
96
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
105
97
|
}
|
106
98
|
}
|
107
99
|
} else {
|
@@ -117,7 +109,7 @@ dump_to_json(VALUE obj, Out out) {
|
|
117
109
|
const char *s;
|
118
110
|
int len;
|
119
111
|
|
120
|
-
if (Yes == out->opts->trace) {
|
112
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
121
113
|
oj_trace("to_json", obj, __FILE__, __LINE__, 0, TraceRubyIn);
|
122
114
|
}
|
123
115
|
if (0 == rb_obj_method_arity(obj, oj_to_json_id)) {
|
@@ -125,7 +117,7 @@ dump_to_json(VALUE obj, Out out) {
|
|
125
117
|
} else {
|
126
118
|
rs = rb_funcall2(obj, oj_to_json_id, out->argc, out->argv);
|
127
119
|
}
|
128
|
-
if (Yes == out->opts->trace) {
|
120
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
129
121
|
oj_trace("to_json", obj, __FILE__, __LINE__, 0, TraceRubyOut);
|
130
122
|
}
|
131
123
|
|
@@ -133,8 +125,7 @@ dump_to_json(VALUE obj, Out out) {
|
|
133
125
|
len = (int)RSTRING_LEN(rs);
|
134
126
|
|
135
127
|
assure_size(out, len + 1);
|
136
|
-
|
137
|
-
out->cur += len;
|
128
|
+
APPEND_CHARS(out->cur, s, len);
|
138
129
|
*out->cur = '\0';
|
139
130
|
}
|
140
131
|
|
@@ -164,25 +155,23 @@ dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
|
164
155
|
} else {
|
165
156
|
size = d2 * out->indent + 2;
|
166
157
|
}
|
158
|
+
assure_size(out, size * cnt);
|
167
159
|
cnt--;
|
168
160
|
for (i = 0; i <= cnt; i++) {
|
169
|
-
assure_size(out, size);
|
170
161
|
if (out->opts->dump_opts.use) {
|
171
162
|
if (0 < out->opts->dump_opts.array_size) {
|
172
|
-
|
173
|
-
out->cur += out->opts->dump_opts.array_size;
|
163
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
174
164
|
}
|
175
165
|
if (0 < out->opts->dump_opts.indent_size) {
|
176
166
|
int i;
|
177
167
|
for (i = d2; 0 < i; i--) {
|
178
|
-
|
179
|
-
out->cur += out->opts->dump_opts.indent_size;
|
168
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
180
169
|
}
|
181
170
|
}
|
182
171
|
} else {
|
183
172
|
fill_indent(out, d2);
|
184
173
|
}
|
185
|
-
oj_dump_compat_val(
|
174
|
+
oj_dump_compat_val(RARRAY_AREF(a, i), d2, out, true);
|
186
175
|
if (i < cnt) {
|
187
176
|
*out->cur++ = ',';
|
188
177
|
}
|
@@ -191,15 +180,13 @@ dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
|
191
180
|
size = out->opts->dump_opts.array_size + out->opts->dump_opts.indent_size * depth + 1;
|
192
181
|
assure_size(out, size);
|
193
182
|
if (0 < out->opts->dump_opts.array_size) {
|
194
|
-
|
195
|
-
out->cur += out->opts->dump_opts.array_size;
|
183
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
196
184
|
}
|
197
185
|
if (0 < out->opts->dump_opts.indent_size) {
|
198
186
|
int i;
|
199
187
|
|
200
188
|
for (i = depth; 0 < i; i--) {
|
201
|
-
|
202
|
-
out->cur += out->opts->dump_opts.indent_size;
|
189
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
203
190
|
}
|
204
191
|
}
|
205
192
|
} else {
|
@@ -336,33 +323,25 @@ exception_alt(VALUE obj, int depth, Out out) {
|
|
336
323
|
assure_size(out, size + sep_len + 6);
|
337
324
|
*out->cur++ = ',';
|
338
325
|
fill_indent(out, d3);
|
339
|
-
|
340
|
-
*out->cur++ = 'm';
|
341
|
-
*out->cur++ = '"';
|
326
|
+
APPEND_CHARS(out->cur, "\"m\"", 3);
|
342
327
|
if (0 < out->opts->dump_opts.before_size) {
|
343
|
-
|
344
|
-
out->cur += out->opts->dump_opts.before_size;
|
328
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
|
345
329
|
}
|
346
330
|
*out->cur++ = ':';
|
347
331
|
if (0 < out->opts->dump_opts.after_size) {
|
348
|
-
|
349
|
-
out->cur += out->opts->dump_opts.after_size;
|
332
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
|
350
333
|
}
|
351
334
|
oj_dump_str(rb_funcall(obj, message_id, 0), 0, out, false);
|
352
335
|
assure_size(out, size + sep_len + 6);
|
353
336
|
*out->cur++ = ',';
|
354
337
|
fill_indent(out, d3);
|
355
|
-
|
356
|
-
*out->cur++ = 'b';
|
357
|
-
*out->cur++ = '"';
|
338
|
+
APPEND_CHARS(out->cur, "\"b\"", 3);
|
358
339
|
if (0 < out->opts->dump_opts.before_size) {
|
359
|
-
|
360
|
-
out->cur += out->opts->dump_opts.before_size;
|
340
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
|
361
341
|
}
|
362
342
|
*out->cur++ = ':';
|
363
343
|
if (0 < out->opts->dump_opts.after_size) {
|
364
|
-
|
365
|
-
out->cur += out->opts->dump_opts.after_size;
|
344
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
|
366
345
|
}
|
367
346
|
dump_array(rb_funcall(obj, backtrace_id, 0), depth, out, false);
|
368
347
|
fill_indent(out, depth);
|
@@ -398,17 +377,13 @@ range_alt(VALUE obj, int depth, Out out) {
|
|
398
377
|
assure_size(out, size + sep_len + 6);
|
399
378
|
*out->cur++ = ',';
|
400
379
|
fill_indent(out, d3);
|
401
|
-
|
402
|
-
*out->cur++ = 'a';
|
403
|
-
*out->cur++ = '"';
|
380
|
+
APPEND_CHARS(out->cur, "\"a\"", 3);
|
404
381
|
if (0 < out->opts->dump_opts.before_size) {
|
405
|
-
|
406
|
-
out->cur += out->opts->dump_opts.before_size;
|
382
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
|
407
383
|
}
|
408
384
|
*out->cur++ = ':';
|
409
385
|
if (0 < out->opts->dump_opts.after_size) {
|
410
|
-
|
411
|
-
out->cur += out->opts->dump_opts.after_size;
|
386
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
|
412
387
|
}
|
413
388
|
args[0] = rb_funcall(obj, oj_begin_id, 0);
|
414
389
|
args[1] = rb_funcall(obj, oj_end_id, 0);
|
@@ -469,20 +444,15 @@ time_alt(VALUE obj, int depth, Out out) {
|
|
469
444
|
time_t sec;
|
470
445
|
long long nsec;
|
471
446
|
|
472
|
-
#ifdef HAVE_RB_TIME_TIMESPEC
|
473
447
|
if (16 <= sizeof(struct timespec)) {
|
474
448
|
struct timespec ts = rb_time_timespec(obj);
|
475
449
|
|
476
450
|
sec = (long long)ts.tv_sec;
|
477
451
|
nsec = ts.tv_nsec;
|
478
452
|
} else {
|
479
|
-
sec =
|
480
|
-
nsec =
|
453
|
+
sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
454
|
+
nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
481
455
|
}
|
482
|
-
#else
|
483
|
-
sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
484
|
-
nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
485
|
-
#endif
|
486
456
|
|
487
457
|
attrs[0].num = sec;
|
488
458
|
attrs[1].num = nsec;
|
@@ -613,18 +583,21 @@ dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
|
613
583
|
} else if (OJ_INFINITY == d) {
|
614
584
|
if (WordNan == out->opts->dump_opts.nan_dump) {
|
615
585
|
strcpy(buf, "Infinity");
|
586
|
+
cnt = 8;
|
616
587
|
} else {
|
617
588
|
raise_json_err("Infinity not allowed in JSON.", "GeneratorError");
|
618
589
|
}
|
619
590
|
} else if (-OJ_INFINITY == d) {
|
620
591
|
if (WordNan == out->opts->dump_opts.nan_dump) {
|
621
592
|
strcpy(buf, "-Infinity");
|
593
|
+
cnt = 9;
|
622
594
|
} else {
|
623
595
|
raise_json_err("-Infinity not allowed in JSON.", "GeneratorError");
|
624
596
|
}
|
625
597
|
} else if (isnan(d)) {
|
626
598
|
if (WordNan == out->opts->dump_opts.nan_dump) {
|
627
599
|
strcpy(buf, "NaN");
|
600
|
+
cnt = 3;
|
628
601
|
} else {
|
629
602
|
raise_json_err("NaN not allowed in JSON.", "GeneratorError");
|
630
603
|
}
|
@@ -639,9 +612,7 @@ dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
|
639
612
|
cnt = (int)RSTRING_LEN(rstr);
|
640
613
|
}
|
641
614
|
assure_size(out, cnt);
|
642
|
-
|
643
|
-
*out->cur++ = *b;
|
644
|
-
}
|
615
|
+
APPEND_CHARS(out->cur, buf, cnt);
|
645
616
|
*out->cur = '\0';
|
646
617
|
}
|
647
618
|
|
@@ -659,14 +630,12 @@ hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
659
630
|
} else {
|
660
631
|
assure_size(out, depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
|
661
632
|
if (0 < out->opts->dump_opts.hash_size) {
|
662
|
-
|
663
|
-
out->cur += out->opts->dump_opts.hash_size;
|
633
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
|
664
634
|
}
|
665
635
|
if (0 < out->opts->dump_opts.indent_size) {
|
666
636
|
int i;
|
667
637
|
for (i = depth; 0 < i; i--) {
|
668
|
-
|
669
|
-
out->cur += out->opts->dump_opts.indent_size;
|
638
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
670
639
|
}
|
671
640
|
}
|
672
641
|
}
|
@@ -687,13 +656,11 @@ hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
687
656
|
} else {
|
688
657
|
assure_size(out, out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2);
|
689
658
|
if (0 < out->opts->dump_opts.before_size) {
|
690
|
-
|
691
|
-
out->cur += out->opts->dump_opts.before_size;
|
659
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
|
692
660
|
}
|
693
661
|
*out->cur++ = ':';
|
694
662
|
if (0 < out->opts->dump_opts.after_size) {
|
695
|
-
|
696
|
-
out->cur += out->opts->dump_opts.after_size;
|
663
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
|
697
664
|
}
|
698
665
|
}
|
699
666
|
oj_dump_compat_val(value, depth, out, true);
|
@@ -719,8 +686,7 @@ dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
|
|
719
686
|
cnt = (int)RHASH_SIZE(obj);
|
720
687
|
assure_size(out, 2);
|
721
688
|
if (0 == cnt) {
|
722
|
-
|
723
|
-
*out->cur++ = '}';
|
689
|
+
APPEND_CHARS(out->cur, "{}", 2);
|
724
690
|
} else {
|
725
691
|
*out->cur++ = '{';
|
726
692
|
out->depth = depth + 1;
|
@@ -734,15 +700,13 @@ dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
|
|
734
700
|
} else {
|
735
701
|
assure_size(out, depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
|
736
702
|
if (0 < out->opts->dump_opts.hash_size) {
|
737
|
-
|
738
|
-
out->cur += out->opts->dump_opts.hash_size;
|
703
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
|
739
704
|
}
|
740
705
|
if (0 < out->opts->dump_opts.indent_size) {
|
741
706
|
int i;
|
742
707
|
|
743
708
|
for (i = depth; 0 < i; i--) {
|
744
|
-
|
745
|
-
out->cur += out->opts->dump_opts.indent_size;
|
709
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
746
710
|
}
|
747
711
|
}
|
748
712
|
}
|
@@ -786,8 +750,7 @@ dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
786
750
|
*out->cur++ = '"';
|
787
751
|
oj_dump_compat_val(rb_funcall(obj, oj_begin_id, 0), 0, out, false);
|
788
752
|
assure_size(out, 3);
|
789
|
-
|
790
|
-
*out->cur++ = '.';
|
753
|
+
APPEND_CHARS(out->cur, "..", 2);
|
791
754
|
if (Qtrue == rb_funcall(obj, oj_exclude_end_id, 0)) {
|
792
755
|
*out->cur++ = '.';
|
793
756
|
}
|
@@ -833,17 +796,13 @@ dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
833
796
|
assure_size(out, size + sep_len + 6);
|
834
797
|
*out->cur++ = ',';
|
835
798
|
fill_indent(out, d3);
|
836
|
-
|
837
|
-
*out->cur++ = 'v';
|
838
|
-
*out->cur++ = '"';
|
799
|
+
APPEND_CHARS(out->cur, "\"v\"", 3);
|
839
800
|
if (0 < out->opts->dump_opts.before_size) {
|
840
|
-
|
841
|
-
out->cur += out->opts->dump_opts.before_size;
|
801
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
|
842
802
|
}
|
843
803
|
*out->cur++ = ':';
|
844
804
|
if (0 < out->opts->dump_opts.after_size) {
|
845
|
-
|
846
|
-
out->cur += out->opts->dump_opts.after_size;
|
805
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
|
847
806
|
}
|
848
807
|
for (i = 0; i < cnt; i++) {
|
849
808
|
#ifdef RSTRUCT_LEN
|
@@ -886,8 +845,7 @@ dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
|
|
886
845
|
} else {
|
887
846
|
assure_size(out, cnt);
|
888
847
|
}
|
889
|
-
|
890
|
-
out->cur += cnt;
|
848
|
+
APPEND_CHARS(out->cur, RSTRING_PTR(rs), cnt);
|
891
849
|
if (dump_as_string) {
|
892
850
|
*out->cur++ = '"';
|
893
851
|
}
|
@@ -935,7 +893,7 @@ void
|
|
935
893
|
oj_dump_compat_val(VALUE obj, int depth, Out out, bool as_ok) {
|
936
894
|
int type = rb_type(obj);
|
937
895
|
|
938
|
-
if (Yes == out->opts->trace) {
|
896
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
939
897
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
940
898
|
}
|
941
899
|
if (out->opts->dump_opts.max_depth <= depth) {
|
@@ -960,14 +918,14 @@ oj_dump_compat_val(VALUE obj, int depth, Out out, bool as_ok) {
|
|
960
918
|
|
961
919
|
if (NULL != f) {
|
962
920
|
f(obj, depth, out, as_ok);
|
963
|
-
if (Yes == out->opts->trace) {
|
921
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
964
922
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
965
923
|
}
|
966
924
|
return;
|
967
925
|
}
|
968
926
|
}
|
969
927
|
oj_dump_nil(Qnil, depth, out, false);
|
970
|
-
if (Yes == out->opts->trace) {
|
928
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
971
929
|
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
972
930
|
}
|
973
931
|
}
|
data/ext/oj/dump_leaf.c
CHANGED
@@ -8,36 +8,9 @@
|
|
8
8
|
|
9
9
|
static void dump_leaf(Leaf leaf, int depth, Out out);
|
10
10
|
|
11
|
-
static void grow(Out out, size_t len) {
|
12
|
-
size_t size = out->end - out->buf;
|
13
|
-
long pos = out->cur - out->buf;
|
14
|
-
char * buf;
|
15
|
-
|
16
|
-
size *= 2;
|
17
|
-
if (size <= len * 2 + pos) {
|
18
|
-
size += len;
|
19
|
-
}
|
20
|
-
if (out->allocated) {
|
21
|
-
buf = REALLOC_N(out->buf, char, (size + BUFFER_EXTRA));
|
22
|
-
} else {
|
23
|
-
buf = ALLOC_N(char, (size + BUFFER_EXTRA));
|
24
|
-
out->allocated = true;
|
25
|
-
memcpy(buf, out->buf, out->end - out->buf + BUFFER_EXTRA);
|
26
|
-
}
|
27
|
-
if (0 == buf) {
|
28
|
-
rb_raise(rb_eNoMemError, "Failed to create string. [%d:%s]\n", ENOSPC, strerror(ENOSPC));
|
29
|
-
}
|
30
|
-
out->buf = buf;
|
31
|
-
out->end = buf + size;
|
32
|
-
out->cur = out->buf + pos;
|
33
|
-
}
|
34
|
-
|
35
11
|
inline static void dump_chars(const char *s, size_t size, Out out) {
|
36
|
-
|
37
|
-
|
38
|
-
}
|
39
|
-
memcpy(out->cur, s, size);
|
40
|
-
out->cur += size;
|
12
|
+
assure_size(out, size);
|
13
|
+
APPEND_CHARS(out->cur, s, size);
|
41
14
|
*out->cur = '\0';
|
42
15
|
}
|
43
16
|
|
@@ -81,9 +54,7 @@ static void dump_leaf_array(Leaf leaf, int depth, Out out) {
|
|
81
54
|
int d2 = depth + 1;
|
82
55
|
|
83
56
|
size = 2;
|
84
|
-
|
85
|
-
grow(out, size);
|
86
|
-
}
|
57
|
+
assure_size(out, size);
|
87
58
|
*out->cur++ = '[';
|
88
59
|
if (0 == leaf->elements) {
|
89
60
|
*out->cur++ = ']';
|
@@ -93,9 +64,7 @@ static void dump_leaf_array(Leaf leaf, int depth, Out out) {
|
|
93
64
|
|
94
65
|
size = d2 * out->indent + 2;
|
95
66
|
do {
|
96
|
-
|
97
|
-
grow(out, size);
|
98
|
-
}
|
67
|
+
assure_size(out, size);
|
99
68
|
fill_indent(out, d2);
|
100
69
|
dump_leaf(e, d2, out);
|
101
70
|
if (e->next != first) {
|
@@ -104,9 +73,7 @@ static void dump_leaf_array(Leaf leaf, int depth, Out out) {
|
|
104
73
|
e = e->next;
|
105
74
|
} while (e != first);
|
106
75
|
size = depth * out->indent + 1;
|
107
|
-
|
108
|
-
grow(out, size);
|
109
|
-
}
|
76
|
+
assure_size(out, size);
|
110
77
|
fill_indent(out, depth);
|
111
78
|
*out->cur++ = ']';
|
112
79
|
}
|
@@ -118,9 +85,7 @@ static void dump_leaf_hash(Leaf leaf, int depth, Out out) {
|
|
118
85
|
int d2 = depth + 1;
|
119
86
|
|
120
87
|
size = 2;
|
121
|
-
|
122
|
-
grow(out, size);
|
123
|
-
}
|
88
|
+
assure_size(out, size);
|
124
89
|
*out->cur++ = '{';
|
125
90
|
if (0 == leaf->elements) {
|
126
91
|
*out->cur++ = '}';
|
@@ -130,9 +95,7 @@ static void dump_leaf_hash(Leaf leaf, int depth, Out out) {
|
|
130
95
|
|
131
96
|
size = d2 * out->indent + 2;
|
132
97
|
do {
|
133
|
-
|
134
|
-
grow(out, size);
|
135
|
-
}
|
98
|
+
assure_size(out, size);
|
136
99
|
fill_indent(out, d2);
|
137
100
|
oj_dump_cstr(e->key, strlen(e->key), 0, 0, out);
|
138
101
|
*out->cur++ = ':';
|
@@ -143,9 +106,7 @@ static void dump_leaf_hash(Leaf leaf, int depth, Out out) {
|
|
143
106
|
e = e->next;
|
144
107
|
} while (e != first);
|
145
108
|
size = depth * out->indent + 1;
|
146
|
-
|
147
|
-
grow(out, size);
|
148
|
-
}
|
109
|
+
assure_size(out, size);
|
149
110
|
fill_indent(out, depth);
|
150
111
|
*out->cur++ = '}';
|
151
112
|
}
|
@@ -168,10 +129,7 @@ static void dump_leaf(Leaf leaf, int depth, Out out) {
|
|
168
129
|
|
169
130
|
void oj_dump_leaf_to_json(Leaf leaf, Options copts, Out out) {
|
170
131
|
if (0 == out->buf) {
|
171
|
-
out
|
172
|
-
out->end = out->buf + 4095 -
|
173
|
-
BUFFER_EXTRA; // 1 less than end plus extra for possible errors
|
174
|
-
out->allocated = true;
|
132
|
+
oj_out_init(out);
|
175
133
|
}
|
176
134
|
out->cur = out->buf;
|
177
135
|
out->circ_cnt = 0;
|
@@ -182,14 +140,12 @@ void oj_dump_leaf_to_json(Leaf leaf, Options copts, Out out) {
|
|
182
140
|
}
|
183
141
|
|
184
142
|
void oj_write_leaf_to_file(Leaf leaf, const char *path, Options copts) {
|
185
|
-
char buf[4096];
|
186
143
|
struct _out out;
|
187
144
|
size_t size;
|
188
145
|
FILE * f;
|
189
146
|
|
190
|
-
out
|
191
|
-
|
192
|
-
out.allocated = false;
|
147
|
+
oj_out_init(&out);
|
148
|
+
|
193
149
|
out.omit_nil = copts->dump_opts.omit_nil;
|
194
150
|
oj_dump_leaf_to_json(leaf, copts, &out);
|
195
151
|
size = out.cur - out.buf;
|
@@ -201,8 +157,8 @@ void oj_write_leaf_to_file(Leaf leaf, const char *path, Options copts) {
|
|
201
157
|
|
202
158
|
rb_raise(rb_eIOError, "Write failed. [%d:%s]\n", err, strerror(err));
|
203
159
|
}
|
204
|
-
|
205
|
-
|
206
|
-
|
160
|
+
|
161
|
+
oj_out_free(&out);
|
162
|
+
|
207
163
|
fclose(f);
|
208
164
|
}
|