oj 3.11.5 → 3.12.3
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/README.md +5 -1
- data/ext/oj/compat.c +32 -27
- data/ext/oj/custom.c +3 -15
- data/ext/oj/dump.c +39 -42
- data/ext/oj/dump_strict.c +1 -1
- data/ext/oj/fast.c +53 -22
- data/ext/oj/hash.c +41 -4
- data/ext/oj/hash.h +2 -0
- data/ext/oj/mimic_json.c +15 -13
- data/ext/oj/object.c +33 -5
- data/ext/oj/oj.c +116 -33
- data/ext/oj/oj.h +3 -1
- data/ext/oj/parse.c +1 -1
- data/ext/oj/parse.h +3 -0
- data/ext/oj/rails.c +2 -1
- data/ext/oj/scp.c +4 -16
- data/ext/oj/strict.c +67 -22
- data/ext/oj/wab.c +35 -18
- data/lib/oj/mimic.rb +2 -0
- data/lib/oj/version.rb +1 -1
- data/pages/Modes.md +2 -0
- data/pages/Options.md +23 -5
- data/test/foo.rb +2 -44
- data/test/perf.rb +1 -1
- data/test/perf_scp.rb +11 -10
- data/test/perf_strict.rb +17 -23
- data/test/test_fast.rb +32 -2
- data/test/test_various.rb +2 -0
- metadata +3 -3
data/ext/oj/hash.h
CHANGED
@@ -11,6 +11,8 @@ typedef struct _hash *Hash;
|
|
11
11
|
extern void oj_hash_init();
|
12
12
|
|
13
13
|
extern VALUE oj_class_hash_get(const char *key, size_t len, VALUE **slotp);
|
14
|
+
extern VALUE oj_str_hash_get(const char *key, size_t len, VALUE **slotp);
|
15
|
+
extern VALUE oj_sym_hash_get(const char *key, size_t len, VALUE **slotp);
|
14
16
|
extern ID oj_attr_hash_get(const char *key, size_t len, ID **slotp);
|
15
17
|
|
16
18
|
extern void oj_hash_print();
|
data/ext/oj/mimic_json.c
CHANGED
@@ -389,9 +389,9 @@ static VALUE mimic_generate_core(int argc, VALUE *argv, Options copts) {
|
|
389
389
|
} else {
|
390
390
|
VALUE active_hack[1];
|
391
391
|
|
392
|
-
|
393
|
-
|
394
|
-
|
392
|
+
if (Qundef == state_class) {
|
393
|
+
oj_define_mimic_json(0, NULL, Qnil);
|
394
|
+
}
|
395
395
|
active_hack[0] = rb_funcall(state_class, oj_new_id, 0);
|
396
396
|
oj_dump_obj_to_json_using_params(*argv, copts, &out, 1, active_hack);
|
397
397
|
}
|
@@ -464,23 +464,23 @@ oj_mimic_pretty_generate(int argc, VALUE *argv, VALUE self) {
|
|
464
464
|
} else {
|
465
465
|
h = argv[1];
|
466
466
|
}
|
467
|
-
if (
|
467
|
+
if (!oj_hash_has_key(h, oj_indent_sym)) {
|
468
468
|
rb_hash_aset(h, oj_indent_sym, rb_str_new2(" "));
|
469
469
|
}
|
470
|
-
if (
|
470
|
+
if (!oj_hash_has_key(h, oj_space_before_sym)) {
|
471
471
|
rb_hash_aset(h, oj_space_before_sym, rb_str_new2(""));
|
472
472
|
}
|
473
|
-
if (
|
473
|
+
if (!oj_hash_has_key(h, oj_space_sym)) {
|
474
474
|
rb_hash_aset(h, oj_space_sym, rb_str_new2(" "));
|
475
475
|
}
|
476
|
-
if (
|
476
|
+
if (!oj_hash_has_key(h, oj_object_nl_sym)) {
|
477
477
|
rb_hash_aset(h, oj_object_nl_sym, rb_str_new2("\n"));
|
478
478
|
}
|
479
|
-
if (
|
479
|
+
if (!oj_hash_has_key(h, oj_array_nl_sym)) {
|
480
480
|
rb_hash_aset(h, oj_array_nl_sym, rb_str_new2("\n"));
|
481
481
|
}
|
482
482
|
if (Qundef == state_class) {
|
483
|
-
|
483
|
+
oj_define_mimic_json(0, NULL, Qnil);
|
484
484
|
}
|
485
485
|
rargs[1] = rb_funcall(state_class, oj_new_id, 1, h);
|
486
486
|
|
@@ -548,7 +548,7 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
|
|
548
548
|
pi.options.allow_nan = (Qtrue == v) ? Yes : No;
|
549
549
|
}
|
550
550
|
|
551
|
-
if (
|
551
|
+
if (oj_hash_has_key(ropts, oj_hash_class_sym)) {
|
552
552
|
if (Qnil == (v = rb_hash_lookup(ropts, oj_hash_class_sym))) {
|
553
553
|
pi.options.hash_class = Qnil;
|
554
554
|
} else {
|
@@ -556,7 +556,7 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
|
|
556
556
|
pi.options.hash_class = v;
|
557
557
|
}
|
558
558
|
}
|
559
|
-
if (
|
559
|
+
if (oj_hash_has_key(ropts, oj_object_class_sym)) {
|
560
560
|
if (Qnil == (v = rb_hash_lookup(ropts, oj_object_class_sym))) {
|
561
561
|
pi.options.hash_class = Qnil;
|
562
562
|
} else {
|
@@ -564,7 +564,7 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
|
|
564
564
|
pi.options.hash_class = v;
|
565
565
|
}
|
566
566
|
}
|
567
|
-
if (
|
567
|
+
if (oj_hash_has_key(ropts, oj_array_class_sym)) {
|
568
568
|
if (Qnil == (v = rb_hash_lookup(ropts, oj_array_class_sym))) {
|
569
569
|
pi.options.array_class = Qnil;
|
570
570
|
} else {
|
@@ -572,7 +572,7 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
|
|
572
572
|
pi.options.array_class = v;
|
573
573
|
}
|
574
574
|
}
|
575
|
-
if (
|
575
|
+
if (oj_hash_has_key(ropts, oj_decimal_class_sym)) {
|
576
576
|
pi.options.compat_bigdec = (oj_bigdecimal_class ==
|
577
577
|
rb_hash_lookup(ropts, oj_decimal_class_sym));
|
578
578
|
}
|
@@ -713,6 +713,8 @@ static struct _options mimic_object_to_json_options = {0, // indent
|
|
713
713
|
No, // safe
|
714
714
|
false, // sec_prec_set
|
715
715
|
No, // ignore_under
|
716
|
+
Yes, // cache_keys
|
717
|
+
3, // cache_str
|
716
718
|
0, // int_range_min
|
717
719
|
0, // int_range_max
|
718
720
|
oj_json_class, // create_id
|
data/ext/oj/object.c
CHANGED
@@ -30,11 +30,38 @@ inline static long read_long(const char *str, size_t len) {
|
|
30
30
|
|
31
31
|
static VALUE calc_hash_key(ParseInfo pi, Val kval, char k1) {
|
32
32
|
volatile VALUE rkey;
|
33
|
+
#if 0
|
34
|
+
VALUE *slot;
|
33
35
|
|
36
|
+
if (':' == k1) {
|
37
|
+
if (Qnil == (rkey = oj_sym_hash_get(kval->key + 1, kval->klen - 1, &slot))) {
|
38
|
+
rkey = rb_str_new(kval->key + 1, kval->klen - 1);
|
39
|
+
rkey = oj_encode(rkey);
|
40
|
+
rkey = rb_str_intern(rkey);
|
41
|
+
*slot = rkey;
|
42
|
+
rb_gc_register_address(slot);
|
43
|
+
}
|
44
|
+
} else if (Yes == pi->options.sym_key) {
|
45
|
+
if (Qnil == (rkey = oj_sym_hash_get(kval->key, kval->klen, &slot))) {
|
46
|
+
rkey = rb_str_new(kval->key, kval->klen);
|
47
|
+
rkey = oj_encode(rkey);
|
48
|
+
rkey = rb_str_intern(rkey);
|
49
|
+
*slot = rkey;
|
50
|
+
rb_gc_register_address(slot);
|
51
|
+
}
|
52
|
+
} else {
|
53
|
+
if (Qnil == (rkey = oj_str_hash_get(kval->key, kval->klen, &slot))) {
|
54
|
+
rkey = rb_str_new(kval->key, kval->klen);
|
55
|
+
rkey = oj_encode(rkey);
|
56
|
+
*slot = rkey;
|
57
|
+
rb_gc_register_address(slot);
|
58
|
+
}
|
59
|
+
}
|
60
|
+
#else
|
34
61
|
if (':' == k1) {
|
35
62
|
rkey = rb_str_new(kval->key + 1, kval->klen - 1);
|
36
63
|
rkey = oj_encode(rkey);
|
37
|
-
|
64
|
+
rkey = rb_str_intern(rkey);
|
38
65
|
} else {
|
39
66
|
rkey = rb_str_new(kval->key, kval->klen);
|
40
67
|
rkey = oj_encode(rkey);
|
@@ -42,6 +69,7 @@ static VALUE calc_hash_key(ParseInfo pi, Val kval, char k1) {
|
|
42
69
|
rkey = rb_str_intern(rkey);
|
43
70
|
}
|
44
71
|
}
|
72
|
+
#endif
|
45
73
|
return rkey;
|
46
74
|
}
|
47
75
|
|
@@ -405,22 +433,22 @@ void oj_set_obj_ivar(Val parent, Val kval, VALUE value) {
|
|
405
433
|
char *buf = ALLOC_N(char, klen + 2);
|
406
434
|
|
407
435
|
if ('~' == *key) {
|
408
|
-
|
436
|
+
memcpy(buf, key + 1, klen - 1);
|
409
437
|
buf[klen - 1] = '\0';
|
410
438
|
} else {
|
411
439
|
*buf = '@';
|
412
|
-
|
440
|
+
memcpy(buf + 1, key, klen);
|
413
441
|
buf[klen + 1] = '\0';
|
414
442
|
}
|
415
443
|
var_id = rb_intern(buf);
|
416
444
|
xfree(buf);
|
417
445
|
} else {
|
418
446
|
if ('~' == *key) {
|
419
|
-
|
447
|
+
memcpy(attr, key + 1, klen - 1);
|
420
448
|
attr[klen - 1] = '\0';
|
421
449
|
} else {
|
422
450
|
*attr = '@';
|
423
|
-
|
451
|
+
memcpy(attr + 1, key, klen);
|
424
452
|
attr[klen + 1] = '\0';
|
425
453
|
}
|
426
454
|
var_id = rb_intern(attr);
|
data/ext/oj/oj.c
CHANGED
@@ -40,7 +40,6 @@ ID oj_error_id;
|
|
40
40
|
ID oj_file_id;
|
41
41
|
ID oj_fileno_id;
|
42
42
|
ID oj_ftype_id;
|
43
|
-
ID oj_has_key_id;
|
44
43
|
ID oj_hash_end_id;
|
45
44
|
ID oj_hash_key_id;
|
46
45
|
ID oj_hash_set_id;
|
@@ -106,6 +105,8 @@ static VALUE auto_sym;
|
|
106
105
|
static VALUE bigdecimal_as_decimal_sym;
|
107
106
|
static VALUE bigdecimal_load_sym;
|
108
107
|
static VALUE bigdecimal_sym;
|
108
|
+
static VALUE cache_keys_sym;
|
109
|
+
static VALUE cache_str_sym;
|
109
110
|
static VALUE circular_sym;
|
110
111
|
static VALUE class_cache_sym;
|
111
112
|
static VALUE compat_bigdecimal_sym;
|
@@ -186,6 +187,8 @@ struct _options oj_default_options = {
|
|
186
187
|
No, // safe
|
187
188
|
false, // sec_prec_set
|
188
189
|
No, // ignore_under
|
190
|
+
Yes, // cache_keys
|
191
|
+
3, // cache_str
|
189
192
|
0, // int_range_min
|
190
193
|
0, // int_range_max
|
191
194
|
oj_json_class, // create_id
|
@@ -279,9 +282,11 @@ struct _options oj_default_options = {
|
|
279
282
|
*used
|
280
283
|
* - *:array_class* [_Class_|_nil_] Class to use instead of Array on load
|
281
284
|
* - *:omit_nil* [_true_|_false_] if true Hash and Object attributes with nil values are omitted
|
282
|
-
* - *:ignore* [_nil_|
|
283
|
-
* - *:ignore_under* [
|
285
|
+
* - *:ignore* [_nil_|_Array_] either nil or an Array of classes to ignore when dumping
|
286
|
+
* - *:ignore_under* [_Boolean_] if true then attributes that start with _ are ignored when dumping in
|
284
287
|
*object or custom mode.
|
288
|
+
* - *:cache_keys* [_Boolean_] if true then hash keys are cached
|
289
|
+
* - *:cache_str* [_Fixnum_] maximum string value length to cache
|
285
290
|
* - *:integer_range* [_Range_] Dump integers outside range as strings.
|
286
291
|
* - *:trace* [_true,_|_false_] Trace all load and dump calls, default is false (trace is off)
|
287
292
|
* - *:safe* [_true,_|_false_] Safe mimic breaks JSON mimic to be safer, default is false (safe is
|
@@ -389,11 +394,17 @@ static VALUE get_def_opts(VALUE self) {
|
|
389
394
|
? Qtrue
|
390
395
|
: ((No == oj_default_options.safe) ? Qfalse : Qnil));
|
391
396
|
rb_hash_aset(opts, float_prec_sym, INT2FIX(oj_default_options.float_prec));
|
397
|
+
rb_hash_aset(opts, cache_str_sym, INT2FIX(oj_default_options.cache_str));
|
392
398
|
rb_hash_aset(opts,
|
393
399
|
ignore_under_sym,
|
394
400
|
(Yes == oj_default_options.ignore_under)
|
395
401
|
? Qtrue
|
396
402
|
: ((No == oj_default_options.ignore_under) ? Qfalse : Qnil));
|
403
|
+
rb_hash_aset(opts,
|
404
|
+
cache_keys_sym,
|
405
|
+
(Yes == oj_default_options.cache_keys)
|
406
|
+
? Qtrue
|
407
|
+
: ((No == oj_default_options.cache_keys) ? Qfalse : Qnil));
|
397
408
|
switch (oj_default_options.mode) {
|
398
409
|
case StrictMode: rb_hash_aset(opts, mode_sym, strict_sym); break;
|
399
410
|
case CompatMode: rb_hash_aset(opts, mode_sym, compat_sym); break;
|
@@ -557,6 +568,8 @@ static VALUE get_def_opts(VALUE self) {
|
|
557
568
|
* - *:ignore* [_nil_|Array] either nil or an Array of classes to ignore when dumping
|
558
569
|
* - *:ignore_under* [_Boolean_] if true then attributes that start with _ are ignored when
|
559
570
|
*dumping in object or custom mode.
|
571
|
+
* - *:cache_keys* [_Boolean_] if true then hash keys are cached
|
572
|
+
* - *:cache_str* [_Fixnum_] maximum string vsalue length to cache
|
560
573
|
* - *:integer_range* [_Range_] Dump integers outside range as strings.
|
561
574
|
* - *:trace* [_Boolean_] turn trace on or off.
|
562
575
|
* - *:safe* [_Boolean_] turn safe mimic on or off.
|
@@ -568,6 +581,14 @@ static VALUE set_def_opts(VALUE self, VALUE opts) {
|
|
568
581
|
return Qnil;
|
569
582
|
}
|
570
583
|
|
584
|
+
bool oj_hash_has_key(VALUE hash, VALUE key)
|
585
|
+
{
|
586
|
+
if (Qundef == rb_hash_lookup2(hash, key, Qundef)) {
|
587
|
+
return false;
|
588
|
+
}
|
589
|
+
return true;
|
590
|
+
}
|
591
|
+
|
571
592
|
void oj_parse_options(VALUE ropts, Options copts) {
|
572
593
|
struct _yesNoOpt ynos[] = {{circular_sym, &copts->circular},
|
573
594
|
{auto_define_sym, &copts->auto_define},
|
@@ -589,6 +610,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
|
|
589
610
|
{oj_safe_sym, &copts->safe},
|
590
611
|
{ignore_under_sym, &copts->ignore_under},
|
591
612
|
{oj_create_additions_sym, &copts->create_ok},
|
613
|
+
{cache_keys_sym, &copts->cache_keys},
|
592
614
|
{Qnil, 0}};
|
593
615
|
YesNoOpt o;
|
594
616
|
volatile VALUE v;
|
@@ -597,7 +619,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
|
|
597
619
|
if (T_HASH != rb_type(ropts)) {
|
598
620
|
return;
|
599
621
|
}
|
600
|
-
if (
|
622
|
+
if (oj_hash_has_key(ropts, oj_indent_sym)) {
|
601
623
|
v = rb_hash_lookup(ropts, oj_indent_sym);
|
602
624
|
switch (rb_type(v)) {
|
603
625
|
case T_NIL:
|
@@ -647,6 +669,28 @@ void oj_parse_options(VALUE ropts, Options copts) {
|
|
647
669
|
copts->float_prec = n;
|
648
670
|
}
|
649
671
|
}
|
672
|
+
if (Qnil != (v = rb_hash_lookup(ropts, cache_str_sym))) {
|
673
|
+
int n;
|
674
|
+
|
675
|
+
#ifdef RUBY_INTEGER_UNIFICATION
|
676
|
+
if (rb_cInteger != rb_obj_class(v)) {
|
677
|
+
rb_raise(rb_eArgError, ":cache_str must be a Integer.");
|
678
|
+
}
|
679
|
+
#else
|
680
|
+
if (T_FIXNUM != rb_type(v)) {
|
681
|
+
rb_raise(rb_eArgError, ":cache_str must be a Fixnum.");
|
682
|
+
}
|
683
|
+
#endif
|
684
|
+
n = FIX2INT(v);
|
685
|
+
if (0 >= n) {
|
686
|
+
copts->cache_str = 0;
|
687
|
+
} else {
|
688
|
+
if (32 < n) {
|
689
|
+
n = 32;
|
690
|
+
}
|
691
|
+
copts->cache_str = (char)n;
|
692
|
+
}
|
693
|
+
}
|
650
694
|
if (Qnil != (v = rb_hash_lookup(ropts, sec_prec_sym))) {
|
651
695
|
int n;
|
652
696
|
|
@@ -736,7 +780,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
|
|
736
780
|
if (Qnil != (v = rb_hash_lookup(ropts, compat_bigdecimal_sym))) {
|
737
781
|
copts->compat_bigdec = (Qtrue == v);
|
738
782
|
}
|
739
|
-
if (
|
783
|
+
if (oj_hash_has_key(ropts, oj_decimal_class_sym)) {
|
740
784
|
v = rb_hash_lookup(ropts, oj_decimal_class_sym);
|
741
785
|
if (rb_cFloat == v) {
|
742
786
|
copts->compat_bigdec = false;
|
@@ -746,7 +790,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
|
|
746
790
|
rb_raise(rb_eArgError, ":decimal_class must be BigDecimal or Float.");
|
747
791
|
}
|
748
792
|
}
|
749
|
-
if (
|
793
|
+
if (oj_hash_has_key(ropts, create_id_sym)) {
|
750
794
|
v = rb_hash_lookup(ropts, create_id_sym);
|
751
795
|
if (Qnil == v) {
|
752
796
|
if (oj_json_class != oj_default_options.create_id && NULL != copts->create_id) {
|
@@ -768,7 +812,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
|
|
768
812
|
}
|
769
813
|
}
|
770
814
|
for (o = ynos; 0 != o->attr; o++) {
|
771
|
-
if (
|
815
|
+
if (oj_hash_has_key(ropts, o->sym)) {
|
772
816
|
v = rb_hash_lookup(ropts, o->sym);
|
773
817
|
if (Qnil == v) {
|
774
818
|
*o->attr = NotSet;
|
@@ -783,7 +827,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
|
|
783
827
|
}
|
784
828
|
}
|
785
829
|
}
|
786
|
-
if (
|
830
|
+
if (oj_hash_has_key(ropts, oj_space_sym)) {
|
787
831
|
if (Qnil == (v = rb_hash_lookup(ropts, oj_space_sym))) {
|
788
832
|
copts->dump_opts.after_size = 0;
|
789
833
|
*copts->dump_opts.after_sep = '\0';
|
@@ -798,7 +842,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
|
|
798
842
|
copts->dump_opts.after_size = (uint8_t)len;
|
799
843
|
}
|
800
844
|
}
|
801
|
-
if (
|
845
|
+
if (oj_hash_has_key(ropts, oj_space_before_sym)) {
|
802
846
|
if (Qnil == (v = rb_hash_lookup(ropts, oj_space_before_sym))) {
|
803
847
|
copts->dump_opts.before_size = 0;
|
804
848
|
*copts->dump_opts.before_sep = '\0';
|
@@ -813,7 +857,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
|
|
813
857
|
copts->dump_opts.before_size = (uint8_t)len;
|
814
858
|
}
|
815
859
|
}
|
816
|
-
if (
|
860
|
+
if (oj_hash_has_key(ropts, oj_object_nl_sym)) {
|
817
861
|
if (Qnil == (v = rb_hash_lookup(ropts, oj_object_nl_sym))) {
|
818
862
|
copts->dump_opts.hash_size = 0;
|
819
863
|
*copts->dump_opts.hash_nl = '\0';
|
@@ -828,7 +872,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
|
|
828
872
|
copts->dump_opts.hash_size = (uint8_t)len;
|
829
873
|
}
|
830
874
|
}
|
831
|
-
if (
|
875
|
+
if (oj_hash_has_key(ropts, oj_array_nl_sym)) {
|
832
876
|
if (Qnil == (v = rb_hash_lookup(ropts, oj_array_nl_sym))) {
|
833
877
|
copts->dump_opts.array_size = 0;
|
834
878
|
*copts->dump_opts.array_nl = '\0';
|
@@ -877,7 +921,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
|
|
877
921
|
} else if (Qfalse == v) {
|
878
922
|
copts->escape_mode = JSONEsc;
|
879
923
|
}
|
880
|
-
if (
|
924
|
+
if (oj_hash_has_key(ropts, oj_hash_class_sym)) {
|
881
925
|
if (Qnil == (v = rb_hash_lookup(ropts, oj_hash_class_sym))) {
|
882
926
|
copts->hash_class = Qnil;
|
883
927
|
} else {
|
@@ -885,7 +929,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
|
|
885
929
|
copts->hash_class = v;
|
886
930
|
}
|
887
931
|
}
|
888
|
-
if (
|
932
|
+
if (oj_hash_has_key(ropts, oj_object_class_sym)) {
|
889
933
|
if (Qnil == (v = rb_hash_lookup(ropts, oj_object_class_sym))) {
|
890
934
|
copts->hash_class = Qnil;
|
891
935
|
} else {
|
@@ -893,7 +937,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
|
|
893
937
|
copts->hash_class = v;
|
894
938
|
}
|
895
939
|
}
|
896
|
-
if (
|
940
|
+
if (oj_hash_has_key(ropts, oj_array_class_sym)) {
|
897
941
|
if (Qnil == (v = rb_hash_lookup(ropts, oj_array_class_sym))) {
|
898
942
|
copts->array_class = Qnil;
|
899
943
|
} else {
|
@@ -902,7 +946,7 @@ void oj_parse_options(VALUE ropts, Options copts) {
|
|
902
946
|
}
|
903
947
|
}
|
904
948
|
oj_parse_opt_match_string(&copts->str_rx, ropts);
|
905
|
-
if (
|
949
|
+
if (oj_hash_has_key(ropts, ignore_sym)) {
|
906
950
|
xfree(copts->ignore);
|
907
951
|
copts->ignore = NULL;
|
908
952
|
if (Qnil != (v = rb_hash_lookup(ropts, ignore_sym))) {
|
@@ -1200,6 +1244,38 @@ static VALUE safe_load(VALUE self, VALUE doc) {
|
|
1200
1244
|
* - *io* [_IO__|_String_] IO Object to read from
|
1201
1245
|
*/
|
1202
1246
|
|
1247
|
+
struct dump_arg {
|
1248
|
+
struct _out *out;
|
1249
|
+
struct _options *copts;
|
1250
|
+
int argc;
|
1251
|
+
VALUE *argv;
|
1252
|
+
};
|
1253
|
+
|
1254
|
+
static VALUE dump_body(VALUE a)
|
1255
|
+
{
|
1256
|
+
volatile struct dump_arg *arg = (void *)a;
|
1257
|
+
VALUE rstr;
|
1258
|
+
|
1259
|
+
oj_dump_obj_to_json_using_params(*arg->argv, arg->copts, arg->out, arg->argc - 1, arg->argv + 1);
|
1260
|
+
if (0 == arg->out->buf) {
|
1261
|
+
rb_raise(rb_eNoMemError, "Not enough memory.");
|
1262
|
+
}
|
1263
|
+
rstr = rb_str_new2(arg->out->buf);
|
1264
|
+
rstr = oj_encode(rstr);
|
1265
|
+
|
1266
|
+
return rstr;
|
1267
|
+
}
|
1268
|
+
|
1269
|
+
static VALUE dump_ensure(VALUE a)
|
1270
|
+
{
|
1271
|
+
volatile struct dump_arg *arg = (void *)a;
|
1272
|
+
|
1273
|
+
if (arg->out->allocated) {
|
1274
|
+
xfree(arg->out->buf);
|
1275
|
+
}
|
1276
|
+
return Qnil;
|
1277
|
+
}
|
1278
|
+
|
1203
1279
|
/* Document-method: dump
|
1204
1280
|
* call-seq: dump(obj, options={})
|
1205
1281
|
*
|
@@ -1209,9 +1285,9 @@ static VALUE safe_load(VALUE self, VALUE doc) {
|
|
1209
1285
|
*/
|
1210
1286
|
static VALUE dump(int argc, VALUE *argv, VALUE self) {
|
1211
1287
|
char buf[4096];
|
1288
|
+
struct dump_arg arg;
|
1212
1289
|
struct _out out;
|
1213
1290
|
struct _options copts = oj_default_options;
|
1214
|
-
VALUE rstr;
|
1215
1291
|
|
1216
1292
|
if (1 > argc) {
|
1217
1293
|
rb_raise(rb_eArgError, "wrong number of arguments (0 for 1).");
|
@@ -1225,21 +1301,18 @@ static VALUE dump(int argc, VALUE *argv, VALUE self) {
|
|
1225
1301
|
if (CompatMode == copts.mode && copts.escape_mode != ASCIIEsc) {
|
1226
1302
|
copts.escape_mode = JSONEsc;
|
1227
1303
|
}
|
1228
|
-
out
|
1229
|
-
|
1230
|
-
|
1231
|
-
|
1232
|
-
|
1233
|
-
|
1234
|
-
|
1235
|
-
|
1236
|
-
|
1237
|
-
|
1238
|
-
|
1239
|
-
|
1240
|
-
xfree(out.buf);
|
1241
|
-
}
|
1242
|
-
return rstr;
|
1304
|
+
arg.out = &out;
|
1305
|
+
arg.copts = &copts;
|
1306
|
+
arg.argc = argc;
|
1307
|
+
arg.argv = argv;
|
1308
|
+
|
1309
|
+
arg.out->buf = buf;
|
1310
|
+
arg.out->end = buf + sizeof(buf) - 10;
|
1311
|
+
arg.out->allocated = false;
|
1312
|
+
arg.out->omit_nil = copts.dump_opts.omit_nil;
|
1313
|
+
arg.out->caller = CALLER_DUMP;
|
1314
|
+
|
1315
|
+
return rb_ensure(dump_body, (VALUE)&arg, dump_ensure, (VALUE)&arg);
|
1243
1316
|
}
|
1244
1317
|
|
1245
1318
|
/* Document-method: to_json
|
@@ -1636,13 +1709,20 @@ extern VALUE oj_optimize_rails(VALUE self);
|
|
1636
1709
|
|
1637
1710
|
/*
|
1638
1711
|
extern void oj_hash_test();
|
1639
|
-
|
1640
1712
|
static VALUE
|
1641
1713
|
hash_test(VALUE self) {
|
1642
1714
|
oj_hash_test();
|
1643
1715
|
return Qnil;
|
1644
1716
|
}
|
1645
1717
|
*/
|
1718
|
+
/*
|
1719
|
+
extern void oj_hash_sizes();
|
1720
|
+
static VALUE
|
1721
|
+
hash_test(VALUE self) {
|
1722
|
+
oj_hash_sizes();
|
1723
|
+
return Qnil;
|
1724
|
+
}
|
1725
|
+
*/
|
1646
1726
|
|
1647
1727
|
static VALUE protect_require(VALUE x) {
|
1648
1728
|
rb_require("time");
|
@@ -1741,7 +1821,6 @@ void Init_oj() {
|
|
1741
1821
|
oj_file_id = rb_intern("file?");
|
1742
1822
|
oj_fileno_id = rb_intern("fileno");
|
1743
1823
|
oj_ftype_id = rb_intern("ftype");
|
1744
|
-
oj_has_key_id = rb_intern("has_key?");
|
1745
1824
|
oj_hash_end_id = rb_intern("hash_end");
|
1746
1825
|
oj_hash_key_id = rb_intern("hash_key");
|
1747
1826
|
oj_hash_set_id = rb_intern("hash_set");
|
@@ -1816,6 +1895,10 @@ void Init_oj() {
|
|
1816
1895
|
rb_gc_register_address(&bigdecimal_load_sym);
|
1817
1896
|
bigdecimal_sym = ID2SYM(rb_intern("bigdecimal"));
|
1818
1897
|
rb_gc_register_address(&bigdecimal_sym);
|
1898
|
+
cache_keys_sym = ID2SYM(rb_intern("cache_keys"));
|
1899
|
+
rb_gc_register_address(&cache_keys_sym);
|
1900
|
+
cache_str_sym = ID2SYM(rb_intern("cache_str"));
|
1901
|
+
rb_gc_register_address(&cache_str_sym);
|
1819
1902
|
circular_sym = ID2SYM(rb_intern("circular"));
|
1820
1903
|
rb_gc_register_address(&circular_sym);
|
1821
1904
|
class_cache_sym = ID2SYM(rb_intern("class_cache"));
|