oj 3.15.0 → 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 +6 -0
- data/ext/oj/code.c +3 -10
- data/ext/oj/compat.c +5 -18
- data/ext/oj/custom.c +5 -13
- data/ext/oj/dump.c +25 -20
- 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 +0 -1
- data/ext/oj/oj.c +4 -4
- data/ext/oj/oj.h +7 -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/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/test/foo.rb +10 -5
- data/test/perf_dump.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 257582096951b3c4db4b4979c49afd542ae855ba454bd6d51dcb1a69f68c2405
|
4
|
+
data.tar.gz: d835a958d019f7034e93d3f97ca1829fad74a4e26743f6a8b2b581c03ac9f14a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 374e55547de2db4b2199c05bebe5fa74953021883f7f609e328466c076016817b0cb8a7be03ead9c68b3fe4895eb5de0bcd60e1384ff7f1a5f7cd480824faba0
|
7
|
+
data.tar.gz: ec9cf41116602a51c49ff73ba6fc39ecbb501d51cbab0a6065bb38d2ac15a7f42332dc66f0d97df40bea6da5fafbc15209d06039180829c4c4b299b0e138676e
|
data/CHANGELOG.md
CHANGED
data/ext/oj/code.c
CHANGED
@@ -185,24 +185,17 @@ void oj_code_attrs(VALUE obj, Attr attrs, int depth, Out out, bool with_class) {
|
|
185
185
|
} else {
|
186
186
|
char buf[32];
|
187
187
|
char *b = buf + sizeof(buf) - 1;
|
188
|
-
|
188
|
+
bool neg = false;
|
189
189
|
long num = attrs->num;
|
190
190
|
size_t cnt = 0;
|
191
191
|
|
192
192
|
if (0 > num) {
|
193
|
-
neg =
|
193
|
+
neg = true;
|
194
194
|
num = -num;
|
195
195
|
}
|
196
196
|
*b-- = '\0';
|
197
197
|
if (0 < num) {
|
198
|
-
|
199
|
-
*b = (num % 10) + '0';
|
200
|
-
}
|
201
|
-
if (neg) {
|
202
|
-
*b = '-';
|
203
|
-
} else {
|
204
|
-
b++;
|
205
|
-
}
|
198
|
+
b = oj_longlong_to_string(num, neg, b);
|
206
199
|
} else {
|
207
200
|
*b = '0';
|
208
201
|
}
|
data/ext/oj/compat.c
CHANGED
@@ -13,32 +13,19 @@
|
|
13
13
|
#include "trace.h"
|
14
14
|
|
15
15
|
static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
|
16
|
-
const char
|
17
|
-
int
|
18
|
-
Val
|
19
|
-
volatile VALUE rkey = kval->key_val;
|
16
|
+
const char *key = kval->key;
|
17
|
+
int klen = kval->klen;
|
18
|
+
Val parent = stack_peek(&pi->stack);
|
20
19
|
|
21
|
-
if (Qundef ==
|
20
|
+
if (Qundef == kval->key_val && Yes == pi->options.create_ok && NULL != pi->options.create_id &&
|
22
21
|
*pi->options.create_id == *key && (int)pi->options.create_id_len == klen &&
|
23
22
|
0 == strncmp(pi->options.create_id, key, klen)) {
|
24
23
|
parent->classname = oj_strndup(str, len);
|
25
24
|
parent->clen = len;
|
26
25
|
} else {
|
27
26
|
volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
|
27
|
+
volatile VALUE rkey = oj_calc_hash_key(pi, kval);
|
28
28
|
|
29
|
-
if (Qundef == rkey) {
|
30
|
-
if (Yes != pi->options.cache_keys) {
|
31
|
-
if (Yes == pi->options.sym_key) {
|
32
|
-
rkey = ID2SYM(rb_intern3(key, klen, oj_utf8_encoding));
|
33
|
-
} else {
|
34
|
-
rkey = rb_utf8_str_new(key, klen);
|
35
|
-
}
|
36
|
-
} else if (Yes == pi->options.sym_key) {
|
37
|
-
rkey = oj_sym_intern(key, klen);
|
38
|
-
} else {
|
39
|
-
rkey = oj_str_intern(key, klen);
|
40
|
-
}
|
41
|
-
}
|
42
29
|
if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
|
43
30
|
VALUE clas = oj_rxclass_match(&pi->options.str_rx, str, (int)len);
|
44
31
|
|
data/ext/oj/custom.c
CHANGED
@@ -889,12 +889,11 @@ void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok) {
|
|
889
889
|
///// load functions /////
|
890
890
|
|
891
891
|
static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
|
892
|
-
const char
|
893
|
-
int
|
894
|
-
Val
|
895
|
-
volatile VALUE rkey = kval->key_val;
|
892
|
+
const char *key = kval->key;
|
893
|
+
int klen = kval->klen;
|
894
|
+
Val parent = stack_peek(&pi->stack);
|
896
895
|
|
897
|
-
if (Qundef ==
|
896
|
+
if (Qundef == kval->key_val && Yes == pi->options.create_ok && NULL != pi->options.create_id &&
|
898
897
|
*pi->options.create_id == *key && (int)pi->options.create_id_len == klen &&
|
899
898
|
0 == strncmp(pi->options.create_id, key, klen)) {
|
900
899
|
parent->clas = oj_name2class(pi, str, len, false, rb_eArgError);
|
@@ -907,15 +906,8 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
|
|
907
906
|
}
|
908
907
|
} else {
|
909
908
|
volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
|
910
|
-
|
909
|
+
volatile VALUE rkey = oj_calc_hash_key(pi, kval);
|
911
910
|
|
912
|
-
if (Qundef == rkey) {
|
913
|
-
if (Yes == pi->options.sym_key) {
|
914
|
-
rkey = ID2SYM(rb_intern3(key, klen, oj_utf8_encoding));
|
915
|
-
} else {
|
916
|
-
rkey = rb_utf8_str_new(key, klen);
|
917
|
-
}
|
918
|
-
}
|
919
911
|
if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
|
920
912
|
VALUE clas = oj_rxclass_match(&pi->options.str_rx, str, (int)len);
|
921
913
|
|
data/ext/oj/dump.c
CHANGED
@@ -1010,11 +1010,33 @@ static const char digits_table[] = "\
|
|
1010
1010
|
80818283848586878889\
|
1011
1011
|
90919293949596979899";
|
1012
1012
|
|
1013
|
+
char *oj_longlong_to_string(long long num, bool negative, char *buf) {
|
1014
|
+
while (100 <= num) {
|
1015
|
+
unsigned idx = num % 100 * 2;
|
1016
|
+
*buf-- = digits_table[idx + 1];
|
1017
|
+
*buf-- = digits_table[idx];
|
1018
|
+
num /= 100;
|
1019
|
+
}
|
1020
|
+
if (num < 10) {
|
1021
|
+
*buf-- = num + '0';
|
1022
|
+
} else {
|
1023
|
+
*buf-- = digits_table[num * 2 + 1];
|
1024
|
+
*buf-- = digits_table[num * 2];
|
1025
|
+
}
|
1026
|
+
|
1027
|
+
if (negative) {
|
1028
|
+
*buf = '-';
|
1029
|
+
} else {
|
1030
|
+
buf++;
|
1031
|
+
}
|
1032
|
+
return buf;
|
1033
|
+
}
|
1034
|
+
|
1013
1035
|
void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
|
1014
1036
|
char buf[32];
|
1015
1037
|
char *b = buf + sizeof(buf) - 1;
|
1016
1038
|
long long num = NUM2LL(obj);
|
1017
|
-
|
1039
|
+
bool neg = false;
|
1018
1040
|
size_t cnt = 0;
|
1019
1041
|
bool dump_as_string = false;
|
1020
1042
|
|
@@ -1023,7 +1045,7 @@ void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1023
1045
|
dump_as_string = true;
|
1024
1046
|
}
|
1025
1047
|
if (0 > num) {
|
1026
|
-
neg =
|
1048
|
+
neg = true;
|
1027
1049
|
num = -num;
|
1028
1050
|
}
|
1029
1051
|
*b-- = '\0';
|
@@ -1032,24 +1054,7 @@ void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1032
1054
|
*b-- = '"';
|
1033
1055
|
}
|
1034
1056
|
if (0 < num) {
|
1035
|
-
|
1036
|
-
unsigned idx = num % 100 * 2;
|
1037
|
-
*b-- = digits_table[idx + 1];
|
1038
|
-
*b-- = digits_table[idx];
|
1039
|
-
num /= 100;
|
1040
|
-
}
|
1041
|
-
if (num < 10) {
|
1042
|
-
*b-- = num + '0';
|
1043
|
-
} else {
|
1044
|
-
*b-- = digits_table[num * 2 + 1];
|
1045
|
-
*b-- = digits_table[num * 2];
|
1046
|
-
}
|
1047
|
-
|
1048
|
-
if (neg) {
|
1049
|
-
*b = '-';
|
1050
|
-
} else {
|
1051
|
-
b++;
|
1052
|
-
}
|
1057
|
+
b = oj_longlong_to_string(num, neg, b);
|
1053
1058
|
} else {
|
1054
1059
|
*b = '0';
|
1055
1060
|
}
|
data/ext/oj/dump.h
CHANGED
@@ -93,10 +93,7 @@ inline static void dump_ulong(unsigned long num, Out out) {
|
|
93
93
|
|
94
94
|
*b-- = '\0';
|
95
95
|
if (0 < num) {
|
96
|
-
|
97
|
-
*b = (num % 10) + '0';
|
98
|
-
}
|
99
|
-
b++;
|
96
|
+
b = oj_longlong_to_string((long long)num, false, b);
|
100
97
|
} else {
|
101
98
|
*b = '0';
|
102
99
|
}
|
data/ext/oj/extconf.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'mkmf'
|
2
4
|
require 'rbconfig'
|
3
5
|
|
@@ -6,7 +8,7 @@ dir_config(extension_name)
|
|
6
8
|
|
7
9
|
parts = RUBY_DESCRIPTION.split(' ')
|
8
10
|
type = parts[0]
|
9
|
-
type = type[4
|
11
|
+
type = type[4..] if type.start_with?('tcs-')
|
10
12
|
is_windows = RbConfig::CONFIG['host_os'] =~ /(mingw|mswin)/
|
11
13
|
platform = RUBY_PLATFORM
|
12
14
|
version = RUBY_VERSION.split('.')
|
@@ -56,7 +58,7 @@ dflags.each do |k, v|
|
|
56
58
|
end
|
57
59
|
|
58
60
|
$CPPFLAGS += ' -Wall'
|
59
|
-
#puts "*** $CPPFLAGS: #{$CPPFLAGS}"
|
61
|
+
# puts "*** $CPPFLAGS: #{$CPPFLAGS}"
|
60
62
|
# Adding the __attribute__ flag only works with gcc compilers and even then it
|
61
63
|
# does not work to check args with varargs so just remove the check.
|
62
64
|
CONFIG['warnflags'].slice!(/ -Wsuggest-attribute=format/)
|
data/ext/oj/fast.c
CHANGED
@@ -40,7 +40,7 @@ typedef struct _doc {
|
|
40
40
|
Leaf *where; // points to current location
|
41
41
|
Leaf where_path[MAX_STACK]; // points to head of path
|
42
42
|
char *json;
|
43
|
-
unsigned long size;
|
43
|
+
unsigned long size; // number of leaves/branches in the doc
|
44
44
|
VALUE self;
|
45
45
|
Batch batches;
|
46
46
|
struct _batch batch0;
|
@@ -114,10 +114,7 @@ inline static char *ulong_fill(char *s, size_t num) {
|
|
114
114
|
char *b = buf + sizeof(buf) - 1;
|
115
115
|
|
116
116
|
*b-- = '\0';
|
117
|
-
|
118
|
-
*b = (num % 10) + '0';
|
119
|
-
}
|
120
|
-
b++;
|
117
|
+
b = oj_longlong_to_string((long long)num, false, b);
|
121
118
|
if ('\0' == *b) {
|
122
119
|
b--;
|
123
120
|
*b = '0';
|
@@ -576,7 +573,7 @@ static char *read_quoted_value(ParseInfo pi) {
|
|
576
573
|
char *h = pi->s; // head
|
577
574
|
char *t = h; // tail
|
578
575
|
|
579
|
-
h++;
|
576
|
+
h++; // skip quote character
|
580
577
|
t++;
|
581
578
|
value = h;
|
582
579
|
for (; '"' != *h; h++, t++) {
|
data/ext/oj/mimic_json.c
CHANGED
@@ -574,7 +574,6 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
|
|
574
574
|
if (T_HASH != rb_type(ropts)) {
|
575
575
|
rb_raise(rb_eArgError, "options must be a hash.");
|
576
576
|
}
|
577
|
-
|
578
577
|
rb_hash_foreach(ropts, parse_options_cb, (VALUE)&pi);
|
579
578
|
v = rb_hash_lookup(ropts, oj_max_nesting_sym);
|
580
579
|
if (Qtrue == v) {
|
data/ext/oj/oj.c
CHANGED
@@ -232,7 +232,7 @@ struct _options oj_default_options = {
|
|
232
232
|
NULL, // tail
|
233
233
|
{'\0'}, // err
|
234
234
|
},
|
235
|
-
NULL,
|
235
|
+
NULL, // ignore
|
236
236
|
};
|
237
237
|
|
238
238
|
/* Document-method: default_options()
|
@@ -1294,9 +1294,9 @@ static VALUE dump(int argc, VALUE *argv, VALUE self) {
|
|
1294
1294
|
|
1295
1295
|
oj_out_init(arg.out);
|
1296
1296
|
|
1297
|
-
arg.out->omit_nil
|
1297
|
+
arg.out->omit_nil = copts.dump_opts.omit_nil;
|
1298
1298
|
arg.out->omit_null_byte = copts.dump_opts.omit_null_byte;
|
1299
|
-
arg.out->caller
|
1299
|
+
arg.out->caller = CALLER_DUMP;
|
1300
1300
|
|
1301
1301
|
return rb_ensure(dump_body, (VALUE)&arg, dump_ensure, (VALUE)&arg);
|
1302
1302
|
}
|
@@ -1343,7 +1343,7 @@ static VALUE to_json(int argc, VALUE *argv, VALUE self) {
|
|
1343
1343
|
|
1344
1344
|
oj_out_init(&out);
|
1345
1345
|
|
1346
|
-
out.omit_nil
|
1346
|
+
out.omit_nil = copts.dump_opts.omit_nil;
|
1347
1347
|
out.omit_null_byte = copts.dump_opts.omit_null_byte;
|
1348
1348
|
// For obj.to_json or generate nan is not allowed but if called from dump
|
1349
1349
|
// it is.
|
data/ext/oj/oj.h
CHANGED
@@ -262,12 +262,13 @@ extern VALUE oj_custom_parse_cstr(int argc, VALUE *argv, char *json, size_t len)
|
|
262
262
|
extern bool oj_hash_has_key(VALUE hash, VALUE key);
|
263
263
|
extern void oj_parse_options(VALUE ropts, Options copts);
|
264
264
|
|
265
|
-
extern void
|
266
|
-
extern void
|
267
|
-
extern void
|
268
|
-
extern void
|
269
|
-
extern void
|
270
|
-
extern void
|
265
|
+
extern void oj_dump_obj_to_json(VALUE obj, Options copts, Out out);
|
266
|
+
extern void oj_dump_obj_to_json_using_params(VALUE obj, Options copts, Out out, int argc, VALUE *argv);
|
267
|
+
extern void oj_write_obj_to_file(VALUE obj, const char *path, Options copts);
|
268
|
+
extern void oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts);
|
269
|
+
extern void oj_dump_leaf_to_json(Leaf leaf, Options copts, Out out);
|
270
|
+
extern void oj_write_leaf_to_file(Leaf leaf, const char *path, Options copts);
|
271
|
+
extern char *oj_longlong_to_string(long long num, bool negative, char *buf);
|
271
272
|
|
272
273
|
extern void oj_str_writer_push_key(StrWriter sw, const char *key);
|
273
274
|
extern void oj_str_writer_push_object(StrWriter sw, const char *key);
|
data/ext/oj/parse.c
CHANGED
@@ -426,6 +426,7 @@ static void read_num(ParseInfo pi) {
|
|
426
426
|
struct _numInfo ni;
|
427
427
|
Val parent = stack_peek(&pi->stack);
|
428
428
|
|
429
|
+
ni.pi = pi;
|
429
430
|
ni.str = pi->cur;
|
430
431
|
ni.i = 0;
|
431
432
|
ni.num = 0;
|
@@ -709,10 +710,7 @@ void oj_parse2(ParseInfo pi) {
|
|
709
710
|
case '[': array_start(pi); break;
|
710
711
|
case ']': array_end(pi); break;
|
711
712
|
case ',': comma(pi); break;
|
712
|
-
case '"':
|
713
|
-
read_str(pi);
|
714
|
-
break;
|
715
|
-
// case '+':
|
713
|
+
case '"': read_str(pi); break;
|
716
714
|
case '+':
|
717
715
|
if (CompatMode == pi->options.mode) {
|
718
716
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "unexpected character");
|
@@ -877,7 +875,7 @@ oj_num_as_value(NumInfo ni) {
|
|
877
875
|
double d = strtod(ni->str, &end);
|
878
876
|
|
879
877
|
if ((long)ni->len != (long)(end - ni->str)) {
|
880
|
-
rb_raise(
|
878
|
+
rb_raise(ni->pi->err_class, "Invalid float");
|
881
879
|
}
|
882
880
|
rnum = rb_float_new(d);
|
883
881
|
}
|
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
|
@@ -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
data/test/foo.rb
CHANGED
@@ -5,11 +5,16 @@ $LOAD_PATH << '.'
|
|
5
5
|
$LOAD_PATH << File.join(__dir__, '../lib')
|
6
6
|
$LOAD_PATH << File.join(__dir__, '../ext')
|
7
7
|
|
8
|
+
require 'active_support'
|
9
|
+
require 'json'
|
8
10
|
require 'oj'
|
9
11
|
|
10
|
-
|
12
|
+
Oj.mimic_JSON()
|
13
|
+
# Oj::Rails.mimic_JSON()
|
11
14
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
begin
|
16
|
+
::JSON.parse('{ "foo": 84e }')
|
17
|
+
#::JSON.parse('{ "foo": 84eb234 }')
|
18
|
+
rescue Exception => e
|
19
|
+
puts "#{e.class}: #{e.message}"
|
20
|
+
end
|
data/test/perf_dump.rb
CHANGED
@@ -24,8 +24,8 @@ opts.parse(ARGV)
|
|
24
24
|
@obj = {
|
25
25
|
'a' => 'Alpha', # string
|
26
26
|
'b' => true, # boolean
|
27
|
-
'c' =>
|
28
|
-
'd' => [ true, [false, [-
|
27
|
+
'c' => 12_345, # number
|
28
|
+
'd' => [ true, [false, [-123_456_789, nil], 3.9676, ['Something else.', false], nil]], # mix it up array
|
29
29
|
'e' => { 'zero' => nil, 'one' => 1, 'two' => 2, 'three' => [3], 'four' => [0, 1, 2, 3, 4] }, # hash
|
30
30
|
'f' => nil, # nil
|
31
31
|
'h' => { 'a' => { 'b' => { 'c' => { 'd' => {'e' => { 'f' => { 'g' => nil }}}}}}}, # deep hash, not that deep
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oj
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.15.
|
4
|
+
version: 3.15.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Ohler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|