oj 3.13.9 → 3.13.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +9 -0
- data/ext/oj/circarray.c +1 -1
- data/ext/oj/code.c +15 -22
- data/ext/oj/custom.c +32 -59
- data/ext/oj/dump.c +129 -175
- data/ext/oj/dump.h +25 -8
- data/ext/oj/dump_compat.c +44 -81
- data/ext/oj/dump_leaf.c +14 -58
- data/ext/oj/dump_object.c +68 -129
- data/ext/oj/dump_strict.c +14 -26
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/fast.c +15 -9
- data/ext/oj/intern.c +9 -2
- data/ext/oj/intern.h +1 -1
- data/ext/oj/mimic_json.c +73 -73
- data/ext/oj/object.c +1 -1
- data/ext/oj/odd.c +83 -63
- data/ext/oj/odd.h +13 -13
- data/ext/oj/oj.c +29 -17
- data/ext/oj/oj.h +20 -2
- data/ext/oj/parse.c +3 -2
- data/ext/oj/parser.c +10 -15
- data/ext/oj/rails.c +43 -62
- data/ext/oj/rails.h +1 -1
- data/ext/oj/reader.c +2 -0
- data/ext/oj/saj.c +11 -23
- data/ext/oj/stream_writer.c +3 -1
- data/ext/oj/string_writer.c +12 -5
- data/ext/oj/wab.c +9 -9
- data/lib/oj/version.rb +1 -1
- data/pages/JsonGem.md +15 -0
- data/pages/Modes.md +6 -3
- data/pages/Rails.md +12 -0
- data/test/bar.rb +1 -8
- data/test/foo.rb +70 -13
- data/test/perf_dump.rb +50 -0
- data/test/test_fast.rb +19 -0
- data/test/test_object.rb +12 -7
- data/test/test_saj.rb +1 -1
- data/test/test_various.rb +27 -2
- data/test/tests.rb +0 -1
- metadata +6 -3
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,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
|
-
|
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 {
|
158
144
|
fill_indent(out, d2);
|
159
145
|
}
|
160
|
-
oj_dump_obj_val(
|
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
|
-
|
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 {
|
@@ -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 (
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
}
|
@@ -342,7 +322,7 @@ static int dump_attr_cb(ID key, VALUE value, VALUE ov) {
|
|
342
322
|
size_t size = depth * out->indent + 1;
|
343
323
|
const char *attr = rb_id2name(key);
|
344
324
|
|
345
|
-
if (
|
325
|
+
if (dump_ignore(out->opts, value)) {
|
346
326
|
return ST_CONTINUE;
|
347
327
|
}
|
348
328
|
if (out->omit_nil && Qnil == value) {
|
@@ -401,11 +381,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
|
|
401
381
|
size = d2 * out->indent + clen + 10;
|
402
382
|
assure_size(out, size);
|
403
383
|
fill_indent(out, d2);
|
404
|
-
|
405
|
-
*out->cur++ = '^';
|
406
|
-
*out->cur++ = 'O';
|
407
|
-
*out->cur++ = '"';
|
408
|
-
*out->cur++ = ':';
|
384
|
+
APPEND_CHARS(out->cur, "\"^O\":", 5);
|
409
385
|
oj_dump_cstr(class_name, clen, 0, 0, out);
|
410
386
|
*out->cur++ = ',';
|
411
387
|
}
|
@@ -423,12 +399,9 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
|
|
423
399
|
assure_size(out, size);
|
424
400
|
fill_indent(out, d2);
|
425
401
|
*out->cur++ = '"';
|
426
|
-
|
427
|
-
out->cur
|
428
|
-
|
429
|
-
*out->cur++ = ':';
|
430
|
-
memcpy(out->cur, s, len);
|
431
|
-
out->cur += len;
|
402
|
+
APPEND_CHARS(out->cur, name, nlen);
|
403
|
+
APPEND_CHARS(out->cur, "\":", 2);
|
404
|
+
APPEND_CHARS(out->cur, s, len);
|
432
405
|
*out->cur = '\0';
|
433
406
|
}
|
434
407
|
} else {
|
@@ -439,7 +412,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
|
|
439
412
|
assure_size(out, size);
|
440
413
|
name = rb_id2name(*idp);
|
441
414
|
nlen = strlen(name);
|
442
|
-
if (
|
415
|
+
if (NULL != *fp) {
|
443
416
|
v = (*fp)(obj);
|
444
417
|
} else if (0 == strchr(name, '.')) {
|
445
418
|
v = rb_funcall(obj, *idp, 0);
|
@@ -502,22 +475,14 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
|
|
502
475
|
|
503
476
|
assure_size(out, d2 * out->indent + clen + 10);
|
504
477
|
fill_indent(out, d2);
|
505
|
-
|
506
|
-
*out->cur++ = '^';
|
507
|
-
*out->cur++ = 'o';
|
508
|
-
*out->cur++ = '"';
|
509
|
-
*out->cur++ = ':';
|
478
|
+
APPEND_CHARS(out->cur, "\"^o\":", 5);
|
510
479
|
oj_dump_cstr(class_name, clen, 0, 0, out);
|
511
480
|
}
|
512
481
|
if (0 < id) {
|
513
482
|
assure_size(out, d2 * out->indent + 16);
|
514
483
|
*out->cur++ = ',';
|
515
484
|
fill_indent(out, d2);
|
516
|
-
|
517
|
-
*out->cur++ = '^';
|
518
|
-
*out->cur++ = 'i';
|
519
|
-
*out->cur++ = '"';
|
520
|
-
*out->cur++ = ':';
|
485
|
+
APPEND_CHARS(out->cur, "\"^i\":", 5);
|
521
486
|
dump_ulong(id, out);
|
522
487
|
}
|
523
488
|
switch (type) {
|
@@ -525,39 +490,21 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
|
|
525
490
|
assure_size(out, d2 * out->indent + 14);
|
526
491
|
*out->cur++ = ',';
|
527
492
|
fill_indent(out, d2);
|
528
|
-
|
529
|
-
*out->cur++ = 's';
|
530
|
-
*out->cur++ = 'e';
|
531
|
-
*out->cur++ = 'l';
|
532
|
-
*out->cur++ = 'f';
|
533
|
-
*out->cur++ = '"';
|
534
|
-
*out->cur++ = ':';
|
493
|
+
APPEND_CHARS(out->cur, "\"self\":", 7);
|
535
494
|
oj_dump_cstr(RSTRING_PTR(obj), (int)RSTRING_LEN(obj), 0, 0, out);
|
536
495
|
break;
|
537
496
|
case T_ARRAY:
|
538
497
|
assure_size(out, d2 * out->indent + 14);
|
539
498
|
*out->cur++ = ',';
|
540
499
|
fill_indent(out, d2);
|
541
|
-
|
542
|
-
*out->cur++ = 's';
|
543
|
-
*out->cur++ = 'e';
|
544
|
-
*out->cur++ = 'l';
|
545
|
-
*out->cur++ = 'f';
|
546
|
-
*out->cur++ = '"';
|
547
|
-
*out->cur++ = ':';
|
500
|
+
APPEND_CHARS(out->cur, "\"self\":", 7);
|
548
501
|
dump_array_class(obj, Qundef, depth + 1, out);
|
549
502
|
break;
|
550
503
|
case T_HASH:
|
551
504
|
assure_size(out, d2 * out->indent + 14);
|
552
505
|
*out->cur++ = ',';
|
553
506
|
fill_indent(out, d2);
|
554
|
-
|
555
|
-
*out->cur++ = 's';
|
556
|
-
*out->cur++ = 'e';
|
557
|
-
*out->cur++ = 'l';
|
558
|
-
*out->cur++ = 'f';
|
559
|
-
*out->cur++ = '"';
|
560
|
-
*out->cur++ = ':';
|
507
|
+
APPEND_CHARS(out->cur, "\"self\":", 7);
|
561
508
|
dump_hash_class(obj, Qundef, depth + 1, out);
|
562
509
|
break;
|
563
510
|
default: break;
|
@@ -605,7 +552,7 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
|
|
605
552
|
}
|
606
553
|
value = rb_ivar_get(obj, vid);
|
607
554
|
|
608
|
-
if (
|
555
|
+
if (dump_ignore(out->opts, value)) {
|
609
556
|
continue;
|
610
557
|
}
|
611
558
|
if (out->omit_nil && Qnil == value) {
|
@@ -681,12 +628,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
681
628
|
assure_size(out, size);
|
682
629
|
*out->cur++ = '{';
|
683
630
|
fill_indent(out, d2);
|
684
|
-
|
685
|
-
*out->cur++ = '^';
|
686
|
-
*out->cur++ = 'u';
|
687
|
-
*out->cur++ = '"';
|
688
|
-
*out->cur++ = ':';
|
689
|
-
*out->cur++ = '[';
|
631
|
+
APPEND_CHARS(out->cur, "\"^u\":[", 6);
|
690
632
|
if ('#' == *class_name) {
|
691
633
|
VALUE ma = rb_struct_s_members(clas);
|
692
634
|
const char *name;
|
@@ -694,7 +636,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
694
636
|
|
695
637
|
*out->cur++ = '[';
|
696
638
|
for (i = 0; i < cnt; i++) {
|
697
|
-
volatile VALUE s = rb_sym2str(
|
639
|
+
volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
|
698
640
|
|
699
641
|
name = RSTRING_PTR(s);
|
700
642
|
len = (int)RSTRING_LEN(s);
|
@@ -704,16 +646,14 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
704
646
|
*out->cur++ = ',';
|
705
647
|
}
|
706
648
|
*out->cur++ = '"';
|
707
|
-
|
708
|
-
out->cur += len;
|
649
|
+
APPEND_CHARS(out->cur, name, len);
|
709
650
|
*out->cur++ = '"';
|
710
651
|
}
|
711
652
|
*out->cur++ = ']';
|
712
653
|
} else {
|
713
654
|
fill_indent(out, d3);
|
714
655
|
*out->cur++ = '"';
|
715
|
-
|
716
|
-
out->cur += len;
|
656
|
+
APPEND_CHARS(out->cur, class_name, len);
|
717
657
|
*out->cur++ = '"';
|
718
658
|
}
|
719
659
|
*out->cur++ = ',';
|
@@ -730,7 +670,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
730
670
|
|
731
671
|
for (i = 0; i < cnt; i++) {
|
732
672
|
v = RSTRUCT_GET(obj, i);
|
733
|
-
if (
|
673
|
+
if (dump_ignore(out->opts, v)) {
|
734
674
|
v = Qnil;
|
735
675
|
}
|
736
676
|
assure_size(out, size);
|
@@ -748,7 +688,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
748
688
|
for (i = 0; i < slen; i++) {
|
749
689
|
assure_size(out, size);
|
750
690
|
fill_indent(out, d3);
|
751
|
-
if (
|
691
|
+
if (dump_ignore(out->opts, v)) {
|
752
692
|
v = Qnil;
|
753
693
|
}
|
754
694
|
oj_dump_obj_val(rb_struct_aref(obj, INT2FIX(i)), d3, out, 0, 0, true);
|
@@ -757,8 +697,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
757
697
|
}
|
758
698
|
#endif
|
759
699
|
out->cur--;
|
760
|
-
|
761
|
-
*out->cur++ = '}';
|
700
|
+
APPEND_CHARS(out->cur, "]}", 2);
|
762
701
|
*out->cur = '\0';
|
763
702
|
}
|
764
703
|
|
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,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
|
-
|
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 {
|
153
149
|
fill_indent(out, d2);
|
154
150
|
}
|
155
151
|
if (NullMode == out->opts->mode) {
|
156
|
-
oj_dump_null_val(
|
152
|
+
oj_dump_null_val(RARRAY_AREF(a, i), d2, out);
|
157
153
|
} else {
|
158
|
-
oj_dump_strict_val(
|
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
|
-
|
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
|
}
|
data/ext/oj/encoder.c
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
// Copyright (c) 2011, 2022 Peter Ohler. All rights reserved.
|
2
|
+
// Licensed under the MIT License. See LICENSE file in the project root for license details.
|
3
|
+
|
4
|
+
#include "oj.h"
|
5
|
+
|
6
|
+
typedef struct _encoder {
|
7
|
+
int indent; // indention for dump, default 2
|
8
|
+
char circular; // YesNo
|
9
|
+
char escape_mode; // Escape_Mode
|
10
|
+
char mode; // Mode
|
11
|
+
char time_format; // TimeFormat
|
12
|
+
char bigdec_as_num; // YesNo
|
13
|
+
char to_hash; // YesNo
|
14
|
+
char to_json; // YesNo
|
15
|
+
char as_json; // YesNo
|
16
|
+
char raw_json; // YesNo
|
17
|
+
char trace; // YesNo
|
18
|
+
char sec_prec_set; // boolean (0 or 1)
|
19
|
+
char ignore_under; // YesNo - ignore attrs starting with _ if true in object and custom modes
|
20
|
+
int64_t int_range_min; // dump numbers below as string
|
21
|
+
int64_t int_range_max; // dump numbers above as string
|
22
|
+
const char* create_id; // 0 or string
|
23
|
+
size_t create_id_len; // length of create_id
|
24
|
+
int sec_prec; // second precision when dumping time
|
25
|
+
char float_prec; // float precision, linked to float_fmt
|
26
|
+
char float_fmt[7]; // float format for dumping, if empty use Ruby
|
27
|
+
struct _dumpOpts dump_opts;
|
28
|
+
struct _rxClass str_rx;
|
29
|
+
VALUE* ignore; // Qnil terminated array of classes or NULL
|
30
|
+
} * Encoder;
|
31
|
+
|
32
|
+
/*
|
33
|
+
rb_define_module_function(Oj, "encode", encode, -1);
|
34
|
+
rb_define_module_function(Oj, "to_file", to_file, -1); // or maybe just write
|
35
|
+
rb_define_module_function(Oj, "to_stream", to_stream, -1);
|
36
|
+
*/
|
37
|
+
|
38
|
+
// write(to, obj)
|
39
|
+
// if to is a string then open file
|
40
|
+
// else if stream then write to stream
|
41
|
+
// handle non-blocking
|
42
|
+
|
43
|
+
// should each mode have a different encoder or use delegates like the parser?
|
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
|
@@ -771,7 +772,7 @@ static VALUE parse_json(VALUE clas, char *json, bool given, bool allocated) {
|
|
771
772
|
pi.doc = doc;
|
772
773
|
#if IS_WINDOWS
|
773
774
|
// assume a 1M stack and give half to ruby
|
774
|
-
pi.stack_min = (void*)((char*)&pi - (
|
775
|
+
pi.stack_min = (void *)((char *)&pi - (512L * 1024L));
|
775
776
|
#else
|
776
777
|
{
|
777
778
|
struct rlimit lim;
|
@@ -1492,6 +1493,7 @@ static VALUE doc_each_child(int argc, VALUE *argv, VALUE self) {
|
|
1492
1493
|
Doc doc = self_doc(self);
|
1493
1494
|
const char *path = 0;
|
1494
1495
|
size_t wlen;
|
1496
|
+
Leaf * where_orig = doc->where;
|
1495
1497
|
|
1496
1498
|
wlen = doc->where - doc->where_path;
|
1497
1499
|
if (0 < wlen) {
|
@@ -1508,9 +1510,13 @@ static VALUE doc_each_child(int argc, VALUE *argv, VALUE self) {
|
|
1508
1510
|
if (0 < wlen) {
|
1509
1511
|
memcpy(doc->where_path, save_path, sizeof(Leaf) * (wlen + 1));
|
1510
1512
|
}
|
1513
|
+
doc->where = where_orig;
|
1511
1514
|
return Qnil;
|
1512
1515
|
}
|
1513
1516
|
}
|
1517
|
+
if (NULL == doc->where || NULL == *doc->where) {
|
1518
|
+
return Qnil;
|
1519
|
+
}
|
1514
1520
|
if (COL_VAL == (*doc->where)->value_type && 0 != (*doc->where)->elements) {
|
1515
1521
|
Leaf first = (*doc->where)->elements->next;
|
1516
1522
|
Leaf e = first;
|
@@ -1525,6 +1531,7 @@ static VALUE doc_each_child(int argc, VALUE *argv, VALUE self) {
|
|
1525
1531
|
if (0 < wlen) {
|
1526
1532
|
memcpy(doc->where_path, save_path, sizeof(Leaf) * (wlen + 1));
|
1527
1533
|
}
|
1534
|
+
doc->where = where_orig;
|
1528
1535
|
}
|
1529
1536
|
return Qnil;
|
1530
1537
|
}
|
@@ -1604,18 +1611,15 @@ static VALUE doc_dump(int argc, VALUE *argv, VALUE self) {
|
|
1604
1611
|
volatile VALUE rjson;
|
1605
1612
|
|
1606
1613
|
if (0 == filename) {
|
1607
|
-
char buf[4096];
|
1608
1614
|
struct _out out;
|
1609
1615
|
|
1610
|
-
out
|
1611
|
-
|
1612
|
-
out.allocated = false;
|
1616
|
+
oj_out_init(&out);
|
1617
|
+
|
1613
1618
|
out.omit_nil = oj_default_options.dump_opts.omit_nil;
|
1614
1619
|
oj_dump_leaf_to_json(leaf, &oj_default_options, &out);
|
1615
1620
|
rjson = rb_str_new2(out.buf);
|
1616
|
-
|
1617
|
-
|
1618
|
-
}
|
1621
|
+
|
1622
|
+
oj_out_free(&out);
|
1619
1623
|
} else {
|
1620
1624
|
oj_write_leaf_to_file(leaf, filename, &oj_default_options);
|
1621
1625
|
rjson = Qnil;
|
@@ -1711,8 +1715,10 @@ static VALUE doc_not_implemented(VALUE self) {
|
|
1711
1715
|
* # Now try again using a path to Oj::Doc.fetch() directly and not using a
|
1712
1716
|
* block. doc = Oj::Doc.open(json) doc.fetch('/2/three') #=> 3 doc.close()
|
1713
1717
|
*/
|
1714
|
-
void oj_init_doc() {
|
1718
|
+
void oj_init_doc(void) {
|
1715
1719
|
oj_doc_class = rb_define_class_under(Oj, "Doc", rb_cObject);
|
1720
|
+
rb_gc_register_address(&oj_doc_class);
|
1721
|
+
rb_undef_alloc_func(oj_doc_class);
|
1716
1722
|
rb_define_singleton_method(oj_doc_class, "open", doc_open, 1);
|
1717
1723
|
rb_define_singleton_method(oj_doc_class, "open_file", doc_open_file, 1);
|
1718
1724
|
rb_define_singleton_method(oj_doc_class, "parse", doc_open, 1);
|
data/ext/oj/intern.c
CHANGED
@@ -86,8 +86,12 @@ static VALUE form_attr(const char *str, size_t len) {
|
|
86
86
|
return (VALUE)rb_intern3(buf, len + 1, oj_utf8_encoding);
|
87
87
|
}
|
88
88
|
|
89
|
-
void oj_hash_init() {
|
89
|
+
void oj_hash_init(void) {
|
90
90
|
VALUE cache_class = rb_define_class_under(Oj, "Cache", rb_cObject);
|
91
|
+
rb_undef_alloc_func(cache_class);
|
92
|
+
|
93
|
+
rb_gc_register_address(&cache_class);
|
94
|
+
rb_undef_alloc_func(cache_class);
|
91
95
|
|
92
96
|
str_cache = cache_create(0, form_str, true, true);
|
93
97
|
str_cache_obj = Data_Wrap_Struct(cache_class, cache_mark, cache_free, str_cache);
|
@@ -275,6 +279,7 @@ VALUE oj_class_intern(const char *key, size_t len, bool safe, ParseInfo pi, int
|
|
275
279
|
bucket->len = len;
|
276
280
|
bucket->val = resolve_classpath(pi, key, len, auto_define, error_class);
|
277
281
|
}
|
282
|
+
rb_gc_register_mark_object(bucket->val);
|
278
283
|
return bucket->val;
|
279
284
|
}
|
280
285
|
|
@@ -287,8 +292,10 @@ char *oj_strndup(const char *s, size_t len) {
|
|
287
292
|
return d;
|
288
293
|
}
|
289
294
|
|
290
|
-
|
295
|
+
/*
|
296
|
+
void intern_cleanup(void) {
|
291
297
|
cache_free(str_cache);
|
292
298
|
cache_free(sym_cache);
|
293
299
|
cache_free(attr_cache);
|
294
300
|
}
|
301
|
+
*/
|