oj 3.13.23 → 3.14.2
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 +16 -0
- data/README.md +2 -1
- data/ext/oj/buf.h +6 -5
- data/ext/oj/cache.c +11 -10
- data/ext/oj/cache8.c +3 -2
- data/ext/oj/circarray.c +6 -5
- data/ext/oj/compat.c +12 -31
- data/ext/oj/custom.c +16 -31
- data/ext/oj/dump.c +10 -13
- data/ext/oj/dump_compat.c +9 -19
- data/ext/oj/dump_object.c +8 -13
- data/ext/oj/dump_strict.c +8 -18
- data/ext/oj/extconf.rb +10 -2
- data/ext/oj/fast.c +31 -47
- data/ext/oj/intern.c +7 -5
- data/ext/oj/mem.c +324 -0
- data/ext/oj/mem.h +53 -0
- data/ext/oj/mimic_json.c +3 -2
- data/ext/oj/object.c +9 -13
- data/ext/oj/odd.c +7 -6
- data/ext/oj/oj.c +12 -5
- data/ext/oj/oj.h +6 -0
- data/ext/oj/parse.c +18 -13
- data/ext/oj/parser.c +7 -7
- data/ext/oj/rails.c +19 -28
- data/ext/oj/reader.c +4 -3
- data/ext/oj/reader.h +3 -1
- data/ext/oj/rxclass.c +5 -4
- data/ext/oj/saj.c +6 -5
- data/ext/oj/saj2.c +10 -5
- data/ext/oj/sparse.c +5 -4
- data/ext/oj/stream_writer.c +5 -4
- data/ext/oj/strict.c +4 -12
- data/ext/oj/string_writer.c +7 -6
- data/ext/oj/trace.h +16 -0
- data/ext/oj/usual.c +28 -27
- data/ext/oj/val_stack.h +4 -3
- data/ext/oj/wab.c +9 -21
- data/lib/oj/version.rb +1 -1
- data/pages/InstallOptions.md +20 -0
- data/test/foo.rb +46 -65
- data/test/perf_parser.rb +1 -0
- data/test/test_compat.rb +9 -0
- metadata +7 -3
data/ext/oj/string_writer.c
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
// Copyright (c) 2012, 2017 Peter Ohler. All rights reserved.
|
2
2
|
// Licensed under the MIT License. See LICENSE file in the project root for license details.
|
3
3
|
|
4
|
+
#include "mem.h"
|
4
5
|
#include "dump.h"
|
5
6
|
#include "encode.h"
|
6
7
|
|
@@ -20,7 +21,7 @@ static void push_type(StrWriter sw, DumpType type) {
|
|
20
21
|
if (sw->types_end <= sw->types + sw->depth + 1) {
|
21
22
|
size_t size = (sw->types_end - sw->types) * 2;
|
22
23
|
|
23
|
-
|
24
|
+
OJ_R_REALLOC_N(sw->types, char, size);
|
24
25
|
sw->types_end = sw->types + size;
|
25
26
|
}
|
26
27
|
sw->depth++;
|
@@ -43,7 +44,7 @@ static void maybe_comma(StrWriter sw) {
|
|
43
44
|
void oj_str_writer_init(StrWriter sw, int buf_size) {
|
44
45
|
sw->opts = oj_default_options;
|
45
46
|
sw->depth = 0;
|
46
|
-
sw->types =
|
47
|
+
sw->types = OJ_R_ALLOC_N(char, 256);
|
47
48
|
sw->types_end = sw->types + 256;
|
48
49
|
*sw->types = '\0';
|
49
50
|
sw->keyWritten = 0;
|
@@ -55,7 +56,7 @@ void oj_str_writer_init(StrWriter sw, int buf_size) {
|
|
55
56
|
}
|
56
57
|
// Must be allocated. Using the out.stack_buffer results in double frees
|
57
58
|
// and I haven't figured out why yet.
|
58
|
-
sw->out.buf =
|
59
|
+
sw->out.buf = OJ_R_ALLOC_N(char, buf_size);
|
59
60
|
sw->out.cur = sw->out.buf;
|
60
61
|
sw->out.end = sw->out.buf + buf_size - BUFFER_EXTRA;
|
61
62
|
sw->out.allocated = true;
|
@@ -235,8 +236,8 @@ static void str_writer_free(void *ptr) {
|
|
235
236
|
|
236
237
|
oj_out_free(&sw->out);
|
237
238
|
|
238
|
-
|
239
|
-
|
239
|
+
OJ_R_FREE(sw->types);
|
240
|
+
OJ_R_FREE(ptr);
|
240
241
|
}
|
241
242
|
|
242
243
|
/* Document-method: new
|
@@ -256,7 +257,7 @@ static void str_writer_free(void *ptr) {
|
|
256
257
|
* - *options* [_Hash_] formatting options
|
257
258
|
*/
|
258
259
|
static VALUE str_writer_new(int argc, VALUE *argv, VALUE self) {
|
259
|
-
StrWriter sw =
|
260
|
+
StrWriter sw = OJ_R_ALLOC(struct _strWriter);
|
260
261
|
|
261
262
|
oj_str_writer_init(sw, 0);
|
262
263
|
if (1 == argc) {
|
data/ext/oj/trace.h
CHANGED
@@ -25,4 +25,20 @@ extern void
|
|
25
25
|
extern void oj_trace_parse_hash_end(struct _parseInfo *pi, const char *file, int line);
|
26
26
|
extern void oj_trace_parse_array_end(struct _parseInfo *pi, const char *file, int line);
|
27
27
|
|
28
|
+
|
29
|
+
#ifdef OJ_ENABLE_TRACE_LOG
|
30
|
+
#define TRACE(option, func, obj, depth, where) if (RB_UNLIKELY(Yes == option)) { oj_trace(func, obj, __FILE__, __LINE__, depth, where); }
|
31
|
+
#define TRACE_PARSE_IN(option, func, pi) if (RB_UNLIKELY(Yes == option)) { oj_trace_parse_in(func, pi, __FILE__, __LINE__); }
|
32
|
+
#define TRACE_PARSE_CALL(option, func, pi, obj) if (RB_UNLIKELY(Yes == option)) { oj_trace_parse_call(func, pi, __FILE__, __LINE__, obj); }
|
33
|
+
#define TRACE_PARSE_HASH_END(option, pi) if (RB_UNLIKELY(Yes == option)) { oj_trace_parse_hash_end(pi, __FILE__, __LINE__); }
|
34
|
+
#define TRACE_PARSE_ARRAY_END(option, pi) if (RB_UNLIKELY(Yes == option)) { oj_trace_parse_array_end(pi, __FILE__, __LINE__); }
|
35
|
+
#else
|
36
|
+
#define TRACE(option, func, obj, depth, where)
|
37
|
+
#define TRACE_PARSE_IN(option, func, pi)
|
38
|
+
#define TRACE_PARSE_CALL(option, func, pi, obj)
|
39
|
+
#define TRACE_PARSE_HASH_END(option, pi)
|
40
|
+
#define TRACE_PARSE_ARRAY_END(option, pi)
|
41
|
+
#endif
|
42
|
+
|
43
|
+
|
28
44
|
#endif /* OJ_TRACE_H */
|
data/ext/oj/usual.c
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
// Copyright (c) 2021, Peter Ohler, All rights reserved.
|
2
2
|
|
3
|
+
#include "mem.h"
|
3
4
|
#include "cache.h"
|
4
5
|
#include "oj.h"
|
5
6
|
#include "parser.h"
|
@@ -34,7 +35,7 @@ static ID ltlt_id = 0;
|
|
34
35
|
static ID hset_id = 0;
|
35
36
|
|
36
37
|
static char *str_dup(const char *s, size_t len) {
|
37
|
-
char *d =
|
38
|
+
char *d = OJ_R_ALLOC_N(char, len + 1);
|
38
39
|
|
39
40
|
memcpy(d, s, len);
|
40
41
|
d[len] = '\0';
|
@@ -54,7 +55,7 @@ static VALUE form_attr(const char *str, size_t len) {
|
|
54
55
|
char buf[256];
|
55
56
|
|
56
57
|
if (sizeof(buf) - 2 <= len) {
|
57
|
-
char *b =
|
58
|
+
char *b = OJ_R_ALLOC_N(char, len + 2);
|
58
59
|
ID id;
|
59
60
|
|
60
61
|
*b = '@';
|
@@ -62,7 +63,7 @@ static VALUE form_attr(const char *str, size_t len) {
|
|
62
63
|
b[len + 1] = '\0';
|
63
64
|
|
64
65
|
id = rb_intern3(buf, len + 1, oj_utf8_encoding);
|
65
|
-
|
66
|
+
OJ_R_FREE(b);
|
66
67
|
return id;
|
67
68
|
}
|
68
69
|
*buf = '@';
|
@@ -130,7 +131,7 @@ static void assure_cstack(Usual d) {
|
|
130
131
|
long pos = d->ctail - d->chead;
|
131
132
|
|
132
133
|
cap *= 2;
|
133
|
-
|
134
|
+
OJ_R_REALLOC_N(d->chead, struct _col, cap);
|
134
135
|
d->ctail = d->chead + pos;
|
135
136
|
d->cend = d->chead + cap;
|
136
137
|
}
|
@@ -144,7 +145,7 @@ static void push(ojParser p, VALUE v) {
|
|
144
145
|
long pos = d->vtail - d->vhead;
|
145
146
|
|
146
147
|
cap *= 2;
|
147
|
-
|
148
|
+
OJ_R_REALLOC_N(d->vhead, VALUE, cap);
|
148
149
|
d->vtail = d->vhead + pos;
|
149
150
|
d->vend = d->vhead + cap;
|
150
151
|
}
|
@@ -194,7 +195,7 @@ static void push_key(ojParser p) {
|
|
194
195
|
long pos = d->ktail - d->khead;
|
195
196
|
|
196
197
|
cap *= 2;
|
197
|
-
|
198
|
+
OJ_R_REALLOC_N(d->khead, union _key, cap);
|
198
199
|
d->ktail = d->khead + pos;
|
199
200
|
d->kend = d->khead + cap;
|
200
201
|
}
|
@@ -216,7 +217,7 @@ static void push2(ojParser p, VALUE v) {
|
|
216
217
|
long pos = d->vtail - d->vhead;
|
217
218
|
|
218
219
|
cap *= 2;
|
219
|
-
|
220
|
+
OJ_R_REALLOC_N(d->vhead, VALUE, cap);
|
220
221
|
d->vtail = d->vhead + pos;
|
221
222
|
d->vend = d->vhead + cap;
|
222
223
|
}
|
@@ -283,7 +284,7 @@ static void close_object(ojParser p) {
|
|
283
284
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
284
285
|
*vp = d->get_key(p, kp);
|
285
286
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
286
|
-
|
287
|
+
OJ_R_FREE(kp->key);
|
287
288
|
}
|
288
289
|
}
|
289
290
|
rb_hash_bulk_insert(d->vtail - head, head, obj);
|
@@ -291,7 +292,7 @@ static void close_object(ojParser p) {
|
|
291
292
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
292
293
|
rb_hash_aset(obj, d->get_key(p, kp), *(vp + 1));
|
293
294
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
294
|
-
|
295
|
+
OJ_R_FREE(kp->key);
|
295
296
|
}
|
296
297
|
}
|
297
298
|
#endif
|
@@ -315,7 +316,7 @@ static void close_object_class(ojParser p) {
|
|
315
316
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
316
317
|
rb_funcall(obj, hset_id, 2, d->get_key(p, kp), *(vp + 1));
|
317
318
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
318
|
-
|
319
|
+
OJ_R_FREE(kp->key);
|
319
320
|
}
|
320
321
|
}
|
321
322
|
d->ktail = d->khead + c->ki;
|
@@ -343,7 +344,7 @@ static void close_object_create(ojParser p) {
|
|
343
344
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
344
345
|
*vp = d->get_key(p, kp);
|
345
346
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
346
|
-
|
347
|
+
OJ_R_FREE(kp->key);
|
347
348
|
}
|
348
349
|
}
|
349
350
|
rb_hash_bulk_insert(d->vtail - head, head, obj);
|
@@ -351,7 +352,7 @@ static void close_object_create(ojParser p) {
|
|
351
352
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
352
353
|
rb_hash_aset(obj, d->get_key(p, kp), *(vp + 1));
|
353
354
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
354
|
-
|
355
|
+
OJ_R_FREE(kp->key);
|
355
356
|
}
|
356
357
|
}
|
357
358
|
#endif
|
@@ -360,7 +361,7 @@ static void close_object_create(ojParser p) {
|
|
360
361
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
361
362
|
rb_funcall(obj, hset_id, 2, d->get_key(p, kp), *(vp + 1));
|
362
363
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
363
|
-
|
364
|
+
OJ_R_FREE(kp->key);
|
364
365
|
}
|
365
366
|
}
|
366
367
|
}
|
@@ -375,7 +376,7 @@ static void close_object_create(ojParser p) {
|
|
375
376
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
376
377
|
*vp = d->get_key(p, kp);
|
377
378
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
378
|
-
|
379
|
+
OJ_R_FREE(kp->key);
|
379
380
|
}
|
380
381
|
}
|
381
382
|
rb_hash_bulk_insert(d->vtail - head, head, arg);
|
@@ -383,7 +384,7 @@ static void close_object_create(ojParser p) {
|
|
383
384
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
384
385
|
rb_hash_aset(arg, d->get_key(p, kp), *(vp + 1));
|
385
386
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
386
|
-
|
387
|
+
OJ_R_FREE(kp->key);
|
387
388
|
}
|
388
389
|
}
|
389
390
|
#endif
|
@@ -393,7 +394,7 @@ static void close_object_create(ojParser p) {
|
|
393
394
|
for (vp = head; kp < d->ktail; kp++, vp += 2) {
|
394
395
|
rb_ivar_set(obj, get_attr_id(p, kp), *(vp + 1));
|
395
396
|
if (sizeof(kp->buf) <= (size_t)kp->len) {
|
396
|
-
|
397
|
+
OJ_R_FREE(kp->key);
|
397
398
|
}
|
398
399
|
}
|
399
400
|
}
|
@@ -621,11 +622,11 @@ static void dfree(ojParser p) {
|
|
621
622
|
if (NULL != d->class_cache) {
|
622
623
|
cache_free(d->class_cache);
|
623
624
|
}
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
625
|
+
OJ_R_FREE(d->vhead);
|
626
|
+
OJ_R_FREE(d->chead);
|
627
|
+
OJ_R_FREE(d->khead);
|
628
|
+
OJ_R_FREE(d->create_id);
|
629
|
+
OJ_R_FREE(p->ctx);
|
629
630
|
p->ctx = NULL;
|
630
631
|
}
|
631
632
|
|
@@ -777,14 +778,14 @@ static VALUE opt_capacity_set(ojParser p, VALUE value) {
|
|
777
778
|
if (d->vend - d->vhead < cap) {
|
778
779
|
long pos = d->vtail - d->vhead;
|
779
780
|
|
780
|
-
|
781
|
+
OJ_R_REALLOC_N(d->vhead, VALUE, cap);
|
781
782
|
d->vtail = d->vhead + pos;
|
782
783
|
d->vend = d->vhead + cap;
|
783
784
|
}
|
784
785
|
if (d->kend - d->khead < cap) {
|
785
786
|
long pos = d->ktail - d->khead;
|
786
787
|
|
787
|
-
|
788
|
+
OJ_R_REALLOC_N(d->khead, union _key, cap);
|
788
789
|
d->ktail = d->khead + pos;
|
789
790
|
d->kend = d->khead + cap;
|
790
791
|
}
|
@@ -1111,16 +1112,16 @@ static VALUE option(ojParser p, const char *key, VALUE value) {
|
|
1111
1112
|
void oj_init_usual(ojParser p, Usual d) {
|
1112
1113
|
int cap = 4096;
|
1113
1114
|
|
1114
|
-
d->vhead =
|
1115
|
+
d->vhead = OJ_R_ALLOC_N(VALUE, cap);
|
1115
1116
|
d->vend = d->vhead + cap;
|
1116
1117
|
d->vtail = d->vhead;
|
1117
1118
|
|
1118
|
-
d->khead =
|
1119
|
+
d->khead = OJ_R_ALLOC_N(union _key, cap);
|
1119
1120
|
d->kend = d->khead + cap;
|
1120
1121
|
d->ktail = d->khead;
|
1121
1122
|
|
1122
1123
|
cap = 256;
|
1123
|
-
d->chead =
|
1124
|
+
d->chead = OJ_R_ALLOC_N(struct _col, cap);
|
1124
1125
|
d->cend = d->chead + cap;
|
1125
1126
|
d->ctail = d->chead;
|
1126
1127
|
|
@@ -1201,7 +1202,7 @@ void oj_init_usual(ojParser p, Usual d) {
|
|
1201
1202
|
}
|
1202
1203
|
|
1203
1204
|
void oj_set_parser_usual(ojParser p) {
|
1204
|
-
Usual d =
|
1205
|
+
Usual d = OJ_R_ALLOC(struct _usual);
|
1205
1206
|
|
1206
1207
|
oj_init_usual(p, d);
|
1207
1208
|
}
|
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
|
@@ -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/wab.c
CHANGED
@@ -226,13 +226,13 @@ static void dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
|
|
226
226
|
if (rb_cTime == clas) {
|
227
227
|
dump_time(obj, out);
|
228
228
|
} else if (oj_bigdecimal_class == clas) {
|
229
|
-
volatile VALUE rstr =
|
229
|
+
volatile VALUE rstr = oj_safe_string_convert(obj);
|
230
230
|
|
231
231
|
oj_dump_raw(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), out);
|
232
232
|
} else if (resolve_wab_uuid_class() == clas) {
|
233
|
-
oj_dump_str(
|
233
|
+
oj_dump_str(oj_safe_string_convert(obj), depth, out, false);
|
234
234
|
} else if (resolve_uri_http_class() == clas) {
|
235
|
-
oj_dump_str(
|
235
|
+
oj_dump_str(oj_safe_string_convert(obj), depth, out, false);
|
236
236
|
} else {
|
237
237
|
raise_wab(obj);
|
238
238
|
}
|
@@ -266,9 +266,7 @@ static DumpFunc wab_funcs[] = {
|
|
266
266
|
void oj_dump_wab_val(VALUE obj, int depth, Out out) {
|
267
267
|
int type = rb_type(obj);
|
268
268
|
|
269
|
-
|
270
|
-
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
271
|
-
}
|
269
|
+
TRACE(out->opts->trace, "dump", obj, depth, TraceIn);
|
272
270
|
if (MAX_DEPTH < depth) {
|
273
271
|
rb_raise(rb_eNoMemError, "Too deeply nested.\n");
|
274
272
|
}
|
@@ -277,9 +275,7 @@ void oj_dump_wab_val(VALUE obj, int depth, Out out) {
|
|
277
275
|
|
278
276
|
if (NULL != f) {
|
279
277
|
f(obj, depth, out, false);
|
280
|
-
|
281
|
-
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
282
|
-
}
|
278
|
+
TRACE(out->opts->trace, "dump", obj, depth, TraceOut);
|
283
279
|
return;
|
284
280
|
}
|
285
281
|
}
|
@@ -312,15 +308,11 @@ static VALUE calc_hash_key(ParseInfo pi, Val parent) {
|
|
312
308
|
}
|
313
309
|
|
314
310
|
static void hash_end(ParseInfo pi) {
|
315
|
-
|
316
|
-
oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
|
317
|
-
}
|
311
|
+
TRACE_PARSE_HASH_END(pi->options.trace, pi);
|
318
312
|
}
|
319
313
|
|
320
314
|
static void array_end(ParseInfo pi) {
|
321
|
-
|
322
|
-
oj_trace_parse_array_end(pi, __FILE__, __LINE__);
|
323
|
-
}
|
315
|
+
TRACE_PARSE_ARRAY_END(pi->options.trace, pi);
|
324
316
|
}
|
325
317
|
|
326
318
|
static VALUE noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
|
@@ -494,9 +486,7 @@ static void add_num(ParseInfo pi, NumInfo ni) {
|
|
494
486
|
}
|
495
487
|
|
496
488
|
static VALUE start_hash(ParseInfo pi) {
|
497
|
-
|
498
|
-
oj_trace_parse_in("start_hash", pi, __FILE__, __LINE__);
|
499
|
-
}
|
489
|
+
TRACE_PARSE_IN(pi->options.trace, "start_hash", pi);
|
500
490
|
if (Qnil != pi->options.hash_class) {
|
501
491
|
return rb_class_new_instance(0, NULL, pi->options.hash_class);
|
502
492
|
}
|
@@ -533,9 +523,7 @@ static void hash_set_value(ParseInfo pi, Val parent, VALUE value) {
|
|
533
523
|
}
|
534
524
|
|
535
525
|
static VALUE start_array(ParseInfo pi) {
|
536
|
-
|
537
|
-
oj_trace_parse_in("start_array", pi, __FILE__, __LINE__);
|
538
|
-
}
|
526
|
+
TRACE_PARSE_IN(pi->options.trace, "start_array", pi);
|
539
527
|
return rb_ary_new();
|
540
528
|
}
|
541
529
|
|
data/lib/oj/version.rb
CHANGED
@@ -0,0 +1,20 @@
|
|
1
|
+
# Oj Install Options
|
2
|
+
|
3
|
+
### Enable trace log
|
4
|
+
|
5
|
+
```
|
6
|
+
$ gem install oj -- --enable-trace-log
|
7
|
+
```
|
8
|
+
|
9
|
+
To enable Oj trace feature, it uses `--enable-trace-log` option when installing the gem.
|
10
|
+
Then, the trace logs will be displayed when `:trace` option is set to `true`.
|
11
|
+
|
12
|
+
|
13
|
+
### Enable SIMD instructions
|
14
|
+
|
15
|
+
```
|
16
|
+
$ gem install oj -- --with-sse42
|
17
|
+
```
|
18
|
+
|
19
|
+
To enable the use of SIMD instructions in Oj, it uses the `--with-sse42` option when installing the gem.
|
20
|
+
This will enable the use of the SSE4.2 instructions in the internal.
|
data/test/foo.rb
CHANGED
@@ -5,73 +5,54 @@ $: << File.join(File.dirname(__FILE__), "../lib")
|
|
5
5
|
$: << File.join(File.dirname(__FILE__), "../ext")
|
6
6
|
|
7
7
|
require "oj"
|
8
|
-
require "socket"
|
9
|
-
require 'io/nonblock'
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
=
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
1_000_000.times do |i|
|
27
|
-
begin
|
28
|
-
Oj.to_stream(w, { x: i})
|
29
|
-
rescue IOError => e
|
30
|
-
puts "*** #{i} raised #{e.class}: #{e}"
|
31
|
-
IO.select(nil, [w])
|
32
|
-
retry
|
33
|
-
end
|
34
|
-
w.puts
|
35
|
-
end
|
36
|
-
else
|
37
|
-
w.close
|
38
|
-
sleep(0.1)
|
39
|
-
r.each_line { |b|
|
40
|
-
#print b
|
41
|
-
}
|
42
|
-
r.close
|
43
|
-
Process.exit(0)
|
9
|
+
class Stuff
|
10
|
+
attr_accessor :alpha, :bravo, :charlie, :delta, :echo, :foxtrot, :golf, :hotel, :india, :juliet
|
11
|
+
def self.json_create(arg)
|
12
|
+
obj = self.new
|
13
|
+
obj.alpha = arg["alpha"]
|
14
|
+
obj.bravo = arg["bravo"]
|
15
|
+
obj.charlie = arg["charlie"]
|
16
|
+
obj.delta = arg["delta"]
|
17
|
+
obj.echo = arg["echo"]
|
18
|
+
obj.foxtrot = arg["foxtrot"]
|
19
|
+
obj.golf = arg["golf"]
|
20
|
+
obj.hotel = arg["hotel"]
|
21
|
+
obj.india = arg["india"]
|
22
|
+
obj.juliet = arg["juliet"]
|
23
|
+
obj
|
44
24
|
end
|
45
25
|
end
|
46
|
-
=end
|
47
26
|
|
48
|
-
=
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
r.close
|
74
|
-
Process.exit(0)
|
75
|
-
end
|
27
|
+
$obj_json = %|{
|
28
|
+
"alpha": [0, 1,2,3,4,5,6,7,8,9],
|
29
|
+
"bravo": true,
|
30
|
+
"charlie": 123,
|
31
|
+
"delta": "some string",
|
32
|
+
"echo": null,
|
33
|
+
"^": "Stuff",
|
34
|
+
"foxtrot": false,
|
35
|
+
"golf": "gulp",
|
36
|
+
"hotel": {"x": true, "y": false},
|
37
|
+
"india": [null, true, 123],
|
38
|
+
"juliet": "junk"
|
39
|
+
}|
|
40
|
+
|
41
|
+
def parse(json)
|
42
|
+
p_usual = Oj::Parser.new(:usual)
|
43
|
+
p_usual.cache_keys = true
|
44
|
+
p_usual.cache_strings = (p_usual.cache_keys ? 6 : 0)
|
45
|
+
p_usual.symbol_keys = true
|
46
|
+
p_usual.create_id = '^'
|
47
|
+
p_usual.class_cache = true
|
48
|
+
p_usual.ignore_json_create = true
|
49
|
+
|
50
|
+
p_usual.parse(json)
|
51
|
+
nil
|
76
52
|
end
|
77
|
-
|
53
|
+
|
54
|
+
parse($obj_json)
|
55
|
+
|
56
|
+
Oj.mem_report()
|
57
|
+
|
58
|
+
Oj.mem_report()
|
data/test/perf_parser.rb
CHANGED
@@ -181,6 +181,7 @@ perf = Perf.new()
|
|
181
181
|
perf.add('Oj::Parser.usual', '') { p_usual.parse($obj_json) }
|
182
182
|
perf.add('Oj::compat_load', '') { Oj.compat_load($obj_json) }
|
183
183
|
perf.add('JSON::Ext', 'parse') { JSON.load($obj_json) }
|
184
|
+
|
184
185
|
perf.run($iter)
|
185
186
|
|
186
187
|
unless $failed.empty?
|
data/test/test_compat.rb
CHANGED
@@ -513,6 +513,15 @@ class CompatJuice < Minitest::Test
|
|
513
513
|
assert_equal("aaaa\nbbbb\rcccc\tddd\feee\bf/\\ぴーたー ", Oj.load(json))
|
514
514
|
end
|
515
515
|
|
516
|
+
def test_invalid_to_s
|
517
|
+
obj = Object.new
|
518
|
+
def obj.to_s
|
519
|
+
nil
|
520
|
+
end
|
521
|
+
|
522
|
+
assert_raises(TypeError) { Oj.dump(obj, mode: :compat) }
|
523
|
+
end
|
524
|
+
|
516
525
|
def dump_and_load(obj, trace=false)
|
517
526
|
json = Oj.dump(obj)
|
518
527
|
puts json if trace
|
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.
|
4
|
+
version: 3.14.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Ohler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-02-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -72,6 +72,7 @@ extra_rdoc_files:
|
|
72
72
|
- pages/Compatibility.md
|
73
73
|
- pages/Custom.md
|
74
74
|
- pages/Encoding.md
|
75
|
+
- pages/InstallOptions.md
|
75
76
|
- pages/JsonGem.md
|
76
77
|
- pages/Modes.md
|
77
78
|
- pages/Options.md
|
@@ -110,6 +111,8 @@ files:
|
|
110
111
|
- ext/oj/fast.c
|
111
112
|
- ext/oj/intern.c
|
112
113
|
- ext/oj/intern.h
|
114
|
+
- ext/oj/mem.c
|
115
|
+
- ext/oj/mem.h
|
113
116
|
- ext/oj/mimic_json.c
|
114
117
|
- ext/oj/object.c
|
115
118
|
- ext/oj/odd.c
|
@@ -161,6 +164,7 @@ files:
|
|
161
164
|
- pages/Compatibility.md
|
162
165
|
- pages/Custom.md
|
163
166
|
- pages/Encoding.md
|
167
|
+
- pages/InstallOptions.md
|
164
168
|
- pages/JsonGem.md
|
165
169
|
- pages/Modes.md
|
166
170
|
- pages/Options.md
|
@@ -302,7 +306,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
302
306
|
- !ruby/object:Gem::Version
|
303
307
|
version: '0'
|
304
308
|
requirements: []
|
305
|
-
rubygems_version: 3.
|
309
|
+
rubygems_version: 3.4.1
|
306
310
|
signing_key:
|
307
311
|
specification_version: 4
|
308
312
|
summary: A fast JSON parser and serializer.
|