oj 3.11.5 → 3.16.5
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 +1421 -0
- data/README.md +19 -5
- data/RELEASE_NOTES.md +61 -0
- data/ext/oj/buf.h +20 -6
- data/ext/oj/cache.c +329 -0
- data/ext/oj/cache.h +22 -0
- data/ext/oj/cache8.c +10 -9
- data/ext/oj/circarray.c +8 -6
- data/ext/oj/circarray.h +2 -2
- data/ext/oj/code.c +19 -33
- data/ext/oj/code.h +2 -2
- data/ext/oj/compat.c +27 -77
- data/ext/oj/custom.c +86 -179
- data/ext/oj/debug.c +126 -0
- data/ext/oj/dump.c +256 -249
- data/ext/oj/dump.h +26 -12
- data/ext/oj/dump_compat.c +565 -642
- data/ext/oj/dump_leaf.c +17 -63
- data/ext/oj/dump_object.c +65 -187
- data/ext/oj/dump_strict.c +27 -51
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/err.c +2 -13
- data/ext/oj/err.h +24 -8
- data/ext/oj/extconf.rb +21 -6
- data/ext/oj/fast.c +149 -149
- data/ext/oj/intern.c +313 -0
- data/ext/oj/intern.h +22 -0
- data/ext/oj/mem.c +318 -0
- data/ext/oj/mem.h +53 -0
- data/ext/oj/mimic_json.c +121 -106
- data/ext/oj/object.c +85 -162
- data/ext/oj/odd.c +89 -67
- data/ext/oj/odd.h +15 -15
- data/ext/oj/oj.c +542 -411
- data/ext/oj/oj.h +99 -73
- data/ext/oj/parse.c +175 -187
- data/ext/oj/parse.h +26 -24
- data/ext/oj/parser.c +1600 -0
- data/ext/oj/parser.h +101 -0
- data/ext/oj/rails.c +112 -159
- data/ext/oj/rails.h +1 -1
- data/ext/oj/reader.c +11 -14
- data/ext/oj/reader.h +4 -2
- data/ext/oj/resolve.c +5 -24
- data/ext/oj/rxclass.c +7 -6
- data/ext/oj/rxclass.h +1 -1
- data/ext/oj/saj.c +22 -33
- data/ext/oj/saj2.c +584 -0
- data/ext/oj/saj2.h +23 -0
- data/ext/oj/scp.c +5 -28
- data/ext/oj/sparse.c +28 -72
- data/ext/oj/stream_writer.c +50 -40
- data/ext/oj/strict.c +56 -61
- data/ext/oj/string_writer.c +72 -39
- data/ext/oj/trace.h +31 -4
- data/ext/oj/usual.c +1218 -0
- data/ext/oj/usual.h +69 -0
- data/ext/oj/util.h +1 -1
- data/ext/oj/val_stack.c +14 -3
- data/ext/oj/val_stack.h +8 -7
- data/ext/oj/validate.c +46 -0
- data/ext/oj/wab.c +63 -88
- data/lib/oj/active_support_helper.rb +1 -3
- data/lib/oj/bag.rb +7 -1
- data/lib/oj/easy_hash.rb +4 -5
- data/lib/oj/error.rb +1 -2
- data/lib/oj/json.rb +162 -150
- data/lib/oj/mimic.rb +9 -7
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/schandler.rb +5 -4
- data/lib/oj/state.rb +12 -8
- data/lib/oj/version.rb +1 -2
- data/lib/oj.rb +2 -0
- data/pages/Compatibility.md +1 -1
- data/pages/InstallOptions.md +20 -0
- data/pages/JsonGem.md +15 -0
- data/pages/Modes.md +8 -3
- data/pages/Options.md +43 -5
- data/pages/Parser.md +309 -0
- data/pages/Rails.md +14 -2
- data/test/_test_active.rb +8 -9
- data/test/_test_active_mimic.rb +7 -8
- data/test/_test_mimic_rails.rb +17 -20
- data/test/activerecord/result_test.rb +5 -6
- data/test/activesupport6/encoding_test.rb +63 -28
- data/test/{activesupport5 → activesupport7}/abstract_unit.rb +16 -12
- data/test/{activesupport5 → activesupport7}/decoding_test.rb +2 -10
- data/test/{activesupport5 → activesupport7}/encoding_test.rb +86 -50
- data/test/{activesupport5 → activesupport7}/encoding_test_cases.rb +6 -0
- data/test/{activesupport5 → activesupport7}/time_zone_test_helpers.rb +8 -0
- data/test/files.rb +15 -15
- data/test/foo.rb +16 -45
- data/test/helper.rb +11 -8
- data/test/isolated/shared.rb +3 -2
- data/test/json_gem/json_addition_test.rb +2 -2
- data/test/json_gem/json_common_interface_test.rb +8 -6
- data/test/json_gem/json_encoding_test.rb +0 -0
- data/test/json_gem/json_ext_parser_test.rb +1 -0
- data/test/json_gem/json_fixtures_test.rb +3 -2
- data/test/json_gem/json_generator_test.rb +56 -38
- data/test/json_gem/json_generic_object_test.rb +11 -11
- data/test/json_gem/json_parser_test.rb +54 -47
- data/test/json_gem/json_string_matching_test.rb +9 -9
- data/test/json_gem/test_helper.rb +7 -3
- data/test/mem.rb +34 -0
- data/test/perf.rb +22 -27
- data/test/perf_compat.rb +31 -33
- data/test/perf_dump.rb +50 -0
- data/test/perf_fast.rb +80 -82
- data/test/perf_file.rb +27 -29
- data/test/perf_object.rb +65 -69
- data/test/perf_once.rb +59 -0
- data/test/perf_parser.rb +183 -0
- data/test/perf_saj.rb +46 -54
- data/test/perf_scp.rb +58 -69
- data/test/perf_simple.rb +41 -39
- data/test/perf_strict.rb +74 -82
- data/test/perf_wab.rb +67 -69
- data/test/prec.rb +5 -5
- data/test/sample/change.rb +0 -1
- data/test/sample/dir.rb +0 -1
- data/test/sample/doc.rb +0 -1
- data/test/sample/file.rb +0 -1
- data/test/sample/group.rb +0 -1
- data/test/sample/hasprops.rb +0 -1
- data/test/sample/layer.rb +0 -1
- data/test/sample/rect.rb +0 -1
- data/test/sample/shape.rb +0 -1
- data/test/sample/text.rb +0 -1
- data/test/sample.rb +16 -16
- data/test/sample_json.rb +8 -8
- data/test/test_compat.rb +95 -43
- data/test/test_custom.rb +73 -51
- data/test/test_debian.rb +7 -10
- data/test/test_fast.rb +135 -79
- data/test/test_file.rb +41 -30
- data/test/test_gc.rb +16 -5
- data/test/test_generate.rb +5 -5
- data/test/test_hash.rb +5 -5
- data/test/test_integer_range.rb +9 -9
- data/test/test_null.rb +20 -20
- data/test/test_object.rb +99 -96
- data/test/test_parser.rb +11 -0
- data/test/test_parser_debug.rb +27 -0
- data/test/test_parser_saj.rb +337 -0
- data/test/test_parser_usual.rb +251 -0
- data/test/test_rails.rb +2 -2
- data/test/test_saj.rb +10 -8
- data/test/test_scp.rb +37 -39
- data/test/test_strict.rb +40 -32
- data/test/test_various.rb +165 -84
- data/test/test_wab.rb +48 -44
- data/test/test_writer.rb +47 -47
- data/test/tests.rb +13 -5
- data/test/tests_mimic.rb +12 -3
- data/test/tests_mimic_addition.rb +12 -3
- metadata +74 -128
- data/ext/oj/hash.c +0 -131
- data/ext/oj/hash.h +0 -19
- data/ext/oj/hash_test.c +0 -491
- data/test/activesupport4/decoding_test.rb +0 -108
- data/test/activesupport4/encoding_test.rb +0 -531
- data/test/activesupport4/test_helper.rb +0 -41
- data/test/activesupport5/test_helper.rb +0 -72
- data/test/bar.rb +0 -35
- data/test/baz.rb +0 -16
- data/test/zoo.rb +0 -13
data/ext/oj/usual.h
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
// Copyright (c) 2022, Peter Ohler, All rights reserved.
|
2
|
+
|
3
|
+
#include <ruby.h>
|
4
|
+
#include <stdbool.h>
|
5
|
+
#include <stdint.h>
|
6
|
+
|
7
|
+
struct _cache;
|
8
|
+
struct _ojParser;
|
9
|
+
|
10
|
+
// Used to mark the start of each Hash, Array, or Object. The members point at
|
11
|
+
// positions of the start in the value stack and if not an Array into the key
|
12
|
+
// stack.
|
13
|
+
typedef struct _col {
|
14
|
+
long vi; // value stack index
|
15
|
+
long ki; // key stack index if an hash else -1 for an array
|
16
|
+
} *Col;
|
17
|
+
|
18
|
+
typedef union _key {
|
19
|
+
struct {
|
20
|
+
int16_t len;
|
21
|
+
char buf[30];
|
22
|
+
};
|
23
|
+
struct {
|
24
|
+
int16_t xlen; // should be the same as len
|
25
|
+
char *key;
|
26
|
+
};
|
27
|
+
} *Key;
|
28
|
+
|
29
|
+
#define MISS_AUTO 'A'
|
30
|
+
#define MISS_RAISE 'R'
|
31
|
+
#define MISS_IGNORE 'I'
|
32
|
+
|
33
|
+
typedef struct _usual {
|
34
|
+
VALUE *vhead;
|
35
|
+
VALUE *vtail;
|
36
|
+
VALUE *vend;
|
37
|
+
|
38
|
+
Col chead;
|
39
|
+
Col ctail;
|
40
|
+
Col cend;
|
41
|
+
|
42
|
+
Key khead;
|
43
|
+
Key ktail;
|
44
|
+
Key kend;
|
45
|
+
|
46
|
+
VALUE (*get_key)(struct _ojParser *p, Key kp);
|
47
|
+
struct _cache *key_cache; // same as str_cache or sym_cache
|
48
|
+
struct _cache *str_cache;
|
49
|
+
struct _cache *sym_cache;
|
50
|
+
struct _cache *class_cache;
|
51
|
+
struct _cache *attr_cache;
|
52
|
+
|
53
|
+
VALUE array_class;
|
54
|
+
VALUE hash_class;
|
55
|
+
|
56
|
+
char *create_id;
|
57
|
+
uint8_t create_id_len;
|
58
|
+
uint8_t cache_str;
|
59
|
+
uint8_t cache_xrate;
|
60
|
+
uint8_t miss_class;
|
61
|
+
bool cache_keys;
|
62
|
+
bool ignore_json_create;
|
63
|
+
bool raise_on_empty;
|
64
|
+
} *Usual;
|
65
|
+
|
66
|
+
// Initialize the parser with the usual delegate. If the usual delegate is
|
67
|
+
// wrapped then this function is called first and then the parser functions
|
68
|
+
// can be replaced.
|
69
|
+
extern void oj_init_usual(struct _ojParser *p, Usual d);
|
data/ext/oj/util.h
CHANGED
data/ext/oj/val_stack.c
CHANGED
@@ -8,11 +8,11 @@
|
|
8
8
|
#include "odd.h"
|
9
9
|
#include "oj.h"
|
10
10
|
|
11
|
-
static void
|
11
|
+
static void stack_mark(void *ptr) {
|
12
12
|
ValStack stack = (ValStack)ptr;
|
13
13
|
Val v;
|
14
14
|
|
15
|
-
if (
|
15
|
+
if (NULL == ptr) {
|
16
16
|
return;
|
17
17
|
}
|
18
18
|
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
@@ -46,6 +46,17 @@ static void mark(void *ptr) {
|
|
46
46
|
#endif
|
47
47
|
}
|
48
48
|
|
49
|
+
static const rb_data_type_t oj_stack_type = {
|
50
|
+
"Oj/stack",
|
51
|
+
{
|
52
|
+
stack_mark,
|
53
|
+
NULL,
|
54
|
+
NULL,
|
55
|
+
},
|
56
|
+
0,
|
57
|
+
0,
|
58
|
+
};
|
59
|
+
|
49
60
|
VALUE
|
50
61
|
oj_stack_init(ValStack stack) {
|
51
62
|
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
@@ -70,7 +81,7 @@ oj_stack_init(ValStack stack) {
|
|
70
81
|
stack->head->clen = 0;
|
71
82
|
stack->head->next = NEXT_NONE;
|
72
83
|
|
73
|
-
return
|
84
|
+
return TypedData_Wrap_Struct(oj_cstack_class, &oj_stack_type, stack);
|
74
85
|
}
|
75
86
|
|
76
87
|
const char *oj_stack_next_string(ValNext n) {
|
data/ext/oj/val_stack.h
CHANGED
@@ -6,6 +6,7 @@
|
|
6
6
|
|
7
7
|
#include <stdint.h>
|
8
8
|
|
9
|
+
#include "mem.h"
|
9
10
|
#include "odd.h"
|
10
11
|
#include "ruby.h"
|
11
12
|
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
@@ -28,10 +29,10 @@ typedef enum {
|
|
28
29
|
|
29
30
|
typedef struct _val {
|
30
31
|
volatile VALUE val;
|
31
|
-
const char
|
32
|
+
const char *key;
|
32
33
|
char karray[32];
|
33
34
|
volatile VALUE key_val;
|
34
|
-
const char
|
35
|
+
const char *classname;
|
35
36
|
VALUE clas;
|
36
37
|
OddArgs odd_args;
|
37
38
|
uint16_t klen;
|
@@ -39,7 +40,7 @@ typedef struct _val {
|
|
39
40
|
char next; // ValNext
|
40
41
|
char k1; // first original character in the key
|
41
42
|
char kalloc;
|
42
|
-
} *
|
43
|
+
} *Val;
|
43
44
|
|
44
45
|
typedef struct _valStack {
|
45
46
|
struct _val base[STACK_INC];
|
@@ -52,7 +53,7 @@ typedef struct _valStack {
|
|
52
53
|
VALUE mutex;
|
53
54
|
#endif
|
54
55
|
|
55
|
-
} *
|
56
|
+
} *ValStack;
|
56
57
|
|
57
58
|
extern VALUE oj_stack_init(ValStack stack);
|
58
59
|
|
@@ -62,7 +63,7 @@ inline static int stack_empty(ValStack stack) {
|
|
62
63
|
|
63
64
|
inline static void stack_cleanup(ValStack stack) {
|
64
65
|
if (stack->base != stack->head) {
|
65
|
-
|
66
|
+
OJ_R_FREE(stack->head);
|
66
67
|
stack->head = NULL;
|
67
68
|
}
|
68
69
|
}
|
@@ -76,10 +77,10 @@ inline static void stack_push(ValStack stack, VALUE val, ValNext next) {
|
|
76
77
|
// A realloc can trigger a GC so make sure it happens outside the lock
|
77
78
|
// but lock before changing pointers.
|
78
79
|
if (stack->base == stack->head) {
|
79
|
-
head =
|
80
|
+
head = OJ_R_ALLOC_N(struct _val, len + STACK_INC);
|
80
81
|
memcpy(head, stack->base, sizeof(struct _val) * len);
|
81
82
|
} else {
|
82
|
-
|
83
|
+
OJ_R_REALLOC_N(head, struct _val, len + STACK_INC);
|
83
84
|
}
|
84
85
|
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
85
86
|
pthread_mutex_lock(&stack->mutex);
|
data/ext/oj/validate.c
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
// Copyright (c) 2021, Peter Ohler, All rights reserved.
|
2
|
+
|
3
|
+
#include "parser.h"
|
4
|
+
|
5
|
+
static void noop(ojParser p) {
|
6
|
+
}
|
7
|
+
|
8
|
+
static VALUE option(ojParser p, const char *key, VALUE value) {
|
9
|
+
rb_raise(rb_eArgError, "%s is not an option for the validate delegate", key);
|
10
|
+
return Qnil;
|
11
|
+
}
|
12
|
+
|
13
|
+
static VALUE result(ojParser p) {
|
14
|
+
return Qnil;
|
15
|
+
}
|
16
|
+
|
17
|
+
static void dfree(ojParser p) {
|
18
|
+
}
|
19
|
+
|
20
|
+
static void mark(ojParser p) {
|
21
|
+
}
|
22
|
+
|
23
|
+
void oj_set_parser_validator(ojParser p) {
|
24
|
+
Funcs end = p->funcs + 3;
|
25
|
+
Funcs f;
|
26
|
+
p->ctx = NULL;
|
27
|
+
|
28
|
+
for (f = p->funcs; f < end; f++) {
|
29
|
+
f->add_null = noop;
|
30
|
+
f->add_true = noop;
|
31
|
+
f->add_false = noop;
|
32
|
+
f->add_int = noop;
|
33
|
+
f->add_float = noop;
|
34
|
+
f->add_big = noop;
|
35
|
+
f->add_str = noop;
|
36
|
+
f->open_array = noop;
|
37
|
+
f->close_array = noop;
|
38
|
+
f->open_object = noop;
|
39
|
+
f->close_object = noop;
|
40
|
+
}
|
41
|
+
p->option = option;
|
42
|
+
p->result = result;
|
43
|
+
p->free = dfree;
|
44
|
+
p->mark = mark;
|
45
|
+
p->start = noop;
|
46
|
+
}
|
data/ext/oj/wab.c
CHANGED
@@ -10,6 +10,7 @@
|
|
10
10
|
#include "dump.h"
|
11
11
|
#include "encode.h"
|
12
12
|
#include "err.h"
|
13
|
+
#include "intern.h"
|
13
14
|
#include "oj.h"
|
14
15
|
#include "parse.h"
|
15
16
|
#include "trace.h"
|
@@ -34,7 +35,7 @@ static VALUE uri_http_clas = Qundef;
|
|
34
35
|
|
35
36
|
///// dump functions /////
|
36
37
|
|
37
|
-
static VALUE resolve_wab_uuid_class() {
|
38
|
+
static VALUE resolve_wab_uuid_class(void) {
|
38
39
|
if (Qundef == wab_uuid_clas) {
|
39
40
|
volatile VALUE wab_module;
|
40
41
|
|
@@ -49,7 +50,7 @@ static VALUE resolve_wab_uuid_class() {
|
|
49
50
|
return wab_uuid_clas;
|
50
51
|
}
|
51
52
|
|
52
|
-
static VALUE resolve_uri_class() {
|
53
|
+
static VALUE resolve_uri_class(void) {
|
53
54
|
if (Qundef == uri_clas) {
|
54
55
|
uri_clas = Qnil;
|
55
56
|
if (rb_const_defined_at(rb_cObject, rb_intern("URI"))) {
|
@@ -59,7 +60,7 @@ static VALUE resolve_uri_class() {
|
|
59
60
|
return uri_clas;
|
60
61
|
}
|
61
62
|
|
62
|
-
static VALUE resolve_uri_http_class() {
|
63
|
+
static VALUE resolve_uri_http_class(void) {
|
63
64
|
if (Qundef == uri_http_clas) {
|
64
65
|
volatile VALUE uri_module;
|
65
66
|
|
@@ -75,15 +76,13 @@ static VALUE resolve_uri_http_class() {
|
|
75
76
|
}
|
76
77
|
|
77
78
|
static void raise_wab(VALUE obj) {
|
78
|
-
rb_raise(rb_eTypeError,
|
79
|
-
"Failed to dump %s Object to JSON in wab mode.\n",
|
80
|
-
rb_class2name(rb_obj_class(obj)));
|
79
|
+
rb_raise(rb_eTypeError, "Failed to dump %s Object to JSON in wab mode.\n", rb_class2name(rb_obj_class(obj)));
|
81
80
|
}
|
82
81
|
|
83
82
|
// Removed dependencies on math due to problems with CentOS 5.4.
|
84
83
|
static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
85
84
|
char buf[64];
|
86
|
-
char
|
85
|
+
char *b;
|
87
86
|
double d = rb_num2dbl(obj);
|
88
87
|
int cnt = 0;
|
89
88
|
|
@@ -123,11 +122,11 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
|
|
123
122
|
*out->cur++ = ']';
|
124
123
|
} else {
|
125
124
|
size = d2 * out->indent + 2;
|
125
|
+
assure_size(out, size * cnt);
|
126
126
|
cnt--;
|
127
127
|
for (i = 0; i <= cnt; i++) {
|
128
|
-
assure_size(out, size);
|
129
128
|
fill_indent(out, d2);
|
130
|
-
oj_dump_wab_val(
|
129
|
+
oj_dump_wab_val(RARRAY_AREF(a, i), d2, out);
|
131
130
|
if (i < cnt) {
|
132
131
|
*out->cur++ = ',';
|
133
132
|
}
|
@@ -193,20 +192,15 @@ static void dump_time(VALUE obj, Out out) {
|
|
193
192
|
time_t sec;
|
194
193
|
long long nsec;
|
195
194
|
|
196
|
-
#ifdef HAVE_RB_TIME_TIMESPEC
|
197
195
|
if (16 <= sizeof(struct timespec)) {
|
198
196
|
struct timespec ts = rb_time_timespec(obj);
|
199
197
|
|
200
198
|
sec = ts.tv_sec;
|
201
199
|
nsec = ts.tv_nsec;
|
202
200
|
} else {
|
203
|
-
sec =
|
204
|
-
nsec =
|
201
|
+
sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
202
|
+
nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
205
203
|
}
|
206
|
-
#else
|
207
|
-
sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
|
208
|
-
nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
|
209
|
-
#endif
|
210
204
|
|
211
205
|
assure_size(out, 36);
|
212
206
|
// 2012-01-05T23:58:07.123456000Z
|
@@ -230,13 +224,13 @@ static void dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
|
|
230
224
|
if (rb_cTime == clas) {
|
231
225
|
dump_time(obj, out);
|
232
226
|
} else if (oj_bigdecimal_class == clas) {
|
233
|
-
volatile VALUE rstr =
|
227
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
234
228
|
|
235
|
-
oj_dump_raw(
|
229
|
+
oj_dump_raw(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), out);
|
236
230
|
} else if (resolve_wab_uuid_class() == clas) {
|
237
|
-
oj_dump_str(
|
231
|
+
oj_dump_str(oj_safe_string_convert(obj), depth, out, false);
|
238
232
|
} else if (resolve_uri_http_class() == clas) {
|
239
|
-
oj_dump_str(
|
233
|
+
oj_dump_str(oj_safe_string_convert(obj), depth, out, false);
|
240
234
|
} else {
|
241
235
|
raise_wab(obj);
|
242
236
|
}
|
@@ -270,9 +264,7 @@ static DumpFunc wab_funcs[] = {
|
|
270
264
|
void oj_dump_wab_val(VALUE obj, int depth, Out out) {
|
271
265
|
int type = rb_type(obj);
|
272
266
|
|
273
|
-
|
274
|
-
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
275
|
-
}
|
267
|
+
TRACE(out->opts->trace, "dump", obj, depth, TraceIn);
|
276
268
|
if (MAX_DEPTH < depth) {
|
277
269
|
rb_raise(rb_eNoMemError, "Too deeply nested.\n");
|
278
270
|
}
|
@@ -281,9 +273,7 @@ void oj_dump_wab_val(VALUE obj, int depth, Out out) {
|
|
281
273
|
|
282
274
|
if (NULL != f) {
|
283
275
|
f(obj, depth, out, false);
|
284
|
-
|
285
|
-
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
286
|
-
}
|
276
|
+
TRACE(out->opts->trace, "dump", obj, depth, TraceOut);
|
287
277
|
return;
|
288
278
|
}
|
289
279
|
}
|
@@ -292,16 +282,35 @@ void oj_dump_wab_val(VALUE obj, int depth, Out out) {
|
|
292
282
|
|
293
283
|
///// load functions /////
|
294
284
|
|
295
|
-
static
|
296
|
-
|
297
|
-
|
285
|
+
static VALUE calc_hash_key(ParseInfo pi, Val parent) {
|
286
|
+
volatile VALUE rkey = parent->key_val;
|
287
|
+
|
288
|
+
if (Qundef != rkey) {
|
289
|
+
rkey = oj_encode(rkey);
|
290
|
+
rkey = rb_str_intern(rkey);
|
291
|
+
|
292
|
+
return rkey;
|
298
293
|
}
|
294
|
+
if (Yes == pi->options.cache_keys) {
|
295
|
+
rkey = oj_sym_intern(parent->key, parent->klen);
|
296
|
+
} else {
|
297
|
+
#if HAVE_RB_ENC_INTERNED_STR
|
298
|
+
rkey = rb_enc_interned_str(parent->key, parent->klen, oj_utf8_encoding);
|
299
|
+
#else
|
300
|
+
rkey = rb_utf8_str_new(parent->key, parent->klen);
|
301
|
+
rkey = rb_str_intern(rkey);
|
302
|
+
OBJ_FREEZE(rkey);
|
303
|
+
#endif
|
304
|
+
}
|
305
|
+
return rkey;
|
306
|
+
}
|
307
|
+
|
308
|
+
static void hash_end(ParseInfo pi) {
|
309
|
+
TRACE_PARSE_HASH_END(pi->options.trace, pi);
|
299
310
|
}
|
300
311
|
|
301
312
|
static void array_end(ParseInfo pi) {
|
302
|
-
|
303
|
-
oj_trace_parse_array_end(pi, __FILE__, __LINE__);
|
304
|
-
}
|
313
|
+
TRACE_PARSE_ARRAY_END(pi->options.trace, pi);
|
305
314
|
}
|
306
315
|
|
307
316
|
static VALUE noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
|
@@ -309,9 +318,7 @@ static VALUE noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
|
|
309
318
|
}
|
310
319
|
|
311
320
|
static void add_value(ParseInfo pi, VALUE val) {
|
312
|
-
|
313
|
-
oj_trace_parse_call("add_value", pi, __FILE__, __LINE__, val);
|
314
|
-
}
|
321
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_value", pi, val);
|
315
322
|
pi->stack.head->val = val;
|
316
323
|
}
|
317
324
|
|
@@ -432,36 +439,34 @@ static VALUE protect_uri(VALUE rstr) {
|
|
432
439
|
return rb_funcall(resolve_uri_class(), oj_parse_id, 1, rstr);
|
433
440
|
}
|
434
441
|
|
435
|
-
static VALUE cstr_to_rstr(const char *str, size_t len) {
|
442
|
+
static VALUE cstr_to_rstr(ParseInfo pi, const char *str, size_t len) {
|
436
443
|
volatile VALUE v = Qnil;
|
437
444
|
|
438
|
-
if (30 == len && '-' == str[4] && '-' == str[7] && 'T' == str[10] && ':' == str[13] &&
|
439
|
-
'
|
445
|
+
if (30 == len && '-' == str[4] && '-' == str[7] && 'T' == str[10] && ':' == str[13] && ':' == str[16] &&
|
446
|
+
'.' == str[19] && 'Z' == str[29]) {
|
440
447
|
if (Qnil != (v = time_parse(str, (int)len))) {
|
441
448
|
return v;
|
442
449
|
}
|
443
450
|
}
|
444
|
-
if (36 == len && '-' == str[8] && '-' == str[13] && '-' == str[18] && '-' == str[23] &&
|
445
|
-
|
451
|
+
if (36 == len && '-' == str[8] && '-' == str[13] && '-' == str[18] && '-' == str[23] && uuid_check(str, (int)len) &&
|
452
|
+
Qnil != resolve_wab_uuid_class()) {
|
446
453
|
return rb_funcall(wab_uuid_clas, oj_new_id, 1, rb_str_new(str, len));
|
447
454
|
}
|
448
|
-
v = rb_str_new(str, len);
|
449
455
|
if (7 < len && 0 == strncasecmp("http://", str, 7)) {
|
450
|
-
int
|
456
|
+
int err = 0;
|
457
|
+
v = rb_str_new(str, len);
|
451
458
|
volatile VALUE uri = rb_protect(protect_uri, v, &err);
|
452
459
|
|
453
460
|
if (0 == err) {
|
454
461
|
return uri;
|
455
462
|
}
|
456
463
|
}
|
457
|
-
return
|
464
|
+
return oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
|
458
465
|
}
|
459
466
|
|
460
467
|
static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
461
|
-
pi->stack.head->val = cstr_to_rstr(str, len);
|
462
|
-
|
463
|
-
oj_trace_parse_call("add_string", pi, __FILE__, __LINE__, pi->stack.head->val);
|
464
|
-
}
|
468
|
+
pi->stack.head->val = cstr_to_rstr(pi, str, len);
|
469
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_string", pi, pi->stack.head->val);
|
465
470
|
}
|
466
471
|
|
467
472
|
static void add_num(ParseInfo pi, NumInfo ni) {
|
@@ -469,40 +474,22 @@ static void add_num(ParseInfo pi, NumInfo ni) {
|
|
469
474
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
|
470
475
|
}
|
471
476
|
pi->stack.head->val = oj_num_as_value(ni);
|
472
|
-
|
473
|
-
oj_trace_parse_call("add_number", pi, __FILE__, __LINE__, pi->stack.head->val);
|
474
|
-
}
|
477
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_number", pi, pi->stack.head->val);
|
475
478
|
}
|
476
479
|
|
477
480
|
static VALUE start_hash(ParseInfo pi) {
|
478
|
-
|
479
|
-
oj_trace_parse_in("start_hash", pi, __FILE__, __LINE__);
|
480
|
-
}
|
481
|
+
TRACE_PARSE_IN(pi->options.trace, "start_hash", pi);
|
481
482
|
if (Qnil != pi->options.hash_class) {
|
482
483
|
return rb_class_new_instance(0, NULL, pi->options.hash_class);
|
483
484
|
}
|
484
485
|
return rb_hash_new();
|
485
486
|
}
|
486
487
|
|
487
|
-
static VALUE calc_hash_key(ParseInfo pi, Val parent) {
|
488
|
-
volatile VALUE rkey = parent->key_val;
|
489
|
-
|
490
|
-
if (Qundef == rkey) {
|
491
|
-
rkey = rb_str_new(parent->key, parent->klen);
|
492
|
-
}
|
493
|
-
rkey = oj_encode(rkey);
|
494
|
-
rkey = rb_str_intern(rkey);
|
495
|
-
|
496
|
-
return rkey;
|
497
|
-
}
|
498
|
-
|
499
488
|
static void hash_set_cstr(ParseInfo pi, Val parent, const char *str, size_t len, const char *orig) {
|
500
|
-
volatile VALUE rval = cstr_to_rstr(str, len);
|
489
|
+
volatile VALUE rval = cstr_to_rstr(pi, str, len);
|
501
490
|
|
502
491
|
rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), rval);
|
503
|
-
|
504
|
-
oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rval);
|
505
|
-
}
|
492
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_string", pi, rval);
|
506
493
|
}
|
507
494
|
|
508
495
|
static void hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
|
@@ -513,32 +500,24 @@ static void hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
|
|
513
500
|
}
|
514
501
|
rval = oj_num_as_value(ni);
|
515
502
|
rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), rval);
|
516
|
-
|
517
|
-
oj_trace_parse_call("set_number", pi, __FILE__, __LINE__, rval);
|
518
|
-
}
|
503
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_number", pi, rval);
|
519
504
|
}
|
520
505
|
|
521
506
|
static void hash_set_value(ParseInfo pi, Val parent, VALUE value) {
|
522
507
|
rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), value);
|
523
|
-
|
524
|
-
oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
|
525
|
-
}
|
508
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_value", pi, value);
|
526
509
|
}
|
527
510
|
|
528
511
|
static VALUE start_array(ParseInfo pi) {
|
529
|
-
|
530
|
-
oj_trace_parse_in("start_array", pi, __FILE__, __LINE__);
|
531
|
-
}
|
512
|
+
TRACE_PARSE_IN(pi->options.trace, "start_array", pi);
|
532
513
|
return rb_ary_new();
|
533
514
|
}
|
534
515
|
|
535
516
|
static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
536
|
-
volatile VALUE rval = cstr_to_rstr(str, len);
|
517
|
+
volatile VALUE rval = cstr_to_rstr(pi, str, len);
|
537
518
|
|
538
519
|
rb_ary_push(stack_peek(&pi->stack)->val, rval);
|
539
|
-
|
540
|
-
oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, rval);
|
541
|
-
}
|
520
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_value", pi, rval);
|
542
521
|
}
|
543
522
|
|
544
523
|
static void array_append_num(ParseInfo pi, NumInfo ni) {
|
@@ -549,16 +528,12 @@ static void array_append_num(ParseInfo pi, NumInfo ni) {
|
|
549
528
|
}
|
550
529
|
rval = oj_num_as_value(ni);
|
551
530
|
rb_ary_push(stack_peek(&pi->stack)->val, rval);
|
552
|
-
|
553
|
-
oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
|
554
|
-
}
|
531
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_number", pi, rval);
|
555
532
|
}
|
556
533
|
|
557
534
|
static void array_append_value(ParseInfo pi, VALUE value) {
|
558
535
|
rb_ary_push(stack_peek(&pi->stack)->val, value);
|
559
|
-
|
560
|
-
oj_trace_parse_call("append_value", pi, __FILE__, __LINE__, value);
|
561
|
-
}
|
536
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_value", pi, value);
|
562
537
|
}
|
563
538
|
|
564
539
|
void oj_set_wab_callbacks(ParseInfo pi) {
|
@@ -1,16 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
require 'active_support/time'
|
3
4
|
|
4
5
|
module Oj
|
5
|
-
|
6
6
|
# Exists only to handle the ActiveSupport::TimeWithZone.
|
7
7
|
class ActiveSupportHelper
|
8
|
-
|
9
8
|
def self.createTimeWithZone(utc, zone)
|
10
9
|
ActiveSupport::TimeWithZone.new(utc - utc.gmt_offset, ActiveSupport::TimeZone[zone])
|
11
10
|
end
|
12
11
|
end
|
13
|
-
|
14
12
|
end
|
15
13
|
|
16
14
|
Oj.register_odd(ActiveSupport::TimeWithZone, Oj::ActiveSupportHelper, :createTimeWithZone, :utc, 'time_zone.name')
|
data/lib/oj/bag.rb
CHANGED
@@ -15,7 +15,7 @@ module Oj
|
|
15
15
|
# @example Oj::Bag.new(:@x => 42, :@y => 57)
|
16
16
|
# @param [Hash] args instance variable symbols and their values
|
17
17
|
def initialize(args = {})
|
18
|
-
args.each do |k,v|
|
18
|
+
args.each do |k, v|
|
19
19
|
self.instance_variable_set(k, v)
|
20
20
|
end
|
21
21
|
end
|
@@ -26,6 +26,7 @@ module Oj
|
|
26
26
|
# variable reader, otherwise false.
|
27
27
|
def respond_to?(m)
|
28
28
|
return true if super
|
29
|
+
|
29
30
|
instance_variables.include?(:"@#{m}")
|
30
31
|
end
|
31
32
|
|
@@ -37,8 +38,10 @@ module Oj
|
|
37
38
|
# @raise [NoMethodError] if the instance variable is not defined.
|
38
39
|
def method_missing(m, *args, &block)
|
39
40
|
raise ArgumentError.new("wrong number of arguments (#{args.size} for 0) to method #{m}") unless args.nil? or args.empty?
|
41
|
+
|
40
42
|
at_m = :"@#{m}"
|
41
43
|
raise NoMethodError.new("undefined method #{m}", m) unless instance_variable_defined?(at_m)
|
44
|
+
|
42
45
|
instance_variable_get(at_m)
|
43
46
|
end
|
44
47
|
|
@@ -47,9 +50,11 @@ module Oj
|
|
47
50
|
# @return [Boolean] true if each variable and value are the same, otherwise false.
|
48
51
|
def eql?(other)
|
49
52
|
return false if (other.nil? or self.class != other.class)
|
53
|
+
|
50
54
|
ova = other.instance_variables
|
51
55
|
iv = instance_variables
|
52
56
|
return false if ova.size != iv.size
|
57
|
+
|
53
58
|
iv.all? { |vid| instance_variable_get(vid) != other.instance_variable_get(vid) }
|
54
59
|
end
|
55
60
|
alias == eql?
|
@@ -65,6 +70,7 @@ module Oj
|
|
65
70
|
classname = classname.to_s unless classname.is_a?(String)
|
66
71
|
tokens = classname.split('::').map(&:to_sym)
|
67
72
|
raise NameError.new("Invalid classname '#{classname}") if tokens.empty?
|
73
|
+
|
68
74
|
m = Object
|
69
75
|
tokens[0..-2].each do |sym|
|
70
76
|
if m.const_defined?(sym)
|
data/lib/oj/easy_hash.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
module Oj
|
3
2
|
|
4
3
|
# A Hash subclass that normalizes the hash keys to allow lookup by the
|
@@ -6,10 +5,6 @@ module Oj
|
|
6
5
|
# that match the keys.
|
7
6
|
class EasyHash < Hash
|
8
7
|
|
9
|
-
# Initializes the instance to an empty Hash.
|
10
|
-
def initialize()
|
11
|
-
end
|
12
|
-
|
13
8
|
# Replaces the Object.respond_to?() method.
|
14
9
|
# @param [Symbol] m method symbol
|
15
10
|
# @param [Boolean] include_all whether to include private and protected methods in the search
|
@@ -19,12 +14,14 @@ module Oj
|
|
19
14
|
return true if super
|
20
15
|
return true if has_key?(m)
|
21
16
|
return true if has_key?(m.to_s)
|
17
|
+
|
22
18
|
has_key?(m.to_sym)
|
23
19
|
end
|
24
20
|
|
25
21
|
def [](key)
|
26
22
|
return fetch(key, nil) if has_key?(key)
|
27
23
|
return fetch(key.to_s, nil) if has_key?(key.to_s)
|
24
|
+
|
28
25
|
fetch(key.to_sym, nil)
|
29
26
|
end
|
30
27
|
|
@@ -36,9 +33,11 @@ module Oj
|
|
36
33
|
def method_missing(m, *args, &block)
|
37
34
|
if m.to_s.end_with?('=')
|
38
35
|
raise ArgumentError.new("wrong number of arguments (#{args.size} for 1 with #{m}) to method #{m}") if args.nil? or 1 != args.length
|
36
|
+
|
39
37
|
m = m[0..-2]
|
40
38
|
return store(m.to_s, args[0]) if has_key?(m.to_s)
|
41
39
|
return store(m.to_sym, args[0]) if has_key?(m.to_sym)
|
40
|
+
|
42
41
|
return store(m, args[0])
|
43
42
|
else
|
44
43
|
raise ArgumentError.new("wrong number of arguments (#{args.size} for 0 with #{m}) to method #{m}") unless args.nil? or args.empty?
|
data/lib/oj/error.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
module Oj
|
3
2
|
|
4
3
|
# Inherit Error class from StandardError.
|
@@ -16,7 +15,7 @@ module Oj
|
|
16
15
|
# An Exception that is raised if a file fails to load.
|
17
16
|
LoadError = Class.new(Error)
|
18
17
|
|
19
|
-
# An Exception that is raised if there is a conflict with
|
18
|
+
# An Exception that is raised if there is a conflict with mimicking JSON
|
20
19
|
MimicError = Class.new(Error)
|
21
20
|
|
22
21
|
end # Oj
|