oj 3.13.9 → 3.16.1
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 +101 -0
- data/README.md +13 -2
- data/ext/oj/buf.h +11 -6
- data/ext/oj/cache.c +25 -24
- 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 +20 -60
- data/ext/oj/custom.c +76 -155
- data/ext/oj/debug.c +3 -9
- data/ext/oj/dump.c +203 -213
- 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 +59 -181
- data/ext/oj/dump_strict.c +24 -48
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/err.c +2 -13
- data/ext/oj/err.h +9 -12
- data/ext/oj/extconf.rb +18 -7
- data/ext/oj/fast.c +83 -108
- data/ext/oj/intern.c +52 -50
- data/ext/oj/intern.h +4 -8
- data/ext/oj/mem.c +318 -0
- data/ext/oj/mem.h +53 -0
- data/ext/oj/mimic_json.c +104 -81
- data/ext/oj/object.c +50 -67
- data/ext/oj/odd.c +89 -67
- data/ext/oj/odd.h +15 -15
- data/ext/oj/oj.c +171 -106
- data/ext/oj/oj.h +96 -74
- data/ext/oj/parse.c +169 -189
- data/ext/oj/parse.h +23 -24
- data/ext/oj/parser.c +89 -34
- data/ext/oj/parser.h +20 -9
- data/ext/oj/rails.c +86 -151
- data/ext/oj/rails.h +1 -1
- data/ext/oj/reader.c +12 -15
- data/ext/oj/reader.h +4 -2
- data/ext/oj/resolve.c +3 -4
- data/ext/oj/rxclass.c +6 -5
- data/ext/oj/rxclass.h +1 -1
- data/ext/oj/saj.c +21 -32
- data/ext/oj/saj2.c +329 -93
- data/ext/oj/saj2.h +23 -0
- data/ext/oj/scp.c +3 -14
- data/ext/oj/sparse.c +26 -70
- data/ext/oj/stream_writer.c +12 -22
- data/ext/oj/strict.c +20 -52
- data/ext/oj/string_writer.c +21 -22
- data/ext/oj/trace.h +31 -4
- data/ext/oj/usual.c +105 -150
- data/ext/oj/usual.h +68 -0
- data/ext/oj/util.h +1 -1
- data/ext/oj/val_stack.c +1 -1
- data/ext/oj/val_stack.h +8 -7
- data/ext/oj/validate.c +21 -26
- data/ext/oj/wab.c +32 -69
- 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 +0 -1
- data/lib/oj/json.rb +162 -150
- data/lib/oj/mimic.rb +6 -2
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/state.rb +9 -6
- 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 +6 -3
- data/pages/Options.md +10 -0
- data/pages/Rails.md +12 -0
- 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/{activesupport5 → activesupport7}/abstract_unit.rb +16 -12
- data/test/{activesupport5 → activesupport7}/decoding_test.rb +2 -10
- data/test/{activesupport5 → activesupport7}/encoding_test.rb +20 -34
- 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 +15 -15
- 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 +49 -37
- 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 +13 -12
- data/test/perf.rb +21 -26
- 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 +12 -11
- data/test/perf_parser.rb +42 -48
- data/test/perf_saj.rb +46 -54
- data/test/perf_scp.rb +57 -69
- data/test/perf_simple.rb +41 -39
- data/test/perf_strict.rb +68 -70
- data/test/perf_wab.rb +67 -69
- data/test/prec.rb +3 -3
- 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 +72 -51
- data/test/test_debian.rb +7 -10
- data/test/test_fast.rb +102 -87
- 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 +4 -4
- data/test/test_integer_range.rb +9 -9
- data/test/test_null.rb +20 -20
- data/test/test_object.rb +85 -96
- data/test/test_parser.rb +6 -22
- data/test/test_parser_debug.rb +27 -0
- data/test/test_parser_saj.rb +115 -23
- data/test/test_parser_usual.rb +6 -6
- 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 +163 -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 +34 -144
- 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 -16
- data/test/baz.rb +0 -16
- data/test/bug.rb +0 -16
- data/test/zoo.rb +0 -13
data/ext/oj/mimic_json.c
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
#include "dump.h"
|
5
5
|
#include "encode.h"
|
6
|
+
#include "mem.h"
|
6
7
|
#include "oj.h"
|
7
8
|
#include "parse.h"
|
8
9
|
|
@@ -198,7 +199,6 @@ static int mimic_limit_arg(VALUE a) {
|
|
198
199
|
* Returns [_String_] a JSON string.
|
199
200
|
*/
|
200
201
|
static VALUE mimic_dump(int argc, VALUE *argv, VALUE self) {
|
201
|
-
char buf[4096];
|
202
202
|
struct _out out;
|
203
203
|
struct _options copts = oj_default_options;
|
204
204
|
VALUE rstr;
|
@@ -206,10 +206,9 @@ static VALUE mimic_dump(int argc, VALUE *argv, VALUE self) {
|
|
206
206
|
|
207
207
|
copts.str_rx.head = NULL;
|
208
208
|
copts.str_rx.tail = NULL;
|
209
|
-
|
210
|
-
out
|
211
|
-
|
212
|
-
out.caller = CALLER_DUMP;
|
209
|
+
|
210
|
+
oj_out_init(&out);
|
211
|
+
|
213
212
|
copts.escape_mode = JXEsc;
|
214
213
|
copts.mode = CompatMode;
|
215
214
|
|
@@ -257,9 +256,9 @@ static VALUE mimic_dump(int argc, VALUE *argv, VALUE self) {
|
|
257
256
|
rb_funcall2(io, oj_write_id, 1, args);
|
258
257
|
rstr = io;
|
259
258
|
}
|
260
|
-
|
261
|
-
|
262
|
-
|
259
|
+
|
260
|
+
oj_out_free(&out);
|
261
|
+
|
263
262
|
return rstr;
|
264
263
|
}
|
265
264
|
|
@@ -272,7 +271,7 @@ static int mimic_walk(VALUE key, VALUE obj, VALUE proc) {
|
|
272
271
|
size_t i;
|
273
272
|
|
274
273
|
for (i = 0; i < cnt; i++) {
|
275
|
-
mimic_walk(Qnil,
|
274
|
+
mimic_walk(Qnil, RARRAY_AREF(obj, i), proc);
|
276
275
|
}
|
277
276
|
break;
|
278
277
|
}
|
@@ -349,26 +348,25 @@ static VALUE mimic_load(int argc, VALUE *argv, VALUE self) {
|
|
349
348
|
static VALUE mimic_dump_load(int argc, VALUE *argv, VALUE self) {
|
350
349
|
if (1 > argc) {
|
351
350
|
rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
|
352
|
-
}
|
351
|
+
}
|
352
|
+
if (T_STRING == rb_type(*argv)) {
|
353
353
|
return mimic_load(argc, argv, self);
|
354
|
-
} else {
|
355
|
-
return mimic_dump(argc, argv, self);
|
356
354
|
}
|
357
|
-
return
|
355
|
+
return mimic_dump(argc, argv, self);
|
358
356
|
}
|
359
357
|
|
360
358
|
static VALUE mimic_generate_core(int argc, VALUE *argv, Options copts) {
|
361
|
-
char buf[4096];
|
362
359
|
struct _out out;
|
363
360
|
VALUE rstr;
|
364
361
|
|
365
|
-
|
362
|
+
if (0 == argc) {
|
363
|
+
rb_raise(rb_eArgError, "wrong number of arguments (0))");
|
364
|
+
}
|
365
|
+
memset(out.stack_buffer, 0, sizeof(out.stack_buffer));
|
366
|
+
|
367
|
+
oj_out_init(&out);
|
366
368
|
|
367
|
-
out.
|
368
|
-
out.end = buf + sizeof(buf) - 10;
|
369
|
-
out.allocated = false;
|
370
|
-
out.omit_nil = copts->dump_opts.omit_nil;
|
371
|
-
out.caller = CALLER_GENERATE;
|
369
|
+
out.omit_nil = copts->dump_opts.omit_nil;
|
372
370
|
// For obj.to_json or generate nan is not allowed but if called from dump
|
373
371
|
// it is.
|
374
372
|
copts->dump_opts.nan_dump = RaiseNan;
|
@@ -388,6 +386,8 @@ static VALUE mimic_generate_core(int argc, VALUE *argv, Options copts) {
|
|
388
386
|
VALUE active_hack[1];
|
389
387
|
|
390
388
|
if (Qundef == state_class) {
|
389
|
+
rb_warn("Oj::Rails.mimic_JSON was called implicitly. "
|
390
|
+
"Call it explicitly beforehand if you want to remove this warning.");
|
391
391
|
oj_define_mimic_json(0, NULL, Qnil);
|
392
392
|
}
|
393
393
|
active_hack[0] = rb_funcall(state_class, oj_new_id, 0);
|
@@ -398,9 +398,9 @@ static VALUE mimic_generate_core(int argc, VALUE *argv, Options copts) {
|
|
398
398
|
}
|
399
399
|
rstr = rb_str_new2(out.buf);
|
400
400
|
rstr = oj_encode(rstr);
|
401
|
-
|
402
|
-
|
403
|
-
|
401
|
+
|
402
|
+
oj_out_free(&out);
|
403
|
+
|
404
404
|
return rstr;
|
405
405
|
}
|
406
406
|
|
@@ -457,7 +457,10 @@ oj_mimic_pretty_generate(int argc, VALUE *argv, VALUE self) {
|
|
457
457
|
// a Hash. I haven't dug deep enough to find out why but using a State
|
458
458
|
// instance and not a Hash gives the desired behavior.
|
459
459
|
*rargs = *argv;
|
460
|
-
if (
|
460
|
+
if (0 == argc) {
|
461
|
+
rb_raise(rb_eArgError, "wrong number of arguments (0))");
|
462
|
+
}
|
463
|
+
if (1 == argc || Qnil == argv[1]) {
|
461
464
|
h = rb_hash_new();
|
462
465
|
} else {
|
463
466
|
h = argv[1];
|
@@ -478,6 +481,8 @@ oj_mimic_pretty_generate(int argc, VALUE *argv, VALUE self) {
|
|
478
481
|
rb_hash_aset(h, oj_array_nl_sym, rb_str_new2("\n"));
|
479
482
|
}
|
480
483
|
if (Qundef == state_class) {
|
484
|
+
rb_warn("Oj::Rails.mimic_JSON was called implicitly. "
|
485
|
+
"Call it explicitly beforehand if you want to remove this warning.");
|
481
486
|
oj_define_mimic_json(0, NULL, Qnil);
|
482
487
|
}
|
483
488
|
rargs[1] = rb_funcall(state_class, oj_new_id, 1, h);
|
@@ -499,6 +504,44 @@ oj_mimic_pretty_generate(int argc, VALUE *argv, VALUE self) {
|
|
499
504
|
return mimic_generate_core(2, rargs, &copts);
|
500
505
|
}
|
501
506
|
|
507
|
+
static int parse_options_cb(VALUE k, VALUE v, VALUE info) {
|
508
|
+
struct _parseInfo *pi = (struct _parseInfo *)info;
|
509
|
+
|
510
|
+
if (oj_symbolize_names_sym == k) {
|
511
|
+
pi->options.sym_key = (Qtrue == v) ? Yes : No;
|
512
|
+
} else if (oj_quirks_mode_sym == k) {
|
513
|
+
pi->options.quirks_mode = (Qtrue == v) ? Yes : No;
|
514
|
+
} else if (oj_create_additions_sym == k) {
|
515
|
+
pi->options.create_ok = (Qtrue == v) ? Yes : No;
|
516
|
+
} else if (oj_allow_nan_sym == k) {
|
517
|
+
pi->options.allow_nan = (Qtrue == v) ? Yes : No;
|
518
|
+
} else if (oj_hash_class_sym == k) {
|
519
|
+
if (Qnil == v) {
|
520
|
+
pi->options.hash_class = Qnil;
|
521
|
+
} else {
|
522
|
+
rb_check_type(v, T_CLASS);
|
523
|
+
pi->options.hash_class = v;
|
524
|
+
}
|
525
|
+
} else if (oj_object_class_sym == k) {
|
526
|
+
if (Qnil == v) {
|
527
|
+
pi->options.hash_class = Qnil;
|
528
|
+
} else {
|
529
|
+
rb_check_type(v, T_CLASS);
|
530
|
+
pi->options.hash_class = v;
|
531
|
+
}
|
532
|
+
} else if (oj_array_class_sym == k) {
|
533
|
+
if (Qnil == v) {
|
534
|
+
pi->options.array_class = Qnil;
|
535
|
+
} else {
|
536
|
+
rb_check_type(v, T_CLASS);
|
537
|
+
pi->options.array_class = v;
|
538
|
+
}
|
539
|
+
} else if (oj_decimal_class_sym == k) {
|
540
|
+
pi->options.compat_bigdec = (oj_bigdecimal_class == v);
|
541
|
+
}
|
542
|
+
return ST_CONTINUE;
|
543
|
+
}
|
544
|
+
|
502
545
|
static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
|
503
546
|
struct _parseInfo pi;
|
504
547
|
VALUE ropts;
|
@@ -529,46 +572,7 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
|
|
529
572
|
if (T_HASH != rb_type(ropts)) {
|
530
573
|
rb_raise(rb_eArgError, "options must be a hash.");
|
531
574
|
}
|
532
|
-
|
533
|
-
pi.options.sym_key = (Qtrue == v) ? Yes : No;
|
534
|
-
}
|
535
|
-
if (Qnil != (v = rb_hash_lookup(ropts, oj_quirks_mode_sym))) {
|
536
|
-
pi.options.quirks_mode = (Qtrue == v) ? Yes : No;
|
537
|
-
}
|
538
|
-
if (Qnil != (v = rb_hash_lookup(ropts, oj_create_additions_sym))) {
|
539
|
-
pi.options.create_ok = (Qtrue == v) ? Yes : No;
|
540
|
-
}
|
541
|
-
if (Qnil != (v = rb_hash_lookup(ropts, oj_allow_nan_sym))) {
|
542
|
-
pi.options.allow_nan = (Qtrue == v) ? Yes : No;
|
543
|
-
}
|
544
|
-
|
545
|
-
if (oj_hash_has_key(ropts, oj_hash_class_sym)) {
|
546
|
-
if (Qnil == (v = rb_hash_lookup(ropts, oj_hash_class_sym))) {
|
547
|
-
pi.options.hash_class = Qnil;
|
548
|
-
} else {
|
549
|
-
rb_check_type(v, T_CLASS);
|
550
|
-
pi.options.hash_class = v;
|
551
|
-
}
|
552
|
-
}
|
553
|
-
if (oj_hash_has_key(ropts, oj_object_class_sym)) {
|
554
|
-
if (Qnil == (v = rb_hash_lookup(ropts, oj_object_class_sym))) {
|
555
|
-
pi.options.hash_class = Qnil;
|
556
|
-
} else {
|
557
|
-
rb_check_type(v, T_CLASS);
|
558
|
-
pi.options.hash_class = v;
|
559
|
-
}
|
560
|
-
}
|
561
|
-
if (oj_hash_has_key(ropts, oj_array_class_sym)) {
|
562
|
-
if (Qnil == (v = rb_hash_lookup(ropts, oj_array_class_sym))) {
|
563
|
-
pi.options.array_class = Qnil;
|
564
|
-
} else {
|
565
|
-
rb_check_type(v, T_CLASS);
|
566
|
-
pi.options.array_class = v;
|
567
|
-
}
|
568
|
-
}
|
569
|
-
if (oj_hash_has_key(ropts, oj_decimal_class_sym)) {
|
570
|
-
pi.options.compat_bigdec = (oj_bigdecimal_class == rb_hash_lookup(ropts, oj_decimal_class_sym));
|
571
|
-
}
|
575
|
+
rb_hash_foreach(ropts, parse_options_cb, (VALUE)&pi);
|
572
576
|
v = rb_hash_lookup(ropts, oj_max_nesting_sym);
|
573
577
|
if (Qtrue == v) {
|
574
578
|
pi.max_depth = 100;
|
@@ -646,23 +650,22 @@ static VALUE mimic_recurse_proc(VALUE self, VALUE obj) {
|
|
646
650
|
*
|
647
651
|
* - *id* [_nil_|String] new create_id
|
648
652
|
*
|
649
|
-
* Returns [_String_] the id.
|
653
|
+
* Returns [_nil_|_String_] the id.
|
650
654
|
*/
|
651
655
|
static VALUE mimic_set_create_id(VALUE self, VALUE id) {
|
652
|
-
Check_Type(id, T_STRING);
|
653
|
-
|
654
656
|
if (NULL != oj_default_options.create_id) {
|
655
657
|
if (oj_json_class != oj_default_options.create_id) {
|
656
|
-
|
658
|
+
OJ_R_FREE((char *)oj_default_options.create_id);
|
657
659
|
}
|
658
660
|
oj_default_options.create_id = NULL;
|
659
661
|
oj_default_options.create_id_len = 0;
|
660
662
|
}
|
661
663
|
if (Qnil != id) {
|
662
|
-
|
664
|
+
const char *ptr = StringValueCStr(id);
|
665
|
+
size_t len = RSTRING_LEN(id) + 1;
|
663
666
|
|
664
|
-
oj_default_options.create_id =
|
665
|
-
strcpy((char *)oj_default_options.create_id,
|
667
|
+
oj_default_options.create_id = OJ_R_ALLOC_N(char, len);
|
668
|
+
strcpy((char *)oj_default_options.create_id, ptr);
|
666
669
|
oj_default_options.create_id_len = len - 1;
|
667
670
|
}
|
668
671
|
return id;
|
@@ -732,6 +735,7 @@ static struct _options mimic_object_to_json_options = {0, // indent
|
|
732
735
|
0, // array_size
|
733
736
|
RaiseNan, // nan_dump
|
734
737
|
false, // omit_nil
|
738
|
+
false, // omit_null_byte
|
735
739
|
100, // max_depth
|
736
740
|
},
|
737
741
|
{
|
@@ -742,19 +746,18 @@ static struct _options mimic_object_to_json_options = {0, // indent
|
|
742
746
|
}};
|
743
747
|
|
744
748
|
static VALUE mimic_object_to_json(int argc, VALUE *argv, VALUE self) {
|
745
|
-
char buf[4096];
|
746
749
|
struct _out out;
|
747
750
|
VALUE rstr;
|
748
751
|
struct _options copts = oj_default_options;
|
749
752
|
|
750
753
|
copts.str_rx.head = NULL;
|
751
754
|
copts.str_rx.tail = NULL;
|
752
|
-
|
753
|
-
out
|
754
|
-
|
755
|
-
out.omit_nil
|
756
|
-
copts.mode
|
757
|
-
copts.to_json
|
755
|
+
|
756
|
+
oj_out_init(&out);
|
757
|
+
|
758
|
+
out.omit_nil = copts.dump_opts.omit_nil;
|
759
|
+
copts.mode = CompatMode;
|
760
|
+
copts.to_json = No;
|
758
761
|
if (1 <= argc && Qnil != argv[0]) {
|
759
762
|
oj_parse_mimic_dump_options(argv[0], &copts);
|
760
763
|
}
|
@@ -767,9 +770,9 @@ static VALUE mimic_object_to_json(int argc, VALUE *argv, VALUE self) {
|
|
767
770
|
}
|
768
771
|
rstr = rb_str_new2(out.buf);
|
769
772
|
rstr = oj_encode(rstr);
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
+
|
774
|
+
oj_out_free(&out);
|
775
|
+
|
773
776
|
return rstr;
|
774
777
|
}
|
775
778
|
|
@@ -786,28 +789,48 @@ void oj_mimic_json_methods(VALUE json) {
|
|
786
789
|
VALUE json_error;
|
787
790
|
VALUE generator;
|
788
791
|
VALUE ext;
|
792
|
+
VALUE verbose;
|
793
|
+
|
794
|
+
// rb_undef_method doesn't work for modules or maybe sometimes
|
795
|
+
// doesn't. Anyway setting verbose should hide the warning.
|
796
|
+
verbose = rb_gv_get("$VERBOSE");
|
797
|
+
rb_gv_set("$VERBOSE", Qfalse);
|
789
798
|
|
799
|
+
rb_undef_method(json, "create_id=");
|
790
800
|
rb_define_module_function(json, "create_id=", mimic_set_create_id, 1);
|
801
|
+
rb_undef_method(json, "create_id");
|
791
802
|
rb_define_module_function(json, "create_id", mimic_create_id, 0);
|
792
803
|
|
804
|
+
rb_undef_method(json, "dump");
|
793
805
|
rb_define_module_function(json, "dump", mimic_dump, -1);
|
806
|
+
rb_undef_method(json, "load");
|
794
807
|
rb_define_module_function(json, "load", mimic_load, -1);
|
795
808
|
rb_define_module_function(json, "restore", mimic_load, -1);
|
809
|
+
rb_undef_method(json, "recurse_proc");
|
796
810
|
rb_define_module_function(json, "recurse_proc", mimic_recurse_proc, 1);
|
811
|
+
rb_undef_method(json, "[]");
|
797
812
|
rb_define_module_function(json, "[]", mimic_dump_load, -1);
|
798
813
|
|
814
|
+
rb_undef_method(json, "generate");
|
799
815
|
rb_define_module_function(json, "generate", oj_mimic_generate, -1);
|
816
|
+
rb_undef_method(json, "fast_generate");
|
800
817
|
rb_define_module_function(json, "fast_generate", oj_mimic_generate, -1);
|
818
|
+
rb_undef_method(json, "pretty_generate");
|
801
819
|
rb_define_module_function(json, "pretty_generate", oj_mimic_pretty_generate, -1);
|
802
820
|
// For older versions of JSON, the deprecated unparse methods.
|
821
|
+
rb_undef_method(json, "unparse");
|
803
822
|
rb_define_module_function(json, "unparse", oj_mimic_generate, -1);
|
804
823
|
rb_define_module_function(json, "fast_unparse", oj_mimic_generate, -1);
|
805
824
|
rb_define_module_function(json, "pretty_unparse", oj_mimic_pretty_generate, -1);
|
806
825
|
|
826
|
+
rb_undef_method(json, "parse");
|
807
827
|
rb_define_module_function(json, "parse", oj_mimic_parse, -1);
|
828
|
+
rb_undef_method(json, "parse!");
|
808
829
|
rb_define_module_function(json, "parse!", mimic_parse_bang, -1);
|
809
830
|
|
831
|
+
rb_undef_method(json, "state");
|
810
832
|
rb_define_module_function(json, "state", mimic_state, 0);
|
833
|
+
rb_gv_set("$VERBOSE", verbose);
|
811
834
|
|
812
835
|
if (rb_const_defined_at(json, rb_intern("JSONError"))) {
|
813
836
|
json_error = rb_const_get(json, rb_intern("JSONError"));
|
data/ext/oj/object.c
CHANGED
@@ -67,9 +67,9 @@ static VALUE str_to_value(ParseInfo pi, const char *str, size_t len, const char
|
|
67
67
|
|
68
68
|
// The much faster approach (4x faster)
|
69
69
|
static int parse_num(const char *str, const char *end, int cnt) {
|
70
|
-
int
|
70
|
+
int n = 0;
|
71
71
|
char c;
|
72
|
-
int
|
72
|
+
int i;
|
73
73
|
|
74
74
|
for (i = cnt; 0 < i; i--, str++) {
|
75
75
|
c = *str;
|
@@ -83,9 +83,9 @@ static int parse_num(const char *str, const char *end, int cnt) {
|
|
83
83
|
|
84
84
|
VALUE
|
85
85
|
oj_parse_xml_time(const char *str, int len) {
|
86
|
-
VALUE
|
86
|
+
VALUE args[8];
|
87
87
|
const char *end = str + len;
|
88
|
-
int
|
88
|
+
int n;
|
89
89
|
|
90
90
|
// year
|
91
91
|
if (0 > (n = parse_num(str, end, 4))) {
|
@@ -269,19 +269,10 @@ static int hat_num(ParseInfo pi, Val parent, Val kval, NumInfo ni) {
|
|
269
269
|
// match the expected value.
|
270
270
|
parent->val = rb_funcall2(parent->val, oj_utc_id, 0, 0);
|
271
271
|
} else if (ni->has_exp) {
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
sec_as_time(t, &ti);
|
277
|
-
args[0] = LONG2NUM((long)(ti.year));
|
278
|
-
args[1] = LONG2NUM(ti.mon);
|
279
|
-
args[2] = LONG2NUM(ti.day);
|
280
|
-
args[3] = LONG2NUM(ti.hour);
|
281
|
-
args[4] = LONG2NUM(ti.min);
|
282
|
-
args[5] = rb_float_new((double)ti.sec + ((double)nsec + 0.5) / 1000000000.0);
|
283
|
-
args[6] = LONG2NUM(ni->exp);
|
284
|
-
parent->val = rb_funcall2(rb_cTime, oj_new_id, 7, args);
|
272
|
+
struct timespec ts;
|
273
|
+
ts.tv_sec = ni->i;
|
274
|
+
ts.tv_nsec = nsec;
|
275
|
+
parent->val = rb_time_timespec_new(&ts, (int)ni->exp);
|
285
276
|
} else {
|
286
277
|
parent->val = rb_time_nano_new(ni->i, (long)nsec);
|
287
278
|
}
|
@@ -317,7 +308,7 @@ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, vol
|
|
317
308
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "Invalid struct data");
|
318
309
|
return 1;
|
319
310
|
}
|
320
|
-
e1 = *
|
311
|
+
e1 = *RARRAY_CONST_PTR(value);
|
321
312
|
// check for anonymous Struct
|
322
313
|
if (T_ARRAY == rb_type(e1)) {
|
323
314
|
VALUE args[1024];
|
@@ -325,46 +316,50 @@ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, vol
|
|
325
316
|
int i, cnt = (int)RARRAY_LEN(e1);
|
326
317
|
|
327
318
|
for (i = 0; i < cnt; i++) {
|
328
|
-
rstr =
|
319
|
+
rstr = RARRAY_AREF(e1, i);
|
329
320
|
args[i] = rb_funcall(rstr, oj_to_sym_id, 0);
|
330
321
|
}
|
331
322
|
sc = rb_funcall2(rb_cStruct, oj_new_id, cnt, args);
|
332
323
|
} else {
|
333
324
|
// If struct is not defined then we let this fail and raise an exception.
|
334
|
-
sc = oj_name2struct(pi, *
|
325
|
+
sc = oj_name2struct(pi, *RARRAY_CONST_PTR(value), rb_eArgError);
|
335
326
|
}
|
336
|
-
|
337
|
-
|
338
|
-
|
327
|
+
if (sc == rb_cRange) {
|
328
|
+
parent->val = rb_class_new_instance(len - 1, RARRAY_CONST_PTR(value) + 1, rb_cRange);
|
329
|
+
} else {
|
330
|
+
// Create a properly initialized struct instance without calling the initialize method.
|
331
|
+
parent->val = rb_obj_alloc(sc);
|
332
|
+
// If the JSON array has more entries than the struct class allows, we record an error.
|
339
333
|
#ifdef RSTRUCT_LEN
|
340
334
|
#if RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
341
|
-
|
335
|
+
slen = (int)NUM2LONG(RSTRUCT_LEN(parent->val));
|
342
336
|
#else // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
343
|
-
|
337
|
+
slen = (int)RSTRUCT_LEN(parent->val);
|
344
338
|
#endif // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
|
345
339
|
#else
|
346
|
-
|
340
|
+
slen = FIX2INT(rb_funcall2(parent->val, oj_length_id, 0, 0));
|
347
341
|
#endif
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
342
|
+
// MRI >= 1.9
|
343
|
+
if (len - 1 > slen) {
|
344
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "Invalid struct data");
|
345
|
+
} else {
|
346
|
+
int i;
|
353
347
|
|
354
|
-
|
355
|
-
|
348
|
+
for (i = 0; i < len - 1; i++) {
|
349
|
+
rb_struct_aset(parent->val, INT2FIX(i), RARRAY_CONST_PTR(value)[i + 1]);
|
350
|
+
}
|
356
351
|
}
|
357
352
|
}
|
358
353
|
return 1;
|
359
354
|
} else if (3 <= klen && '#' == key[1]) {
|
360
|
-
volatile VALUE *a;
|
355
|
+
volatile const VALUE *a;
|
361
356
|
|
362
357
|
if (2 != len) {
|
363
358
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "invalid hash pair");
|
364
359
|
return 1;
|
365
360
|
}
|
366
361
|
parent->val = rb_hash_new();
|
367
|
-
a =
|
362
|
+
a = RARRAY_CONST_PTR(value);
|
368
363
|
rb_hash_aset(parent->val, *a, a[1]);
|
369
364
|
|
370
365
|
return 1;
|
@@ -374,11 +369,17 @@ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, vol
|
|
374
369
|
}
|
375
370
|
|
376
371
|
void oj_set_obj_ivar(Val parent, Val kval, VALUE value) {
|
377
|
-
|
372
|
+
if (kval->klen == 5 && strncmp("~mesg", kval->key, 5) == 0 && rb_obj_is_kind_of(parent->val, rb_eException)) {
|
373
|
+
parent->val = rb_funcall(parent->val, rb_intern("exception"), 1, value);
|
374
|
+
} else if (kval->klen == 3 && strncmp("~bt", kval->key, 3) == 0 && rb_obj_is_kind_of(parent->val, rb_eException)) {
|
375
|
+
rb_funcall(parent->val, rb_intern("set_backtrace"), 1, value);
|
376
|
+
} else {
|
377
|
+
rb_ivar_set(parent->val, oj_attr_intern(kval->key, kval->klen), value);
|
378
|
+
}
|
378
379
|
}
|
379
380
|
|
380
381
|
static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
|
381
|
-
const char
|
382
|
+
const char *key = kval->key;
|
382
383
|
int klen = kval->klen;
|
383
384
|
Val parent = stack_peek(&pi->stack);
|
384
385
|
volatile VALUE rval = Qnil;
|
@@ -445,13 +446,11 @@ WHICH_TYPE:
|
|
445
446
|
rb_class2name(rb_obj_class(parent->val)));
|
446
447
|
return;
|
447
448
|
}
|
448
|
-
|
449
|
-
oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rval);
|
450
|
-
}
|
449
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_string", pi, rval);
|
451
450
|
}
|
452
451
|
|
453
452
|
static void hash_set_num(ParseInfo pi, Val kval, NumInfo ni) {
|
454
|
-
const char
|
453
|
+
const char *key = kval->key;
|
455
454
|
int klen = kval->klen;
|
456
455
|
Val parent = stack_peek(&pi->stack);
|
457
456
|
volatile VALUE rval = Qnil;
|
@@ -516,9 +515,7 @@ WHICH_TYPE:
|
|
516
515
|
rb_class2name(rb_obj_class(parent->val)));
|
517
516
|
return;
|
518
517
|
}
|
519
|
-
|
520
|
-
oj_trace_parse_call("add_number", pi, __FILE__, __LINE__, rval);
|
521
|
-
}
|
518
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_number", pi, rval);
|
522
519
|
}
|
523
520
|
|
524
521
|
static void hash_set_value(ParseInfo pi, Val kval, VALUE value) {
|
@@ -544,8 +541,8 @@ WHICH_TYPE:
|
|
544
541
|
}
|
545
542
|
} else {
|
546
543
|
if (3 <= klen && '^' == *key && '#' == key[1] && T_ARRAY == rb_type(value)) {
|
547
|
-
long
|
548
|
-
volatile VALUE *a =
|
544
|
+
long len = RARRAY_LEN(value);
|
545
|
+
volatile const VALUE *a = RARRAY_CONST_PTR(value);
|
549
546
|
|
550
547
|
if (2 != len) {
|
551
548
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "invalid hash pair");
|
@@ -602,15 +599,11 @@ WHICH_TYPE:
|
|
602
599
|
rb_class2name(rb_obj_class(parent->val)));
|
603
600
|
return;
|
604
601
|
}
|
605
|
-
|
606
|
-
oj_trace_parse_call("add_value", pi, __FILE__, __LINE__, value);
|
607
|
-
}
|
602
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_value", pi, value);
|
608
603
|
}
|
609
604
|
|
610
605
|
static VALUE start_hash(ParseInfo pi) {
|
611
|
-
|
612
|
-
oj_trace_parse_in("start_hash", pi, __FILE__, __LINE__);
|
613
|
-
}
|
606
|
+
TRACE_PARSE_IN(pi->options.trace, "start_hash", pi);
|
614
607
|
return Qnil;
|
615
608
|
}
|
616
609
|
|
@@ -626,9 +619,7 @@ static void end_hash(ParseInfo pi) {
|
|
626
619
|
oj_odd_free(oa);
|
627
620
|
parent->odd_args = NULL;
|
628
621
|
}
|
629
|
-
|
630
|
-
oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
|
631
|
-
}
|
622
|
+
TRACE_PARSE_HASH_END(pi->options.trace, pi);
|
632
623
|
}
|
633
624
|
|
634
625
|
static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
@@ -654,32 +645,24 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
|
|
654
645
|
}
|
655
646
|
rval = str_to_value(pi, str, len, orig);
|
656
647
|
rb_ary_push(stack_peek(&pi->stack)->val, rval);
|
657
|
-
|
658
|
-
oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rval);
|
659
|
-
}
|
648
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_string", pi, rval);
|
660
649
|
}
|
661
650
|
|
662
651
|
static void array_append_num(ParseInfo pi, NumInfo ni) {
|
663
652
|
volatile VALUE rval = oj_num_as_value(ni);
|
664
653
|
|
665
654
|
rb_ary_push(stack_peek(&pi->stack)->val, rval);
|
666
|
-
|
667
|
-
oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
|
668
|
-
}
|
655
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_number", pi, rval);
|
669
656
|
}
|
670
657
|
|
671
658
|
static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
672
659
|
pi->stack.head->val = str_to_value(pi, str, len, orig);
|
673
|
-
|
674
|
-
oj_trace_parse_call("add_string", pi, __FILE__, __LINE__, pi->stack.head->val);
|
675
|
-
}
|
660
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_string", pi, pi->stack.head->val);
|
676
661
|
}
|
677
662
|
|
678
663
|
static void add_num(ParseInfo pi, NumInfo ni) {
|
679
664
|
pi->stack.head->val = oj_num_as_value(ni);
|
680
|
-
|
681
|
-
oj_trace_parse_call("add_num", pi, __FILE__, __LINE__, pi->stack.head->val);
|
682
|
-
}
|
665
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_num", pi, pi->stack.head->val);
|
683
666
|
}
|
684
667
|
|
685
668
|
void oj_set_object_callbacks(ParseInfo pi) {
|