oj 3.14.3 → 3.15.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 +10 -0
- data/ext/oj/code.c +3 -10
- data/ext/oj/compat.c +5 -18
- data/ext/oj/custom.c +10 -28
- data/ext/oj/dump.c +40 -10
- data/ext/oj/dump.h +1 -4
- data/ext/oj/extconf.rb +4 -2
- data/ext/oj/fast.c +3 -6
- data/ext/oj/mimic_json.c +21 -1
- data/ext/oj/object.c +7 -21
- data/ext/oj/oj.c +24 -4
- data/ext/oj/oj.h +10 -6
- data/ext/oj/parse.c +3 -5
- data/ext/oj/parse.h +16 -14
- data/ext/oj/parser.h +2 -2
- data/ext/oj/reader.c +1 -3
- data/ext/oj/saj.c +1 -1
- data/ext/oj/strict.c +9 -27
- data/ext/oj/wab.c +9 -27
- data/lib/oj/active_support_helper.rb +2 -3
- data/lib/oj/json.rb +156 -149
- data/lib/oj/mimic.rb +3 -1
- data/lib/oj/version.rb +1 -1
- data/lib/oj.rb +3 -0
- data/pages/Options.md +4 -0
- data/test/_test_active.rb +8 -8
- data/test/_test_active_mimic.rb +7 -7
- data/test/_test_mimic_rails.rb +17 -19
- data/test/files.rb +14 -14
- data/test/foo.rb +15 -10
- data/test/helper.rb +4 -4
- data/test/mem.rb +8 -7
- data/test/perf.rb +21 -26
- data/test/perf_compat.rb +30 -32
- data/test/perf_dump.rb +27 -27
- data/test/perf_fast.rb +80 -82
- data/test/perf_file.rb +27 -29
- data/test/perf_object.rb +65 -68
- data/test/perf_once.rb +8 -7
- data/test/perf_parser.rb +40 -46
- data/test/perf_saj.rb +46 -53
- data/test/perf_scp.rb +57 -69
- data/test/perf_simple.rb +40 -38
- data/test/perf_strict.rb +68 -70
- data/test/perf_wab.rb +67 -69
- data/test/prec.rb +3 -3
- data/test/sample.rb +16 -15
- data/test/sample_json.rb +8 -7
- data/test/test_compat.rb +44 -46
- data/test/test_custom.rb +56 -42
- data/test/test_debian.rb +6 -9
- data/test/test_fast.rb +78 -72
- data/test/test_file.rb +16 -21
- data/test/test_gc.rb +5 -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 +18 -20
- data/test/test_object.rb +76 -86
- data/test/test_parser.rb +4 -4
- data/test/test_parser_debug.rb +4 -4
- data/test/test_parser_saj.rb +31 -31
- data/test/test_parser_usual.rb +3 -3
- data/test/test_rails.rb +2 -2
- data/test/test_saj.rb +8 -8
- data/test/test_scp.rb +29 -29
- data/test/test_strict.rb +25 -31
- data/test/test_various.rb +121 -75
- data/test/test_wab.rb +43 -42
- data/test/test_writer.rb +46 -46
- data/test/tests.rb +7 -7
- data/test/tests_mimic.rb +6 -6
- data/test/tests_mimic_addition.rb +6 -6
- metadata +3 -6
- data/test/bar.rb +0 -11
- data/test/baz.rb +0 -16
- data/test/bug.rb +0 -16
- data/test/zoo.rb +0 -13
data/ext/oj/parse.h
CHANGED
@@ -16,22 +16,24 @@
|
|
16
16
|
#include "val_stack.h"
|
17
17
|
|
18
18
|
struct _rxClass;
|
19
|
+
struct _parseInfo;
|
19
20
|
|
20
21
|
typedef struct _numInfo {
|
21
|
-
int64_t
|
22
|
-
int64_t
|
23
|
-
int64_t
|
24
|
-
int64_t
|
25
|
-
const char
|
26
|
-
size_t
|
27
|
-
long
|
28
|
-
|
29
|
-
int
|
30
|
-
int
|
31
|
-
int
|
32
|
-
int
|
33
|
-
int
|
34
|
-
int
|
22
|
+
int64_t i;
|
23
|
+
int64_t num;
|
24
|
+
int64_t div;
|
25
|
+
int64_t di;
|
26
|
+
const char *str;
|
27
|
+
size_t len;
|
28
|
+
long exp;
|
29
|
+
struct _parseInfo *pi;
|
30
|
+
int big;
|
31
|
+
int infinity;
|
32
|
+
int nan;
|
33
|
+
int neg;
|
34
|
+
int has_exp;
|
35
|
+
int no_big;
|
36
|
+
int bigdec_load;
|
35
37
|
} *NumInfo;
|
36
38
|
|
37
39
|
typedef struct _parseInfo {
|
data/ext/oj/parser.h
CHANGED
@@ -32,9 +32,9 @@ typedef struct _num {
|
|
32
32
|
long double dub;
|
33
33
|
int64_t fixnum; // holds all digits
|
34
34
|
uint32_t len;
|
35
|
-
int16_t div;
|
35
|
+
int16_t div; // 10^div
|
36
36
|
int16_t exp;
|
37
|
-
uint8_t shift;
|
37
|
+
uint8_t shift; // shift of fixnum to get decimal
|
38
38
|
bool neg;
|
39
39
|
bool exp_neg;
|
40
40
|
// for numbers as strings, reuse buf
|
data/ext/oj/reader.c
CHANGED
@@ -101,7 +101,7 @@ int oj_reader_read(Reader reader) {
|
|
101
101
|
} else {
|
102
102
|
shift = reader->pro - reader->head - 1; // leave one character so we can backup one
|
103
103
|
}
|
104
|
-
if (0 >= shift) {
|
104
|
+
if (0 >= shift) { /* no space left so allocate more */
|
105
105
|
const char *old = reader->head;
|
106
106
|
size_t size = reader->end - reader->head + BUF_PAD;
|
107
107
|
|
@@ -164,7 +164,6 @@ static VALUE partial_io_cb(VALUE rbuf) {
|
|
164
164
|
}
|
165
165
|
str = StringValuePtr(rstr);
|
166
166
|
cnt = RSTRING_LEN(rstr);
|
167
|
-
// printf("*** partial read %lu bytes, str: '%s'\n", cnt, str);
|
168
167
|
strcpy(reader->tail, str);
|
169
168
|
reader->read_end = reader->tail + cnt;
|
170
169
|
|
@@ -185,7 +184,6 @@ static VALUE io_cb(VALUE rbuf) {
|
|
185
184
|
}
|
186
185
|
str = StringValuePtr(rstr);
|
187
186
|
cnt = RSTRING_LEN(rstr);
|
188
|
-
// printf("*** read %lu bytes, str: '%s'\n", cnt, str);
|
189
187
|
strcpy(reader->tail, str);
|
190
188
|
reader->read_end = reader->tail + cnt;
|
191
189
|
|
data/ext/oj/saj.c
CHANGED
@@ -587,7 +587,7 @@ static void saj_parse(VALUE handler, char *json) {
|
|
587
587
|
if (0 == getrlimit(RLIMIT_STACK, &lim) && RLIM_INFINITY != lim.rlim_cur) {
|
588
588
|
pi.stack_min = (void *)((char *)&obj - (lim.rlim_cur / 4 * 3)); /* let 3/4ths of the stack be used only */
|
589
589
|
} else {
|
590
|
-
pi.stack_min = 0;
|
590
|
+
pi.stack_min = 0; /* indicates not to check stack limit */
|
591
591
|
}
|
592
592
|
}
|
593
593
|
#endif
|
data/ext/oj/strict.c
CHANGED
@@ -62,9 +62,7 @@ static VALUE noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
|
|
62
62
|
}
|
63
63
|
|
64
64
|
static void add_value(ParseInfo pi, VALUE val) {
|
65
|
-
|
66
|
-
oj_trace_parse_call("add_value", pi, __FILE__, __LINE__, val);
|
67
|
-
}
|
65
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_value", pi, val);
|
68
66
|
pi->stack.head->val = val;
|
69
67
|
}
|
70
68
|
|
@@ -72,9 +70,7 @@ static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig
|
|
72
70
|
volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
|
73
71
|
|
74
72
|
pi->stack.head->val = rstr;
|
75
|
-
|
76
|
-
oj_trace_parse_call("add_string", pi, __FILE__, __LINE__, rstr);
|
77
|
-
}
|
73
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_string", pi, rstr);
|
78
74
|
}
|
79
75
|
|
80
76
|
static void add_num(ParseInfo pi, NumInfo ni) {
|
@@ -82,9 +78,7 @@ static void add_num(ParseInfo pi, NumInfo ni) {
|
|
82
78
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
|
83
79
|
}
|
84
80
|
pi->stack.head->val = oj_num_as_value(ni);
|
85
|
-
|
86
|
-
oj_trace_parse_call("add_number", pi, __FILE__, __LINE__, pi->stack.head->val);
|
87
|
-
}
|
81
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_number", pi, pi->stack.head->val);
|
88
82
|
}
|
89
83
|
|
90
84
|
static VALUE start_hash(ParseInfo pi) {
|
@@ -99,9 +93,7 @@ static void hash_set_cstr(ParseInfo pi, Val parent, const char *str, size_t len,
|
|
99
93
|
volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
|
100
94
|
|
101
95
|
rb_hash_aset(stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, parent), rstr);
|
102
|
-
|
103
|
-
oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rstr);
|
104
|
-
}
|
96
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_string", pi, rstr);
|
105
97
|
}
|
106
98
|
|
107
99
|
static void hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
|
@@ -112,16 +104,12 @@ static void hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
|
|
112
104
|
}
|
113
105
|
v = oj_num_as_value(ni);
|
114
106
|
rb_hash_aset(stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, parent), v);
|
115
|
-
|
116
|
-
oj_trace_parse_call("set_number", pi, __FILE__, __LINE__, v);
|
117
|
-
}
|
107
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_number", pi, v);
|
118
108
|
}
|
119
109
|
|
120
110
|
static void hash_set_value(ParseInfo pi, Val parent, VALUE value) {
|
121
111
|
rb_hash_aset(stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, parent), value);
|
122
|
-
|
123
|
-
oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
|
124
|
-
}
|
112
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_value", pi, value);
|
125
113
|
}
|
126
114
|
|
127
115
|
static VALUE start_array(ParseInfo pi) {
|
@@ -133,9 +121,7 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
|
|
133
121
|
volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
|
134
122
|
|
135
123
|
rb_ary_push(stack_peek(&pi->stack)->val, rstr);
|
136
|
-
|
137
|
-
oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rstr);
|
138
|
-
}
|
124
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_string", pi, rstr);
|
139
125
|
}
|
140
126
|
|
141
127
|
static void array_append_num(ParseInfo pi, NumInfo ni) {
|
@@ -146,16 +132,12 @@ static void array_append_num(ParseInfo pi, NumInfo ni) {
|
|
146
132
|
}
|
147
133
|
v = oj_num_as_value(ni);
|
148
134
|
rb_ary_push(stack_peek(&pi->stack)->val, v);
|
149
|
-
|
150
|
-
oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, v);
|
151
|
-
}
|
135
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_number", pi, v);
|
152
136
|
}
|
153
137
|
|
154
138
|
static void array_append_value(ParseInfo pi, VALUE value) {
|
155
139
|
rb_ary_push(stack_peek(&pi->stack)->val, value);
|
156
|
-
|
157
|
-
oj_trace_parse_call("append_value", pi, __FILE__, __LINE__, value);
|
158
|
-
}
|
140
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_value", pi, value);
|
159
141
|
}
|
160
142
|
|
161
143
|
void oj_set_strict_callbacks(ParseInfo pi) {
|
data/ext/oj/wab.c
CHANGED
@@ -318,9 +318,7 @@ static VALUE noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
|
|
318
318
|
}
|
319
319
|
|
320
320
|
static void add_value(ParseInfo pi, VALUE val) {
|
321
|
-
|
322
|
-
oj_trace_parse_call("add_value", pi, __FILE__, __LINE__, val);
|
323
|
-
}
|
321
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_value", pi, val);
|
324
322
|
pi->stack.head->val = val;
|
325
323
|
}
|
326
324
|
|
@@ -468,9 +466,7 @@ static VALUE cstr_to_rstr(ParseInfo pi, const char *str, size_t len) {
|
|
468
466
|
|
469
467
|
static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
470
468
|
pi->stack.head->val = cstr_to_rstr(pi, str, len);
|
471
|
-
|
472
|
-
oj_trace_parse_call("add_string", pi, __FILE__, __LINE__, pi->stack.head->val);
|
473
|
-
}
|
469
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_string", pi, pi->stack.head->val);
|
474
470
|
}
|
475
471
|
|
476
472
|
static void add_num(ParseInfo pi, NumInfo ni) {
|
@@ -478,9 +474,7 @@ static void add_num(ParseInfo pi, NumInfo ni) {
|
|
478
474
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
|
479
475
|
}
|
480
476
|
pi->stack.head->val = oj_num_as_value(ni);
|
481
|
-
|
482
|
-
oj_trace_parse_call("add_number", pi, __FILE__, __LINE__, pi->stack.head->val);
|
483
|
-
}
|
477
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_number", pi, pi->stack.head->val);
|
484
478
|
}
|
485
479
|
|
486
480
|
static VALUE start_hash(ParseInfo pi) {
|
@@ -495,9 +489,7 @@ static void hash_set_cstr(ParseInfo pi, Val parent, const char *str, size_t len,
|
|
495
489
|
volatile VALUE rval = cstr_to_rstr(pi, str, len);
|
496
490
|
|
497
491
|
rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), rval);
|
498
|
-
|
499
|
-
oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rval);
|
500
|
-
}
|
492
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_string", pi, rval);
|
501
493
|
}
|
502
494
|
|
503
495
|
static void hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
|
@@ -508,16 +500,12 @@ static void hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
|
|
508
500
|
}
|
509
501
|
rval = oj_num_as_value(ni);
|
510
502
|
rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), rval);
|
511
|
-
|
512
|
-
oj_trace_parse_call("set_number", pi, __FILE__, __LINE__, rval);
|
513
|
-
}
|
503
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_number", pi, rval);
|
514
504
|
}
|
515
505
|
|
516
506
|
static void hash_set_value(ParseInfo pi, Val parent, VALUE value) {
|
517
507
|
rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), value);
|
518
|
-
|
519
|
-
oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
|
520
|
-
}
|
508
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_value", pi, value);
|
521
509
|
}
|
522
510
|
|
523
511
|
static VALUE start_array(ParseInfo pi) {
|
@@ -529,9 +517,7 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
|
|
529
517
|
volatile VALUE rval = cstr_to_rstr(pi, str, len);
|
530
518
|
|
531
519
|
rb_ary_push(stack_peek(&pi->stack)->val, rval);
|
532
|
-
|
533
|
-
oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, rval);
|
534
|
-
}
|
520
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_value", pi, rval);
|
535
521
|
}
|
536
522
|
|
537
523
|
static void array_append_num(ParseInfo pi, NumInfo ni) {
|
@@ -542,16 +528,12 @@ static void array_append_num(ParseInfo pi, NumInfo ni) {
|
|
542
528
|
}
|
543
529
|
rval = oj_num_as_value(ni);
|
544
530
|
rb_ary_push(stack_peek(&pi->stack)->val, rval);
|
545
|
-
|
546
|
-
oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
|
547
|
-
}
|
531
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_number", pi, rval);
|
548
532
|
}
|
549
533
|
|
550
534
|
static void array_append_value(ParseInfo pi, VALUE value) {
|
551
535
|
rb_ary_push(stack_peek(&pi->stack)->val, value);
|
552
|
-
|
553
|
-
oj_trace_parse_call("append_value", pi, __FILE__, __LINE__, value);
|
554
|
-
}
|
536
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_value", pi, value);
|
555
537
|
}
|
556
538
|
|
557
539
|
void oj_set_wab_callbacks(ParseInfo pi) {
|
@@ -1,15 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_support/time'
|
2
4
|
|
3
5
|
module Oj
|
4
|
-
|
5
6
|
# Exists only to handle the ActiveSupport::TimeWithZone.
|
6
7
|
class ActiveSupportHelper
|
7
|
-
|
8
8
|
def self.createTimeWithZone(utc, zone)
|
9
9
|
ActiveSupport::TimeWithZone.new(utc - utc.gmt_offset, ActiveSupport::TimeZone[zone])
|
10
10
|
end
|
11
11
|
end
|
12
|
-
|
13
12
|
end
|
14
13
|
|
15
14
|
Oj.register_odd(ActiveSupport::TimeWithZone, Oj::ActiveSupportHelper, :createTimeWithZone, :utc, 'time_zone.name')
|
data/lib/oj/json.rb
CHANGED
@@ -1,178 +1,185 @@
|
|
1
1
|
require 'ostruct'
|
2
2
|
require 'oj/state'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
m[k] = v
|
4
|
+
if defined?(JSON::PRETTY_STATE_PROTOTYPE)
|
5
|
+
warn "WARNING: oj/json is a compatability shim used by Oj. Requiring the file explicitly is no recommended."
|
6
|
+
end
|
7
|
+
|
8
|
+
unless defined?(JSON::PRETTY_STATE_PROTOTYPE)
|
9
|
+
module JSON
|
10
|
+
NaN = 0.0/0.0 unless defined?(::JSON::NaN)
|
11
|
+
Infinity = 1.0/0.0 unless defined?(::JSON::Infinity)
|
12
|
+
MinusInfinity = -1.0/0.0 unless defined?(::JSON::MinusInfinity)
|
13
|
+
# Taken from the unit test. Note that items like check_circular? are not
|
14
|
+
# present.
|
15
|
+
PRETTY_STATE_PROTOTYPE = Ext::Generator::State.from_state({
|
16
|
+
:allow_nan => false,
|
17
|
+
:array_nl => "\n",
|
18
|
+
:ascii_only => false,
|
19
|
+
:buffer_initial_length => 1024,
|
20
|
+
:depth => 0,
|
21
|
+
:indent => " ",
|
22
|
+
:max_nesting => 100,
|
23
|
+
:object_nl => "\n",
|
24
|
+
:space => " ",
|
25
|
+
:space_before => "",
|
26
|
+
}) unless defined?(::JSON::PRETTY_STATE_PROTOTYPE)
|
27
|
+
SAFE_STATE_PROTOTYPE = Ext::Generator::State.from_state({
|
28
|
+
:allow_nan => false,
|
29
|
+
:array_nl => "",
|
30
|
+
:ascii_only => false,
|
31
|
+
:buffer_initial_length => 1024,
|
32
|
+
:depth => 0,
|
33
|
+
:indent => "",
|
34
|
+
:max_nesting => 100,
|
35
|
+
:object_nl => "",
|
36
|
+
:space => "",
|
37
|
+
:space_before => "",
|
38
|
+
}) unless defined?(::JSON::SAFE_STATE_PROTOTYPE)
|
39
|
+
FAST_STATE_PROTOTYPE = Ext::Generator::State.from_state({
|
40
|
+
:allow_nan => false,
|
41
|
+
:array_nl => "",
|
42
|
+
:ascii_only => false,
|
43
|
+
:buffer_initial_length => 1024,
|
44
|
+
:depth => 0,
|
45
|
+
:indent => "",
|
46
|
+
:max_nesting => 0,
|
47
|
+
:object_nl => "",
|
48
|
+
:space => "",
|
49
|
+
:space_before => "",
|
50
|
+
}) unless defined?(::JSON::FAST_STATE_PROTOTYPE)
|
51
|
+
|
52
|
+
def self.dump_default_options
|
53
|
+
Oj::MimicDumpOption.new
|
55
54
|
end
|
56
|
-
end
|
57
55
|
|
58
|
-
|
59
|
-
|
60
|
-
|
56
|
+
def self.dump_default_options=(h)
|
57
|
+
m = Oj::MimicDumpOption.new
|
58
|
+
h.each do |k, v|
|
59
|
+
m[k] = v
|
60
|
+
end
|
61
|
+
end
|
61
62
|
|
62
|
-
|
63
|
-
|
64
|
-
|
63
|
+
def self.parser=(p)
|
64
|
+
@@parser = p
|
65
|
+
end
|
65
66
|
|
66
|
-
|
67
|
-
|
68
|
-
|
67
|
+
def self.parser()
|
68
|
+
@@parser
|
69
|
+
end
|
69
70
|
|
70
|
-
|
71
|
-
|
72
|
-
|
71
|
+
def self.generator=(g)
|
72
|
+
@@generator = g
|
73
|
+
end
|
73
74
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
raise TypeError.new("already initialized") unless @source.nil?
|
75
|
+
def self.generator()
|
76
|
+
@@generator
|
77
|
+
end
|
78
78
|
|
79
|
-
|
80
|
-
|
79
|
+
module Ext
|
80
|
+
class Parser
|
81
|
+
def initialize(src)
|
82
|
+
raise TypeError.new("already initialized") unless @source.nil?
|
81
83
|
|
82
|
-
|
83
|
-
|
84
|
+
@source = src
|
85
|
+
end
|
84
86
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
def parse()
|
89
|
-
raise TypeError.new("already initialized") if @source.nil?
|
87
|
+
def source()
|
88
|
+
raise TypeError.new("already initialized") if @source.nil?
|
90
89
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
end # Parser
|
95
|
-
end # Ext
|
96
|
-
|
97
|
-
State = ::JSON::Ext::Generator::State unless defined?(::JSON::State)
|
98
|
-
|
99
|
-
begin
|
100
|
-
send(:remove_const, :Parser)
|
101
|
-
rescue
|
102
|
-
end
|
103
|
-
Parser = ::JSON::Ext::Parser unless defined?(::JSON::Parser)
|
104
|
-
self.parser = ::JSON::Ext::Parser
|
105
|
-
self.generator = ::JSON::Ext::Generator
|
106
|
-
|
107
|
-
# Taken directly from the json gem. Shamelessly copied. It is similar in
|
108
|
-
# some ways to the Oj::Bag class or the Oj::EasyHash class.
|
109
|
-
class GenericObject < OpenStruct
|
110
|
-
class << self
|
111
|
-
alias [] new
|
112
|
-
|
113
|
-
def json_creatable?
|
114
|
-
@json_creatable
|
115
|
-
end
|
90
|
+
@source
|
91
|
+
end
|
116
92
|
|
117
|
-
|
93
|
+
def parse()
|
94
|
+
raise TypeError.new("already initialized") if @source.nil?
|
118
95
|
|
119
|
-
|
120
|
-
|
121
|
-
data.delete JSON.create_id
|
122
|
-
self[data]
|
123
|
-
end
|
96
|
+
JSON.parse(@source)
|
97
|
+
end
|
124
98
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
99
|
+
end # Parser
|
100
|
+
end # Ext
|
101
|
+
|
102
|
+
State = ::JSON::Ext::Generator::State unless defined?(::JSON::State)
|
103
|
+
|
104
|
+
begin
|
105
|
+
send(:remove_const, :Parser)
|
106
|
+
rescue
|
107
|
+
# ignore and move on
|
108
|
+
end
|
109
|
+
Parser = ::JSON::Ext::Parser unless defined?(::JSON::Parser)
|
110
|
+
self.parser = ::JSON::Ext::Parser
|
111
|
+
self.generator = ::JSON::Ext::Generator
|
112
|
+
|
113
|
+
# Taken directly from the json gem. Shamelessly copied. It is similar in
|
114
|
+
# some ways to the Oj::Bag class or the Oj::EasyHash class.
|
115
|
+
class GenericObject < OpenStruct
|
116
|
+
class << self
|
117
|
+
alias [] new
|
118
|
+
|
119
|
+
def json_creatable?
|
120
|
+
@json_creatable
|
121
|
+
end
|
122
|
+
|
123
|
+
attr_writer :json_creatable
|
124
|
+
|
125
|
+
def json_create(data)
|
126
|
+
data = data.dup
|
127
|
+
data.delete JSON.create_id
|
128
|
+
self[data]
|
129
|
+
end
|
130
|
+
|
131
|
+
def from_hash(object)
|
132
|
+
case
|
133
|
+
when object.respond_to?(:to_hash)
|
134
|
+
result = new
|
135
|
+
object.to_hash.each do |key, value|
|
136
|
+
result[key] = from_hash(value)
|
137
|
+
end
|
138
|
+
result
|
139
|
+
when object.respond_to?(:to_ary)
|
140
|
+
object.to_ary.map { |a| from_hash(a) }
|
141
|
+
else
|
142
|
+
object
|
131
143
|
end
|
132
|
-
result
|
133
|
-
when object.respond_to?(:to_ary)
|
134
|
-
object.to_ary.map { |a| from_hash(a) }
|
135
|
-
else
|
136
|
-
object
|
137
144
|
end
|
138
|
-
end
|
139
145
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
146
|
+
def load(source, proc = nil, opts = {})
|
147
|
+
result = ::JSON.load(source, proc, opts.merge(:object_class => self))
|
148
|
+
result.nil? ? new : result
|
149
|
+
end
|
144
150
|
|
145
|
-
|
146
|
-
|
147
|
-
|
151
|
+
def dump(obj, *args)
|
152
|
+
::JSON.dump(obj, *args)
|
153
|
+
end
|
148
154
|
|
149
|
-
|
155
|
+
end # self
|
150
156
|
|
151
|
-
|
157
|
+
self.json_creatable = false
|
152
158
|
|
153
|
-
|
154
|
-
|
155
|
-
|
159
|
+
def to_hash
|
160
|
+
table
|
161
|
+
end
|
156
162
|
|
157
|
-
|
158
|
-
|
159
|
-
|
163
|
+
def [](name)
|
164
|
+
__send__(name)
|
165
|
+
end unless method_defined?(:[])
|
160
166
|
|
161
|
-
|
162
|
-
|
163
|
-
|
167
|
+
def []=(name, value)
|
168
|
+
__send__("#{name}=", value)
|
169
|
+
end unless method_defined?(:[]=)
|
164
170
|
|
165
|
-
|
166
|
-
|
167
|
-
|
171
|
+
def |(other)
|
172
|
+
self.class[other.to_hash.merge(to_hash)]
|
173
|
+
end
|
168
174
|
|
169
|
-
|
170
|
-
|
171
|
-
|
175
|
+
def as_json(*)
|
176
|
+
{ JSON.create_id => self.class.name }.merge to_hash
|
177
|
+
end
|
172
178
|
|
173
|
-
|
174
|
-
|
179
|
+
def to_json(*a)
|
180
|
+
as_json.to_json(*a)
|
181
|
+
end
|
175
182
|
end
|
176
|
-
|
177
|
-
|
178
|
-
end
|
183
|
+
|
184
|
+
end # JSON
|
185
|
+
end
|
data/lib/oj/mimic.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
1
3
|
require 'bigdecimal'
|
2
4
|
begin
|
3
5
|
require 'ostruct'
|
@@ -266,7 +268,7 @@ module Oj
|
|
266
268
|
end
|
267
269
|
end
|
268
270
|
def self.json_create(h)
|
269
|
-
if usec = h.delete('u')
|
271
|
+
if (usec = h.delete('u'))
|
270
272
|
h['n'] = usec * 1000
|
271
273
|
end
|
272
274
|
if instance_methods.include?(:tv_nsec)
|
data/lib/oj/version.rb
CHANGED