oj 3.15.0 → 3.15.1
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 +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
|