oj 3.11.5 → 3.16.5
Sign up to get free protection for your applications and to get access to all the features.
- 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/rails.h
CHANGED
data/ext/oj/reader.c
CHANGED
@@ -6,12 +6,15 @@
|
|
6
6
|
#include <stdlib.h>
|
7
7
|
#include <strings.h>
|
8
8
|
#include <sys/types.h>
|
9
|
+
#ifdef NEEDS_UIO
|
9
10
|
#if NEEDS_UIO
|
10
11
|
#include <sys/uio.h>
|
11
12
|
#endif
|
13
|
+
#endif
|
12
14
|
#include <time.h>
|
13
15
|
#include <unistd.h>
|
14
16
|
|
17
|
+
#include "mem.h"
|
15
18
|
#include "oj.h"
|
16
19
|
#include "reader.h"
|
17
20
|
#include "ruby.h"
|
@@ -61,8 +64,7 @@ void oj_reader_init(Reader reader, VALUE io, int fd, bool to_s) {
|
|
61
64
|
reader->tail = reader->head;
|
62
65
|
reader->read_end = reader->head + RSTRING_LEN(s);
|
63
66
|
} else if (rb_cFile == io_class && Qnil != (stat = rb_funcall(io, oj_stat_id, 0)) &&
|
64
|
-
Qnil != (ftype = rb_funcall(stat, oj_ftype_id, 0)) &&
|
65
|
-
0 == strcmp("file", StringValuePtr(ftype)) &&
|
67
|
+
Qnil != (ftype = rb_funcall(stat, oj_ftype_id, 0)) && 0 == strcmp("file", StringValuePtr(ftype)) &&
|
66
68
|
0 == FIX2INT(rb_funcall(io, oj_pos_id, 0))) {
|
67
69
|
reader->read_func = read_from_fd;
|
68
70
|
reader->fd = FIX2INT(rb_funcall(io, oj_fileno_id, 0));
|
@@ -73,7 +75,7 @@ void oj_reader_init(Reader reader, VALUE io, int fd, bool to_s) {
|
|
73
75
|
reader->read_func = read_from_io;
|
74
76
|
reader->io = io;
|
75
77
|
} else if (to_s) {
|
76
|
-
volatile VALUE rstr =
|
78
|
+
volatile VALUE rstr = oj_safe_string_convert(io);
|
77
79
|
|
78
80
|
reader->read_func = 0;
|
79
81
|
reader->in_str = StringValuePtr(rstr);
|
@@ -81,8 +83,7 @@ void oj_reader_init(Reader reader, VALUE io, int fd, bool to_s) {
|
|
81
83
|
reader->tail = reader->head;
|
82
84
|
reader->read_end = reader->head + RSTRING_LEN(rstr);
|
83
85
|
} else {
|
84
|
-
rb_raise(rb_eArgError,
|
85
|
-
"parser io argument must be a String or respond to readpartial() or read().\n");
|
86
|
+
rb_raise(rb_eArgError, "parser io argument must be a String or respond to readpartial() or read().\n");
|
86
87
|
}
|
87
88
|
}
|
88
89
|
|
@@ -105,10 +106,10 @@ int oj_reader_read(Reader reader) {
|
|
105
106
|
size_t size = reader->end - reader->head + BUF_PAD;
|
106
107
|
|
107
108
|
if (reader->head == reader->base) {
|
108
|
-
reader->head =
|
109
|
+
reader->head = OJ_R_ALLOC_N(char, size * 2);
|
109
110
|
memcpy((char *)reader->head, old, size);
|
110
111
|
} else {
|
111
|
-
|
112
|
+
OJ_R_REALLOC_N(reader->head, char, size * 2);
|
112
113
|
}
|
113
114
|
reader->free_head = 1;
|
114
115
|
reader->end = reader->head + size * 2 - BUF_PAD;
|
@@ -121,9 +122,7 @@ int oj_reader_read(Reader reader) {
|
|
121
122
|
reader->str = reader->head + (reader->str - old);
|
122
123
|
}
|
123
124
|
} else {
|
124
|
-
memmove((char *)reader->head,
|
125
|
-
reader->head + shift,
|
126
|
-
reader->read_end - (reader->head + shift));
|
125
|
+
memmove((char *)reader->head, reader->head + shift, reader->read_end - (reader->head + shift));
|
127
126
|
reader->tail -= shift;
|
128
127
|
reader->read_end -= shift;
|
129
128
|
if (0 != reader->pro) {
|
@@ -155,7 +154,7 @@ static VALUE partial_io_cb(VALUE rbuf) {
|
|
155
154
|
Reader reader = (Reader)rbuf;
|
156
155
|
VALUE args[1];
|
157
156
|
VALUE rstr;
|
158
|
-
char
|
157
|
+
char *str;
|
159
158
|
size_t cnt;
|
160
159
|
|
161
160
|
args[0] = ULONG2NUM(reader->end - reader->tail);
|
@@ -165,7 +164,6 @@ static VALUE partial_io_cb(VALUE rbuf) {
|
|
165
164
|
}
|
166
165
|
str = StringValuePtr(rstr);
|
167
166
|
cnt = RSTRING_LEN(rstr);
|
168
|
-
// printf("*** partial read %lu bytes, str: '%s'\n", cnt, str);
|
169
167
|
strcpy(reader->tail, str);
|
170
168
|
reader->read_end = reader->tail + cnt;
|
171
169
|
|
@@ -176,7 +174,7 @@ static VALUE io_cb(VALUE rbuf) {
|
|
176
174
|
Reader reader = (Reader)rbuf;
|
177
175
|
VALUE args[1];
|
178
176
|
VALUE rstr;
|
179
|
-
char
|
177
|
+
char *str;
|
180
178
|
size_t cnt;
|
181
179
|
|
182
180
|
args[0] = ULONG2NUM(reader->end - reader->tail);
|
@@ -186,7 +184,6 @@ static VALUE io_cb(VALUE rbuf) {
|
|
186
184
|
}
|
187
185
|
str = StringValuePtr(rstr);
|
188
186
|
cnt = RSTRING_LEN(rstr);
|
189
|
-
// printf("*** read %lu bytes, str: '%s'\n", cnt, str);
|
190
187
|
strcpy(reader->tail, str);
|
191
188
|
reader->read_end = reader->tail + cnt;
|
192
189
|
|
data/ext/oj/reader.h
CHANGED
@@ -4,6 +4,8 @@
|
|
4
4
|
#ifndef OJ_READER_H
|
5
5
|
#define OJ_READER_H
|
6
6
|
|
7
|
+
#include "mem.h"
|
8
|
+
|
7
9
|
typedef struct _reader {
|
8
10
|
char base[0x00001000];
|
9
11
|
char *head;
|
@@ -22,7 +24,7 @@ typedef struct _reader {
|
|
22
24
|
VALUE io;
|
23
25
|
const char *in_str;
|
24
26
|
};
|
25
|
-
} *
|
27
|
+
} *Reader;
|
26
28
|
|
27
29
|
extern void oj_reader_init(Reader reader, VALUE io, int fd, bool to_s);
|
28
30
|
extern int oj_reader_read(Reader reader);
|
@@ -114,7 +116,7 @@ static inline int reader_expect(Reader reader, const char *s) {
|
|
114
116
|
|
115
117
|
static inline void reader_cleanup(Reader reader) {
|
116
118
|
if (reader->free_head && 0 != reader->head) {
|
117
|
-
|
119
|
+
OJ_R_FREE((char *)reader->head);
|
118
120
|
reader->head = 0;
|
119
121
|
reader->free_head = 0;
|
120
122
|
}
|
data/ext/oj/resolve.c
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
#endif
|
10
10
|
|
11
11
|
#include "err.h"
|
12
|
-
#include "
|
12
|
+
#include "intern.h"
|
13
13
|
#include "oj.h"
|
14
14
|
#include "parse.h"
|
15
15
|
|
@@ -27,12 +27,11 @@ inline static VALUE resolve_classname(VALUE mod, const char *classname, int auto
|
|
27
27
|
return clas;
|
28
28
|
}
|
29
29
|
|
30
|
-
static VALUE
|
31
|
-
resolve_classpath(ParseInfo pi, const char *name, size_t len, int auto_define, VALUE error_class) {
|
30
|
+
static VALUE resolve_classpath(ParseInfo pi, const char *name, size_t len, int auto_define, VALUE error_class) {
|
32
31
|
char class_name[1024];
|
33
32
|
VALUE clas;
|
34
|
-
char
|
35
|
-
char
|
33
|
+
char *end = class_name + sizeof(class_name) - 1;
|
34
|
+
char *s;
|
36
35
|
const char *n = name;
|
37
36
|
|
38
37
|
clas = rb_cObject;
|
@@ -66,28 +65,10 @@ resolve_classpath(ParseInfo pi, const char *name, size_t len, int auto_define, V
|
|
66
65
|
|
67
66
|
VALUE
|
68
67
|
oj_name2class(ParseInfo pi, const char *name, size_t len, int auto_define, VALUE error_class) {
|
69
|
-
VALUE clas;
|
70
|
-
VALUE *slot;
|
71
|
-
|
72
68
|
if (No == pi->options.class_cache) {
|
73
69
|
return resolve_classpath(pi, name, len, auto_define, error_class);
|
74
70
|
}
|
75
|
-
|
76
|
-
pthread_mutex_lock(&oj_cache_mutex);
|
77
|
-
#else
|
78
|
-
rb_mutex_lock(oj_cache_mutex);
|
79
|
-
#endif
|
80
|
-
if (Qnil == (clas = oj_class_hash_get(name, len, &slot))) {
|
81
|
-
if (Qundef != (clas = resolve_classpath(pi, name, len, auto_define, error_class))) {
|
82
|
-
*slot = clas;
|
83
|
-
}
|
84
|
-
}
|
85
|
-
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
86
|
-
pthread_mutex_unlock(&oj_cache_mutex);
|
87
|
-
#else
|
88
|
-
rb_mutex_unlock(oj_cache_mutex);
|
89
|
-
#endif
|
90
|
-
return clas;
|
71
|
+
return oj_class_intern(name, len, true, pi, auto_define, error_class);
|
91
72
|
}
|
92
73
|
|
93
74
|
VALUE
|
data/ext/oj/rxclass.c
CHANGED
@@ -10,6 +10,7 @@
|
|
10
10
|
#include <regex.h>
|
11
11
|
#endif
|
12
12
|
|
13
|
+
#include "mem.h"
|
13
14
|
#include "rxclass.h"
|
14
15
|
|
15
16
|
typedef struct _rxC {
|
@@ -20,7 +21,7 @@ typedef struct _rxC {
|
|
20
21
|
#endif
|
21
22
|
VALUE clas;
|
22
23
|
char src[256];
|
23
|
-
} *
|
24
|
+
} *RxC;
|
24
25
|
|
25
26
|
void oj_rxclass_init(RxClass rc) {
|
26
27
|
*rc->err = '\0';
|
@@ -37,13 +38,13 @@ void oj_rxclass_cleanup(RxClass rc) {
|
|
37
38
|
if (Qnil == rxc->rrx) {
|
38
39
|
regfree(&rxc->rx);
|
39
40
|
}
|
40
|
-
|
41
|
+
OJ_R_FREE(rxc);
|
41
42
|
#endif
|
42
43
|
}
|
43
44
|
}
|
44
45
|
|
45
46
|
void oj_rxclass_rappend(RxClass rc, VALUE rx, VALUE clas) {
|
46
|
-
RxC rxc =
|
47
|
+
RxC rxc = OJ_R_ALLOC_N(struct _rxC, 1);
|
47
48
|
|
48
49
|
memset(rxc, 0, sizeof(struct _rxC));
|
49
50
|
rxc->rrx = rx;
|
@@ -70,7 +71,7 @@ int oj_rxclass_append(RxClass rc, const char *expr, VALUE clas) {
|
|
70
71
|
(unsigned long)sizeof(rxc->src));
|
71
72
|
return EINVAL;
|
72
73
|
}
|
73
|
-
rxc =
|
74
|
+
rxc = OJ_R_ALLOC_N(struct _rxC, 1);
|
74
75
|
rxc->next = 0;
|
75
76
|
rxc->clas = clas;
|
76
77
|
|
@@ -80,7 +81,7 @@ int oj_rxclass_append(RxClass rc, const char *expr, VALUE clas) {
|
|
80
81
|
rxc->rrx = Qnil;
|
81
82
|
if (0 != (err = regcomp(&rxc->rx, expr, flags))) {
|
82
83
|
regerror(err, &rxc->rx, rc->err, sizeof(rc->err));
|
83
|
-
|
84
|
+
OJ_FREE(rxc);
|
84
85
|
return err;
|
85
86
|
}
|
86
87
|
#endif
|
@@ -110,7 +111,7 @@ oj_rxclass_match(RxClass rc, const char *str, int len) {
|
|
110
111
|
}
|
111
112
|
} else if (len < (int)sizeof(buf)) {
|
112
113
|
#if !IS_WINDOWS
|
113
|
-
// string is not \0 terminated so copy and
|
114
|
+
// string is not \0 terminated so copy and attempt a match
|
114
115
|
memcpy(buf, str, len);
|
115
116
|
buf[len] = '\0';
|
116
117
|
if (0 == regexec(&rxc->rx, buf, 0, NULL, 0)) { // match
|
data/ext/oj/rxclass.h
CHANGED
data/ext/oj/saj.c
CHANGED
@@ -15,6 +15,7 @@
|
|
15
15
|
#define OJ_INFINITY (1.0 / 0.0)
|
16
16
|
|
17
17
|
#include "encode.h"
|
18
|
+
#include "mem.h"
|
18
19
|
#include "oj.h"
|
19
20
|
|
20
21
|
typedef struct _parseInfo {
|
@@ -28,7 +29,7 @@ typedef struct _parseInfo {
|
|
28
29
|
int has_array_end;
|
29
30
|
int has_add_value;
|
30
31
|
int has_error;
|
31
|
-
} *
|
32
|
+
} *ParseInfo;
|
32
33
|
|
33
34
|
static void read_next(ParseInfo pi, const char *key);
|
34
35
|
static void read_hash(ParseInfo pi, const char *key);
|
@@ -210,10 +211,7 @@ static void read_hash(ParseInfo pi, const char *key) {
|
|
210
211
|
pi->s++;
|
211
212
|
} else {
|
212
213
|
if (pi->has_error) {
|
213
|
-
call_error("invalid format, expected , or } while in an object",
|
214
|
-
pi,
|
215
|
-
__FILE__,
|
216
|
-
__LINE__);
|
214
|
+
call_error("invalid format, expected , or } while in an object", pi, __FILE__, __LINE__);
|
217
215
|
}
|
218
216
|
raise_error("invalid format, expected , or } while in an object", pi->str, pi->s);
|
219
217
|
}
|
@@ -243,10 +241,7 @@ static void read_array(ParseInfo pi, const char *key) {
|
|
243
241
|
break;
|
244
242
|
} else {
|
245
243
|
if (pi->has_error) {
|
246
|
-
call_error("invalid format, expected , or ] while in an array",
|
247
|
-
pi,
|
248
|
-
__FILE__,
|
249
|
-
__LINE__);
|
244
|
+
call_error("invalid format, expected , or ] while in an array", pi, __FILE__, __LINE__);
|
250
245
|
}
|
251
246
|
raise_error("invalid format, expected , or ] while in an array", pi->str, pi->s);
|
252
247
|
}
|
@@ -276,7 +271,7 @@ static void read_str(ParseInfo pi, const char *key) {
|
|
276
271
|
#endif
|
277
272
|
|
278
273
|
static void read_num(ParseInfo pi, const char *key) {
|
279
|
-
char
|
274
|
+
char *start = pi->s;
|
280
275
|
int64_t n = 0;
|
281
276
|
long a = 0;
|
282
277
|
long div = 1;
|
@@ -351,9 +346,7 @@ static void read_num(ParseInfo pi, const char *key) {
|
|
351
346
|
|
352
347
|
*pi->s = '\0';
|
353
348
|
if (pi->has_add_value) {
|
354
|
-
call_add_value(pi->handler,
|
355
|
-
rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new2(start)),
|
356
|
-
key);
|
349
|
+
call_add_value(pi->handler, rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new2(start)), key);
|
357
350
|
}
|
358
351
|
*pi->s = c;
|
359
352
|
} else {
|
@@ -371,9 +364,7 @@ static void read_num(ParseInfo pi, const char *key) {
|
|
371
364
|
|
372
365
|
*pi->s = '\0';
|
373
366
|
if (pi->has_add_value) {
|
374
|
-
call_add_value(pi->handler,
|
375
|
-
rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new2(start)),
|
376
|
-
key);
|
367
|
+
call_add_value(pi->handler, rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new2(start)), key);
|
377
368
|
}
|
378
369
|
*pi->s = c;
|
379
370
|
} else {
|
@@ -505,9 +496,9 @@ static char *unicode_to_chars(ParseInfo pi, char *t, uint32_t code) {
|
|
505
496
|
* reached again. Do not read the character after the terminating quote.
|
506
497
|
*/
|
507
498
|
static char *read_quoted_value(ParseInfo pi) {
|
508
|
-
char
|
509
|
-
char
|
510
|
-
char
|
499
|
+
char *value = 0;
|
500
|
+
char *h = pi->s; /* head */
|
501
|
+
char *t = h; /* tail */
|
511
502
|
uint32_t code;
|
512
503
|
|
513
504
|
h++; /* skip quote character */
|
@@ -587,16 +578,14 @@ static void saj_parse(VALUE handler, char *json) {
|
|
587
578
|
/* initialize parse info */
|
588
579
|
pi.str = json;
|
589
580
|
pi.s = json;
|
590
|
-
#if IS_WINDOWS
|
591
|
-
pi.stack_min = (void *)((char *)&obj -
|
592
|
-
(512 * 1024)); /* assume a 1M stack and give half to ruby */
|
581
|
+
#if IS_WINDOWS || !defined(HAVE_GETRLIMIT)
|
582
|
+
pi.stack_min = (void *)((char *)&obj - (512L * 1024L)); /* assume a 1M stack and give half to ruby */
|
593
583
|
#else
|
594
584
|
{
|
595
585
|
struct rlimit lim;
|
596
586
|
|
597
587
|
if (0 == getrlimit(RLIMIT_STACK, &lim) && RLIM_INFINITY != lim.rlim_cur) {
|
598
|
-
pi.stack_min = (void *)((char *)&obj - (lim.rlim_cur / 4 *
|
599
|
-
3)); /* let 3/4ths of the stack be used only */
|
588
|
+
pi.stack_min = (void *)((char *)&obj - (lim.rlim_cur / 4 * 3)); /* let 3/4ths of the stack be used only */
|
600
589
|
} else {
|
601
590
|
pi.stack_min = 0; /* indicates not to check stack limit */
|
602
591
|
}
|
@@ -628,12 +617,12 @@ static void saj_parse(VALUE handler, char *json) {
|
|
628
617
|
* @param [IO|String] io IO Object to read from
|
629
618
|
* @deprecated The sc_parse() method along with the ScHandler is the preferred
|
630
619
|
* callback parser. It is slightly faster and handles streams while the
|
631
|
-
* saj_parse()
|
620
|
+
* saj_parse() method requires a complete read before parsing.
|
632
621
|
* @see sc_parse
|
633
622
|
*/
|
634
623
|
VALUE
|
635
624
|
oj_saj_parse(int argc, VALUE *argv, VALUE self) {
|
636
|
-
char
|
625
|
+
char *json = 0;
|
637
626
|
size_t len = 0;
|
638
627
|
VALUE input = argv[1];
|
639
628
|
|
@@ -643,7 +632,7 @@ oj_saj_parse(int argc, VALUE *argv, VALUE self) {
|
|
643
632
|
if (rb_type(input) == T_STRING) {
|
644
633
|
// the json string gets modified so make a copy of it
|
645
634
|
len = RSTRING_LEN(input) + 1;
|
646
|
-
json =
|
635
|
+
json = OJ_R_ALLOC_N(char, len);
|
647
636
|
strcpy(json, StringValuePtr(input));
|
648
637
|
} else {
|
649
638
|
VALUE clas = rb_obj_class(input);
|
@@ -652,8 +641,8 @@ oj_saj_parse(int argc, VALUE *argv, VALUE self) {
|
|
652
641
|
if (oj_stringio_class == clas) {
|
653
642
|
s = rb_funcall2(input, oj_string_id, 0, 0);
|
654
643
|
len = RSTRING_LEN(s) + 1;
|
655
|
-
json =
|
656
|
-
strcpy(json,
|
644
|
+
json = OJ_R_ALLOC_N(char, len);
|
645
|
+
strcpy(json, StringValueCStr(s));
|
657
646
|
#if !IS_WINDOWS
|
658
647
|
} else if (rb_cFile == clas && 0 == FIX2INT(rb_funcall(input, oj_pos_id, 0))) {
|
659
648
|
int fd = FIX2INT(rb_funcall(input, oj_fileno_id, 0));
|
@@ -661,7 +650,7 @@ oj_saj_parse(int argc, VALUE *argv, VALUE self) {
|
|
661
650
|
|
662
651
|
len = lseek(fd, 0, SEEK_END);
|
663
652
|
lseek(fd, 0, SEEK_SET);
|
664
|
-
json =
|
653
|
+
json = OJ_R_ALLOC_N(char, len + 1);
|
665
654
|
if (0 >= (cnt = read(fd, json, len)) || cnt != (ssize_t)len) {
|
666
655
|
rb_raise(rb_eIOError, "failed to read from IO Object.");
|
667
656
|
}
|
@@ -670,14 +659,14 @@ oj_saj_parse(int argc, VALUE *argv, VALUE self) {
|
|
670
659
|
} else if (rb_respond_to(input, oj_read_id)) {
|
671
660
|
s = rb_funcall2(input, oj_read_id, 0, 0);
|
672
661
|
len = RSTRING_LEN(s) + 1;
|
673
|
-
json =
|
674
|
-
strcpy(json,
|
662
|
+
json = OJ_R_ALLOC_N(char, len);
|
663
|
+
strcpy(json, StringValueCStr(s));
|
675
664
|
} else {
|
676
665
|
rb_raise(rb_eArgError, "saj_parse() expected a String or IO Object.");
|
677
666
|
}
|
678
667
|
}
|
679
668
|
saj_parse(*argv, json);
|
680
|
-
|
669
|
+
OJ_R_FREE(json);
|
681
670
|
|
682
671
|
return Qnil;
|
683
672
|
}
|