oj 3.14.1 → 3.14.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 +9 -1
- data/README.md +0 -1
- data/ext/oj/buf.h +7 -6
- data/ext/oj/cache.c +25 -24
- data/ext/oj/cache8.c +10 -9
- data/ext/oj/circarray.c +7 -5
- data/ext/oj/circarray.h +2 -2
- data/ext/oj/code.c +2 -2
- data/ext/oj/code.h +2 -2
- data/ext/oj/compat.c +7 -14
- data/ext/oj/custom.c +3 -2
- data/ext/oj/debug.c +3 -9
- data/ext/oj/dump.c +18 -17
- data/ext/oj/dump_compat.c +551 -576
- data/ext/oj/dump_leaf.c +3 -5
- data/ext/oj/dump_object.c +37 -37
- data/ext/oj/dump_strict.c +2 -4
- data/ext/oj/encoder.c +1 -1
- data/ext/oj/err.c +2 -13
- data/ext/oj/err.h +9 -12
- data/ext/oj/extconf.rb +1 -1
- data/ext/oj/fast.c +33 -46
- data/ext/oj/intern.c +44 -46
- data/ext/oj/intern.h +3 -7
- data/ext/oj/mem.c +318 -0
- data/ext/oj/mem.h +53 -0
- data/ext/oj/mimic_json.c +20 -25
- data/ext/oj/object.c +7 -7
- data/ext/oj/odd.c +8 -6
- data/ext/oj/odd.h +4 -4
- data/ext/oj/oj.c +71 -85
- data/ext/oj/oj.h +53 -54
- data/ext/oj/parse.c +67 -128
- data/ext/oj/parse.h +5 -10
- data/ext/oj/parser.c +13 -14
- data/ext/oj/parser.h +7 -8
- data/ext/oj/rails.c +36 -66
- data/ext/oj/reader.c +8 -11
- data/ext/oj/reader.h +4 -2
- data/ext/oj/resolve.c +3 -4
- data/ext/oj/rxclass.c +6 -5
- data/ext/oj/rxclass.h +1 -1
- data/ext/oj/saj.c +9 -8
- data/ext/oj/saj2.c +36 -52
- data/ext/oj/saj2.h +1 -1
- data/ext/oj/scp.c +3 -14
- data/ext/oj/sparse.c +22 -70
- data/ext/oj/stream_writer.c +9 -21
- data/ext/oj/strict.c +7 -13
- data/ext/oj/string_writer.c +11 -18
- data/ext/oj/trace.h +27 -16
- data/ext/oj/usual.c +89 -87
- data/ext/oj/usual.h +6 -6
- data/ext/oj/util.h +1 -1
- data/ext/oj/val_stack.h +8 -7
- data/ext/oj/wab.c +7 -9
- data/lib/oj/active_support_helper.rb +0 -1
- data/lib/oj/bag.rb +7 -1
- data/lib/oj/easy_hash.rb +4 -5
- data/lib/oj/error.rb +0 -1
- data/lib/oj/json.rb +4 -2
- data/lib/oj/mimic.rb +4 -2
- data/lib/oj/state.rb +8 -5
- data/lib/oj/version.rb +1 -2
- data/lib/oj.rb +0 -1
- data/test/_test_active.rb +0 -1
- data/test/_test_active_mimic.rb +0 -1
- data/test/_test_mimic_rails.rb +0 -1
- data/test/activerecord/result_test.rb +5 -6
- data/test/bar.rb +3 -3
- data/test/files.rb +1 -1
- data/test/foo.rb +5 -3
- data/test/helper.rb +1 -4
- 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 +4 -4
- 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 +43 -32
- data/test/json_gem/json_generic_object_test.rb +11 -11
- data/test/json_gem/json_parser_test.rb +46 -46
- data/test/json_gem/json_string_matching_test.rb +9 -9
- data/test/mem.rb +7 -7
- data/test/perf.rb +2 -2
- data/test/perf_compat.rb +1 -1
- data/test/perf_fast.rb +1 -1
- data/test/perf_file.rb +2 -2
- data/test/perf_object.rb +1 -2
- data/test/perf_once.rb +4 -4
- data/test/perf_parser.rb +2 -2
- data/test/perf_saj.rb +1 -2
- data/test/perf_scp.rb +1 -1
- data/test/perf_simple.rb +3 -3
- data/test/perf_strict.rb +1 -1
- data/test/perf_wab.rb +1 -1
- 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 +2 -3
- data/test/sample_json.rb +0 -1
- data/test/test_compat.rb +11 -9
- data/test/test_custom.rb +5 -9
- data/test/test_debian.rb +1 -1
- data/test/test_fast.rb +10 -20
- data/test/test_file.rb +8 -8
- data/test/test_integer_range.rb +2 -2
- data/test/test_null.rb +5 -3
- data/test/test_object.rb +6 -5
- data/test/test_parser_saj.rb +23 -21
- data/test/test_parser_usual.rb +3 -3
- data/test/test_saj.rb +2 -0
- data/test/test_scp.rb +6 -6
- data/test/test_strict.rb +6 -4
- data/test/test_various.rb +21 -24
- data/test/test_wab.rb +6 -5
- data/test/test_writer.rb +1 -1
- metadata +20 -27
- 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/abstract_unit.rb +0 -45
- data/test/activesupport5/decoding_test.rb +0 -133
- data/test/activesupport5/encoding_test.rb +0 -500
- data/test/activesupport5/encoding_test_cases.rb +0 -98
- data/test/activesupport5/test_helper.rb +0 -72
- data/test/activesupport5/time_zone_test_helpers.rb +0 -39
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ce52cbfa0a36f659877cda70d0376fdc19264f96ff8ff1f8085e8cb3560c8bae
|
|
4
|
+
data.tar.gz: 44b94e3e4174f1464dd7b4f025e28110dc273a353c42a4d8460c6e45846d1fab
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 465dd87a8c8e11b562de10d1ab60d78f8e2250c4c06f997455673ea67fb88c75e1c07dea01c01fa864ebfa39a2b0bee1371ee7551895ba6d125bee3af20975ee
|
|
7
|
+
data.tar.gz: 430a1f0a293fe87fd03af88b2e1f27e70ffae7b7ab8a2451dea1de5891ce6b9967f5475bd33f7cb37c728a7e4ed44b2b3c5051ebeb452c76f393f543a42d5dd1
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 3.14.3 - 2023-04-07
|
|
4
|
+
|
|
5
|
+
- Fixed compat parse with optimized Hash when parsing a JSON::GenericObject.
|
|
6
|
+
|
|
7
|
+
## 3.14.2 - 2023-02-10
|
|
8
|
+
|
|
9
|
+
- Fixed check for \0 in strings.
|
|
10
|
+
|
|
3
11
|
## 3.14.1 - 2023-02-01
|
|
4
12
|
|
|
5
13
|
- Fixed issue with uninitialized handler for Oj::Parser::Saj.
|
|
@@ -10,7 +18,7 @@
|
|
|
10
18
|
|
|
11
19
|
- Tracing is now a compile time option giving a 15 to 20% performance boost.
|
|
12
20
|
|
|
13
|
-
- Some cleanup in
|
|
21
|
+
- Some cleanup in the fast parser.
|
|
14
22
|
|
|
15
23
|
## 3.13.23 - 2022-11-06
|
|
16
24
|
|
data/README.md
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
[](https://github.com/ohler55/oj/actions/workflows/CI.yml)
|
|
4
4
|

|
|
5
5
|

|
|
6
|
-
[](https://dependabot.com/compatibility-score.html?dependency-name=oj&package-manager=bundler&version-scheme=semver)
|
|
7
6
|
[](https://tidelift.com/subscription/pkg/rubygems-oj?utm_source=rubygems-oj&utm_medium=referral&utm_campaign=readme)
|
|
8
7
|
|
|
9
8
|
A *fast* JSON parser and Object marshaller as a Ruby gem.
|
data/ext/oj/buf.h
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
#ifndef OJ_BUF_H
|
|
5
5
|
#define OJ_BUF_H
|
|
6
6
|
|
|
7
|
+
#include "mem.h"
|
|
7
8
|
#include "ruby.h"
|
|
8
9
|
|
|
9
10
|
typedef struct _buf {
|
|
@@ -11,7 +12,7 @@ typedef struct _buf {
|
|
|
11
12
|
char *end;
|
|
12
13
|
char *tail;
|
|
13
14
|
char base[1024];
|
|
14
|
-
} *
|
|
15
|
+
} *Buf;
|
|
15
16
|
|
|
16
17
|
inline static void buf_init(Buf buf) {
|
|
17
18
|
buf->head = buf->base;
|
|
@@ -25,7 +26,7 @@ inline static void buf_reset(Buf buf) {
|
|
|
25
26
|
|
|
26
27
|
inline static void buf_cleanup(Buf buf) {
|
|
27
28
|
if (buf->base != buf->head) {
|
|
28
|
-
|
|
29
|
+
OJ_R_FREE(buf->head);
|
|
29
30
|
}
|
|
30
31
|
}
|
|
31
32
|
|
|
@@ -49,10 +50,10 @@ inline static void buf_append_string(Buf buf, const char *s, size_t slen) {
|
|
|
49
50
|
size_t new_len = len + slen + len / 2;
|
|
50
51
|
|
|
51
52
|
if (buf->base == buf->head) {
|
|
52
|
-
buf->head =
|
|
53
|
+
buf->head = OJ_R_ALLOC_N(char, new_len);
|
|
53
54
|
memcpy(buf->head, buf->base, len);
|
|
54
55
|
} else {
|
|
55
|
-
|
|
56
|
+
OJ_R_REALLOC_N(buf->head, char, new_len);
|
|
56
57
|
}
|
|
57
58
|
buf->tail = buf->head + toff;
|
|
58
59
|
buf->end = buf->head + new_len - 1;
|
|
@@ -68,10 +69,10 @@ inline static void buf_append(Buf buf, char c) {
|
|
|
68
69
|
size_t new_len = len + len / 2;
|
|
69
70
|
|
|
70
71
|
if (buf->base == buf->head) {
|
|
71
|
-
buf->head =
|
|
72
|
+
buf->head = OJ_R_ALLOC_N(char, new_len);
|
|
72
73
|
memcpy(buf->head, buf->base, len);
|
|
73
74
|
} else {
|
|
74
|
-
|
|
75
|
+
OJ_R_REALLOC_N(buf->head, char, new_len);
|
|
75
76
|
}
|
|
76
77
|
buf->tail = buf->head + toff;
|
|
77
78
|
buf->end = buf->head + new_len - 1;
|
data/ext/oj/cache.c
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
#include <stdlib.h>
|
|
8
8
|
|
|
9
9
|
#include "cache.h"
|
|
10
|
+
#include "mem.h"
|
|
10
11
|
|
|
11
12
|
// The stdlib calloc, realloc, and free are used instead of the Ruby ALLOC,
|
|
12
13
|
// ALLOC_N, REALLOC, and xfree since the later could trigger a GC which will
|
|
@@ -28,16 +29,16 @@
|
|
|
28
29
|
#define M 0x5bd1e995
|
|
29
30
|
|
|
30
31
|
typedef struct _slot {
|
|
31
|
-
struct _slot
|
|
32
|
+
struct _slot *next;
|
|
32
33
|
VALUE val;
|
|
33
34
|
uint64_t hash;
|
|
34
35
|
volatile uint32_t use_cnt;
|
|
35
36
|
uint8_t klen;
|
|
36
37
|
char key[CACHE_MAX_KEY];
|
|
37
|
-
} *
|
|
38
|
+
} *Slot;
|
|
38
39
|
|
|
39
40
|
typedef struct _cache {
|
|
40
|
-
volatile Slot
|
|
41
|
+
volatile Slot *slots;
|
|
41
42
|
volatile size_t cnt;
|
|
42
43
|
VALUE (*form)(const char *str, size_t len);
|
|
43
44
|
uint64_t size;
|
|
@@ -52,7 +53,7 @@ typedef struct _cache {
|
|
|
52
53
|
#endif
|
|
53
54
|
uint8_t xrate;
|
|
54
55
|
bool mark;
|
|
55
|
-
} *
|
|
56
|
+
} *Cache;
|
|
56
57
|
|
|
57
58
|
void cache_set_form(Cache c, VALUE (*form)(const char *str, size_t len)) {
|
|
58
59
|
c->form = form;
|
|
@@ -94,13 +95,13 @@ static uint64_t hash_calc(const uint8_t *key, size_t len) {
|
|
|
94
95
|
|
|
95
96
|
static void rehash(Cache c) {
|
|
96
97
|
uint64_t osize;
|
|
97
|
-
Slot
|
|
98
|
-
Slot
|
|
98
|
+
Slot *end;
|
|
99
|
+
Slot *sp;
|
|
99
100
|
|
|
100
101
|
osize = c->size;
|
|
101
102
|
c->size = osize * 4;
|
|
102
103
|
c->mask = c->size - 1;
|
|
103
|
-
c->slots =
|
|
104
|
+
c->slots = OJ_REALLOC((void *)c->slots, sizeof(Slot) * c->size);
|
|
104
105
|
memset((Slot *)c->slots + osize, 0, sizeof(Slot) * osize * 3);
|
|
105
106
|
end = (Slot *)c->slots + osize;
|
|
106
107
|
for (sp = (Slot *)c->slots; sp < end; sp++) {
|
|
@@ -110,7 +111,7 @@ static void rehash(Cache c) {
|
|
|
110
111
|
*sp = NULL;
|
|
111
112
|
for (; NULL != s; s = next) {
|
|
112
113
|
uint64_t h = s->hash & c->mask;
|
|
113
|
-
Slot
|
|
114
|
+
Slot *bucket = (Slot *)c->slots + h;
|
|
114
115
|
|
|
115
116
|
next = s->next;
|
|
116
117
|
s->next = *bucket;
|
|
@@ -121,14 +122,14 @@ static void rehash(Cache c) {
|
|
|
121
122
|
|
|
122
123
|
static VALUE lockless_intern(Cache c, const char *key, size_t len) {
|
|
123
124
|
uint64_t h = hash_calc((const uint8_t *)key, len);
|
|
124
|
-
Slot
|
|
125
|
+
Slot *bucket = (Slot *)c->slots + (h & c->mask);
|
|
125
126
|
Slot b;
|
|
126
127
|
volatile VALUE rkey;
|
|
127
128
|
|
|
128
129
|
while (REUSE_MAX < c->rcnt) {
|
|
129
130
|
if (NULL != (b = c->reuse)) {
|
|
130
131
|
c->reuse = b->next;
|
|
131
|
-
|
|
132
|
+
OJ_FREE(b);
|
|
132
133
|
c->rcnt--;
|
|
133
134
|
} else {
|
|
134
135
|
// An accounting error occured somewhere so correct it.
|
|
@@ -143,7 +144,7 @@ static VALUE lockless_intern(Cache c, const char *key, size_t len) {
|
|
|
143
144
|
}
|
|
144
145
|
rkey = c->form(key, len);
|
|
145
146
|
if (NULL == (b = c->reuse)) {
|
|
146
|
-
b =
|
|
147
|
+
b = OJ_CALLOC(1, sizeof(struct _slot));
|
|
147
148
|
} else {
|
|
148
149
|
c->reuse = b->next;
|
|
149
150
|
c->rcnt--;
|
|
@@ -165,7 +166,7 @@ static VALUE lockless_intern(Cache c, const char *key, size_t len) {
|
|
|
165
166
|
|
|
166
167
|
static VALUE locking_intern(Cache c, const char *key, size_t len) {
|
|
167
168
|
uint64_t h;
|
|
168
|
-
Slot
|
|
169
|
+
Slot *bucket;
|
|
169
170
|
Slot b;
|
|
170
171
|
uint64_t old_size;
|
|
171
172
|
volatile VALUE rkey;
|
|
@@ -174,7 +175,7 @@ static VALUE locking_intern(Cache c, const char *key, size_t len) {
|
|
|
174
175
|
while (REUSE_MAX < c->rcnt) {
|
|
175
176
|
if (NULL != (b = c->reuse)) {
|
|
176
177
|
c->reuse = b->next;
|
|
177
|
-
|
|
178
|
+
OJ_FREE(b);
|
|
178
179
|
c->rcnt--;
|
|
179
180
|
} else {
|
|
180
181
|
// An accounting error occured somewhere so correct it.
|
|
@@ -200,7 +201,7 @@ static VALUE locking_intern(Cache c, const char *key, size_t len) {
|
|
|
200
201
|
}
|
|
201
202
|
CACHE_UNLOCK(c);
|
|
202
203
|
if (NULL == b) {
|
|
203
|
-
b =
|
|
204
|
+
b = OJ_CALLOC(1, sizeof(struct _slot));
|
|
204
205
|
}
|
|
205
206
|
rkey = c->form(key, len);
|
|
206
207
|
b->hash = h;
|
|
@@ -228,7 +229,7 @@ static VALUE locking_intern(Cache c, const char *key, size_t len) {
|
|
|
228
229
|
}
|
|
229
230
|
|
|
230
231
|
Cache cache_create(size_t size, VALUE (*form)(const char *str, size_t len), bool mark, bool locking) {
|
|
231
|
-
Cache c =
|
|
232
|
+
Cache c = OJ_CALLOC(1, sizeof(struct _cache));
|
|
232
233
|
int shift = 0;
|
|
233
234
|
|
|
234
235
|
for (; REHASH_LIMIT < size; size /= 2, shift++) {
|
|
@@ -241,12 +242,12 @@ Cache cache_create(size_t size, VALUE (*form)(const char *str, size_t len), bool
|
|
|
241
242
|
#else
|
|
242
243
|
c->mutex = rb_mutex_new();
|
|
243
244
|
#endif
|
|
244
|
-
c->size
|
|
245
|
-
c->mask
|
|
246
|
-
c->slots
|
|
247
|
-
c->form
|
|
248
|
-
c->xrate
|
|
249
|
-
c->mark
|
|
245
|
+
c->size = 1 << shift;
|
|
246
|
+
c->mask = c->size - 1;
|
|
247
|
+
c->slots = OJ_CALLOC(c->size, sizeof(Slot));
|
|
248
|
+
c->form = form;
|
|
249
|
+
c->xrate = 1; // low
|
|
250
|
+
c->mark = mark;
|
|
250
251
|
if (locking) {
|
|
251
252
|
c->intern = locking_intern;
|
|
252
253
|
} else {
|
|
@@ -268,11 +269,11 @@ void cache_free(Cache c) {
|
|
|
268
269
|
|
|
269
270
|
for (s = c->slots[i]; NULL != s; s = next) {
|
|
270
271
|
next = s->next;
|
|
271
|
-
|
|
272
|
+
OJ_FREE(s);
|
|
272
273
|
}
|
|
273
274
|
}
|
|
274
|
-
|
|
275
|
-
|
|
275
|
+
OJ_FREE((void *)c->slots);
|
|
276
|
+
OJ_FREE(c);
|
|
276
277
|
}
|
|
277
278
|
|
|
278
279
|
void cache_mark(Cache c) {
|
data/ext/oj/cache8.c
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
#include <stdlib.h>
|
|
10
10
|
#include <string.h>
|
|
11
11
|
|
|
12
|
+
#include "mem.h"
|
|
12
13
|
#include "ruby.h"
|
|
13
14
|
|
|
14
15
|
#define BITS 4
|
|
@@ -32,16 +33,18 @@ void oj_cache8_new(Cache8 *cache) {
|
|
|
32
33
|
Bucket *b;
|
|
33
34
|
int i;
|
|
34
35
|
|
|
35
|
-
*cache =
|
|
36
|
+
*cache = OJ_R_ALLOC(struct _cache8);
|
|
36
37
|
for (i = SLOT_CNT, b = (*cache)->buckets; 0 < i; i--, b++) {
|
|
37
38
|
b->value = 0;
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
void oj_cache8_delete(Cache8 cache) {
|
|
42
|
+
void oj_cache8_delete(Cache8 cache) {
|
|
43
|
+
cache8_delete(cache, 0);
|
|
44
|
+
}
|
|
42
45
|
|
|
43
46
|
static void cache8_delete(Cache8 cache, int depth) {
|
|
44
|
-
Bucket
|
|
47
|
+
Bucket *b;
|
|
45
48
|
unsigned int i;
|
|
46
49
|
|
|
47
50
|
for (i = 0, b = cache->buckets; i < SLOT_CNT; i++, b++) {
|
|
@@ -51,7 +54,7 @@ static void cache8_delete(Cache8 cache, int depth) {
|
|
|
51
54
|
}
|
|
52
55
|
}
|
|
53
56
|
}
|
|
54
|
-
|
|
57
|
+
OJ_R_FREE(cache);
|
|
55
58
|
}
|
|
56
59
|
|
|
57
60
|
slot_t oj_cache8_get(Cache8 cache, sid_t key, slot_t **slot) {
|
|
@@ -79,7 +82,7 @@ void oj_cache8_print(Cache8 cache) {
|
|
|
79
82
|
}
|
|
80
83
|
|
|
81
84
|
static void slot_print(Cache8 c, sid_t key, unsigned int depth) {
|
|
82
|
-
Bucket
|
|
85
|
+
Bucket *b;
|
|
83
86
|
unsigned int i;
|
|
84
87
|
sid_t k8 = (sid_t)key;
|
|
85
88
|
sid_t k;
|
|
@@ -90,11 +93,9 @@ static void slot_print(Cache8 c, sid_t key, unsigned int depth) {
|
|
|
90
93
|
/*printf("*** key: 0x%016llx depth: %u i: %u\n", k, depth, i); */
|
|
91
94
|
if (DEPTH - 1 == depth) {
|
|
92
95
|
#if IS_WINDOWS
|
|
93
|
-
printf("0x%016lx: %4lu\n", (long unsigned int)k,
|
|
94
|
-
(long unsigned int)b->value);
|
|
96
|
+
printf("0x%016lx: %4lu\n", (long unsigned int)k, (long unsigned int)b->value);
|
|
95
97
|
#else
|
|
96
|
-
printf("0x%016llx: %4llu\n", (long long unsigned int)k,
|
|
97
|
-
(long long unsigned int)b->value);
|
|
98
|
+
printf("0x%016llx: %4llu\n", (long long unsigned int)k, (long long unsigned int)b->value);
|
|
98
99
|
#endif
|
|
99
100
|
} else {
|
|
100
101
|
slot_print(b->child, k, depth + 1);
|
data/ext/oj/circarray.c
CHANGED
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
|
|
4
4
|
#include "circarray.h"
|
|
5
5
|
|
|
6
|
+
#include "mem.h"
|
|
7
|
+
|
|
6
8
|
CircArray oj_circ_array_new(void) {
|
|
7
9
|
CircArray ca;
|
|
8
10
|
|
|
9
|
-
if (0 == (ca =
|
|
11
|
+
if (0 == (ca = OJ_R_ALLOC(struct _circArray))) {
|
|
10
12
|
rb_raise(rb_eNoMemError, "not enough memory\n");
|
|
11
13
|
}
|
|
12
14
|
ca->objs = ca->obj_array;
|
|
@@ -18,9 +20,9 @@ CircArray oj_circ_array_new(void) {
|
|
|
18
20
|
|
|
19
21
|
void oj_circ_array_free(CircArray ca) {
|
|
20
22
|
if (ca->objs != ca->obj_array) {
|
|
21
|
-
|
|
23
|
+
OJ_R_FREE(ca->objs);
|
|
22
24
|
}
|
|
23
|
-
|
|
25
|
+
OJ_R_FREE(ca);
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
void oj_circ_array_set(CircArray ca, VALUE obj, unsigned long id) {
|
|
@@ -31,12 +33,12 @@ void oj_circ_array_set(CircArray ca, VALUE obj, unsigned long id) {
|
|
|
31
33
|
unsigned long cnt = id + 512;
|
|
32
34
|
|
|
33
35
|
if (ca->objs == ca->obj_array) {
|
|
34
|
-
if (0 == (ca->objs =
|
|
36
|
+
if (0 == (ca->objs = OJ_R_ALLOC_N(VALUE, cnt))) {
|
|
35
37
|
rb_raise(rb_eNoMemError, "not enough memory\n");
|
|
36
38
|
}
|
|
37
39
|
memcpy(ca->objs, ca->obj_array, sizeof(VALUE) * ca->cnt);
|
|
38
40
|
} else {
|
|
39
|
-
|
|
41
|
+
OJ_R_REALLOC_N(ca->objs, VALUE, cnt);
|
|
40
42
|
}
|
|
41
43
|
ca->size = cnt;
|
|
42
44
|
}
|
data/ext/oj/circarray.h
CHANGED
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
|
|
10
10
|
typedef struct _circArray {
|
|
11
11
|
VALUE obj_array[1024];
|
|
12
|
-
VALUE
|
|
12
|
+
VALUE* objs;
|
|
13
13
|
unsigned long size; // allocated size or initial array size
|
|
14
14
|
unsigned long cnt;
|
|
15
|
-
}
|
|
15
|
+
}* CircArray;
|
|
16
16
|
|
|
17
17
|
extern CircArray oj_circ_array_new(void);
|
|
18
18
|
extern void oj_circ_array_free(CircArray ca);
|
data/ext/oj/code.c
CHANGED
|
@@ -18,8 +18,8 @@ inline static VALUE resolve_classname(VALUE mod, const char *classname) {
|
|
|
18
18
|
static VALUE path2class(const char *name) {
|
|
19
19
|
char class_name[1024];
|
|
20
20
|
VALUE clas;
|
|
21
|
-
char
|
|
22
|
-
char
|
|
21
|
+
char *end = class_name + sizeof(class_name) - 1;
|
|
22
|
+
char *s;
|
|
23
23
|
const char *n = name;
|
|
24
24
|
|
|
25
25
|
clas = rb_cObject;
|
data/ext/oj/code.h
CHANGED
|
@@ -17,7 +17,7 @@ typedef struct _code {
|
|
|
17
17
|
EncodeFunc encode;
|
|
18
18
|
DecodeFunc decode;
|
|
19
19
|
bool active; // For compat mode.
|
|
20
|
-
} *
|
|
20
|
+
} *Code;
|
|
21
21
|
|
|
22
22
|
// Used by encode functions.
|
|
23
23
|
typedef struct _attr {
|
|
@@ -26,7 +26,7 @@ typedef struct _attr {
|
|
|
26
26
|
VALUE value;
|
|
27
27
|
long num;
|
|
28
28
|
VALUE time;
|
|
29
|
-
} *
|
|
29
|
+
} *Attr;
|
|
30
30
|
|
|
31
31
|
extern bool oj_code_dump(Code codes, VALUE obj, int depth, Out out);
|
|
32
32
|
extern VALUE oj_code_load(Code codes, VALUE clas, VALUE args);
|
data/ext/oj/compat.c
CHANGED
|
@@ -6,13 +6,14 @@
|
|
|
6
6
|
#include "encode.h"
|
|
7
7
|
#include "err.h"
|
|
8
8
|
#include "intern.h"
|
|
9
|
+
#include "mem.h"
|
|
9
10
|
#include "oj.h"
|
|
10
11
|
#include "parse.h"
|
|
11
12
|
#include "resolve.h"
|
|
12
13
|
#include "trace.h"
|
|
13
14
|
|
|
14
15
|
static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
|
|
15
|
-
const char
|
|
16
|
+
const char *key = kval->key;
|
|
16
17
|
int klen = kval->klen;
|
|
17
18
|
Val parent = stack_peek(&pi->stack);
|
|
18
19
|
volatile VALUE rkey = kval->key_val;
|
|
@@ -30,7 +31,7 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
|
|
|
30
31
|
if (Yes == pi->options.sym_key) {
|
|
31
32
|
rkey = ID2SYM(rb_intern3(key, klen, oj_utf8_encoding));
|
|
32
33
|
} else {
|
|
33
|
-
|
|
34
|
+
rkey = rb_utf8_str_new(key, klen);
|
|
34
35
|
}
|
|
35
36
|
} else if (Yes == pi->options.sym_key) {
|
|
36
37
|
rkey = oj_sym_intern(key, klen);
|
|
@@ -85,7 +86,7 @@ static void end_hash(struct _parseInfo *pi) {
|
|
|
85
86
|
}
|
|
86
87
|
}
|
|
87
88
|
if (0 != parent->classname) {
|
|
88
|
-
|
|
89
|
+
OJ_R_FREE((char *)parent->classname);
|
|
89
90
|
parent->classname = 0;
|
|
90
91
|
}
|
|
91
92
|
}
|
|
@@ -115,16 +116,12 @@ static void add_num(ParseInfo pi, NumInfo ni) {
|
|
|
115
116
|
static void hash_set_num(struct _parseInfo *pi, Val parent, NumInfo ni) {
|
|
116
117
|
volatile VALUE rval = oj_num_as_value(ni);
|
|
117
118
|
|
|
118
|
-
if (
|
|
119
|
+
if (rb_cHash != rb_obj_class(parent->val)) {
|
|
119
120
|
// The rb_hash_set would still work but the unit tests for the
|
|
120
121
|
// json gem require the less efficient []= method be called to set
|
|
121
122
|
// values. Even using the store method to set the values will fail
|
|
122
123
|
// the unit tests.
|
|
123
|
-
rb_funcall(stack_peek(&pi->stack)->val,
|
|
124
|
-
rb_intern("[]="),
|
|
125
|
-
2,
|
|
126
|
-
oj_calc_hash_key(pi, parent),
|
|
127
|
-
rval);
|
|
124
|
+
rb_funcall(stack_peek(&pi->stack)->val, rb_intern("[]="), 2, oj_calc_hash_key(pi, parent), rval);
|
|
128
125
|
} else {
|
|
129
126
|
rb_hash_aset(stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, parent), rval);
|
|
130
127
|
}
|
|
@@ -137,11 +134,7 @@ static void hash_set_value(ParseInfo pi, Val parent, VALUE value) {
|
|
|
137
134
|
// json gem require the less efficient []= method be called to set
|
|
138
135
|
// values. Even using the store method to set the values will fail
|
|
139
136
|
// the unit tests.
|
|
140
|
-
rb_funcall(stack_peek(&pi->stack)->val,
|
|
141
|
-
rb_intern("[]="),
|
|
142
|
-
2,
|
|
143
|
-
oj_calc_hash_key(pi, parent),
|
|
144
|
-
value);
|
|
137
|
+
rb_funcall(stack_peek(&pi->stack)->val, rb_intern("[]="), 2, oj_calc_hash_key(pi, parent), value);
|
|
145
138
|
} else {
|
|
146
139
|
rb_hash_aset(stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, parent), value);
|
|
147
140
|
}
|
data/ext/oj/custom.c
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
#include "encode.h"
|
|
10
10
|
#include "err.h"
|
|
11
11
|
#include "intern.h"
|
|
12
|
+
#include "mem.h"
|
|
12
13
|
#include "odd.h"
|
|
13
14
|
#include "oj.h"
|
|
14
15
|
#include "parse.h"
|
|
@@ -437,7 +438,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
|
|
|
437
438
|
ID i;
|
|
438
439
|
|
|
439
440
|
if (sizeof(nbuf) <= nlen) {
|
|
440
|
-
if (NULL == (n2 =
|
|
441
|
+
if (NULL == (n2 = OJ_STRDUP(name))) {
|
|
441
442
|
rb_raise(rb_eNoMemError, "for attribute name.");
|
|
442
443
|
}
|
|
443
444
|
} else {
|
|
@@ -454,7 +455,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
|
|
|
454
455
|
i = rb_intern(n);
|
|
455
456
|
v = rb_funcall(v, i, 0);
|
|
456
457
|
if (nbuf != n2) {
|
|
457
|
-
|
|
458
|
+
OJ_FREE(n2);
|
|
458
459
|
}
|
|
459
460
|
}
|
|
460
461
|
fill_indent(out, d2);
|
data/ext/oj/debug.c
CHANGED
|
@@ -30,9 +30,7 @@ static void add_int(struct _ojParser *p) {
|
|
|
30
30
|
switch (p->stack[p->depth]) {
|
|
31
31
|
case TOP_FUN: printf("*** add_int %lld at top\n", (long long)p->num.fixnum); break;
|
|
32
32
|
case ARRAY_FUN: printf("*** add_int %lld to array\n", (long long)p->num.fixnum); break;
|
|
33
|
-
case OBJECT_FUN:
|
|
34
|
-
printf("*** add_int %lld with '%s'\n", (long long)p->num.fixnum, buf_str(&p->key));
|
|
35
|
-
break;
|
|
33
|
+
case OBJECT_FUN: printf("*** add_int %lld with '%s'\n", (long long)p->num.fixnum, buf_str(&p->key)); break;
|
|
36
34
|
}
|
|
37
35
|
}
|
|
38
36
|
|
|
@@ -48,9 +46,7 @@ static void add_big(struct _ojParser *p) {
|
|
|
48
46
|
switch (p->stack[p->depth]) {
|
|
49
47
|
case TOP_FUN: printf("*** add_big %s at top\n", buf_str(&p->buf)); break;
|
|
50
48
|
case ARRAY_FUN: printf("*** add_big %s to array\n", buf_str(&p->buf)); break;
|
|
51
|
-
case OBJECT_FUN:
|
|
52
|
-
printf("*** add_big %s with '%s'\n", buf_str(&p->buf), buf_str(&p->key));
|
|
53
|
-
break;
|
|
49
|
+
case OBJECT_FUN: printf("*** add_big %s with '%s'\n", buf_str(&p->buf), buf_str(&p->key)); break;
|
|
54
50
|
}
|
|
55
51
|
}
|
|
56
52
|
|
|
@@ -58,9 +54,7 @@ static void add_str(struct _ojParser *p) {
|
|
|
58
54
|
switch (p->stack[p->depth]) {
|
|
59
55
|
case TOP_FUN: printf("*** add_str '%s' at top\n", buf_str(&p->buf)); break;
|
|
60
56
|
case ARRAY_FUN: printf("*** add_str '%s' to array\n", buf_str(&p->buf)); break;
|
|
61
|
-
case OBJECT_FUN:
|
|
62
|
-
printf("*** add_str '%s' with '%s'\n", buf_str(&p->buf), buf_str(&p->key));
|
|
63
|
-
break;
|
|
57
|
+
case OBJECT_FUN: printf("*** add_str '%s' with '%s'\n", buf_str(&p->buf), buf_str(&p->key)); break;
|
|
64
58
|
}
|
|
65
59
|
}
|
|
66
60
|
|
data/ext/oj/dump.c
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
#endif
|
|
16
16
|
|
|
17
17
|
#include "cache8.h"
|
|
18
|
+
#include "mem.h"
|
|
18
19
|
#include "odd.h"
|
|
19
20
|
#include "oj.h"
|
|
20
21
|
#include "trace.h"
|
|
@@ -305,8 +306,8 @@ static const char *dump_unicode(const char *str, const char *end, Out out, const
|
|
|
305
306
|
uint32_t c1;
|
|
306
307
|
|
|
307
308
|
code -= 0x00010000;
|
|
308
|
-
c1
|
|
309
|
-
code
|
|
309
|
+
c1 = ((code >> 10) & 0x000003FF) + 0x0000D800;
|
|
310
|
+
code = (code & 0x000003FF) + 0x0000DC00;
|
|
310
311
|
APPEND_CHARS(out->cur, "\\u", 2);
|
|
311
312
|
for (i = 3; 0 <= i; i--) {
|
|
312
313
|
*out->cur++ = hex_chars[(uint8_t)(c1 >> (i * 4)) & 0x0F];
|
|
@@ -609,7 +610,7 @@ void oj_write_obj_to_file(VALUE obj, const char *path, Options copts) {
|
|
|
609
610
|
|
|
610
611
|
oj_out_init(&out);
|
|
611
612
|
|
|
612
|
-
out.omit_nil
|
|
613
|
+
out.omit_nil = copts->dump_opts.omit_nil;
|
|
613
614
|
oj_dump_obj_to_json(obj, copts, &out);
|
|
614
615
|
size = out.cur - out.buf;
|
|
615
616
|
if (0 == (f = fopen(path, "w"))) {
|
|
@@ -657,7 +658,7 @@ void oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts) {
|
|
|
657
658
|
|
|
658
659
|
oj_out_init(&out);
|
|
659
660
|
|
|
660
|
-
out.omit_nil
|
|
661
|
+
out.omit_nil = copts->dump_opts.omit_nil;
|
|
661
662
|
oj_dump_obj_to_json(obj, copts, &out);
|
|
662
663
|
size = out.cur - out.buf;
|
|
663
664
|
if (oj_stringio_class == clas) {
|
|
@@ -697,7 +698,7 @@ void oj_dump_str(VALUE obj, int depth, Out out, bool as_ok) {
|
|
|
697
698
|
|
|
698
699
|
if (oj_utf8_encoding_index != idx) {
|
|
699
700
|
rb_encoding *enc = rb_enc_from_index(idx);
|
|
700
|
-
obj
|
|
701
|
+
obj = rb_str_conv_enc(obj, enc, oj_utf8_encoding);
|
|
701
702
|
}
|
|
702
703
|
oj_dump_cstr(RSTRING_PTR(obj), (int)RSTRING_LEN(obj), 0, 0, out);
|
|
703
704
|
}
|
|
@@ -760,8 +761,8 @@ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out ou
|
|
|
760
761
|
break;
|
|
761
762
|
case SlashEsc:
|
|
762
763
|
has_hi = true;
|
|
763
|
-
cmap
|
|
764
|
-
size
|
|
764
|
+
cmap = slash_friendly_chars;
|
|
765
|
+
size = slash_friendly_size((uint8_t *)str, cnt);
|
|
765
766
|
break;
|
|
766
767
|
case XSSEsc:
|
|
767
768
|
cmap = xss_friendly_chars;
|
|
@@ -940,15 +941,15 @@ void oj_dump_raw(const char *str, size_t cnt, Out out) {
|
|
|
940
941
|
}
|
|
941
942
|
|
|
942
943
|
void oj_out_init(Out out) {
|
|
943
|
-
out->buf
|
|
944
|
-
out->cur
|
|
945
|
-
out->end
|
|
944
|
+
out->buf = out->stack_buffer;
|
|
945
|
+
out->cur = out->buf;
|
|
946
|
+
out->end = out->buf + sizeof(out->stack_buffer) - BUFFER_EXTRA;
|
|
946
947
|
out->allocated = false;
|
|
947
948
|
}
|
|
948
949
|
|
|
949
950
|
void oj_out_free(Out out) {
|
|
950
951
|
if (out->allocated) {
|
|
951
|
-
|
|
952
|
+
OJ_R_FREE(out->buf); // TBD
|
|
952
953
|
}
|
|
953
954
|
}
|
|
954
955
|
|
|
@@ -962,9 +963,9 @@ void oj_grow_out(Out out, size_t len) {
|
|
|
962
963
|
size += len;
|
|
963
964
|
}
|
|
964
965
|
if (out->allocated) {
|
|
965
|
-
|
|
966
|
+
OJ_R_REALLOC_N(buf, char, (size + BUFFER_EXTRA));
|
|
966
967
|
} else {
|
|
967
|
-
buf =
|
|
968
|
+
buf = OJ_R_ALLOC_N(char, (size + BUFFER_EXTRA));
|
|
968
969
|
out->allocated = true;
|
|
969
970
|
memcpy(buf, out->buf, out->end - out->buf + BUFFER_EXTRA);
|
|
970
971
|
}
|
|
@@ -979,24 +980,24 @@ void oj_grow_out(Out out, size_t len) {
|
|
|
979
980
|
void oj_dump_nil(VALUE obj, int depth, Out out, bool as_ok) {
|
|
980
981
|
assure_size(out, 4);
|
|
981
982
|
APPEND_CHARS(out->cur, "null", 4);
|
|
982
|
-
*out->cur
|
|
983
|
+
*out->cur = '\0';
|
|
983
984
|
}
|
|
984
985
|
|
|
985
986
|
void oj_dump_true(VALUE obj, int depth, Out out, bool as_ok) {
|
|
986
987
|
assure_size(out, 4);
|
|
987
988
|
APPEND_CHARS(out->cur, "true", 4);
|
|
988
|
-
*out->cur
|
|
989
|
+
*out->cur = '\0';
|
|
989
990
|
}
|
|
990
991
|
|
|
991
992
|
void oj_dump_false(VALUE obj, int depth, Out out, bool as_ok) {
|
|
992
993
|
assure_size(out, 5);
|
|
993
994
|
APPEND_CHARS(out->cur, "false", 5);
|
|
994
|
-
*out->cur
|
|
995
|
+
*out->cur = '\0';
|
|
995
996
|
}
|
|
996
997
|
|
|
997
998
|
void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
|
|
998
999
|
char buf[32];
|
|
999
|
-
char
|
|
1000
|
+
char *b = buf + sizeof(buf) - 1;
|
|
1000
1001
|
long long num = NUM2LL(obj);
|
|
1001
1002
|
int neg = 0;
|
|
1002
1003
|
size_t cnt = 0;
|