oj 3.11.5 → 3.16.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1421 -0
- data/README.md +19 -5
- data/RELEASE_NOTES.md +61 -0
- data/ext/oj/buf.h +20 -6
- data/ext/oj/cache.c +329 -0
- data/ext/oj/cache.h +22 -0
- data/ext/oj/cache8.c +10 -9
- data/ext/oj/circarray.c +8 -6
- data/ext/oj/circarray.h +2 -2
- data/ext/oj/code.c +19 -33
- data/ext/oj/code.h +2 -2
- data/ext/oj/compat.c +27 -77
- data/ext/oj/custom.c +86 -179
- data/ext/oj/debug.c +126 -0
- data/ext/oj/dump.c +256 -249
- data/ext/oj/dump.h +26 -12
- data/ext/oj/dump_compat.c +565 -642
- data/ext/oj/dump_leaf.c +17 -63
- data/ext/oj/dump_object.c +65 -187
- data/ext/oj/dump_strict.c +27 -51
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/err.c +2 -13
- data/ext/oj/err.h +24 -8
- data/ext/oj/extconf.rb +21 -6
- data/ext/oj/fast.c +149 -149
- data/ext/oj/intern.c +313 -0
- data/ext/oj/intern.h +22 -0
- data/ext/oj/mem.c +318 -0
- data/ext/oj/mem.h +53 -0
- data/ext/oj/mimic_json.c +121 -106
- data/ext/oj/object.c +85 -162
- data/ext/oj/odd.c +89 -67
- data/ext/oj/odd.h +15 -15
- data/ext/oj/oj.c +542 -411
- data/ext/oj/oj.h +99 -73
- data/ext/oj/parse.c +175 -187
- data/ext/oj/parse.h +26 -24
- data/ext/oj/parser.c +1600 -0
- data/ext/oj/parser.h +101 -0
- data/ext/oj/rails.c +112 -159
- data/ext/oj/rails.h +1 -1
- data/ext/oj/reader.c +11 -14
- data/ext/oj/reader.h +4 -2
- data/ext/oj/resolve.c +5 -24
- data/ext/oj/rxclass.c +7 -6
- data/ext/oj/rxclass.h +1 -1
- data/ext/oj/saj.c +22 -33
- data/ext/oj/saj2.c +584 -0
- data/ext/oj/saj2.h +23 -0
- data/ext/oj/scp.c +5 -28
- data/ext/oj/sparse.c +28 -72
- data/ext/oj/stream_writer.c +50 -40
- data/ext/oj/strict.c +56 -61
- data/ext/oj/string_writer.c +72 -39
- data/ext/oj/trace.h +31 -4
- data/ext/oj/usual.c +1218 -0
- data/ext/oj/usual.h +69 -0
- data/ext/oj/util.h +1 -1
- data/ext/oj/val_stack.c +14 -3
- data/ext/oj/val_stack.h +8 -7
- data/ext/oj/validate.c +46 -0
- data/ext/oj/wab.c +63 -88
- data/lib/oj/active_support_helper.rb +1 -3
- data/lib/oj/bag.rb +7 -1
- data/lib/oj/easy_hash.rb +4 -5
- data/lib/oj/error.rb +1 -2
- data/lib/oj/json.rb +162 -150
- data/lib/oj/mimic.rb +9 -7
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/schandler.rb +5 -4
- data/lib/oj/state.rb +12 -8
- data/lib/oj/version.rb +1 -2
- data/lib/oj.rb +2 -0
- data/pages/Compatibility.md +1 -1
- data/pages/InstallOptions.md +20 -0
- data/pages/JsonGem.md +15 -0
- data/pages/Modes.md +8 -3
- data/pages/Options.md +43 -5
- data/pages/Parser.md +309 -0
- data/pages/Rails.md +14 -2
- data/test/_test_active.rb +8 -9
- data/test/_test_active_mimic.rb +7 -8
- data/test/_test_mimic_rails.rb +17 -20
- data/test/activerecord/result_test.rb +5 -6
- data/test/activesupport6/encoding_test.rb +63 -28
- data/test/{activesupport5 → activesupport7}/abstract_unit.rb +16 -12
- data/test/{activesupport5 → activesupport7}/decoding_test.rb +2 -10
- data/test/{activesupport5 → activesupport7}/encoding_test.rb +86 -50
- data/test/{activesupport5 → activesupport7}/encoding_test_cases.rb +6 -0
- data/test/{activesupport5 → activesupport7}/time_zone_test_helpers.rb +8 -0
- data/test/files.rb +15 -15
- data/test/foo.rb +16 -45
- data/test/helper.rb +11 -8
- data/test/isolated/shared.rb +3 -2
- data/test/json_gem/json_addition_test.rb +2 -2
- data/test/json_gem/json_common_interface_test.rb +8 -6
- data/test/json_gem/json_encoding_test.rb +0 -0
- data/test/json_gem/json_ext_parser_test.rb +1 -0
- data/test/json_gem/json_fixtures_test.rb +3 -2
- data/test/json_gem/json_generator_test.rb +56 -38
- data/test/json_gem/json_generic_object_test.rb +11 -11
- data/test/json_gem/json_parser_test.rb +54 -47
- data/test/json_gem/json_string_matching_test.rb +9 -9
- data/test/json_gem/test_helper.rb +7 -3
- data/test/mem.rb +34 -0
- data/test/perf.rb +22 -27
- data/test/perf_compat.rb +31 -33
- data/test/perf_dump.rb +50 -0
- data/test/perf_fast.rb +80 -82
- data/test/perf_file.rb +27 -29
- data/test/perf_object.rb +65 -69
- data/test/perf_once.rb +59 -0
- data/test/perf_parser.rb +183 -0
- data/test/perf_saj.rb +46 -54
- data/test/perf_scp.rb +58 -69
- data/test/perf_simple.rb +41 -39
- data/test/perf_strict.rb +74 -82
- data/test/perf_wab.rb +67 -69
- data/test/prec.rb +5 -5
- data/test/sample/change.rb +0 -1
- data/test/sample/dir.rb +0 -1
- data/test/sample/doc.rb +0 -1
- data/test/sample/file.rb +0 -1
- data/test/sample/group.rb +0 -1
- data/test/sample/hasprops.rb +0 -1
- data/test/sample/layer.rb +0 -1
- data/test/sample/rect.rb +0 -1
- data/test/sample/shape.rb +0 -1
- data/test/sample/text.rb +0 -1
- data/test/sample.rb +16 -16
- data/test/sample_json.rb +8 -8
- data/test/test_compat.rb +95 -43
- data/test/test_custom.rb +73 -51
- data/test/test_debian.rb +7 -10
- data/test/test_fast.rb +135 -79
- data/test/test_file.rb +41 -30
- data/test/test_gc.rb +16 -5
- data/test/test_generate.rb +5 -5
- data/test/test_hash.rb +5 -5
- data/test/test_integer_range.rb +9 -9
- data/test/test_null.rb +20 -20
- data/test/test_object.rb +99 -96
- data/test/test_parser.rb +11 -0
- data/test/test_parser_debug.rb +27 -0
- data/test/test_parser_saj.rb +337 -0
- data/test/test_parser_usual.rb +251 -0
- data/test/test_rails.rb +2 -2
- data/test/test_saj.rb +10 -8
- data/test/test_scp.rb +37 -39
- data/test/test_strict.rb +40 -32
- data/test/test_various.rb +165 -84
- data/test/test_wab.rb +48 -44
- data/test/test_writer.rb +47 -47
- data/test/tests.rb +13 -5
- data/test/tests_mimic.rb +12 -3
- data/test/tests_mimic_addition.rb +12 -3
- metadata +74 -128
- data/ext/oj/hash.c +0 -131
- data/ext/oj/hash.h +0 -19
- data/ext/oj/hash_test.c +0 -491
- data/test/activesupport4/decoding_test.rb +0 -108
- data/test/activesupport4/encoding_test.rb +0 -531
- data/test/activesupport4/test_helper.rb +0 -41
- data/test/activesupport5/test_helper.rb +0 -72
- data/test/bar.rb +0 -35
- data/test/baz.rb +0 -16
- data/test/zoo.rb +0 -13
data/ext/oj/custom.c
CHANGED
@@ -8,7 +8,8 @@
|
|
8
8
|
#include "dump.h"
|
9
9
|
#include "encode.h"
|
10
10
|
#include "err.h"
|
11
|
-
#include "
|
11
|
+
#include "intern.h"
|
12
|
+
#include "mem.h"
|
12
13
|
#include "odd.h"
|
13
14
|
#include "oj.h"
|
14
15
|
#include "parse.h"
|
@@ -24,21 +25,21 @@ static void dump_obj_str(VALUE obj, int depth, Out out) {
|
|
24
25
|
{"s", 1, Qnil},
|
25
26
|
{NULL, 0, Qnil},
|
26
27
|
};
|
27
|
-
attrs->value =
|
28
|
+
attrs->value = oj_safe_string_convert(obj);
|
28
29
|
|
29
30
|
oj_code_attrs(obj, attrs, depth, out, Yes == out->opts->create_ok);
|
30
31
|
}
|
31
32
|
|
32
33
|
static void dump_obj_as_str(VALUE obj, int depth, Out out) {
|
33
|
-
volatile VALUE rstr =
|
34
|
-
const char
|
34
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
35
|
+
const char *str = RSTRING_PTR(rstr);
|
35
36
|
|
36
37
|
oj_dump_cstr(str, RSTRING_LEN(rstr), 0, 0, out);
|
37
38
|
}
|
38
39
|
|
39
40
|
static void bigdecimal_dump(VALUE obj, int depth, Out out) {
|
40
|
-
volatile VALUE rstr =
|
41
|
-
const char
|
41
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
42
|
+
const char *str = RSTRING_PTR(rstr);
|
42
43
|
int len = (int)RSTRING_LEN(rstr);
|
43
44
|
|
44
45
|
if (0 == strcasecmp("Infinity", str)) {
|
@@ -82,8 +83,7 @@ static VALUE complex_load(VALUE clas, VALUE args) {
|
|
82
83
|
real_id = rb_intern("real");
|
83
84
|
imag_id = rb_intern("imag");
|
84
85
|
}
|
85
|
-
return rb_complex_new(rb_hash_aref(args, rb_id2str(real_id)),
|
86
|
-
rb_hash_aref(args, rb_id2str(imag_id)));
|
86
|
+
return rb_complex_new(rb_hash_aref(args, rb_id2str(real_id)), rb_hash_aref(args, rb_id2str(imag_id)));
|
87
87
|
}
|
88
88
|
|
89
89
|
static void time_dump(VALUE obj, int depth, Out out) {
|
@@ -123,7 +123,7 @@ static void date_dump(VALUE obj, int depth, Out out) {
|
|
123
123
|
case RubyTime:
|
124
124
|
case XmlTime:
|
125
125
|
v = rb_funcall(obj, rb_intern("iso8601"), 0);
|
126
|
-
oj_dump_cstr(
|
126
|
+
oj_dump_cstr(RSTRING_PTR(v), (int)RSTRING_LEN(v), 0, 0, out);
|
127
127
|
break;
|
128
128
|
case UnixZTime:
|
129
129
|
v = rb_funcall(obj, rb_intern("to_time"), 0);
|
@@ -246,8 +246,7 @@ static VALUE rational_load(VALUE clas, VALUE args) {
|
|
246
246
|
numerator_id = rb_intern("numerator");
|
247
247
|
denominator_id = rb_intern("denominator");
|
248
248
|
}
|
249
|
-
return rb_rational_new(rb_hash_aref(args, rb_id2str(numerator_id)),
|
250
|
-
rb_hash_aref(args, rb_id2str(denominator_id)));
|
249
|
+
return rb_rational_new(rb_hash_aref(args, rb_id2str(numerator_id)), rb_hash_aref(args, rb_id2str(denominator_id)));
|
251
250
|
}
|
252
251
|
|
253
252
|
static VALUE regexp_load(VALUE clas, VALUE args) {
|
@@ -282,7 +281,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
282
281
|
Out out = (Out)ov;
|
283
282
|
int depth = out->depth;
|
284
283
|
|
285
|
-
if (
|
284
|
+
if (dump_ignore(out->opts, value)) {
|
286
285
|
return ST_CONTINUE;
|
287
286
|
}
|
288
287
|
if (out->omit_nil && Qnil == value) {
|
@@ -292,38 +291,33 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
292
291
|
assure_size(out, depth * out->indent + 1);
|
293
292
|
fill_indent(out, depth);
|
294
293
|
} else {
|
295
|
-
assure_size(out,
|
296
|
-
depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
|
294
|
+
assure_size(out, depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
|
297
295
|
if (0 < out->opts->dump_opts.hash_size) {
|
298
|
-
|
299
|
-
out->cur += out->opts->dump_opts.hash_size;
|
296
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
|
300
297
|
}
|
301
298
|
if (0 < out->opts->dump_opts.indent_size) {
|
302
299
|
int i;
|
303
300
|
|
304
301
|
for (i = depth; 0 < i; i--) {
|
305
|
-
|
306
|
-
out->cur += out->opts->dump_opts.indent_size;
|
302
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
307
303
|
}
|
308
304
|
}
|
309
305
|
}
|
310
306
|
switch (rb_type(key)) {
|
311
307
|
case T_STRING: oj_dump_str(key, 0, out, false); break;
|
312
308
|
case T_SYMBOL: oj_dump_sym(key, 0, out, false); break;
|
313
|
-
default: oj_dump_str(
|
309
|
+
default: oj_dump_str(oj_safe_string_convert(key), 0, out, false); break;
|
314
310
|
}
|
315
311
|
if (!out->opts->dump_opts.use) {
|
316
312
|
*out->cur++ = ':';
|
317
313
|
} else {
|
318
314
|
assure_size(out, out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2);
|
319
315
|
if (0 < out->opts->dump_opts.before_size) {
|
320
|
-
|
321
|
-
out->cur += out->opts->dump_opts.before_size;
|
316
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
|
322
317
|
}
|
323
318
|
*out->cur++ = ':';
|
324
319
|
if (0 < out->opts->dump_opts.after_size) {
|
325
|
-
|
326
|
-
out->cur += out->opts->dump_opts.after_size;
|
320
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
|
327
321
|
}
|
328
322
|
}
|
329
323
|
oj_dump_custom_val(value, depth, out, true);
|
@@ -344,8 +338,7 @@ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
|
|
344
338
|
cnt = (int)RHASH_SIZE(obj);
|
345
339
|
assure_size(out, 2);
|
346
340
|
if (0 == cnt) {
|
347
|
-
|
348
|
-
*out->cur++ = '}';
|
341
|
+
APPEND_CHARS(out->cur, "{}", 2);
|
349
342
|
} else {
|
350
343
|
*out->cur++ = '{';
|
351
344
|
out->depth = depth + 1;
|
@@ -357,19 +350,15 @@ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
|
|
357
350
|
assure_size(out, depth * out->indent + 2);
|
358
351
|
fill_indent(out, depth);
|
359
352
|
} else {
|
360
|
-
assure_size(
|
361
|
-
out,
|
362
|
-
depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
|
353
|
+
assure_size(out, depth * out->opts->dump_opts.indent_size + out->opts->dump_opts.hash_size + 1);
|
363
354
|
if (0 < out->opts->dump_opts.hash_size) {
|
364
|
-
|
365
|
-
out->cur += out->opts->dump_opts.hash_size;
|
355
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.hash_nl, out->opts->dump_opts.hash_size);
|
366
356
|
}
|
367
357
|
if (0 < out->opts->dump_opts.indent_size) {
|
368
358
|
int i;
|
369
359
|
|
370
360
|
for (i = depth; 0 < i; i--) {
|
371
|
-
|
372
|
-
out->cur += out->opts->dump_opts.indent_size;
|
361
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
373
362
|
}
|
374
363
|
}
|
375
364
|
}
|
@@ -379,10 +368,10 @@ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
|
|
379
368
|
}
|
380
369
|
|
381
370
|
static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
|
382
|
-
ID
|
383
|
-
AttrGetFunc
|
371
|
+
ID *idp;
|
372
|
+
AttrGetFunc *fp;
|
384
373
|
volatile VALUE v;
|
385
|
-
const char
|
374
|
+
const char *name;
|
386
375
|
size_t size;
|
387
376
|
int d2 = depth + 1;
|
388
377
|
|
@@ -391,36 +380,31 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
|
|
391
380
|
if (NULL != out->opts->create_id && Yes == out->opts->create_ok) {
|
392
381
|
const char *classname = rb_class2name(clas);
|
393
382
|
int clen = (int)strlen(classname);
|
394
|
-
size_t
|
383
|
+
size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
|
395
384
|
|
396
385
|
size = d2 * out->indent + 10 + clen + out->opts->create_id_len + sep_len;
|
397
386
|
assure_size(out, size);
|
398
387
|
fill_indent(out, d2);
|
399
388
|
*out->cur++ = '"';
|
400
|
-
|
401
|
-
out->cur += out->opts->create_id_len;
|
389
|
+
APPEND_CHARS(out->cur, out->opts->create_id, out->opts->create_id_len);
|
402
390
|
*out->cur++ = '"';
|
403
391
|
if (0 < out->opts->dump_opts.before_size) {
|
404
|
-
|
405
|
-
out->cur += out->opts->dump_opts.before_size;
|
392
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
|
406
393
|
}
|
407
394
|
*out->cur++ = ':';
|
408
395
|
if (0 < out->opts->dump_opts.after_size) {
|
409
|
-
|
410
|
-
out->cur += out->opts->dump_opts.after_size;
|
396
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
|
411
397
|
}
|
412
398
|
*out->cur++ = '"';
|
413
|
-
|
414
|
-
out->cur
|
415
|
-
*out->cur++ = '"';
|
416
|
-
*out->cur++ = ',';
|
399
|
+
APPEND_CHARS(out->cur, classname, clen);
|
400
|
+
APPEND_CHARS(out->cur, "\",", 2);
|
417
401
|
}
|
418
402
|
if (odd->raw) {
|
419
403
|
v = rb_funcall(obj, *odd->attrs, 0);
|
420
404
|
if (Qundef == v || T_STRING != rb_type(v)) {
|
421
405
|
rb_raise(rb_eEncodingError, "Invalid type for raw JSON.\n");
|
422
406
|
} else {
|
423
|
-
const char *s =
|
407
|
+
const char *s = RSTRING_PTR(v);
|
424
408
|
int len = (int)RSTRING_LEN(v);
|
425
409
|
const char *name = rb_id2name(*odd->attrs);
|
426
410
|
size_t nlen = strlen(name);
|
@@ -429,12 +413,9 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
|
|
429
413
|
assure_size(out, size);
|
430
414
|
fill_indent(out, d2);
|
431
415
|
*out->cur++ = '"';
|
432
|
-
|
433
|
-
out->cur
|
434
|
-
|
435
|
-
*out->cur++ = ':';
|
436
|
-
memcpy(out->cur, s, len);
|
437
|
-
out->cur += len;
|
416
|
+
APPEND_CHARS(out->cur, name, nlen);
|
417
|
+
APPEND_CHARS(out->cur, "\":", 2);
|
418
|
+
APPEND_CHARS(out->cur, s, len);
|
438
419
|
*out->cur = '\0';
|
439
420
|
}
|
440
421
|
} else {
|
@@ -457,7 +438,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
|
|
457
438
|
ID i;
|
458
439
|
|
459
440
|
if (sizeof(nbuf) <= nlen) {
|
460
|
-
if (NULL == (n2 =
|
441
|
+
if (NULL == (n2 = OJ_STRDUP(name))) {
|
461
442
|
rb_raise(rb_eNoMemError, "for attribute name.");
|
462
443
|
}
|
463
444
|
} else {
|
@@ -474,7 +455,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
|
|
474
455
|
i = rb_intern(n);
|
475
456
|
v = rb_funcall(v, i, 0);
|
476
457
|
if (nbuf != n2) {
|
477
|
-
|
458
|
+
OJ_FREE(n2);
|
478
459
|
}
|
479
460
|
}
|
480
461
|
fill_indent(out, d2);
|
@@ -496,33 +477,26 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
|
|
496
477
|
oj_dump_raw_json(obj, depth, out);
|
497
478
|
} else if (Yes == out->opts->to_json && rb_respond_to(obj, oj_to_json_id)) {
|
498
479
|
volatile VALUE rs;
|
499
|
-
const char
|
480
|
+
const char *s;
|
500
481
|
int len;
|
501
482
|
|
502
|
-
|
503
|
-
oj_trace("to_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
|
504
|
-
}
|
483
|
+
TRACE(out->opts->trace, "to_json", obj, depth + 1, TraceRubyIn);
|
505
484
|
if (0 == rb_obj_method_arity(obj, oj_to_json_id)) {
|
506
485
|
rs = rb_funcall(obj, oj_to_json_id, 0);
|
507
486
|
} else {
|
508
487
|
rs = rb_funcall2(obj, oj_to_json_id, out->argc, out->argv);
|
509
488
|
}
|
510
|
-
|
511
|
-
|
512
|
-
}
|
513
|
-
s = rb_string_value_ptr((VALUE *)&rs);
|
489
|
+
TRACE(out->opts->trace, "to_json", obj, depth + 1, TraceRubyOut);
|
490
|
+
s = RSTRING_PTR(rs);
|
514
491
|
len = (int)RSTRING_LEN(rs);
|
515
492
|
|
516
493
|
assure_size(out, len + 1);
|
517
|
-
|
518
|
-
out->cur += len;
|
494
|
+
APPEND_CHARS(out->cur, s, len);
|
519
495
|
*out->cur = '\0';
|
520
496
|
} else if (Yes == out->opts->as_json && rb_respond_to(obj, oj_as_json_id)) {
|
521
497
|
volatile VALUE aj;
|
522
498
|
|
523
|
-
|
524
|
-
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
|
525
|
-
}
|
499
|
+
TRACE(out->opts->trace, "as_json", obj, depth + 1, TraceRubyIn);
|
526
500
|
// Some classes elect to not take an options argument so check the arity
|
527
501
|
// of as_json.
|
528
502
|
if (0 == rb_obj_method_arity(obj, oj_as_json_id)) {
|
@@ -530,18 +504,12 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
|
|
530
504
|
} else {
|
531
505
|
aj = rb_funcall2(obj, oj_as_json_id, out->argc, out->argv);
|
532
506
|
}
|
533
|
-
|
534
|
-
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
|
535
|
-
}
|
507
|
+
TRACE(out->opts->trace, "as_json", obj, depth + 1, TraceRubyOut);
|
536
508
|
// Catch the obvious brain damaged recursive dumping.
|
537
509
|
if (aj == obj) {
|
538
|
-
volatile VALUE rstr =
|
510
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
539
511
|
|
540
|
-
oj_dump_cstr(
|
541
|
-
(int)RSTRING_LEN(rstr),
|
542
|
-
false,
|
543
|
-
false,
|
544
|
-
out);
|
512
|
+
oj_dump_cstr(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), false, false, out);
|
545
513
|
} else {
|
546
514
|
oj_dump_custom_val(aj, depth, out, true);
|
547
515
|
}
|
@@ -577,7 +545,7 @@ static int dump_attr_cb(ID key, VALUE value, VALUE ov) {
|
|
577
545
|
size_t size;
|
578
546
|
const char *attr;
|
579
547
|
|
580
|
-
if (
|
548
|
+
if (dump_ignore(out->opts, value)) {
|
581
549
|
return ST_CONTINUE;
|
582
550
|
}
|
583
551
|
if (out->omit_nil && Qnil == value) {
|
@@ -625,7 +593,7 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
|
|
625
593
|
assure_size(out, 2);
|
626
594
|
*out->cur++ = '{';
|
627
595
|
if (Qundef != clas && NULL != out->opts->create_id && Yes == out->opts->create_ok) {
|
628
|
-
size_t
|
596
|
+
size_t sep_len = out->opts->dump_opts.before_size + out->opts->dump_opts.after_size + 2;
|
629
597
|
const char *classname = rb_obj_classname(obj);
|
630
598
|
size_t len = strlen(classname);
|
631
599
|
|
@@ -633,21 +601,17 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
|
|
633
601
|
assure_size(out, size);
|
634
602
|
fill_indent(out, d2);
|
635
603
|
*out->cur++ = '"';
|
636
|
-
|
637
|
-
out->cur += out->opts->create_id_len;
|
604
|
+
APPEND_CHARS(out->cur, out->opts->create_id, out->opts->create_id_len);
|
638
605
|
*out->cur++ = '"';
|
639
606
|
if (0 < out->opts->dump_opts.before_size) {
|
640
|
-
|
641
|
-
out->cur += out->opts->dump_opts.before_size;
|
607
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.before_sep, out->opts->dump_opts.before_size);
|
642
608
|
}
|
643
609
|
*out->cur++ = ':';
|
644
610
|
if (0 < out->opts->dump_opts.after_size) {
|
645
|
-
|
646
|
-
out->cur += out->opts->dump_opts.after_size;
|
611
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.after_sep, out->opts->dump_opts.after_size);
|
647
612
|
}
|
648
613
|
*out->cur++ = '"';
|
649
|
-
|
650
|
-
out->cur += len;
|
614
|
+
APPEND_CHARS(out->cur, classname, len);
|
651
615
|
*out->cur++ = '"';
|
652
616
|
class_written = true;
|
653
617
|
}
|
@@ -731,25 +695,23 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
|
731
695
|
} else {
|
732
696
|
size = d2 * out->indent + 2;
|
733
697
|
}
|
698
|
+
assure_size(out, size * cnt);
|
734
699
|
cnt--;
|
735
700
|
for (i = 0; i <= cnt; i++) {
|
736
|
-
assure_size(out, size);
|
737
701
|
if (out->opts->dump_opts.use) {
|
738
702
|
if (0 < out->opts->dump_opts.array_size) {
|
739
|
-
|
740
|
-
out->cur += out->opts->dump_opts.array_size;
|
703
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
741
704
|
}
|
742
705
|
if (0 < out->opts->dump_opts.indent_size) {
|
743
706
|
int i;
|
744
707
|
for (i = d2; 0 < i; i--) {
|
745
|
-
|
746
|
-
out->cur += out->opts->dump_opts.indent_size;
|
708
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
747
709
|
}
|
748
710
|
}
|
749
711
|
} else {
|
750
712
|
fill_indent(out, d2);
|
751
713
|
}
|
752
|
-
oj_dump_custom_val(
|
714
|
+
oj_dump_custom_val(RARRAY_AREF(a, i), d2, out, true);
|
753
715
|
if (i < cnt) {
|
754
716
|
*out->cur++ = ',';
|
755
717
|
}
|
@@ -758,15 +720,13 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
|
758
720
|
assure_size(out, size);
|
759
721
|
if (out->opts->dump_opts.use) {
|
760
722
|
if (0 < out->opts->dump_opts.array_size) {
|
761
|
-
|
762
|
-
out->cur += out->opts->dump_opts.array_size;
|
723
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.array_nl, out->opts->dump_opts.array_size);
|
763
724
|
}
|
764
725
|
if (0 < out->opts->dump_opts.indent_size) {
|
765
726
|
int i;
|
766
727
|
|
767
728
|
for (i = depth; 0 < i; i--) {
|
768
|
-
|
769
|
-
out->cur += out->opts->dump_opts.indent_size;
|
729
|
+
APPEND_CHARS(out->cur, out->opts->dump_opts.indent_str, out->opts->dump_opts.indent_size);
|
770
730
|
}
|
771
731
|
}
|
772
732
|
} else {
|
@@ -800,8 +760,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
800
760
|
*out->cur++ = '"';
|
801
761
|
oj_dump_custom_val(rb_funcall(obj, oj_begin_id, 0), d3, out, false);
|
802
762
|
assure_size(out, 3);
|
803
|
-
|
804
|
-
*out->cur++ = '.';
|
763
|
+
APPEND_CHARS(out->cur, "..", 2);
|
805
764
|
if (Qtrue == rb_funcall(obj, oj_exclude_end_id, 0)) {
|
806
765
|
*out->cur++ = '.';
|
807
766
|
}
|
@@ -833,9 +792,9 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
833
792
|
v = rb_struct_aref(obj, INT2FIX(i));
|
834
793
|
#endif
|
835
794
|
if (ma != Qnil) {
|
836
|
-
volatile VALUE s =
|
795
|
+
volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
|
837
796
|
|
838
|
-
name =
|
797
|
+
name = RSTRING_PTR(s);
|
839
798
|
len = (int)RSTRING_LEN(s);
|
840
799
|
} else {
|
841
800
|
len = snprintf(num_id, sizeof(num_id), "%d", i);
|
@@ -844,10 +803,8 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
844
803
|
assure_size(out, size + len + 3);
|
845
804
|
fill_indent(out, d3);
|
846
805
|
*out->cur++ = '"';
|
847
|
-
|
848
|
-
out->cur
|
849
|
-
*out->cur++ = '"';
|
850
|
-
*out->cur++ = ':';
|
806
|
+
APPEND_CHARS(out->cur, name, len);
|
807
|
+
APPEND_CHARS(out->cur, "\":", 2);
|
851
808
|
oj_dump_custom_val(v, d3, out, true);
|
852
809
|
*out->cur++ = ',';
|
853
810
|
}
|
@@ -912,9 +869,7 @@ static DumpFunc custom_funcs[] = {
|
|
912
869
|
void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok) {
|
913
870
|
int type = rb_type(obj);
|
914
871
|
|
915
|
-
|
916
|
-
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
917
|
-
}
|
872
|
+
TRACE(out->opts->trace, "dump", obj, depth, TraceIn);
|
918
873
|
if (MAX_DEPTH < depth) {
|
919
874
|
rb_raise(rb_eNoMemError, "Too deeply nested.\n");
|
920
875
|
}
|
@@ -923,27 +878,22 @@ void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok) {
|
|
923
878
|
|
924
879
|
if (NULL != f) {
|
925
880
|
f(obj, depth, out, true);
|
926
|
-
|
927
|
-
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
928
|
-
}
|
881
|
+
TRACE(out->opts->trace, "dump", obj, depth, TraceOut);
|
929
882
|
return;
|
930
883
|
}
|
931
884
|
}
|
932
885
|
oj_dump_nil(Qnil, depth, out, false);
|
933
|
-
|
934
|
-
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
935
|
-
}
|
886
|
+
TRACE(out->opts->trace, "dump", Qnil, depth, TraceOut);
|
936
887
|
}
|
937
888
|
|
938
889
|
///// load functions /////
|
939
890
|
|
940
891
|
static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
|
941
|
-
const char *
|
942
|
-
int
|
943
|
-
Val
|
944
|
-
volatile VALUE rkey = kval->key_val;
|
892
|
+
const char *key = kval->key;
|
893
|
+
int klen = kval->klen;
|
894
|
+
Val parent = stack_peek(&pi->stack);
|
945
895
|
|
946
|
-
if (Qundef ==
|
896
|
+
if (Qundef == kval->key_val && Yes == pi->options.create_ok && NULL != pi->options.create_id &&
|
947
897
|
*pi->options.create_id == *key && (int)pi->options.create_id_len == klen &&
|
948
898
|
0 == strncmp(pi->options.create_id, key, klen)) {
|
949
899
|
parent->clas = oj_name2class(pi, str, len, false, rb_eArgError);
|
@@ -955,16 +905,9 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
|
|
955
905
|
}
|
956
906
|
}
|
957
907
|
} else {
|
958
|
-
volatile VALUE rstr =
|
959
|
-
|
960
|
-
|
961
|
-
rkey = rb_str_new(key, klen);
|
962
|
-
rstr = oj_encode(rstr);
|
963
|
-
rkey = oj_encode(rkey);
|
964
|
-
if (Yes == pi->options.sym_key) {
|
965
|
-
rkey = rb_str_intern(rkey);
|
966
|
-
}
|
967
|
-
}
|
908
|
+
volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
|
909
|
+
volatile VALUE rkey = oj_calc_hash_key(pi, kval);
|
910
|
+
|
968
911
|
if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
|
969
912
|
VALUE clas = oj_rxclass_match(&pi->options.str_rx, str, (int)len);
|
970
913
|
|
@@ -986,9 +929,7 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
|
|
986
929
|
break;
|
987
930
|
default: break;
|
988
931
|
}
|
989
|
-
|
990
|
-
oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rstr);
|
991
|
-
}
|
932
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_string", pi, rstr);
|
992
933
|
}
|
993
934
|
}
|
994
935
|
|
@@ -1005,22 +946,7 @@ static void end_hash(struct _parseInfo *pi) {
|
|
1005
946
|
}
|
1006
947
|
parent->clas = Qundef;
|
1007
948
|
}
|
1008
|
-
|
1009
|
-
oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
|
1010
|
-
}
|
1011
|
-
}
|
1012
|
-
|
1013
|
-
static VALUE calc_hash_key(ParseInfo pi, Val parent) {
|
1014
|
-
volatile VALUE rkey = parent->key_val;
|
1015
|
-
|
1016
|
-
if (Qundef == rkey) {
|
1017
|
-
rkey = rb_str_new(parent->key, parent->klen);
|
1018
|
-
}
|
1019
|
-
rkey = oj_encode(rkey);
|
1020
|
-
if (Yes == pi->options.sym_key) {
|
1021
|
-
rkey = rb_str_intern(rkey);
|
1022
|
-
}
|
1023
|
-
return rkey;
|
949
|
+
TRACE_PARSE_HASH_END(pi->options.trace, pi);
|
1024
950
|
}
|
1025
951
|
|
1026
952
|
static void hash_set_num(struct _parseInfo *pi, Val kval, NumInfo ni) {
|
@@ -1043,38 +969,26 @@ static void hash_set_num(struct _parseInfo *pi, Val kval, NumInfo ni) {
|
|
1043
969
|
}
|
1044
970
|
if (86400 == ni->exp) { // UTC time
|
1045
971
|
parent->val = rb_time_nano_new(ni->i, (long)nsec);
|
1046
|
-
// Since the ruby C routines
|
972
|
+
// Since the ruby C routines always create local time, the
|
1047
973
|
// offset and then a conversion to UTC keeps makes the time
|
1048
974
|
// match the expected value.
|
1049
975
|
parent->val = rb_funcall2(parent->val, oj_utc_id, 0, 0);
|
1050
976
|
} else if (ni->has_exp) {
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
sec_as_time(t, &ti);
|
1056
|
-
|
1057
|
-
args[0] = LONG2NUM(ti.year);
|
1058
|
-
args[1] = LONG2NUM(ti.mon);
|
1059
|
-
args[2] = LONG2NUM(ti.day);
|
1060
|
-
args[3] = LONG2NUM(ti.hour);
|
1061
|
-
args[4] = LONG2NUM(ti.min);
|
1062
|
-
args[5] = rb_float_new((double)ti.sec + ((double)nsec + 0.5) / 1000000000.0);
|
1063
|
-
args[6] = LONG2NUM(ni->exp);
|
1064
|
-
parent->val = rb_funcall2(rb_cTime, oj_new_id, 7, args);
|
977
|
+
struct timespec ts;
|
978
|
+
ts.tv_sec = ni->i;
|
979
|
+
ts.tv_nsec = nsec;
|
980
|
+
parent->val = rb_time_timespec_new(&ts, (int)ni->exp);
|
1065
981
|
} else {
|
1066
982
|
parent->val = rb_time_nano_new(ni->i, (long)nsec);
|
1067
983
|
}
|
1068
984
|
rval = parent->val;
|
1069
985
|
} else {
|
1070
|
-
rb_hash_aset(parent->val,
|
986
|
+
rb_hash_aset(parent->val, oj_calc_hash_key(pi, kval), rval);
|
1071
987
|
}
|
1072
988
|
break;
|
1073
989
|
default: break;
|
1074
990
|
}
|
1075
|
-
|
1076
|
-
oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rval);
|
1077
|
-
}
|
991
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_string", pi, rval);
|
1078
992
|
}
|
1079
993
|
|
1080
994
|
static void hash_set_value(ParseInfo pi, Val kval, VALUE value) {
|
@@ -1082,12 +996,10 @@ static void hash_set_value(ParseInfo pi, Val kval, VALUE value) {
|
|
1082
996
|
|
1083
997
|
switch (rb_type(parent->val)) {
|
1084
998
|
case T_OBJECT: oj_set_obj_ivar(parent, kval, value); break;
|
1085
|
-
case T_HASH: rb_hash_aset(parent->val,
|
999
|
+
case T_HASH: rb_hash_aset(parent->val, oj_calc_hash_key(pi, kval), value); break;
|
1086
1000
|
default: break;
|
1087
1001
|
}
|
1088
|
-
|
1089
|
-
oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
|
1090
|
-
}
|
1002
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_value", pi, value);
|
1091
1003
|
}
|
1092
1004
|
|
1093
1005
|
static void array_append_num(ParseInfo pi, NumInfo ni) {
|
@@ -1095,15 +1007,12 @@ static void array_append_num(ParseInfo pi, NumInfo ni) {
|
|
1095
1007
|
volatile VALUE rval = oj_num_as_value(ni);
|
1096
1008
|
|
1097
1009
|
rb_ary_push(parent->val, rval);
|
1098
|
-
|
1099
|
-
oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
|
1100
|
-
}
|
1010
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_number", pi, rval);
|
1101
1011
|
}
|
1102
1012
|
|
1103
1013
|
static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
1104
|
-
volatile VALUE rstr =
|
1014
|
+
volatile VALUE rstr = rb_utf8_str_new(str, len);
|
1105
1015
|
|
1106
|
-
rstr = oj_encode(rstr);
|
1107
1016
|
if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
|
1108
1017
|
VALUE clas = oj_rxclass_match(&pi->options.str_rx, str, (int)len);
|
1109
1018
|
|
@@ -1113,9 +1022,7 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
|
|
1113
1022
|
}
|
1114
1023
|
}
|
1115
1024
|
rb_ary_push(stack_peek(&pi->stack)->val, rstr);
|
1116
|
-
|
1117
|
-
oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rstr);
|
1118
|
-
}
|
1025
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_string", pi, rstr);
|
1119
1026
|
}
|
1120
1027
|
|
1121
1028
|
void oj_set_custom_callbacks(ParseInfo pi) {
|