oj 3.16.0 → 3.17.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/CHANGELOG.md +107 -0
- data/README.md +0 -16
- data/ext/oj/cache.c +4 -2
- data/ext/oj/cache.h +3 -2
- data/ext/oj/compat.c +3 -3
- data/ext/oj/custom.c +17 -11
- data/ext/oj/dump.c +624 -90
- data/ext/oj/dump.h +9 -2
- data/ext/oj/dump_compat.c +15 -9
- data/ext/oj/dump_leaf.c +1 -1
- data/ext/oj/dump_object.c +32 -17
- data/ext/oj/dump_strict.c +20 -14
- data/ext/oj/extconf.rb +11 -9
- data/ext/oj/fast.c +50 -32
- data/ext/oj/intern.c +24 -7
- data/ext/oj/mimic_json.c +17 -11
- data/ext/oj/object.c +21 -13
- data/ext/oj/oj.c +387 -140
- data/ext/oj/oj.h +59 -55
- data/ext/oj/parse.c +248 -47
- data/ext/oj/parser.c +179 -89
- data/ext/oj/parser.h +4 -2
- data/ext/oj/rails.c +64 -42
- data/ext/oj/reader.c +1 -1
- data/ext/oj/rxclass.c +1 -1
- data/ext/oj/rxclass.h +1 -1
- data/ext/oj/safe.c +230 -0
- data/ext/oj/safe.h +79 -0
- data/ext/oj/saj.c +15 -10
- data/ext/oj/scp.c +3 -6
- data/ext/oj/simd.h +219 -0
- data/ext/oj/sparse.c +6 -3
- data/ext/oj/stream_writer.c +38 -28
- data/ext/oj/strict.c +2 -4
- data/ext/oj/string_writer.c +54 -22
- data/ext/oj/usual.c +57 -35
- data/ext/oj/usual.h +1 -0
- data/ext/oj/val_stack.c +13 -2
- data/ext/oj/wab.c +5 -4
- data/lib/oj/mimic.rb +1 -5
- data/lib/oj/schandler.rb +5 -4
- data/lib/oj/version.rb +1 -1
- data/pages/Encoding.md +1 -1
- metadata +36 -100
- data/test/_test_active.rb +0 -75
- data/test/_test_active_mimic.rb +0 -95
- data/test/_test_mimic_rails.rb +0 -123
- data/test/activerecord/result_test.rb +0 -31
- data/test/activesupport6/abstract_unit.rb +0 -44
- data/test/activesupport6/decoding_test.rb +0 -133
- data/test/activesupport6/encoding_test.rb +0 -507
- data/test/activesupport6/encoding_test_cases.rb +0 -98
- data/test/activesupport6/test_common.rb +0 -17
- data/test/activesupport6/test_helper.rb +0 -163
- data/test/activesupport6/time_zone_test_helpers.rb +0 -39
- data/test/activesupport7/abstract_unit.rb +0 -49
- data/test/activesupport7/decoding_test.rb +0 -125
- data/test/activesupport7/encoding_test.rb +0 -486
- data/test/activesupport7/encoding_test_cases.rb +0 -104
- data/test/activesupport7/time_zone_test_helpers.rb +0 -47
- data/test/files.rb +0 -29
- data/test/foo.rb +0 -14
- data/test/helper.rb +0 -39
- data/test/isolated/shared.rb +0 -309
- data/test/isolated/test_mimic_after.rb +0 -13
- data/test/isolated/test_mimic_alone.rb +0 -12
- data/test/isolated/test_mimic_as_json.rb +0 -45
- data/test/isolated/test_mimic_before.rb +0 -13
- data/test/isolated/test_mimic_define.rb +0 -28
- data/test/isolated/test_mimic_rails_after.rb +0 -22
- data/test/isolated/test_mimic_rails_before.rb +0 -21
- data/test/isolated/test_mimic_redefine.rb +0 -15
- data/test/json_gem/json_addition_test.rb +0 -216
- data/test/json_gem/json_common_interface_test.rb +0 -155
- data/test/json_gem/json_encoding_test.rb +0 -107
- data/test/json_gem/json_ext_parser_test.rb +0 -21
- data/test/json_gem/json_fixtures_test.rb +0 -36
- data/test/json_gem/json_generator_test.rb +0 -407
- data/test/json_gem/json_generic_object_test.rb +0 -90
- data/test/json_gem/json_parser_test.rb +0 -477
- data/test/json_gem/json_string_matching_test.rb +0 -42
- data/test/json_gem/test_helper.rb +0 -30
- data/test/mem.rb +0 -34
- data/test/perf.rb +0 -102
- data/test/perf_compat.rb +0 -128
- data/test/perf_dump.rb +0 -50
- data/test/perf_fast.rb +0 -162
- data/test/perf_file.rb +0 -62
- data/test/perf_object.rb +0 -134
- data/test/perf_once.rb +0 -59
- data/test/perf_parser.rb +0 -183
- data/test/perf_saj.rb +0 -101
- data/test/perf_scp.rb +0 -140
- data/test/perf_simple.rb +0 -289
- data/test/perf_strict.rb +0 -137
- data/test/perf_wab.rb +0 -129
- data/test/prec.rb +0 -23
- data/test/sample/change.rb +0 -13
- data/test/sample/dir.rb +0 -18
- data/test/sample/doc.rb +0 -35
- data/test/sample/file.rb +0 -47
- data/test/sample/group.rb +0 -15
- data/test/sample/hasprops.rb +0 -15
- data/test/sample/layer.rb +0 -11
- data/test/sample/line.rb +0 -20
- data/test/sample/oval.rb +0 -10
- data/test/sample/rect.rb +0 -9
- data/test/sample/shape.rb +0 -34
- data/test/sample/text.rb +0 -19
- data/test/sample.rb +0 -54
- data/test/sample_json.rb +0 -37
- data/test/test_compat.rb +0 -567
- data/test/test_custom.rb +0 -554
- data/test/test_debian.rb +0 -50
- data/test/test_fast.rb +0 -526
- data/test/test_file.rb +0 -250
- data/test/test_gc.rb +0 -60
- data/test/test_generate.rb +0 -21
- data/test/test_hash.rb +0 -39
- data/test/test_integer_range.rb +0 -72
- data/test/test_null.rb +0 -376
- data/test/test_object.rb +0 -1016
- data/test/test_parser.rb +0 -11
- data/test/test_parser_debug.rb +0 -27
- data/test/test_parser_saj.rb +0 -337
- data/test/test_parser_usual.rb +0 -217
- data/test/test_rails.rb +0 -35
- data/test/test_saj.rb +0 -188
- data/test/test_scp.rb +0 -431
- data/test/test_strict.rb +0 -431
- data/test/test_various.rb +0 -801
- data/test/test_wab.rb +0 -311
- data/test/test_writer.rb +0 -380
- data/test/tests.rb +0 -33
- data/test/tests_mimic.rb +0 -23
- data/test/tests_mimic_addition.rb +0 -16
data/ext/oj/intern.c
CHANGED
|
@@ -69,7 +69,7 @@ static VALUE form_attr(const char *str, size_t len) {
|
|
|
69
69
|
memcpy(b + 1, str, len);
|
|
70
70
|
b[len + 1] = '\0';
|
|
71
71
|
}
|
|
72
|
-
id = rb_intern3(
|
|
72
|
+
id = rb_intern3(b, len + 1, oj_utf8_encoding);
|
|
73
73
|
OJ_R_FREE(b);
|
|
74
74
|
return id;
|
|
75
75
|
}
|
|
@@ -85,20 +85,31 @@ static VALUE form_attr(const char *str, size_t len) {
|
|
|
85
85
|
return (VALUE)rb_intern3(buf, len + 1, oj_utf8_encoding);
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
static const rb_data_type_t oj_cache_type = {
|
|
89
|
+
"Oj/cache",
|
|
90
|
+
{
|
|
91
|
+
cache_mark,
|
|
92
|
+
cache_free,
|
|
93
|
+
NULL,
|
|
94
|
+
},
|
|
95
|
+
0,
|
|
96
|
+
0,
|
|
97
|
+
};
|
|
98
|
+
|
|
88
99
|
void oj_hash_init(void) {
|
|
89
100
|
VALUE cache_class = rb_define_class_under(Oj, "Cache", rb_cObject);
|
|
90
101
|
rb_undef_alloc_func(cache_class);
|
|
91
102
|
|
|
92
103
|
struct _cache *str_cache = cache_create(0, form_str, true, true);
|
|
93
|
-
str_cache_obj =
|
|
104
|
+
str_cache_obj = TypedData_Wrap_Struct(cache_class, &oj_cache_type, str_cache);
|
|
94
105
|
rb_gc_register_address(&str_cache_obj);
|
|
95
106
|
|
|
96
107
|
struct _cache *sym_cache = cache_create(0, form_sym, true, true);
|
|
97
|
-
sym_cache_obj =
|
|
108
|
+
sym_cache_obj = TypedData_Wrap_Struct(cache_class, &oj_cache_type, sym_cache);
|
|
98
109
|
rb_gc_register_address(&sym_cache_obj);
|
|
99
110
|
|
|
100
111
|
struct _cache *attr_cache = cache_create(0, form_attr, false, true);
|
|
101
|
-
attr_cache_obj =
|
|
112
|
+
attr_cache_obj = TypedData_Wrap_Struct(cache_class, &oj_cache_type, attr_cache);
|
|
102
113
|
rb_gc_register_address(&attr_cache_obj);
|
|
103
114
|
|
|
104
115
|
memset(class_hash.slots, 0, sizeof(class_hash.slots));
|
|
@@ -118,17 +129,23 @@ oj_str_intern(const char *key, size_t len) {
|
|
|
118
129
|
#if HAVE_RB_ENC_INTERNED_STR && 0
|
|
119
130
|
return rb_enc_interned_str(key, len, rb_utf8_encoding());
|
|
120
131
|
#else
|
|
121
|
-
|
|
132
|
+
Cache c;
|
|
133
|
+
TypedData_Get_Struct(str_cache_obj, struct _cache, &oj_cache_type, c);
|
|
134
|
+
return cache_intern(c, key, len);
|
|
122
135
|
#endif
|
|
123
136
|
}
|
|
124
137
|
|
|
125
138
|
VALUE
|
|
126
139
|
oj_sym_intern(const char *key, size_t len) {
|
|
127
|
-
|
|
140
|
+
Cache c;
|
|
141
|
+
TypedData_Get_Struct(sym_cache_obj, struct _cache, &oj_cache_type, c);
|
|
142
|
+
return cache_intern(c, key, len);
|
|
128
143
|
}
|
|
129
144
|
|
|
130
145
|
ID oj_attr_intern(const char *key, size_t len) {
|
|
131
|
-
|
|
146
|
+
Cache c;
|
|
147
|
+
TypedData_Get_Struct(attr_cache_obj, struct _cache, &oj_cache_type, c);
|
|
148
|
+
return cache_intern(c, key, len);
|
|
132
149
|
}
|
|
133
150
|
|
|
134
151
|
static uint64_t hash_calc(const uint8_t *key, size_t len) {
|
data/ext/oj/mimic_json.c
CHANGED
|
@@ -246,8 +246,7 @@ static VALUE mimic_dump(int argc, VALUE *argv, VALUE self) {
|
|
|
246
246
|
if (0 == out.buf) {
|
|
247
247
|
rb_raise(rb_eNoMemError, "Not enough memory.");
|
|
248
248
|
}
|
|
249
|
-
rstr =
|
|
250
|
-
rstr = oj_encode(rstr);
|
|
249
|
+
rstr = rb_utf8_str_new_cstr(out.buf);
|
|
251
250
|
if (2 <= argc && Qnil != argv[1] && rb_respond_to(argv[1], oj_write_id)) {
|
|
252
251
|
VALUE io = argv[1];
|
|
253
252
|
VALUE args[1];
|
|
@@ -396,8 +395,7 @@ static VALUE mimic_generate_core(int argc, VALUE *argv, Options copts) {
|
|
|
396
395
|
if (0 == out.buf) {
|
|
397
396
|
rb_raise(rb_eNoMemError, "Not enough memory.");
|
|
398
397
|
}
|
|
399
|
-
rstr =
|
|
400
|
-
rstr = oj_encode(rstr);
|
|
398
|
+
rstr = rb_utf8_str_new_cstr(out.buf);
|
|
401
399
|
|
|
402
400
|
oj_out_free(&out);
|
|
403
401
|
|
|
@@ -425,7 +423,7 @@ static VALUE mimic_generate_core(int argc, VALUE *argv, Options copts) {
|
|
|
425
423
|
* - *:object_nl* [_String_] String placed after a JSON object
|
|
426
424
|
* - *:array_nl* [_String_] String placed after a JSON array
|
|
427
425
|
* - *:ascii_only* [_Boolean_] if not nil or false then use only ascii characters in the output.
|
|
428
|
-
*
|
|
426
|
+
* Note JSON.generate does support this even if it is not documented.
|
|
429
427
|
*
|
|
430
428
|
* Returns [_String_] generated JSON.
|
|
431
429
|
*/
|
|
@@ -605,9 +603,9 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
|
|
|
605
603
|
* - *source* [_String_|IO] source to parse
|
|
606
604
|
* - *opts* [_Hash_] options
|
|
607
605
|
* - *:symbolize* [Boolean] _names flag indicating JSON object keys should be Symbols instead of
|
|
608
|
-
*
|
|
606
|
+
* Strings
|
|
609
607
|
* - *:create_additions* [Boolean] flag indicating a key matching +create_id+ in a JSON object
|
|
610
|
-
*
|
|
608
|
+
* should trigger the creation of Ruby Object
|
|
611
609
|
*
|
|
612
610
|
* Returns [Object]
|
|
613
611
|
* @see create_id=
|
|
@@ -713,6 +711,7 @@ static struct _options mimic_object_to_json_options = {0, // indent
|
|
|
713
711
|
0, // cache_str
|
|
714
712
|
0, // int_range_min
|
|
715
713
|
0, // int_range_max
|
|
714
|
+
0, // max_integer_digits
|
|
716
715
|
oj_json_class, // create_id
|
|
717
716
|
10, // create_id_len
|
|
718
717
|
3, // sec_prec
|
|
@@ -737,6 +736,8 @@ static struct _options mimic_object_to_json_options = {0, // indent
|
|
|
737
736
|
false, // omit_nil
|
|
738
737
|
false, // omit_null_byte
|
|
739
738
|
100, // max_depth
|
|
739
|
+
NULL, // only
|
|
740
|
+
NULL, // except
|
|
740
741
|
},
|
|
741
742
|
{
|
|
742
743
|
// str_rx
|
|
@@ -768,8 +769,7 @@ static VALUE mimic_object_to_json(int argc, VALUE *argv, VALUE self) {
|
|
|
768
769
|
if (NULL == out.buf) {
|
|
769
770
|
rb_raise(rb_eNoMemError, "Not enough memory.");
|
|
770
771
|
}
|
|
771
|
-
rstr =
|
|
772
|
-
rstr = oj_encode(rstr);
|
|
772
|
+
rstr = rb_utf8_str_new_cstr(out.buf);
|
|
773
773
|
|
|
774
774
|
oj_out_free(&out);
|
|
775
775
|
|
|
@@ -837,11 +837,15 @@ void oj_mimic_json_methods(VALUE json) {
|
|
|
837
837
|
} else {
|
|
838
838
|
json_error = rb_define_class_under(json, "JSONError", rb_eStandardError);
|
|
839
839
|
}
|
|
840
|
+
|
|
841
|
+
rb_global_variable(&oj_json_parser_error_class);
|
|
840
842
|
if (rb_const_defined_at(json, rb_intern("ParserError"))) {
|
|
841
843
|
oj_json_parser_error_class = rb_const_get(json, rb_intern("ParserError"));
|
|
842
844
|
} else {
|
|
843
845
|
oj_json_parser_error_class = rb_define_class_under(json, "ParserError", json_error);
|
|
844
846
|
}
|
|
847
|
+
|
|
848
|
+
rb_global_variable(&oj_json_generator_error_class);
|
|
845
849
|
if (rb_const_defined_at(json, rb_intern("GeneratorError"))) {
|
|
846
850
|
oj_json_generator_error_class = rb_const_get(json, rb_intern("GeneratorError"));
|
|
847
851
|
} else {
|
|
@@ -867,8 +871,8 @@ void oj_mimic_json_methods(VALUE json) {
|
|
|
867
871
|
rb_require("oj/state");
|
|
868
872
|
}
|
|
869
873
|
// Pull in the JSON::State mimic file.
|
|
874
|
+
rb_global_variable(&state_class);
|
|
870
875
|
state_class = rb_const_get_at(generator, rb_intern("State"));
|
|
871
|
-
rb_gc_register_mark_object(state_class);
|
|
872
876
|
}
|
|
873
877
|
|
|
874
878
|
/* Document-module: JSON
|
|
@@ -905,7 +909,9 @@ oj_define_mimic_json(int argc, VALUE *argv, VALUE self) {
|
|
|
905
909
|
}
|
|
906
910
|
oj_mimic_json_methods(json);
|
|
907
911
|
|
|
908
|
-
|
|
912
|
+
if (!rb_const_defined(rb_cObject, rb_intern("ActiveSupport"))) {
|
|
913
|
+
rb_define_method(rb_cObject, "to_json", mimic_object_to_json, -1);
|
|
914
|
+
}
|
|
909
915
|
|
|
910
916
|
rb_gv_set("$VERBOSE", verbose);
|
|
911
917
|
|
data/ext/oj/object.c
CHANGED
|
@@ -83,8 +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 args[
|
|
87
|
-
const char *end
|
|
86
|
+
VALUE args[7];
|
|
87
|
+
const char *end = str + len;
|
|
88
|
+
const char *orig = str;
|
|
88
89
|
int n;
|
|
89
90
|
|
|
90
91
|
// year
|
|
@@ -144,7 +145,9 @@ oj_parse_xml_time(const char *str, int len) {
|
|
|
144
145
|
char c = *str++;
|
|
145
146
|
|
|
146
147
|
if ('.' == c) {
|
|
147
|
-
long long
|
|
148
|
+
unsigned long long num = 0;
|
|
149
|
+
unsigned long long den = 1;
|
|
150
|
+
const unsigned long long last_den_limit = ULLONG_MAX / 10;
|
|
148
151
|
|
|
149
152
|
for (; str < end; str++) {
|
|
150
153
|
c = *str;
|
|
@@ -152,9 +155,14 @@ oj_parse_xml_time(const char *str, int len) {
|
|
|
152
155
|
str++;
|
|
153
156
|
break;
|
|
154
157
|
}
|
|
155
|
-
|
|
158
|
+
if (den > last_den_limit) {
|
|
159
|
+
// bail to Time.parse if there are more fractional digits than a ULLONG rational can hold
|
|
160
|
+
return rb_funcall(rb_cTime, oj_parse_id, 1, rb_str_new(orig, len));
|
|
161
|
+
}
|
|
162
|
+
num = num * 10 + (c - '0');
|
|
163
|
+
den *= 10;
|
|
156
164
|
}
|
|
157
|
-
args[5] =
|
|
165
|
+
args[5] = rb_funcall(INT2NUM(n), oj_plus_id, 1, rb_rational_new(ULL2NUM(num), ULL2NUM(den)));
|
|
158
166
|
} else {
|
|
159
167
|
args[5] = rb_ll2inum(n);
|
|
160
168
|
}
|
|
@@ -297,7 +305,7 @@ static int hat_num(ParseInfo pi, Val parent, Val kval, NumInfo ni) {
|
|
|
297
305
|
|
|
298
306
|
static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, volatile VALUE value) {
|
|
299
307
|
if (T_ARRAY == rb_type(value)) {
|
|
300
|
-
|
|
308
|
+
size_t len = RARRAY_LEN(value);
|
|
301
309
|
|
|
302
310
|
if (2 == klen && 'u' == key[1]) {
|
|
303
311
|
volatile VALUE sc;
|
|
@@ -313,19 +321,20 @@ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, vol
|
|
|
313
321
|
if (T_ARRAY == rb_type(e1)) {
|
|
314
322
|
VALUE args[1024];
|
|
315
323
|
volatile VALUE rstr;
|
|
316
|
-
|
|
324
|
+
size_t i;
|
|
325
|
+
size_t cnt = RARRAY_LEN(e1);
|
|
317
326
|
|
|
318
327
|
for (i = 0; i < cnt; i++) {
|
|
319
328
|
rstr = RARRAY_AREF(e1, i);
|
|
320
329
|
args[i] = rb_funcall(rstr, oj_to_sym_id, 0);
|
|
321
330
|
}
|
|
322
|
-
sc = rb_funcall2(rb_cStruct, oj_new_id, cnt, args);
|
|
331
|
+
sc = rb_funcall2(rb_cStruct, oj_new_id, (int)cnt, args);
|
|
323
332
|
} else {
|
|
324
333
|
// If struct is not defined then we let this fail and raise an exception.
|
|
325
334
|
sc = oj_name2struct(pi, *RARRAY_CONST_PTR(value), rb_eArgError);
|
|
326
335
|
}
|
|
327
336
|
if (sc == rb_cRange) {
|
|
328
|
-
parent->val = rb_class_new_instance(len - 1, RARRAY_CONST_PTR(value) + 1, rb_cRange);
|
|
337
|
+
parent->val = rb_class_new_instance((int)(len - 1), RARRAY_CONST_PTR(value) + 1, rb_cRange);
|
|
329
338
|
} else {
|
|
330
339
|
// Create a properly initialized struct instance without calling the initialize method.
|
|
331
340
|
parent->val = rb_obj_alloc(sc);
|
|
@@ -340,10 +349,10 @@ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, vol
|
|
|
340
349
|
slen = FIX2INT(rb_funcall2(parent->val, oj_length_id, 0, 0));
|
|
341
350
|
#endif
|
|
342
351
|
// MRI >= 1.9
|
|
343
|
-
if (len - 1 > slen) {
|
|
352
|
+
if (len - 1 > (size_t)slen) {
|
|
344
353
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "Invalid struct data");
|
|
345
354
|
} else {
|
|
346
|
-
|
|
355
|
+
size_t i;
|
|
347
356
|
|
|
348
357
|
for (i = 0; i < len - 1; i++) {
|
|
349
358
|
rb_struct_aset(parent->val, INT2FIX(i), RARRAY_CONST_PTR(value)[i + 1]);
|
|
@@ -690,9 +699,8 @@ oj_object_parse(int argc, VALUE *argv, VALUE self) {
|
|
|
690
699
|
|
|
691
700
|
if (T_STRING == rb_type(*argv)) {
|
|
692
701
|
return oj_pi_parse(argc, argv, &pi, 0, 0, 1);
|
|
693
|
-
} else {
|
|
694
|
-
return oj_pi_sparse(argc, argv, &pi, 0);
|
|
695
702
|
}
|
|
703
|
+
return oj_pi_sparse(argc, argv, &pi, 0);
|
|
696
704
|
}
|
|
697
705
|
|
|
698
706
|
VALUE
|