oj 3.13.9 → 3.16.1
Sign up to get free protection for your applications and to get access to all the features.
- 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) {
|