oj 3.14.2 → 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 +5 -1
- data/README.md +0 -1
- data/ext/oj/buf.h +2 -2
- data/ext/oj/cache.c +16 -16
- data/ext/oj/cache8.c +7 -7
- data/ext/oj/circarray.c +2 -1
- 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 +6 -14
- data/ext/oj/custom.c +1 -1
- data/ext/oj/debug.c +3 -9
- data/ext/oj/dump.c +16 -16
- data/ext/oj/dump_compat.c +551 -576
- data/ext/oj/dump_leaf.c +3 -5
- data/ext/oj/dump_object.c +35 -36
- 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 +24 -38
- data/ext/oj/intern.c +38 -42
- data/ext/oj/intern.h +3 -7
- data/ext/oj/mem.c +211 -217
- data/ext/oj/mem.h +10 -10
- data/ext/oj/mimic_json.c +18 -24
- data/ext/oj/object.c +5 -5
- data/ext/oj/odd.c +2 -1
- data/ext/oj/odd.h +4 -4
- data/ext/oj/oj.c +60 -81
- data/ext/oj/oj.h +53 -54
- data/ext/oj/parse.c +55 -118
- data/ext/oj/parse.h +5 -10
- data/ext/oj/parser.c +7 -8
- data/ext/oj/parser.h +7 -8
- data/ext/oj/rails.c +28 -59
- data/ext/oj/reader.c +5 -9
- data/ext/oj/reader.h +1 -1
- data/ext/oj/resolve.c +3 -4
- data/ext/oj/rxclass.c +1 -1
- data/ext/oj/rxclass.h +1 -1
- data/ext/oj/saj.c +4 -4
- data/ext/oj/saj2.c +32 -49
- data/ext/oj/saj2.h +1 -1
- data/ext/oj/scp.c +3 -14
- data/ext/oj/sparse.c +18 -67
- data/ext/oj/stream_writer.c +5 -18
- data/ext/oj/strict.c +7 -13
- data/ext/oj/string_writer.c +6 -14
- data/ext/oj/trace.h +27 -16
- data/ext/oj/usual.c +62 -61
- data/ext/oj/usual.h +6 -6
- data/ext/oj/util.h +1 -1
- data/ext/oj/val_stack.h +4 -4
- 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 -48
- 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 +1 -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 +17 -26
- 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
data/ext/oj/dump_leaf.c
CHANGED
@@ -17,9 +17,7 @@ inline static void dump_chars(const char *s, size_t size, Out out) {
|
|
17
17
|
static void dump_leaf_str(Leaf leaf, Out out) {
|
18
18
|
switch (leaf->value_type) {
|
19
19
|
case STR_VAL: oj_dump_cstr(leaf->str, strlen(leaf->str), 0, 0, out); break;
|
20
|
-
case RUBY_VAL:
|
21
|
-
oj_dump_cstr(rb_string_value_cstr(&leaf->value), (int)RSTRING_LEN(leaf->value), 0, 0, out);
|
22
|
-
break;
|
20
|
+
case RUBY_VAL: oj_dump_cstr(StringValueCStr(leaf->value), (int)RSTRING_LEN(leaf->value), 0, 0, out); break;
|
23
21
|
case COL_VAL:
|
24
22
|
default: rb_raise(rb_eTypeError, "Unexpected value type %02x.\n", leaf->value_type); break;
|
25
23
|
}
|
@@ -142,11 +140,11 @@ void oj_dump_leaf_to_json(Leaf leaf, Options copts, Out out) {
|
|
142
140
|
void oj_write_leaf_to_file(Leaf leaf, const char *path, Options copts) {
|
143
141
|
struct _out out;
|
144
142
|
size_t size;
|
145
|
-
FILE
|
143
|
+
FILE *f;
|
146
144
|
|
147
145
|
oj_out_init(&out);
|
148
146
|
|
149
|
-
out.omit_nil
|
147
|
+
out.omit_nil = copts->dump_opts.omit_nil;
|
150
148
|
oj_dump_leaf_to_json(leaf, copts, &out);
|
151
149
|
size = out.cur - out.buf;
|
152
150
|
if (0 == (f = fopen(path, "w"))) {
|
data/ext/oj/dump_object.c
CHANGED
@@ -1,8 +1,8 @@
|
|
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"
|
5
4
|
#include "dump.h"
|
5
|
+
#include "mem.h"
|
6
6
|
#include "odd.h"
|
7
7
|
#include "trace.h"
|
8
8
|
|
@@ -32,7 +32,7 @@ static void dump_data(VALUE obj, int depth, Out out, bool as_ok) {
|
|
32
32
|
} else {
|
33
33
|
if (oj_bigdecimal_class == clas) {
|
34
34
|
volatile VALUE rstr = oj_safe_string_convert(obj);
|
35
|
-
const char
|
35
|
+
const char *str = RSTRING_PTR(rstr);
|
36
36
|
int len = (int)RSTRING_LEN(rstr);
|
37
37
|
|
38
38
|
if (No != out->opts->bigdec_as_num) {
|
@@ -61,7 +61,7 @@ static void dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
|
|
61
61
|
|
62
62
|
if (oj_bigdecimal_class == clas) {
|
63
63
|
volatile VALUE rstr = oj_safe_string_convert(obj);
|
64
|
-
const char
|
64
|
+
const char *str = RSTRING_PTR(rstr);
|
65
65
|
int len = (int)RSTRING_LEN(rstr);
|
66
66
|
|
67
67
|
if (0 == strcasecmp("Infinity", str)) {
|
@@ -224,37 +224,36 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
|
|
224
224
|
oj_dump_obj_val(value, depth, out);
|
225
225
|
break;
|
226
226
|
|
227
|
-
default:
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
*out->cur++ = hex_chars[b];
|
245
|
-
}
|
227
|
+
default: {
|
228
|
+
int d2 = depth + 1;
|
229
|
+
long s2 = size + out->indent + 1;
|
230
|
+
int i;
|
231
|
+
int started = 0;
|
232
|
+
uint8_t b;
|
233
|
+
|
234
|
+
assure_size(out, s2 + 15);
|
235
|
+
APPEND_CHARS(out->cur, "\"^#", 3);
|
236
|
+
out->hash_cnt++;
|
237
|
+
for (i = 28; 0 <= i; i -= 4) {
|
238
|
+
b = (uint8_t)((out->hash_cnt >> i) & 0x0000000F);
|
239
|
+
if ('\0' != b) {
|
240
|
+
started = 1;
|
241
|
+
}
|
242
|
+
if (started) {
|
243
|
+
*out->cur++ = hex_chars[b];
|
246
244
|
}
|
247
|
-
APPEND_CHARS(out->cur, "\":[", 3);
|
248
|
-
fill_indent(out, d2);
|
249
|
-
oj_dump_obj_val(key, d2, out);
|
250
|
-
assure_size(out, s2);
|
251
|
-
*out->cur++ = ',';
|
252
|
-
fill_indent(out, d2);
|
253
|
-
oj_dump_obj_val(value, d2, out);
|
254
|
-
assure_size(out, size);
|
255
|
-
fill_indent(out, depth);
|
256
|
-
*out->cur++ = ']';
|
257
245
|
}
|
246
|
+
APPEND_CHARS(out->cur, "\":[", 3);
|
247
|
+
fill_indent(out, d2);
|
248
|
+
oj_dump_obj_val(key, d2, out);
|
249
|
+
assure_size(out, s2);
|
250
|
+
*out->cur++ = ',';
|
251
|
+
fill_indent(out, d2);
|
252
|
+
oj_dump_obj_val(value, d2, out);
|
253
|
+
assure_size(out, size);
|
254
|
+
fill_indent(out, depth);
|
255
|
+
*out->cur++ = ']';
|
256
|
+
}
|
258
257
|
}
|
259
258
|
out->depth = depth;
|
260
259
|
*out->cur++ = ',';
|
@@ -364,10 +363,10 @@ static void dump_hash(VALUE obj, int depth, Out out, bool as_ok) {
|
|
364
363
|
}
|
365
364
|
|
366
365
|
static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
|
367
|
-
ID
|
368
|
-
AttrGetFunc
|
366
|
+
ID *idp;
|
367
|
+
AttrGetFunc *fp;
|
369
368
|
volatile VALUE v;
|
370
|
-
const char
|
369
|
+
const char *name;
|
371
370
|
size_t size;
|
372
371
|
int d2 = depth + 1;
|
373
372
|
|
@@ -644,7 +643,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
|
|
644
643
|
#endif
|
645
644
|
out->cur--;
|
646
645
|
APPEND_CHARS(out->cur, "]}", 2);
|
647
|
-
*out->cur
|
646
|
+
*out->cur = '\0';
|
648
647
|
}
|
649
648
|
|
650
649
|
static void dump_complex(VALUE obj, int depth, Out out, bool as_ok) {
|
data/ext/oj/dump_strict.c
CHANGED
@@ -22,15 +22,13 @@ static const char ninf_val[] = NINF_VAL;
|
|
22
22
|
static const char nan_val[] = NAN_VAL;
|
23
23
|
|
24
24
|
static void raise_strict(VALUE obj) {
|
25
|
-
rb_raise(rb_eTypeError,
|
26
|
-
"Failed to dump %s Object to JSON in strict mode.\n",
|
27
|
-
rb_class2name(rb_obj_class(obj)));
|
25
|
+
rb_raise(rb_eTypeError, "Failed to dump %s Object to JSON in strict mode.\n", rb_class2name(rb_obj_class(obj)));
|
28
26
|
}
|
29
27
|
|
30
28
|
// Removed dependencies on math due to problems with CentOS 5.4.
|
31
29
|
static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
|
32
30
|
char buf[64];
|
33
|
-
char
|
31
|
+
char* b;
|
34
32
|
double d = rb_num2dbl(obj);
|
35
33
|
int cnt = 0;
|
36
34
|
|
data/ext/oj/encoder.c
CHANGED
data/ext/oj/err.c
CHANGED
@@ -39,11 +39,7 @@ void _oj_err_set_with_location(Err err,
|
|
39
39
|
oj_err_set(err, eclas, "%s at line %d, column %d [%s:%d]", msg, n, col, file, line);
|
40
40
|
}
|
41
41
|
|
42
|
-
void _oj_raise_error(const char *msg,
|
43
|
-
const char *json,
|
44
|
-
const char *current,
|
45
|
-
const char *file,
|
46
|
-
int line) {
|
42
|
+
void _oj_raise_error(const char *msg, const char *json, const char *current, const char *file, int line) {
|
47
43
|
struct _err err;
|
48
44
|
int n = 1;
|
49
45
|
int col = 1;
|
@@ -56,13 +52,6 @@ void _oj_raise_error(const char *msg,
|
|
56
52
|
n++;
|
57
53
|
}
|
58
54
|
}
|
59
|
-
oj_err_set(&err,
|
60
|
-
oj_parse_error_class,
|
61
|
-
"%s at line %d, column %d [%s:%d]",
|
62
|
-
msg,
|
63
|
-
n,
|
64
|
-
col,
|
65
|
-
file,
|
66
|
-
line);
|
55
|
+
oj_err_set(&err, oj_parse_error_class, "%s at line %d, column %d [%s:%d]", msg, n, col, file, line);
|
67
56
|
rb_raise(err.clas, "%s", err.msg);
|
68
57
|
}
|
data/ext/oj/err.h
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
#define OJ_ERR_H
|
6
6
|
|
7
7
|
#include <errno.h>
|
8
|
+
|
8
9
|
#include "ruby.h"
|
9
10
|
|
10
11
|
// Needed to silence 2.4.0 warnings.
|
@@ -12,12 +13,12 @@
|
|
12
13
|
#define NORETURN(x) x
|
13
14
|
#endif
|
14
15
|
|
15
|
-
#define OJ_ERR_START
|
16
|
+
#define OJ_ERR_START 300
|
16
17
|
|
17
18
|
typedef enum {
|
18
|
-
OJ_OK
|
19
|
-
OJ_ERR_MEMORY
|
20
|
-
OJ_ERR_PARSE
|
19
|
+
OJ_OK = 0,
|
20
|
+
OJ_ERR_MEMORY = ENOMEM,
|
21
|
+
OJ_ERR_PARSE = OJ_ERR_START,
|
21
22
|
OJ_ERR_READ,
|
22
23
|
OJ_ERR_WRITE,
|
23
24
|
OJ_ERR_OVERFLOW,
|
@@ -29,13 +30,12 @@ typedef enum {
|
|
29
30
|
OJ_ERR_LAST,
|
30
31
|
} ojStatus;
|
31
32
|
|
32
|
-
#define set_error(err, eclas, msg, json, current)
|
33
|
-
_oj_err_set_with_location(err, eclas, msg, json, current, FILE, LINE)
|
33
|
+
#define set_error(err, eclas, msg, json, current) _oj_err_set_with_location(err, eclas, msg, json, current, FILE, LINE)
|
34
34
|
|
35
35
|
typedef struct _err {
|
36
36
|
VALUE clas;
|
37
37
|
char msg[128];
|
38
|
-
} *
|
38
|
+
} *Err;
|
39
39
|
|
40
40
|
extern VALUE oj_parse_error_class;
|
41
41
|
|
@@ -52,11 +52,8 @@ NORETURN(extern void oj_err_raise(Err e));
|
|
52
52
|
|
53
53
|
#define raise_error(msg, json, current) _oj_raise_error(msg, json, current, __FILE__, __LINE__)
|
54
54
|
|
55
|
-
NORETURN(
|
56
|
-
|
57
|
-
const char *current,
|
58
|
-
const char *file,
|
59
|
-
int line));
|
55
|
+
NORETURN(
|
56
|
+
extern void _oj_raise_error(const char *msg, const char *json, const char *current, const char *file, int line));
|
60
57
|
|
61
58
|
inline static void err_init(Err e) {
|
62
59
|
e->clas = Qnil;
|
data/ext/oj/extconf.rb
CHANGED
data/ext/oj/fast.c
CHANGED
@@ -11,15 +11,15 @@
|
|
11
11
|
#include <stdlib.h>
|
12
12
|
#include <string.h>
|
13
13
|
|
14
|
-
#include "
|
14
|
+
#include "dump.h"
|
15
15
|
#include "encode.h"
|
16
|
+
#include "mem.h"
|
16
17
|
#include "oj.h"
|
17
|
-
#include "dump.h"
|
18
18
|
|
19
19
|
// maximum to allocate on the stack, arbitrary limit
|
20
20
|
#define SMALL_JSON 65536
|
21
21
|
#define MAX_STACK 100
|
22
|
-
|
22
|
+
// #define BATCH_SIZE (4096 / sizeof(struct _leaf) - 1)
|
23
23
|
#define BATCH_SIZE 100
|
24
24
|
|
25
25
|
// Support for compaction
|
@@ -33,25 +33,25 @@ typedef struct _batch {
|
|
33
33
|
struct _batch *next;
|
34
34
|
int next_avail;
|
35
35
|
struct _leaf leaves[BATCH_SIZE];
|
36
|
-
} *
|
36
|
+
} *Batch;
|
37
37
|
|
38
38
|
typedef struct _doc {
|
39
39
|
Leaf data;
|
40
|
-
Leaf
|
40
|
+
Leaf *where; // points to current location
|
41
41
|
Leaf where_path[MAX_STACK]; // points to head of path
|
42
|
-
char
|
42
|
+
char *json;
|
43
43
|
unsigned long size; // number of leaves/branches in the doc
|
44
44
|
VALUE self;
|
45
45
|
Batch batches;
|
46
46
|
struct _batch batch0;
|
47
|
-
} *
|
47
|
+
} *Doc;
|
48
48
|
|
49
49
|
typedef struct _parseInfo {
|
50
50
|
char *str; // buffer being read from
|
51
51
|
char *s; // current position in buffer
|
52
52
|
Doc doc;
|
53
53
|
void *stack_min;
|
54
|
-
} *
|
54
|
+
} *ParseInfo;
|
55
55
|
|
56
56
|
static void leaf_init(Leaf leaf, int type);
|
57
57
|
static Leaf leaf_new(Doc doc, int type);
|
@@ -251,7 +251,7 @@ static void skip_comment(ParseInfo pi) {
|
|
251
251
|
#endif
|
252
252
|
|
253
253
|
static void leaf_fixnum_value(Leaf leaf) {
|
254
|
-
char
|
254
|
+
char *s = leaf->str;
|
255
255
|
int64_t n = 0;
|
256
256
|
int neg = 0;
|
257
257
|
int big = 0;
|
@@ -357,7 +357,7 @@ static Leaf read_next(ParseInfo pi) {
|
|
357
357
|
|
358
358
|
static Leaf read_obj(ParseInfo pi) {
|
359
359
|
Leaf h = leaf_new(pi->doc, T_HASH);
|
360
|
-
char
|
360
|
+
char *end;
|
361
361
|
const char *key = 0;
|
362
362
|
Leaf val = 0;
|
363
363
|
|
@@ -1086,14 +1086,14 @@ static void each_value(Doc doc, Leaf leaf) {
|
|
1086
1086
|
* doc.close()
|
1087
1087
|
*/
|
1088
1088
|
static VALUE doc_open(VALUE clas, VALUE str) {
|
1089
|
-
char
|
1089
|
+
char *json;
|
1090
1090
|
size_t len;
|
1091
1091
|
volatile VALUE obj;
|
1092
1092
|
int given = rb_block_given_p();
|
1093
1093
|
|
1094
1094
|
Check_Type(str, T_STRING);
|
1095
|
-
len
|
1096
|
-
json
|
1095
|
+
len = (int)RSTRING_LEN(str) + 1;
|
1096
|
+
json = OJ_R_ALLOC_N(char, len);
|
1097
1097
|
|
1098
1098
|
memcpy(json, StringValuePtr(str), len);
|
1099
1099
|
obj = parse_json(clas, json, given);
|
@@ -1126,20 +1126,19 @@ static VALUE doc_open(VALUE clas, VALUE str) {
|
|
1126
1126
|
* doc.close()
|
1127
1127
|
*/
|
1128
1128
|
static VALUE doc_open_file(VALUE clas, VALUE filename) {
|
1129
|
-
char
|
1130
|
-
char
|
1131
|
-
FILE
|
1129
|
+
char *path;
|
1130
|
+
char *json;
|
1131
|
+
FILE *f;
|
1132
1132
|
size_t len;
|
1133
1133
|
volatile VALUE obj;
|
1134
1134
|
int given = rb_block_given_p();
|
1135
1135
|
|
1136
|
-
Check_Type(filename, T_STRING);
|
1137
1136
|
path = StringValuePtr(filename);
|
1138
1137
|
if (0 == (f = fopen(path, "r"))) {
|
1139
1138
|
rb_raise(rb_eIOError, "%s", strerror(errno));
|
1140
1139
|
}
|
1141
1140
|
fseek(f, 0, SEEK_END);
|
1142
|
-
len
|
1141
|
+
len = ftell(f);
|
1143
1142
|
json = OJ_R_ALLOC_N(char, len + 1);
|
1144
1143
|
|
1145
1144
|
fseek(f, 0, SEEK_SET);
|
@@ -1152,7 +1151,7 @@ static VALUE doc_open_file(VALUE clas, VALUE filename) {
|
|
1152
1151
|
}
|
1153
1152
|
fclose(f);
|
1154
1153
|
json[len] = '\0';
|
1155
|
-
obj
|
1154
|
+
obj = parse_json(clas, json, given);
|
1156
1155
|
// TBD is this needed
|
1157
1156
|
/*
|
1158
1157
|
if (given) {
|
@@ -1198,11 +1197,11 @@ static VALUE doc_where(VALUE self) {
|
|
1198
1197
|
if (0 == *doc->where_path || doc->where == doc->where_path) {
|
1199
1198
|
return oj_slash_string;
|
1200
1199
|
} else {
|
1201
|
-
Leaf
|
1200
|
+
Leaf *lp;
|
1202
1201
|
Leaf leaf;
|
1203
1202
|
size_t size = 3; // leading / and terminating \0
|
1204
|
-
char
|
1205
|
-
char
|
1203
|
+
char *path;
|
1204
|
+
char *p;
|
1206
1205
|
|
1207
1206
|
for (lp = doc->where_path; lp <= doc->where; lp++) {
|
1208
1207
|
leaf = *lp;
|
@@ -1305,7 +1304,6 @@ static VALUE doc_type(int argc, VALUE *argv, VALUE self) {
|
|
1305
1304
|
VALUE type = Qnil;
|
1306
1305
|
|
1307
1306
|
if (1 <= argc) {
|
1308
|
-
Check_Type(*argv, T_STRING);
|
1309
1307
|
path = StringValuePtr(*argv);
|
1310
1308
|
}
|
1311
1309
|
if (0 != (leaf = get_doc_leaf(doc, path))) {
|
@@ -1314,11 +1312,7 @@ static VALUE doc_type(int argc, VALUE *argv, VALUE self) {
|
|
1314
1312
|
case T_TRUE: type = rb_cTrueClass; break;
|
1315
1313
|
case T_FALSE: type = rb_cFalseClass; break;
|
1316
1314
|
case T_STRING: type = rb_cString; break;
|
1317
|
-
#ifdef RUBY_INTEGER_UNIFICATION
|
1318
1315
|
case T_FIXNUM: type = rb_cInteger; break;
|
1319
|
-
#else
|
1320
|
-
case T_FIXNUM: type = rb_cFixnum; break;
|
1321
|
-
#endif
|
1322
1316
|
case T_FLOAT: type = rb_cFloat; break;
|
1323
1317
|
case T_ARRAY: type = rb_cArray; break;
|
1324
1318
|
case T_HASH: type = rb_cHash; break;
|
@@ -1345,11 +1339,10 @@ static VALUE doc_fetch(int argc, VALUE *argv, VALUE self) {
|
|
1345
1339
|
Doc doc;
|
1346
1340
|
Leaf leaf;
|
1347
1341
|
volatile VALUE val = Qnil;
|
1348
|
-
const char
|
1342
|
+
const char *path = 0;
|
1349
1343
|
|
1350
1344
|
doc = self_doc(self);
|
1351
1345
|
if (1 <= argc) {
|
1352
|
-
Check_Type(*argv, T_STRING);
|
1353
1346
|
path = StringValuePtr(*argv);
|
1354
1347
|
if (2 == argc) {
|
1355
1348
|
val = argv[1];
|
@@ -1374,7 +1367,6 @@ static VALUE doc_exists(VALUE self, VALUE str) {
|
|
1374
1367
|
Leaf leaf;
|
1375
1368
|
|
1376
1369
|
doc = self_doc(self);
|
1377
|
-
Check_Type(str, T_STRING);
|
1378
1370
|
if (0 != (leaf = get_doc_leaf(doc, StringValuePtr(str)))) {
|
1379
1371
|
if (NULL != leaf) {
|
1380
1372
|
return Qtrue;
|
@@ -1411,7 +1403,6 @@ static VALUE doc_each_leaf(int argc, VALUE *argv, VALUE self) {
|
|
1411
1403
|
memcpy(save_path, doc->where_path, sizeof(Leaf) * (wlen + 1));
|
1412
1404
|
}
|
1413
1405
|
if (1 <= argc) {
|
1414
|
-
Check_Type(*argv, T_STRING);
|
1415
1406
|
path = StringValuePtr(*argv);
|
1416
1407
|
if ('/' == *path) {
|
1417
1408
|
doc->where = doc->where_path;
|
@@ -1446,7 +1437,6 @@ static VALUE doc_move(VALUE self, VALUE str) {
|
|
1446
1437
|
const char *path;
|
1447
1438
|
int loc;
|
1448
1439
|
|
1449
|
-
Check_Type(str, T_STRING);
|
1450
1440
|
path = StringValuePtr(str);
|
1451
1441
|
if ('/' == *path) {
|
1452
1442
|
doc->where = doc->where_path;
|
@@ -1481,14 +1471,13 @@ static VALUE doc_each_child(int argc, VALUE *argv, VALUE self) {
|
|
1481
1471
|
Doc doc = self_doc(self);
|
1482
1472
|
const char *path = 0;
|
1483
1473
|
size_t wlen;
|
1484
|
-
Leaf
|
1474
|
+
Leaf *where_orig = doc->where;
|
1485
1475
|
|
1486
1476
|
wlen = doc->where - doc->where_path;
|
1487
1477
|
if (0 < wlen) {
|
1488
1478
|
memcpy(save_path, doc->where_path, sizeof(Leaf) * (wlen + 1));
|
1489
1479
|
}
|
1490
1480
|
if (1 <= argc) {
|
1491
|
-
Check_Type(*argv, T_STRING);
|
1492
1481
|
path = StringValuePtr(*argv);
|
1493
1482
|
if ('/' == *path) {
|
1494
1483
|
doc->where = doc->where_path;
|
@@ -1555,7 +1544,6 @@ static VALUE doc_each_value(int argc, VALUE *argv, VALUE self) {
|
|
1555
1544
|
Leaf leaf;
|
1556
1545
|
|
1557
1546
|
if (1 <= argc) {
|
1558
|
-
Check_Type(*argv, T_STRING);
|
1559
1547
|
path = StringValuePtr(*argv);
|
1560
1548
|
}
|
1561
1549
|
if (0 != (leaf = get_doc_leaf(doc, path))) {
|
@@ -1587,11 +1575,9 @@ static VALUE doc_dump(int argc, VALUE *argv, VALUE self) {
|
|
1587
1575
|
|
1588
1576
|
if (1 <= argc) {
|
1589
1577
|
if (Qnil != *argv) {
|
1590
|
-
Check_Type(*argv, T_STRING);
|
1591
1578
|
path = StringValuePtr(*argv);
|
1592
1579
|
}
|
1593
1580
|
if (2 <= argc) {
|
1594
|
-
Check_Type(argv[1], T_STRING);
|
1595
1581
|
filename = StringValuePtr(argv[1]);
|
1596
1582
|
}
|
1597
1583
|
}
|
@@ -1603,7 +1589,7 @@ static VALUE doc_dump(int argc, VALUE *argv, VALUE self) {
|
|
1603
1589
|
|
1604
1590
|
oj_out_init(&out);
|
1605
1591
|
|
1606
|
-
out.omit_nil
|
1592
|
+
out.omit_nil = oj_default_options.dump_opts.omit_nil;
|
1607
1593
|
oj_dump_leaf_to_json(leaf, &oj_default_options, &out);
|
1608
1594
|
rjson = rb_str_new2(out.buf);
|
1609
1595
|
|
data/ext/oj/intern.c
CHANGED
@@ -9,8 +9,8 @@
|
|
9
9
|
#include <pthread.h>
|
10
10
|
#endif
|
11
11
|
|
12
|
-
#include "mem.h"
|
13
12
|
#include "cache.h"
|
13
|
+
#include "mem.h"
|
14
14
|
#include "parse.h"
|
15
15
|
|
16
16
|
// Only used for the class cache so 256 should be sufficient.
|
@@ -22,10 +22,10 @@
|
|
22
22
|
|
23
23
|
typedef struct _keyVal {
|
24
24
|
struct _keyVal *next;
|
25
|
-
const char
|
25
|
+
const char *key;
|
26
26
|
size_t len;
|
27
27
|
VALUE val;
|
28
|
-
} *
|
28
|
+
} *KeyVal;
|
29
29
|
|
30
30
|
typedef struct _hash {
|
31
31
|
struct _keyVal slots[HASH_SLOT_CNT];
|
@@ -34,16 +34,16 @@ typedef struct _hash {
|
|
34
34
|
#else
|
35
35
|
VALUE mutex;
|
36
36
|
#endif
|
37
|
-
} *
|
37
|
+
} *Hash;
|
38
38
|
|
39
39
|
struct _hash class_hash;
|
40
40
|
struct _hash attr_hash;
|
41
41
|
|
42
|
-
static VALUE
|
42
|
+
static VALUE str_cache_obj;
|
43
43
|
|
44
|
-
static VALUE
|
44
|
+
static VALUE sym_cache_obj;
|
45
45
|
|
46
|
-
static VALUE
|
46
|
+
static VALUE attr_cache_obj;
|
47
47
|
|
48
48
|
static VALUE form_str(const char *str, size_t len) {
|
49
49
|
return rb_str_freeze(rb_utf8_str_new(str, len));
|
@@ -61,26 +61,26 @@ static VALUE form_attr(const char *str, size_t len) {
|
|
61
61
|
ID id;
|
62
62
|
|
63
63
|
if ('~' == *str) {
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
64
|
+
memcpy(b, str + 1, len - 1);
|
65
|
+
b[len - 1] = '\0';
|
66
|
+
len -= 2;
|
67
|
+
} else {
|
68
|
+
*b = '@';
|
69
|
+
memcpy(b + 1, str, len);
|
70
|
+
b[len + 1] = '\0';
|
71
|
+
}
|
72
72
|
id = rb_intern3(buf, len + 1, oj_utf8_encoding);
|
73
73
|
OJ_R_FREE(b);
|
74
74
|
return id;
|
75
75
|
}
|
76
76
|
if ('~' == *str) {
|
77
|
-
|
78
|
-
|
79
|
-
|
77
|
+
memcpy(buf, str + 1, len - 1);
|
78
|
+
buf[len - 1] = '\0';
|
79
|
+
len -= 2;
|
80
80
|
} else {
|
81
|
-
|
82
|
-
|
83
|
-
|
81
|
+
*buf = '@';
|
82
|
+
memcpy(buf + 1, str, len);
|
83
|
+
buf[len + 1] = '\0';
|
84
84
|
}
|
85
85
|
return (VALUE)rb_intern3(buf, len + 1, oj_utf8_encoding);
|
86
86
|
}
|
@@ -89,19 +89,16 @@ void oj_hash_init(void) {
|
|
89
89
|
VALUE cache_class = rb_define_class_under(Oj, "Cache", rb_cObject);
|
90
90
|
rb_undef_alloc_func(cache_class);
|
91
91
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
struct _cache *str_cache = cache_create(0, form_str, true, true);
|
96
|
-
str_cache_obj = Data_Wrap_Struct(cache_class, cache_mark, cache_free, str_cache);
|
92
|
+
struct _cache *str_cache = cache_create(0, form_str, true, true);
|
93
|
+
str_cache_obj = Data_Wrap_Struct(cache_class, cache_mark, cache_free, str_cache);
|
97
94
|
rb_gc_register_address(&str_cache_obj);
|
98
95
|
|
99
|
-
struct _cache *sym_cache
|
100
|
-
sym_cache_obj
|
96
|
+
struct _cache *sym_cache = cache_create(0, form_sym, true, true);
|
97
|
+
sym_cache_obj = Data_Wrap_Struct(cache_class, cache_mark, cache_free, sym_cache);
|
101
98
|
rb_gc_register_address(&sym_cache_obj);
|
102
99
|
|
103
100
|
struct _cache *attr_cache = cache_create(0, form_attr, false, true);
|
104
|
-
attr_cache_obj
|
101
|
+
attr_cache_obj = Data_Wrap_Struct(cache_class, cache_mark, cache_free, attr_cache);
|
105
102
|
rb_gc_register_address(&attr_cache_obj);
|
106
103
|
|
107
104
|
memset(class_hash.slots, 0, sizeof(class_hash.slots));
|
@@ -127,12 +124,11 @@ oj_str_intern(const char *key, size_t len) {
|
|
127
124
|
|
128
125
|
VALUE
|
129
126
|
oj_sym_intern(const char *key, size_t len) {
|
130
|
-
|
127
|
+
return cache_intern(DATA_PTR(sym_cache_obj), key, len);
|
131
128
|
}
|
132
129
|
|
133
|
-
ID
|
134
|
-
|
135
|
-
return cache_intern(DATA_PTR(attr_cache_obj), key, len);
|
130
|
+
ID oj_attr_intern(const char *key, size_t len) {
|
131
|
+
return cache_intern(DATA_PTR(attr_cache_obj), key, len);
|
136
132
|
}
|
137
133
|
|
138
134
|
static uint64_t hash_calc(const uint8_t *key, size_t len) {
|
@@ -186,10 +182,10 @@ static VALUE resolve_classname(VALUE mod, const char *classname, int auto_define
|
|
186
182
|
static VALUE resolve_classpath(ParseInfo pi, const char *name, size_t len, int auto_define, VALUE error_class) {
|
187
183
|
char class_name[1024];
|
188
184
|
VALUE clas;
|
189
|
-
char
|
190
|
-
char
|
191
|
-
const char *n
|
192
|
-
size_t
|
185
|
+
char *end = class_name + sizeof(class_name) - 1;
|
186
|
+
char *s;
|
187
|
+
const char *n = name;
|
188
|
+
size_t nlen = len;
|
193
189
|
|
194
190
|
clas = rb_cObject;
|
195
191
|
for (s = class_name; 0 < len; n++, len--) {
|
@@ -212,11 +208,11 @@ static VALUE resolve_classpath(ParseInfo pi, const char *name, size_t len, int a
|
|
212
208
|
}
|
213
209
|
*s = '\0';
|
214
210
|
if (Qundef == (clas = resolve_classname(clas, class_name, auto_define))) {
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
211
|
+
if (sizeof(class_name) <= nlen) {
|
212
|
+
nlen = sizeof(class_name) - 1;
|
213
|
+
}
|
214
|
+
strncpy(class_name, name, nlen);
|
215
|
+
class_name[nlen] = '\0';
|
220
216
|
oj_set_error_at(pi, error_class, __FILE__, __LINE__, "class '%s' is not defined", class_name);
|
221
217
|
if (Qnil != error_class) {
|
222
218
|
pi->err_class = error_class;
|
data/ext/oj/intern.h
CHANGED
@@ -4,8 +4,8 @@
|
|
4
4
|
#ifndef OJ_INTERN_H
|
5
5
|
#define OJ_INTERN_H
|
6
6
|
|
7
|
-
#include <stdbool.h>
|
8
7
|
#include <ruby.h>
|
8
|
+
#include <stdbool.h>
|
9
9
|
|
10
10
|
struct _parseInfo;
|
11
11
|
|
@@ -14,12 +14,8 @@ extern void oj_hash_init(void);
|
|
14
14
|
extern VALUE oj_str_intern(const char *key, size_t len);
|
15
15
|
extern VALUE oj_sym_intern(const char *key, size_t len);
|
16
16
|
extern ID oj_attr_intern(const char *key, size_t len);
|
17
|
-
extern VALUE
|
18
|
-
|
19
|
-
bool safe,
|
20
|
-
struct _parseInfo *pi,
|
21
|
-
int auto_define,
|
22
|
-
VALUE error_class);
|
17
|
+
extern VALUE
|
18
|
+
oj_class_intern(const char *key, size_t len, bool safe, struct _parseInfo *pi, int auto_define, VALUE error_class);
|
23
19
|
|
24
20
|
extern char *oj_strndup(const char *s, size_t len);
|
25
21
|
|