oj 3.7.4 → 3.13.21
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 +1352 -0
- data/README.md +29 -8
- data/RELEASE_NOTES.md +61 -0
- data/ext/oj/buf.h +53 -72
- data/ext/oj/cache.c +326 -0
- data/ext/oj/cache.h +21 -0
- data/ext/oj/cache8.c +61 -64
- data/ext/oj/cache8.h +12 -39
- data/ext/oj/circarray.c +37 -43
- data/ext/oj/circarray.h +16 -17
- data/ext/oj/code.c +165 -179
- data/ext/oj/code.h +27 -29
- data/ext/oj/compat.c +174 -194
- data/ext/oj/custom.c +809 -866
- data/ext/oj/debug.c +132 -0
- data/ext/oj/dump.c +848 -863
- data/ext/oj/dump.h +81 -67
- data/ext/oj/dump_compat.c +85 -123
- data/ext/oj/dump_leaf.c +100 -188
- data/ext/oj/dump_object.c +527 -656
- data/ext/oj/dump_strict.c +315 -338
- data/ext/oj/encode.h +7 -34
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/err.c +40 -29
- data/ext/oj/err.h +48 -48
- data/ext/oj/extconf.rb +17 -4
- data/ext/oj/fast.c +1070 -1087
- data/ext/oj/intern.c +301 -0
- data/ext/oj/intern.h +26 -0
- data/ext/oj/mimic_json.c +469 -436
- data/ext/oj/object.c +525 -593
- data/ext/oj/odd.c +154 -138
- data/ext/oj/odd.h +37 -38
- data/ext/oj/oj.c +1325 -986
- data/ext/oj/oj.h +333 -316
- data/ext/oj/parse.c +1002 -846
- data/ext/oj/parse.h +92 -87
- data/ext/oj/parser.c +1557 -0
- data/ext/oj/parser.h +91 -0
- data/ext/oj/rails.c +888 -878
- data/ext/oj/rails.h +11 -14
- data/ext/oj/reader.c +141 -147
- data/ext/oj/reader.h +73 -89
- data/ext/oj/resolve.c +41 -62
- data/ext/oj/resolve.h +7 -9
- data/ext/oj/rxclass.c +71 -75
- data/ext/oj/rxclass.h +18 -19
- data/ext/oj/saj.c +443 -486
- data/ext/oj/saj2.c +602 -0
- data/ext/oj/scp.c +88 -113
- data/ext/oj/sparse.c +787 -709
- data/ext/oj/stream_writer.c +133 -159
- data/ext/oj/strict.c +127 -118
- data/ext/oj/string_writer.c +230 -249
- data/ext/oj/trace.c +34 -41
- data/ext/oj/trace.h +19 -19
- data/ext/oj/usual.c +1254 -0
- data/ext/oj/util.c +136 -0
- data/ext/oj/util.h +20 -0
- data/ext/oj/val_stack.c +59 -67
- data/ext/oj/val_stack.h +91 -129
- data/ext/oj/validate.c +46 -0
- data/ext/oj/wab.c +342 -353
- data/lib/oj/bag.rb +1 -0
- data/lib/oj/easy_hash.rb +5 -4
- data/lib/oj/error.rb +1 -1
- data/lib/oj/json.rb +1 -1
- data/lib/oj/mimic.rb +48 -14
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/state.rb +8 -7
- data/lib/oj/version.rb +2 -2
- data/lib/oj.rb +0 -8
- data/pages/Compatibility.md +1 -1
- data/pages/JsonGem.md +15 -0
- data/pages/Modes.md +53 -46
- data/pages/Options.md +72 -11
- data/pages/Parser.md +309 -0
- data/pages/Rails.md +73 -22
- data/pages/Security.md +1 -1
- data/test/activerecord/result_test.rb +7 -2
- data/test/activesupport5/abstract_unit.rb +45 -0
- data/test/activesupport5/decoding_test.rb +68 -60
- data/test/activesupport5/encoding_test.rb +111 -96
- data/test/activesupport5/encoding_test_cases.rb +33 -25
- data/test/activesupport5/test_helper.rb +43 -21
- data/test/activesupport5/time_zone_test_helpers.rb +18 -3
- data/test/activesupport6/abstract_unit.rb +44 -0
- data/test/activesupport6/decoding_test.rb +133 -0
- data/test/activesupport6/encoding_test.rb +507 -0
- data/test/activesupport6/encoding_test_cases.rb +98 -0
- data/test/activesupport6/test_common.rb +17 -0
- data/test/activesupport6/test_helper.rb +163 -0
- data/test/activesupport6/time_zone_test_helpers.rb +39 -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 +6 -12
- data/test/baz.rb +16 -0
- data/test/bug.rb +16 -0
- data/test/foo.rb +69 -75
- data/test/helper.rb +16 -0
- data/test/json_gem/json_common_interface_test.rb +8 -3
- data/test/json_gem/json_generator_test.rb +18 -4
- data/test/json_gem/json_parser_test.rb +9 -0
- data/test/json_gem/test_helper.rb +12 -0
- data/test/mem.rb +33 -0
- data/test/perf.rb +1 -1
- data/test/perf_dump.rb +50 -0
- data/test/perf_once.rb +58 -0
- data/test/perf_parser.rb +189 -0
- data/test/perf_scp.rb +11 -10
- data/test/perf_strict.rb +17 -23
- data/test/prec.rb +23 -0
- data/test/sample_json.rb +1 -1
- data/test/test_compat.rb +46 -10
- data/test/test_custom.rb +147 -8
- data/test/test_fast.rb +62 -2
- data/test/test_file.rb +25 -2
- data/test/test_gc.rb +13 -0
- data/test/test_generate.rb +21 -0
- data/test/test_hash.rb +11 -1
- data/test/test_integer_range.rb +7 -2
- data/test/test_object.rb +85 -9
- data/test/test_parser.rb +27 -0
- data/test/test_parser_saj.rb +335 -0
- data/test/test_parser_usual.rb +217 -0
- data/test/test_rails.rb +35 -0
- data/test/test_saj.rb +1 -1
- data/test/test_scp.rb +5 -5
- data/test/test_strict.rb +26 -1
- data/test/test_various.rb +87 -65
- data/test/test_wab.rb +2 -0
- data/test/test_writer.rb +19 -2
- data/test/tests.rb +1 -1
- data/test/zoo.rb +13 -0
- metadata +60 -110
- data/ext/oj/hash.c +0 -163
- data/ext/oj/hash.h +0 -46
- data/ext/oj/hash_test.c +0 -512
data/ext/oj/strict.c
CHANGED
|
@@ -1,210 +1,219 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* All rights reserved.
|
|
4
|
-
*/
|
|
1
|
+
// Copyright (c) 2012 Peter Ohler. All rights reserved.
|
|
2
|
+
// Licensed under the MIT License. See LICENSE file in the project root for license details.
|
|
5
3
|
|
|
6
|
-
#include <stdlib.h>
|
|
7
4
|
#include <stdio.h>
|
|
5
|
+
#include <stdlib.h>
|
|
8
6
|
#include <string.h>
|
|
9
7
|
#include <unistd.h>
|
|
10
8
|
|
|
11
|
-
#include "
|
|
9
|
+
#include "encode.h"
|
|
12
10
|
#include "err.h"
|
|
11
|
+
#include "intern.h"
|
|
12
|
+
#include "oj.h"
|
|
13
13
|
#include "parse.h"
|
|
14
|
-
#include "encode.h"
|
|
15
14
|
#include "trace.h"
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
VALUE oj_cstr_to_value(const char *str, size_t len, size_t cache_str) {
|
|
17
|
+
volatile VALUE rstr = Qnil;
|
|
18
|
+
|
|
19
|
+
if (len < cache_str) {
|
|
20
|
+
rstr = oj_str_intern(str, len);
|
|
21
|
+
} else {
|
|
22
|
+
rstr = rb_str_new(str, len);
|
|
23
|
+
rstr = oj_encode(rstr);
|
|
21
24
|
}
|
|
25
|
+
return rstr;
|
|
22
26
|
}
|
|
23
27
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
VALUE oj_calc_hash_key(ParseInfo pi, Val parent) {
|
|
29
|
+
volatile VALUE rkey = parent->key_val;
|
|
30
|
+
|
|
31
|
+
if (Qundef != rkey) {
|
|
32
|
+
return rkey;
|
|
28
33
|
}
|
|
34
|
+
if (Yes != pi->options.cache_keys) {
|
|
35
|
+
if (Yes == pi->options.sym_key) {
|
|
36
|
+
rkey = ID2SYM(rb_intern3(parent->key, parent->klen, oj_utf8_encoding));
|
|
37
|
+
} else {
|
|
38
|
+
rkey = rb_str_new(parent->key, parent->klen);
|
|
39
|
+
rkey = oj_encode(rkey);
|
|
40
|
+
OBJ_FREEZE(rkey); // frozen when used as a Hash key anyway
|
|
41
|
+
}
|
|
42
|
+
return rkey;
|
|
43
|
+
}
|
|
44
|
+
if (Yes == pi->options.sym_key) {
|
|
45
|
+
rkey = oj_sym_intern(parent->key, parent->klen);
|
|
46
|
+
} else {
|
|
47
|
+
rkey = oj_str_intern(parent->key, parent->klen);
|
|
48
|
+
}
|
|
49
|
+
return rkey;
|
|
29
50
|
}
|
|
30
51
|
|
|
31
|
-
static
|
|
32
|
-
|
|
52
|
+
static void hash_end(ParseInfo pi) {
|
|
53
|
+
if (RB_UNLIKELY(Yes == pi->options.trace)) {
|
|
54
|
+
oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static void array_end(ParseInfo pi) {
|
|
59
|
+
if (RB_UNLIKELY(Yes == pi->options.trace)) {
|
|
60
|
+
oj_trace_parse_array_end(pi, __FILE__, __LINE__);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
static VALUE noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
|
|
33
65
|
return Qundef;
|
|
34
66
|
}
|
|
35
67
|
|
|
36
|
-
static void
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
oj_trace_parse_call("add_value", pi, __FILE__, __LINE__, val);
|
|
68
|
+
static void add_value(ParseInfo pi, VALUE val) {
|
|
69
|
+
if (RB_UNLIKELY(Yes == pi->options.trace)) {
|
|
70
|
+
oj_trace_parse_call("add_value", pi, __FILE__, __LINE__, val);
|
|
40
71
|
}
|
|
41
72
|
pi->stack.head->val = val;
|
|
42
73
|
}
|
|
43
74
|
|
|
44
|
-
static void
|
|
45
|
-
|
|
46
|
-
volatile VALUE rstr = rb_str_new(str, len);
|
|
75
|
+
static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
|
76
|
+
volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
|
|
47
77
|
|
|
48
|
-
rstr = oj_encode(rstr);
|
|
49
78
|
pi->stack.head->val = rstr;
|
|
50
|
-
if (Yes == pi->options.trace) {
|
|
51
|
-
|
|
79
|
+
if (RB_UNLIKELY(Yes == pi->options.trace)) {
|
|
80
|
+
oj_trace_parse_call("add_string", pi, __FILE__, __LINE__, rstr);
|
|
52
81
|
}
|
|
53
82
|
}
|
|
54
83
|
|
|
55
|
-
static void
|
|
56
|
-
add_num(ParseInfo pi, NumInfo ni) {
|
|
84
|
+
static void add_num(ParseInfo pi, NumInfo ni) {
|
|
57
85
|
if (ni->infinity || ni->nan) {
|
|
58
|
-
|
|
86
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
|
|
59
87
|
}
|
|
60
88
|
pi->stack.head->val = oj_num_as_value(ni);
|
|
61
|
-
if (Yes == pi->options.trace) {
|
|
62
|
-
|
|
89
|
+
if (RB_UNLIKELY(Yes == pi->options.trace)) {
|
|
90
|
+
oj_trace_parse_call("add_number", pi, __FILE__, __LINE__, pi->stack.head->val);
|
|
63
91
|
}
|
|
64
92
|
}
|
|
65
93
|
|
|
66
|
-
static VALUE
|
|
67
|
-
start_hash(ParseInfo pi) {
|
|
94
|
+
static VALUE start_hash(ParseInfo pi) {
|
|
68
95
|
if (Qnil != pi->options.hash_class) {
|
|
69
|
-
|
|
96
|
+
return rb_class_new_instance(0, NULL, pi->options.hash_class);
|
|
70
97
|
}
|
|
71
|
-
if (Yes == pi->options.trace) {
|
|
72
|
-
|
|
98
|
+
if (RB_UNLIKELY(Yes == pi->options.trace)) {
|
|
99
|
+
oj_trace_parse_in("start_hash", pi, __FILE__, __LINE__);
|
|
73
100
|
}
|
|
74
101
|
return rb_hash_new();
|
|
75
102
|
}
|
|
76
103
|
|
|
77
|
-
static
|
|
78
|
-
|
|
79
|
-
volatile VALUE rkey = parent->key_val;
|
|
104
|
+
static void hash_set_cstr(ParseInfo pi, Val parent, const char *str, size_t len, const char *orig) {
|
|
105
|
+
volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
|
|
80
106
|
|
|
81
|
-
|
|
82
|
-
|
|
107
|
+
rb_hash_aset(stack_peek(&pi->stack)->val,
|
|
108
|
+
oj_calc_hash_key(pi, parent),
|
|
109
|
+
rstr);
|
|
110
|
+
if (RB_UNLIKELY(Yes == pi->options.trace)) {
|
|
111
|
+
oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rstr);
|
|
83
112
|
}
|
|
84
|
-
rkey = oj_encode(rkey);
|
|
85
|
-
if (Yes == pi->options.sym_key) {
|
|
86
|
-
rkey = rb_str_intern(rkey);
|
|
87
|
-
}
|
|
88
|
-
return rkey;
|
|
89
113
|
}
|
|
90
114
|
|
|
91
|
-
static void
|
|
92
|
-
|
|
93
|
-
volatile VALUE rstr = rb_str_new(str, len);
|
|
94
|
-
|
|
95
|
-
rstr = oj_encode(rstr);
|
|
96
|
-
rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), rstr);
|
|
97
|
-
if (Yes == pi->options.trace) {
|
|
98
|
-
oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rstr);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
115
|
+
static void hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
|
|
116
|
+
volatile VALUE v;
|
|
101
117
|
|
|
102
|
-
static void
|
|
103
|
-
hash_set_num(struct _ParseInfo *pi, Val parent, NumInfo ni) {
|
|
104
|
-
volatile VALUE v;
|
|
105
|
-
|
|
106
118
|
if (ni->infinity || ni->nan) {
|
|
107
|
-
|
|
119
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
|
|
108
120
|
}
|
|
109
121
|
v = oj_num_as_value(ni);
|
|
110
|
-
rb_hash_aset(stack_peek(&pi->stack)->val,
|
|
111
|
-
|
|
112
|
-
|
|
122
|
+
rb_hash_aset(stack_peek(&pi->stack)->val,
|
|
123
|
+
oj_calc_hash_key(pi, parent),
|
|
124
|
+
v);
|
|
125
|
+
if (RB_UNLIKELY(Yes == pi->options.trace)) {
|
|
126
|
+
oj_trace_parse_call("set_number", pi, __FILE__, __LINE__, v);
|
|
113
127
|
}
|
|
114
128
|
}
|
|
115
129
|
|
|
116
|
-
static void
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
130
|
+
static void hash_set_value(ParseInfo pi, Val parent, VALUE value) {
|
|
131
|
+
rb_hash_aset(stack_peek(&pi->stack)->val,
|
|
132
|
+
oj_calc_hash_key(pi, parent),
|
|
133
|
+
value);
|
|
134
|
+
if (RB_UNLIKELY(Yes == pi->options.trace)) {
|
|
135
|
+
oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
|
|
121
136
|
}
|
|
122
137
|
}
|
|
123
138
|
|
|
124
|
-
static VALUE
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
oj_trace_parse_in("start_array", pi, __FILE__, __LINE__);
|
|
139
|
+
static VALUE start_array(ParseInfo pi) {
|
|
140
|
+
if (RB_UNLIKELY(Yes == pi->options.trace)) {
|
|
141
|
+
oj_trace_parse_in("start_array", pi, __FILE__, __LINE__);
|
|
128
142
|
}
|
|
129
143
|
return rb_ary_new();
|
|
130
144
|
}
|
|
131
145
|
|
|
132
|
-
static void
|
|
133
|
-
|
|
134
|
-
volatile VALUE rstr = rb_str_new(str, len);
|
|
146
|
+
static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
|
147
|
+
volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
|
|
135
148
|
|
|
136
|
-
rstr = oj_encode(rstr);
|
|
137
149
|
rb_ary_push(stack_peek(&pi->stack)->val, rstr);
|
|
138
|
-
if (Yes == pi->options.trace) {
|
|
139
|
-
|
|
150
|
+
if (RB_UNLIKELY(Yes == pi->options.trace)) {
|
|
151
|
+
oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rstr);
|
|
140
152
|
}
|
|
141
153
|
}
|
|
142
154
|
|
|
143
|
-
static void
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
155
|
+
static void array_append_num(ParseInfo pi, NumInfo ni) {
|
|
156
|
+
volatile VALUE v;
|
|
157
|
+
|
|
147
158
|
if (ni->infinity || ni->nan) {
|
|
148
|
-
|
|
159
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
|
|
149
160
|
}
|
|
150
161
|
v = oj_num_as_value(ni);
|
|
151
162
|
rb_ary_push(stack_peek(&pi->stack)->val, v);
|
|
152
|
-
if (Yes == pi->options.trace) {
|
|
153
|
-
|
|
163
|
+
if (RB_UNLIKELY(Yes == pi->options.trace)) {
|
|
164
|
+
oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, v);
|
|
154
165
|
}
|
|
155
166
|
}
|
|
156
167
|
|
|
157
|
-
static void
|
|
158
|
-
array_append_value(ParseInfo pi, VALUE value) {
|
|
168
|
+
static void array_append_value(ParseInfo pi, VALUE value) {
|
|
159
169
|
rb_ary_push(stack_peek(&pi->stack)->val, value);
|
|
160
|
-
if (Yes == pi->options.trace) {
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
void
|
|
166
|
-
|
|
167
|
-
pi->
|
|
168
|
-
pi->
|
|
169
|
-
pi->
|
|
170
|
-
pi->
|
|
171
|
-
pi->
|
|
172
|
-
pi->
|
|
173
|
-
pi->
|
|
174
|
-
pi->
|
|
175
|
-
pi->
|
|
176
|
-
pi->array_append_num = array_append_num;
|
|
170
|
+
if (RB_UNLIKELY(Yes == pi->options.trace)) {
|
|
171
|
+
oj_trace_parse_call("append_value", pi, __FILE__, __LINE__, value);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
void oj_set_strict_callbacks(ParseInfo pi) {
|
|
176
|
+
pi->start_hash = start_hash;
|
|
177
|
+
pi->end_hash = hash_end;
|
|
178
|
+
pi->hash_key = noop_hash_key;
|
|
179
|
+
pi->hash_set_cstr = hash_set_cstr;
|
|
180
|
+
pi->hash_set_num = hash_set_num;
|
|
181
|
+
pi->hash_set_value = hash_set_value;
|
|
182
|
+
pi->start_array = start_array;
|
|
183
|
+
pi->end_array = array_end;
|
|
184
|
+
pi->array_append_cstr = array_append_cstr;
|
|
185
|
+
pi->array_append_num = array_append_num;
|
|
177
186
|
pi->array_append_value = array_append_value;
|
|
178
|
-
pi->add_cstr
|
|
179
|
-
pi->add_num
|
|
180
|
-
pi->add_value
|
|
181
|
-
pi->expect_value
|
|
187
|
+
pi->add_cstr = add_cstr;
|
|
188
|
+
pi->add_num = add_num;
|
|
189
|
+
pi->add_value = add_value;
|
|
190
|
+
pi->expect_value = 1;
|
|
182
191
|
}
|
|
183
192
|
|
|
184
193
|
VALUE
|
|
185
194
|
oj_strict_parse(int argc, VALUE *argv, VALUE self) {
|
|
186
|
-
struct
|
|
195
|
+
struct _parseInfo pi;
|
|
187
196
|
|
|
188
197
|
parse_info_init(&pi);
|
|
189
|
-
pi.options
|
|
190
|
-
pi.handler
|
|
198
|
+
pi.options = oj_default_options;
|
|
199
|
+
pi.handler = Qnil;
|
|
191
200
|
pi.err_class = Qnil;
|
|
192
201
|
oj_set_strict_callbacks(&pi);
|
|
193
202
|
|
|
194
203
|
if (T_STRING == rb_type(*argv)) {
|
|
195
|
-
|
|
204
|
+
return oj_pi_parse(argc, argv, &pi, 0, 0, true);
|
|
196
205
|
} else {
|
|
197
|
-
|
|
206
|
+
return oj_pi_sparse(argc, argv, &pi, 0);
|
|
198
207
|
}
|
|
199
208
|
}
|
|
200
209
|
|
|
201
210
|
VALUE
|
|
202
211
|
oj_strict_parse_cstr(int argc, VALUE *argv, char *json, size_t len) {
|
|
203
|
-
struct
|
|
212
|
+
struct _parseInfo pi;
|
|
204
213
|
|
|
205
214
|
parse_info_init(&pi);
|
|
206
|
-
pi.options
|
|
207
|
-
pi.handler
|
|
215
|
+
pi.options = oj_default_options;
|
|
216
|
+
pi.handler = Qnil;
|
|
208
217
|
pi.err_class = Qnil;
|
|
209
218
|
oj_set_strict_callbacks(&pi);
|
|
210
219
|
|