oj 3.13.7 → 3.13.23
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 +75 -0
- data/README.md +11 -0
- data/ext/oj/buf.h +4 -0
- data/ext/oj/circarray.c +1 -1
- data/ext/oj/code.c +15 -22
- data/ext/oj/compat.c +10 -10
- data/ext/oj/custom.c +66 -112
- data/ext/oj/dump.c +147 -184
- data/ext/oj/dump.h +25 -8
- data/ext/oj/dump_compat.c +47 -89
- data/ext/oj/dump_leaf.c +14 -58
- data/ext/oj/dump_object.c +72 -188
- data/ext/oj/dump_strict.c +19 -31
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/extconf.rb +5 -4
- data/ext/oj/fast.c +36 -24
- data/ext/oj/intern.c +22 -12
- data/ext/oj/intern.h +1 -1
- data/ext/oj/mimic_json.c +74 -73
- data/ext/oj/object.c +54 -72
- data/ext/oj/odd.c +83 -63
- data/ext/oj/odd.h +13 -13
- data/ext/oj/oj.c +166 -175
- data/ext/oj/oj.h +25 -3
- data/ext/oj/parse.c +123 -79
- data/ext/oj/parse.h +2 -0
- data/ext/oj/parser.c +77 -21
- data/ext/oj/parser.h +12 -0
- data/ext/oj/rails.c +46 -70
- data/ext/oj/rails.h +1 -1
- data/ext/oj/reader.c +2 -0
- data/ext/oj/saj.c +11 -23
- data/ext/oj/saj2.c +333 -85
- data/ext/oj/saj2.h +23 -0
- data/ext/oj/sparse.c +4 -0
- data/ext/oj/stream_writer.c +3 -1
- data/ext/oj/strict.c +13 -13
- data/ext/oj/string_writer.c +12 -5
- data/ext/oj/usual.c +86 -131
- data/ext/oj/usual.h +68 -0
- data/ext/oj/val_stack.c +1 -1
- data/ext/oj/validate.c +21 -26
- data/ext/oj/wab.c +22 -27
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/state.rb +1 -1
- data/lib/oj/version.rb +1 -1
- data/pages/Compatibility.md +1 -1
- data/pages/JsonGem.md +15 -0
- data/pages/Modes.md +6 -3
- data/pages/Options.md +6 -0
- data/pages/Rails.md +12 -0
- data/test/activesupport7/abstract_unit.rb +49 -0
- data/test/activesupport7/decoding_test.rb +125 -0
- data/test/activesupport7/encoding_test.rb +486 -0
- data/test/activesupport7/encoding_test_cases.rb +104 -0
- data/test/activesupport7/time_zone_test_helpers.rb +47 -0
- data/test/bar.rb +3 -8
- data/test/bug.rb +16 -0
- data/test/foo.rb +71 -7
- data/test/helper.rb +8 -2
- data/test/json_gem/json_generator_test.rb +5 -4
- data/test/json_gem/json_parser_test.rb +8 -1
- data/test/json_gem/test_helper.rb +7 -3
- data/test/perf_dump.rb +50 -0
- data/test/test_compat.rb +25 -0
- data/test/test_custom.rb +13 -2
- data/test/test_fast.rb +37 -7
- data/test/test_file.rb +23 -7
- data/test/test_gc.rb +11 -0
- data/test/test_object.rb +8 -10
- data/test/test_parser.rb +3 -19
- data/test/test_parser_debug.rb +27 -0
- data/test/test_parser_saj.rb +92 -2
- data/test/test_saj.rb +1 -1
- data/test/test_scp.rb +2 -4
- data/test/test_strict.rb +2 -0
- data/test/test_various.rb +32 -2
- data/test/test_wab.rb +2 -0
- data/test/tests.rb +9 -1
- data/test/tests_mimic.rb +9 -0
- data/test/tests_mimic_addition.rb +9 -0
- metadata +15 -115
data/ext/oj/oj.c
CHANGED
@@ -32,6 +32,7 @@ ID oj_array_append_id;
|
|
32
32
|
ID oj_array_end_id;
|
33
33
|
ID oj_array_start_id;
|
34
34
|
ID oj_as_json_id;
|
35
|
+
ID oj_at_id;
|
35
36
|
ID oj_begin_id;
|
36
37
|
ID oj_bigdecimal_id;
|
37
38
|
ID oj_end_id;
|
@@ -45,7 +46,6 @@ ID oj_hash_key_id;
|
|
45
46
|
ID oj_hash_set_id;
|
46
47
|
ID oj_hash_start_id;
|
47
48
|
ID oj_iconv_id;
|
48
|
-
ID oj_instance_variables_id;
|
49
49
|
ID oj_json_create_id;
|
50
50
|
ID oj_length_id;
|
51
51
|
ID oj_new_id;
|
@@ -90,10 +90,13 @@ VALUE oj_array_class_sym;
|
|
90
90
|
VALUE oj_create_additions_sym;
|
91
91
|
VALUE oj_decimal_class_sym;
|
92
92
|
VALUE oj_hash_class_sym;
|
93
|
+
VALUE oj_in_sym;
|
93
94
|
VALUE oj_indent_sym;
|
95
|
+
VALUE oj_nanosecond_sym;
|
94
96
|
VALUE oj_object_class_sym;
|
95
97
|
VALUE oj_quirks_mode_sym;
|
96
98
|
VALUE oj_safe_sym;
|
99
|
+
VALUE oj_symbolize_names_sym;
|
97
100
|
VALUE oj_trace_sym;
|
98
101
|
|
99
102
|
static VALUE allow_blank_sym;
|
@@ -136,6 +139,7 @@ static VALUE rails_sym;
|
|
136
139
|
static VALUE raise_sym;
|
137
140
|
static VALUE ruby_sym;
|
138
141
|
static VALUE sec_prec_sym;
|
142
|
+
static VALUE slash_sym;
|
139
143
|
static VALUE strict_sym;
|
140
144
|
static VALUE symbol_keys_sym;
|
141
145
|
static VALUE time_format_sym;
|
@@ -152,6 +156,7 @@ static VALUE xmlschema_sym;
|
|
152
156
|
static VALUE xss_safe_sym;
|
153
157
|
|
154
158
|
rb_encoding *oj_utf8_encoding = 0;
|
159
|
+
int oj_utf8_encoding_index = 0;
|
155
160
|
|
156
161
|
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
157
162
|
pthread_mutex_t oj_cache_mutex;
|
@@ -238,7 +243,7 @@ struct _options oj_default_options = {
|
|
238
243
|
*references
|
239
244
|
* - *:auto_define* [_Boolean_|_nil_] automatically define classes if they do not exist
|
240
245
|
* - *:symbol_keys* [_Boolean_|_nil_] use symbols instead of strings for hash keys
|
241
|
-
* - *:escape_mode* [_:newline_|_:json_|_:xss_safe_|_:ascii_|
|
246
|
+
* - *:escape_mode* [_:newline_|_:json_|_:slash_|_:xss_safe_|_:ascii_|_:unicode_xss_|_nil_] determines the
|
242
247
|
*characters to escape
|
243
248
|
* - *:class_cache* [_Boolean_|_nil_] cache classes for faster parsing (if dynamically modifying
|
244
249
|
*classes or reloading classes then don't use this)
|
@@ -246,7 +251,7 @@ struct _options oj_default_options = {
|
|
246
251
|
*to use for JSON
|
247
252
|
* - *:time_format* [_:unix_|_:unix_zone_|_:xmlschema_|_:ruby_] time format when dumping
|
248
253
|
* - *:bigdecimal_as_decimal* [_Boolean_|_nil_] dump BigDecimal as a decimal number or as a String
|
249
|
-
* - *:bigdecimal_load* [_:bigdecimal_|_:float_|_:auto_|_:fast_] load decimals as BigDecimal instead
|
254
|
+
* - *:bigdecimal_load* [_:bigdecimal_|_:float_|_:auto_|_:fast_|_:ruby_] load decimals as BigDecimal instead
|
250
255
|
*of as a Float. :auto pick the most precise for the number of digits. :float should be the same as
|
251
256
|
*ruby. :fast may require rounding but is must faster.
|
252
257
|
* - *:compat_bigdecimal* [_true_|_false_] load decimals as BigDecimal instead of as a Float when in
|
@@ -308,106 +313,76 @@ static VALUE get_def_opts(VALUE self) {
|
|
308
313
|
rb_hash_aset(opts, sec_prec_sym, INT2FIX(oj_default_options.sec_prec));
|
309
314
|
rb_hash_aset(opts,
|
310
315
|
circular_sym,
|
311
|
-
(Yes == oj_default_options.circular)
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
auto_define_sym,
|
321
|
-
(Yes == oj_default_options.auto_define)
|
322
|
-
? Qtrue
|
323
|
-
: ((No == oj_default_options.auto_define) ? Qfalse : Qnil));
|
316
|
+
(Yes == oj_default_options.circular) ? Qtrue : ((No == oj_default_options.circular) ? Qfalse : Qnil));
|
317
|
+
rb_hash_aset(
|
318
|
+
opts,
|
319
|
+
class_cache_sym,
|
320
|
+
(Yes == oj_default_options.class_cache) ? Qtrue : ((No == oj_default_options.class_cache) ? Qfalse : Qnil));
|
321
|
+
rb_hash_aset(
|
322
|
+
opts,
|
323
|
+
auto_define_sym,
|
324
|
+
(Yes == oj_default_options.auto_define) ? Qtrue : ((No == oj_default_options.auto_define) ? Qfalse : Qnil));
|
324
325
|
rb_hash_aset(opts,
|
325
326
|
symbol_keys_sym,
|
326
|
-
(Yes == oj_default_options.sym_key)
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
oj_create_additions_sym,
|
336
|
-
(Yes == oj_default_options.create_ok)
|
337
|
-
? Qtrue
|
338
|
-
: ((No == oj_default_options.create_ok) ? Qfalse : Qnil));
|
327
|
+
(Yes == oj_default_options.sym_key) ? Qtrue : ((No == oj_default_options.sym_key) ? Qfalse : Qnil));
|
328
|
+
rb_hash_aset(
|
329
|
+
opts,
|
330
|
+
bigdecimal_as_decimal_sym,
|
331
|
+
(Yes == oj_default_options.bigdec_as_num) ? Qtrue : ((No == oj_default_options.bigdec_as_num) ? Qfalse : Qnil));
|
332
|
+
rb_hash_aset(
|
333
|
+
opts,
|
334
|
+
oj_create_additions_sym,
|
335
|
+
(Yes == oj_default_options.create_ok) ? Qtrue : ((No == oj_default_options.create_ok) ? Qfalse : Qnil));
|
339
336
|
rb_hash_aset(opts,
|
340
337
|
use_to_json_sym,
|
341
|
-
(Yes == oj_default_options.to_json)
|
342
|
-
? Qtrue
|
343
|
-
: ((No == oj_default_options.to_json) ? Qfalse : Qnil));
|
338
|
+
(Yes == oj_default_options.to_json) ? Qtrue : ((No == oj_default_options.to_json) ? Qfalse : Qnil));
|
344
339
|
rb_hash_aset(opts,
|
345
340
|
use_to_hash_sym,
|
346
|
-
(Yes == oj_default_options.to_hash)
|
347
|
-
? Qtrue
|
348
|
-
: ((No == oj_default_options.to_hash) ? Qfalse : Qnil));
|
341
|
+
(Yes == oj_default_options.to_hash) ? Qtrue : ((No == oj_default_options.to_hash) ? Qfalse : Qnil));
|
349
342
|
rb_hash_aset(opts,
|
350
343
|
use_as_json_sym,
|
351
|
-
(Yes == oj_default_options.as_json)
|
352
|
-
? Qtrue
|
353
|
-
: ((No == oj_default_options.as_json) ? Qfalse : Qnil));
|
344
|
+
(Yes == oj_default_options.as_json) ? Qtrue : ((No == oj_default_options.as_json) ? Qfalse : Qnil));
|
354
345
|
rb_hash_aset(opts,
|
355
346
|
use_raw_json_sym,
|
356
|
-
(Yes == oj_default_options.raw_json)
|
357
|
-
? Qtrue
|
358
|
-
: ((No == oj_default_options.raw_json) ? Qfalse : Qnil));
|
347
|
+
(Yes == oj_default_options.raw_json) ? Qtrue : ((No == oj_default_options.raw_json) ? Qfalse : Qnil));
|
359
348
|
rb_hash_aset(opts,
|
360
349
|
nilnil_sym,
|
361
|
-
(Yes == oj_default_options.nilnil)
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
(Yes == oj_default_options.empty_string)
|
367
|
-
? Qtrue
|
368
|
-
: ((No == oj_default_options.empty_string) ? Qfalse : Qnil));
|
350
|
+
(Yes == oj_default_options.nilnil) ? Qtrue : ((No == oj_default_options.nilnil) ? Qfalse : Qnil));
|
351
|
+
rb_hash_aset(
|
352
|
+
opts,
|
353
|
+
empty_string_sym,
|
354
|
+
(Yes == oj_default_options.empty_string) ? Qtrue : ((No == oj_default_options.empty_string) ? Qfalse : Qnil));
|
369
355
|
rb_hash_aset(opts,
|
370
356
|
allow_gc_sym,
|
371
|
-
(Yes == oj_default_options.allow_gc)
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
rb_hash_aset(opts,
|
385
|
-
oj_allow_nan_sym,
|
386
|
-
(Yes == oj_default_options.allow_nan)
|
387
|
-
? Qtrue
|
388
|
-
: ((No == oj_default_options.allow_nan) ? Qfalse : Qnil));
|
357
|
+
(Yes == oj_default_options.allow_gc) ? Qtrue : ((No == oj_default_options.allow_gc) ? Qfalse : Qnil));
|
358
|
+
rb_hash_aset(
|
359
|
+
opts,
|
360
|
+
oj_quirks_mode_sym,
|
361
|
+
(Yes == oj_default_options.quirks_mode) ? Qtrue : ((No == oj_default_options.quirks_mode) ? Qfalse : Qnil));
|
362
|
+
rb_hash_aset(
|
363
|
+
opts,
|
364
|
+
allow_invalid_unicode_sym,
|
365
|
+
(Yes == oj_default_options.allow_invalid) ? Qtrue : ((No == oj_default_options.allow_invalid) ? Qfalse : Qnil));
|
366
|
+
rb_hash_aset(
|
367
|
+
opts,
|
368
|
+
oj_allow_nan_sym,
|
369
|
+
(Yes == oj_default_options.allow_nan) ? Qtrue : ((No == oj_default_options.allow_nan) ? Qfalse : Qnil));
|
389
370
|
rb_hash_aset(opts,
|
390
371
|
oj_trace_sym,
|
391
|
-
(Yes == oj_default_options.trace)
|
392
|
-
? Qtrue
|
393
|
-
: ((No == oj_default_options.trace) ? Qfalse : Qnil));
|
372
|
+
(Yes == oj_default_options.trace) ? Qtrue : ((No == oj_default_options.trace) ? Qfalse : Qnil));
|
394
373
|
rb_hash_aset(opts,
|
395
374
|
oj_safe_sym,
|
396
|
-
(Yes == oj_default_options.safe)
|
397
|
-
? Qtrue
|
398
|
-
: ((No == oj_default_options.safe) ? Qfalse : Qnil));
|
375
|
+
(Yes == oj_default_options.safe) ? Qtrue : ((No == oj_default_options.safe) ? Qfalse : Qnil));
|
399
376
|
rb_hash_aset(opts, float_prec_sym, INT2FIX(oj_default_options.float_prec));
|
400
377
|
rb_hash_aset(opts, cache_str_sym, INT2FIX(oj_default_options.cache_str));
|
401
|
-
rb_hash_aset(
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
? Qtrue
|
410
|
-
: ((No == oj_default_options.cache_keys) ? Qfalse : Qnil));
|
378
|
+
rb_hash_aset(
|
379
|
+
opts,
|
380
|
+
ignore_under_sym,
|
381
|
+
(Yes == oj_default_options.ignore_under) ? Qtrue : ((No == oj_default_options.ignore_under) ? Qfalse : Qnil));
|
382
|
+
rb_hash_aset(
|
383
|
+
opts,
|
384
|
+
cache_keys_sym,
|
385
|
+
(Yes == oj_default_options.cache_keys) ? Qtrue : ((No == oj_default_options.cache_keys) ? Qfalse : Qnil));
|
411
386
|
switch (oj_default_options.mode) {
|
412
387
|
case StrictMode: rb_hash_aset(opts, mode_sym, strict_sym); break;
|
413
388
|
case CompatMode: rb_hash_aset(opts, mode_sym, compat_sym); break;
|
@@ -433,6 +408,7 @@ static VALUE get_def_opts(VALUE self) {
|
|
433
408
|
switch (oj_default_options.escape_mode) {
|
434
409
|
case NLEsc: rb_hash_aset(opts, escape_mode_sym, newline_sym); break;
|
435
410
|
case JSONEsc: rb_hash_aset(opts, escape_mode_sym, json_sym); break;
|
411
|
+
case SlashEsc: rb_hash_aset(opts, escape_mode_sym, slash_sym); break;
|
436
412
|
case XSSEsc: rb_hash_aset(opts, escape_mode_sym, xss_safe_sym); break;
|
437
413
|
case ASCIIEsc: rb_hash_aset(opts, escape_mode_sym, ascii_sym); break;
|
438
414
|
case JXEsc: rb_hash_aset(opts, escape_mode_sym, unicode_xss_sym); break;
|
@@ -453,30 +429,25 @@ static VALUE get_def_opts(VALUE self) {
|
|
453
429
|
default: rb_hash_aset(opts, bigdecimal_load_sym, auto_sym); break;
|
454
430
|
}
|
455
431
|
rb_hash_aset(opts, compat_bigdecimal_sym, oj_default_options.compat_bigdec ? Qtrue : Qfalse);
|
432
|
+
rb_hash_aset(opts,
|
433
|
+
create_id_sym,
|
434
|
+
(NULL == oj_default_options.create_id) ? Qnil : rb_str_new2(oj_default_options.create_id));
|
456
435
|
rb_hash_aset(
|
457
436
|
opts,
|
458
|
-
|
459
|
-
(
|
460
|
-
rb_hash_aset(
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
(0 == oj_default_options.dump_opts.hash_size)
|
473
|
-
? Qnil
|
474
|
-
: rb_str_new2(oj_default_options.dump_opts.hash_nl));
|
475
|
-
rb_hash_aset(opts,
|
476
|
-
oj_array_nl_sym,
|
477
|
-
(0 == oj_default_options.dump_opts.array_size)
|
478
|
-
? Qnil
|
479
|
-
: rb_str_new2(oj_default_options.dump_opts.array_nl));
|
437
|
+
oj_space_sym,
|
438
|
+
(0 == oj_default_options.dump_opts.after_size) ? Qnil : rb_str_new2(oj_default_options.dump_opts.after_sep));
|
439
|
+
rb_hash_aset(
|
440
|
+
opts,
|
441
|
+
oj_space_before_sym,
|
442
|
+
(0 == oj_default_options.dump_opts.before_size) ? Qnil : rb_str_new2(oj_default_options.dump_opts.before_sep));
|
443
|
+
rb_hash_aset(
|
444
|
+
opts,
|
445
|
+
oj_object_nl_sym,
|
446
|
+
(0 == oj_default_options.dump_opts.hash_size) ? Qnil : rb_str_new2(oj_default_options.dump_opts.hash_nl));
|
447
|
+
rb_hash_aset(
|
448
|
+
opts,
|
449
|
+
oj_array_nl_sym,
|
450
|
+
(0 == oj_default_options.dump_opts.array_size) ? Qnil : rb_str_new2(oj_default_options.dump_opts.array_nl));
|
480
451
|
|
481
452
|
switch (oj_default_options.dump_opts.nan_dump) {
|
482
453
|
case NullNan: rb_hash_aset(opts, nan_sym, null_sym); break;
|
@@ -584,16 +555,14 @@ static VALUE set_def_opts(VALUE self, VALUE opts) {
|
|
584
555
|
return Qnil;
|
585
556
|
}
|
586
557
|
|
587
|
-
bool oj_hash_has_key(VALUE hash, VALUE key)
|
588
|
-
{
|
558
|
+
bool oj_hash_has_key(VALUE hash, VALUE key) {
|
589
559
|
if (Qundef == rb_hash_lookup2(hash, key, Qundef)) {
|
590
560
|
return false;
|
591
561
|
}
|
592
562
|
return true;
|
593
563
|
}
|
594
564
|
|
595
|
-
bool set_yesno_options(VALUE key, VALUE value, Options copts)
|
596
|
-
{
|
565
|
+
bool set_yesno_options(VALUE key, VALUE value, Options copts) {
|
597
566
|
struct _yesNoOpt ynos[] = {{circular_sym, &copts->circular},
|
598
567
|
{auto_define_sym, &copts->auto_define},
|
599
568
|
{symbol_keys_sym, &copts->sym_key},
|
@@ -616,29 +585,26 @@ bool set_yesno_options(VALUE key, VALUE value, Options copts)
|
|
616
585
|
{oj_create_additions_sym, &copts->create_ok},
|
617
586
|
{cache_keys_sym, &copts->cache_keys},
|
618
587
|
{Qnil, 0}};
|
619
|
-
YesNoOpt
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
}
|
636
|
-
}
|
588
|
+
YesNoOpt o;
|
589
|
+
|
590
|
+
for (o = ynos; 0 != o->attr; o++) {
|
591
|
+
if (key == o->sym) {
|
592
|
+
if (Qnil == value) {
|
593
|
+
*o->attr = NotSet;
|
594
|
+
} else if (Qtrue == value) {
|
595
|
+
*o->attr = Yes;
|
596
|
+
} else if (Qfalse == value) {
|
597
|
+
*o->attr = No;
|
598
|
+
} else {
|
599
|
+
rb_raise(rb_eArgError, "%s must be true, false, or nil.", rb_id2name(key));
|
600
|
+
}
|
601
|
+
return true;
|
602
|
+
}
|
603
|
+
}
|
637
604
|
return false;
|
638
605
|
}
|
639
606
|
|
640
|
-
static int parse_options_cb(VALUE k, VALUE v, VALUE opts)
|
641
|
-
{
|
607
|
+
static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
642
608
|
Options copts = (Options)opts;
|
643
609
|
size_t len;
|
644
610
|
|
@@ -753,8 +719,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts)
|
|
753
719
|
} else if (rails_sym == v) {
|
754
720
|
copts->mode = RailsMode;
|
755
721
|
} else {
|
756
|
-
rb_raise(rb_eArgError,
|
757
|
-
":mode must be :object, :strict, :compat, :null, :custom, :rails, or :wab.");
|
722
|
+
rb_raise(rb_eArgError, ":mode must be :object, :strict, :compat, :null, :custom, :rails, or :wab.");
|
758
723
|
}
|
759
724
|
} else if (time_format_sym == k) {
|
760
725
|
if (unix_sym == v) {
|
@@ -773,6 +738,8 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts)
|
|
773
738
|
copts->escape_mode = NLEsc;
|
774
739
|
} else if (json_sym == v) {
|
775
740
|
copts->escape_mode = JSONEsc;
|
741
|
+
} else if (slash_sym == v) {
|
742
|
+
copts->escape_mode = SlashEsc;
|
776
743
|
} else if (xss_safe_sym == v) {
|
777
744
|
copts->escape_mode = XSSEsc;
|
778
745
|
} else if (ascii_sym == v) {
|
@@ -780,8 +747,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts)
|
|
780
747
|
} else if (unicode_xss_sym == v) {
|
781
748
|
copts->escape_mode = JXEsc;
|
782
749
|
} else {
|
783
|
-
rb_raise(rb_eArgError,
|
784
|
-
":encoding must be :newline, :json, :xss_safe, :unicode_xss, or :ascii.");
|
750
|
+
rb_raise(rb_eArgError, ":encoding must be :newline, :json, :xss_safe, :unicode_xss, or :ascii.");
|
785
751
|
}
|
786
752
|
} else if (bigdecimal_load_sym == k) {
|
787
753
|
if (Qnil == v) {
|
@@ -892,7 +858,6 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts)
|
|
892
858
|
if (Qnil == v) {
|
893
859
|
return ST_CONTINUE;
|
894
860
|
}
|
895
|
-
|
896
861
|
if (null_sym == v) {
|
897
862
|
copts->dump_opts.nan_dump = NullNan;
|
898
863
|
} else if (huge_sym == v) {
|
@@ -910,7 +875,6 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts)
|
|
910
875
|
if (Qnil == v) {
|
911
876
|
return ST_CONTINUE;
|
912
877
|
}
|
913
|
-
|
914
878
|
if (Qtrue == v) {
|
915
879
|
copts->dump_opts.omit_nil = true;
|
916
880
|
} else if (Qfalse == v) {
|
@@ -918,7 +882,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts)
|
|
918
882
|
} else {
|
919
883
|
rb_raise(rb_eArgError, ":omit_nil must be true or false.");
|
920
884
|
}
|
921
|
-
} else if(oj_ascii_only_sym == k) {
|
885
|
+
} else if (oj_ascii_only_sym == k) {
|
922
886
|
// This is here only for backwards compatibility with the original Oj.
|
923
887
|
if (Qtrue == v) {
|
924
888
|
copts->escape_mode = ASCIIEsc;
|
@@ -959,7 +923,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts)
|
|
959
923
|
|
960
924
|
copts->ignore = ALLOC_N(VALUE, cnt + 1);
|
961
925
|
for (i = 0; i < cnt; i++) {
|
962
|
-
copts->ignore[i] =
|
926
|
+
copts->ignore[i] = RARRAY_AREF(v, i);
|
963
927
|
}
|
964
928
|
copts->ignore[i] = Qnil;
|
965
929
|
}
|
@@ -968,8 +932,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts)
|
|
968
932
|
if (Qnil == v) {
|
969
933
|
return ST_CONTINUE;
|
970
934
|
}
|
971
|
-
|
972
|
-
if (TYPE(v) == T_STRUCT && rb_obj_class(v) == rb_cRange) {
|
935
|
+
if (rb_obj_class(v) == rb_cRange) {
|
973
936
|
VALUE min = rb_funcall(v, oj_begin_id, 0);
|
974
937
|
VALUE max = rb_funcall(v, oj_end_id, 0);
|
975
938
|
|
@@ -982,8 +945,12 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts)
|
|
982
945
|
} else if (Qfalse != v) {
|
983
946
|
rb_raise(rb_eArgError, ":integer_range must be a range of Fixnum.");
|
984
947
|
}
|
948
|
+
} else if (symbol_keys_sym == k || oj_symbolize_names_sym == k) {
|
949
|
+
if (Qnil == v) {
|
950
|
+
return ST_CONTINUE;
|
951
|
+
}
|
952
|
+
copts->sym_key = (Qtrue == v) ? Yes : No;
|
985
953
|
}
|
986
|
-
|
987
954
|
return ST_CONTINUE;
|
988
955
|
}
|
989
956
|
|
@@ -1014,9 +981,7 @@ static int match_string_cb(VALUE key, VALUE value, VALUE rx) {
|
|
1014
981
|
rb_raise(rb_eArgError, "%s", rc->err);
|
1015
982
|
}
|
1016
983
|
break;
|
1017
|
-
default:
|
1018
|
-
rb_raise(rb_eArgError, "for :match_string, keys must either a String or RegExp.");
|
1019
|
-
break;
|
984
|
+
default: rb_raise(rb_eArgError, "for :match_string, keys must either a String or RegExp."); break;
|
1020
985
|
}
|
1021
986
|
return ST_CONTINUE;
|
1022
987
|
}
|
@@ -1184,14 +1149,22 @@ static VALUE load_file(int argc, VALUE *argv, VALUE self) {
|
|
1184
1149
|
} else if (wab_sym == v) {
|
1185
1150
|
mode = WabMode;
|
1186
1151
|
} else {
|
1187
|
-
rb_raise(
|
1188
|
-
rb_eArgError,
|
1189
|
-
":mode must be :object, :strict, :compat, :null, :custom, :rails, or :wab.");
|
1152
|
+
rb_raise(rb_eArgError, ":mode must be :object, :strict, :compat, :null, :custom, :rails, or :wab.");
|
1190
1153
|
}
|
1191
1154
|
}
|
1192
1155
|
}
|
1193
1156
|
path = StringValuePtr(*argv);
|
1194
|
-
|
1157
|
+
#ifdef _WIN32
|
1158
|
+
{
|
1159
|
+
WCHAR *wide_path;
|
1160
|
+
wide_path = rb_w32_mbstr_to_wstr(CP_UTF8, path, -1, NULL);
|
1161
|
+
fd = rb_w32_wopen(wide_path, O_RDONLY);
|
1162
|
+
free(wide_path);
|
1163
|
+
}
|
1164
|
+
#else
|
1165
|
+
fd = open(path, O_RDONLY);
|
1166
|
+
#endif
|
1167
|
+
if (0 == fd) {
|
1195
1168
|
rb_raise(rb_eIOError, "%s", strerror(errno));
|
1196
1169
|
}
|
1197
1170
|
switch (mode) {
|
@@ -1264,16 +1237,15 @@ static VALUE safe_load(VALUE self, VALUE doc) {
|
|
1264
1237
|
*/
|
1265
1238
|
|
1266
1239
|
struct dump_arg {
|
1267
|
-
struct _out
|
1240
|
+
struct _out * out;
|
1268
1241
|
struct _options *copts;
|
1269
|
-
int
|
1270
|
-
VALUE *argv;
|
1242
|
+
int argc;
|
1243
|
+
VALUE * argv;
|
1271
1244
|
};
|
1272
1245
|
|
1273
|
-
static VALUE dump_body(VALUE a)
|
1274
|
-
{
|
1246
|
+
static VALUE dump_body(VALUE a) {
|
1275
1247
|
volatile struct dump_arg *arg = (void *)a;
|
1276
|
-
VALUE
|
1248
|
+
VALUE rstr;
|
1277
1249
|
|
1278
1250
|
oj_dump_obj_to_json_using_params(*arg->argv, arg->copts, arg->out, arg->argc - 1, arg->argv + 1);
|
1279
1251
|
if (0 == arg->out->buf) {
|
@@ -1285,13 +1257,11 @@ static VALUE dump_body(VALUE a)
|
|
1285
1257
|
return rstr;
|
1286
1258
|
}
|
1287
1259
|
|
1288
|
-
static VALUE dump_ensure(VALUE a)
|
1289
|
-
{
|
1260
|
+
static VALUE dump_ensure(VALUE a) {
|
1290
1261
|
volatile struct dump_arg *arg = (void *)a;
|
1291
1262
|
|
1292
|
-
|
1293
|
-
|
1294
|
-
}
|
1263
|
+
oj_out_free(arg->out);
|
1264
|
+
|
1295
1265
|
return Qnil;
|
1296
1266
|
}
|
1297
1267
|
|
@@ -1303,7 +1273,6 @@ static VALUE dump_ensure(VALUE a)
|
|
1303
1273
|
* - *options* [_Hash_] same as default_options
|
1304
1274
|
*/
|
1305
1275
|
static VALUE dump(int argc, VALUE *argv, VALUE self) {
|
1306
|
-
char buf[4096];
|
1307
1276
|
struct dump_arg arg;
|
1308
1277
|
struct _out out;
|
1309
1278
|
struct _options copts = oj_default_options;
|
@@ -1320,14 +1289,13 @@ static VALUE dump(int argc, VALUE *argv, VALUE self) {
|
|
1320
1289
|
if (CompatMode == copts.mode && copts.escape_mode != ASCIIEsc) {
|
1321
1290
|
copts.escape_mode = JSONEsc;
|
1322
1291
|
}
|
1323
|
-
arg.out
|
1292
|
+
arg.out = &out;
|
1324
1293
|
arg.copts = &copts;
|
1325
|
-
arg.argc
|
1326
|
-
arg.argv
|
1294
|
+
arg.argc = argc;
|
1295
|
+
arg.argv = argv;
|
1296
|
+
|
1297
|
+
oj_out_init(arg.out);
|
1327
1298
|
|
1328
|
-
arg.out->buf = buf;
|
1329
|
-
arg.out->end = buf + sizeof(buf) - 10;
|
1330
|
-
arg.out->allocated = false;
|
1331
1299
|
arg.out->omit_nil = copts.dump_opts.omit_nil;
|
1332
1300
|
arg.out->caller = CALLER_DUMP;
|
1333
1301
|
|
@@ -1359,7 +1327,6 @@ static VALUE dump(int argc, VALUE *argv, VALUE self) {
|
|
1359
1327
|
* Returns [_String_] the encoded JSON.
|
1360
1328
|
*/
|
1361
1329
|
static VALUE to_json(int argc, VALUE *argv, VALUE self) {
|
1362
|
-
char buf[4096];
|
1363
1330
|
struct _out out;
|
1364
1331
|
struct _options copts = oj_default_options;
|
1365
1332
|
VALUE rstr;
|
@@ -1374,9 +1341,9 @@ static VALUE to_json(int argc, VALUE *argv, VALUE self) {
|
|
1374
1341
|
}
|
1375
1342
|
copts.mode = CompatMode;
|
1376
1343
|
copts.to_json = Yes;
|
1377
|
-
|
1378
|
-
out
|
1379
|
-
|
1344
|
+
|
1345
|
+
oj_out_init(&out);
|
1346
|
+
|
1380
1347
|
out.omit_nil = copts.dump_opts.omit_nil;
|
1381
1348
|
// For obj.to_json or generate nan is not allowed but if called from dump
|
1382
1349
|
// it is.
|
@@ -1387,9 +1354,9 @@ static VALUE to_json(int argc, VALUE *argv, VALUE self) {
|
|
1387
1354
|
}
|
1388
1355
|
rstr = rb_str_new2(out.buf);
|
1389
1356
|
rstr = oj_encode(rstr);
|
1390
|
-
|
1391
|
-
|
1392
|
-
|
1357
|
+
|
1358
|
+
oj_out_free(&out);
|
1359
|
+
|
1393
1360
|
return rstr;
|
1394
1361
|
}
|
1395
1362
|
|
@@ -1749,6 +1716,15 @@ static VALUE protect_require(VALUE x) {
|
|
1749
1716
|
return Qnil;
|
1750
1717
|
}
|
1751
1718
|
|
1719
|
+
extern void print_all_odds(const char *label);
|
1720
|
+
|
1721
|
+
static VALUE
|
1722
|
+
debug_odd(VALUE self, VALUE label) {
|
1723
|
+
print_all_odds(RSTRING_PTR(label));
|
1724
|
+
return Qnil;
|
1725
|
+
}
|
1726
|
+
|
1727
|
+
|
1752
1728
|
/* Document-module: Oj
|
1753
1729
|
*
|
1754
1730
|
* Optimized JSON (Oj), as the name implies was written to provide speed
|
@@ -1777,15 +1753,19 @@ static VALUE protect_require(VALUE x) {
|
|
1777
1753
|
*
|
1778
1754
|
* - *:wab* specifically for WAB data exchange.
|
1779
1755
|
*/
|
1780
|
-
void Init_oj() {
|
1756
|
+
void Init_oj(void) {
|
1781
1757
|
int err = 0;
|
1782
1758
|
|
1783
1759
|
#if HAVE_RB_EXT_RACTOR_SAFE
|
1784
1760
|
rb_ext_ractor_safe(true);
|
1785
1761
|
#endif
|
1786
1762
|
Oj = rb_define_module("Oj");
|
1763
|
+
rb_gc_register_address(&Oj);
|
1787
1764
|
|
1788
1765
|
oj_cstack_class = rb_define_class_under(Oj, "CStack", rb_cObject);
|
1766
|
+
rb_gc_register_address(&oj_cstack_class);
|
1767
|
+
|
1768
|
+
rb_undef_alloc_func(oj_cstack_class);
|
1789
1769
|
|
1790
1770
|
oj_string_writer_init();
|
1791
1771
|
oj_stream_writer_init();
|
@@ -1794,9 +1774,11 @@ void Init_oj() {
|
|
1794
1774
|
// On Rubinius the require fails but can be done from a ruby file.
|
1795
1775
|
rb_protect(protect_require, Qnil, &err);
|
1796
1776
|
rb_require("stringio");
|
1797
|
-
|
1777
|
+
oj_utf8_encoding_index = rb_enc_find_index("UTF-8");
|
1778
|
+
oj_utf8_encoding = rb_enc_from_index(oj_utf8_encoding_index);
|
1798
1779
|
|
1799
1780
|
// rb_define_module_function(Oj, "hash_test", hash_test, 0);
|
1781
|
+
rb_define_module_function(Oj, "debug_odd", debug_odd, 1);
|
1800
1782
|
|
1801
1783
|
rb_define_module_function(Oj, "default_options", get_def_opts, 0);
|
1802
1784
|
rb_define_module_function(Oj, "default_options=", set_def_opts, 1);
|
@@ -1835,6 +1817,7 @@ void Init_oj() {
|
|
1835
1817
|
oj_array_end_id = rb_intern("array_end");
|
1836
1818
|
oj_array_start_id = rb_intern("array_start");
|
1837
1819
|
oj_as_json_id = rb_intern("as_json");
|
1820
|
+
oj_at_id = rb_intern("at");
|
1838
1821
|
oj_begin_id = rb_intern("begin");
|
1839
1822
|
oj_bigdecimal_id = rb_intern("BigDecimal");
|
1840
1823
|
oj_end_id = rb_intern("end");
|
@@ -1848,7 +1831,6 @@ void Init_oj() {
|
|
1848
1831
|
oj_hash_set_id = rb_intern("hash_set");
|
1849
1832
|
oj_hash_start_id = rb_intern("hash_start");
|
1850
1833
|
oj_iconv_id = rb_intern("iconv");
|
1851
|
-
oj_instance_variables_id = rb_intern("instance_variables");
|
1852
1834
|
oj_json_create_id = rb_intern("json_create");
|
1853
1835
|
oj_length_id = rb_intern("length");
|
1854
1836
|
oj_new_id = rb_intern("new");
|
@@ -1983,10 +1965,14 @@ void Init_oj() {
|
|
1983
1965
|
rb_gc_register_address(&oj_decimal_class_sym);
|
1984
1966
|
oj_hash_class_sym = ID2SYM(rb_intern("hash_class"));
|
1985
1967
|
rb_gc_register_address(&oj_hash_class_sym);
|
1968
|
+
oj_in_sym = ID2SYM(rb_intern("in"));
|
1969
|
+
rb_gc_register_address(&oj_in_sym);
|
1986
1970
|
oj_indent_sym = ID2SYM(rb_intern("indent"));
|
1987
1971
|
rb_gc_register_address(&oj_indent_sym);
|
1988
1972
|
oj_max_nesting_sym = ID2SYM(rb_intern("max_nesting"));
|
1989
1973
|
rb_gc_register_address(&oj_max_nesting_sym);
|
1974
|
+
oj_nanosecond_sym = ID2SYM(rb_intern("nanosecond"));
|
1975
|
+
rb_gc_register_address(&oj_nanosecond_sym);
|
1990
1976
|
oj_object_class_sym = ID2SYM(rb_intern("object_class"));
|
1991
1977
|
rb_gc_register_address(&oj_object_class_sym);
|
1992
1978
|
oj_object_nl_sym = ID2SYM(rb_intern("object_nl"));
|
@@ -2011,10 +1997,14 @@ void Init_oj() {
|
|
2011
1997
|
rb_gc_register_address(&ruby_sym);
|
2012
1998
|
sec_prec_sym = ID2SYM(rb_intern("second_precision"));
|
2013
1999
|
rb_gc_register_address(&sec_prec_sym);
|
2000
|
+
slash_sym = ID2SYM(rb_intern("slash"));
|
2001
|
+
rb_gc_register_address(&slash_sym);
|
2014
2002
|
strict_sym = ID2SYM(rb_intern("strict"));
|
2015
2003
|
rb_gc_register_address(&strict_sym);
|
2016
2004
|
symbol_keys_sym = ID2SYM(rb_intern("symbol_keys"));
|
2017
2005
|
rb_gc_register_address(&symbol_keys_sym);
|
2006
|
+
oj_symbolize_names_sym = ID2SYM(rb_intern("symbolize_names"));
|
2007
|
+
rb_gc_register_address(&oj_symbolize_names_sym);
|
2018
2008
|
time_format_sym = ID2SYM(rb_intern("time_format"));
|
2019
2009
|
rb_gc_register_address(&time_format_sym);
|
2020
2010
|
unicode_xss_sym = ID2SYM(rb_intern("unicode_xss"));
|
@@ -2061,4 +2051,5 @@ void Init_oj() {
|
|
2061
2051
|
oj_init_doc();
|
2062
2052
|
|
2063
2053
|
oj_parser_init();
|
2054
|
+
oj_scanner_init();
|
2064
2055
|
}
|