oj 3.13.11 → 3.13.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/ext/oj/circarray.c +1 -1
- data/ext/oj/code.c +15 -22
- data/ext/oj/custom.c +28 -55
- data/ext/oj/dump.c +65 -88
- data/ext/oj/dump.h +12 -8
- data/ext/oj/dump_compat.c +43 -80
- data/ext/oj/dump_leaf.c +14 -58
- data/ext/oj/dump_object.c +28 -96
- data/ext/oj/dump_strict.c +12 -24
- data/ext/oj/fast.c +9 -9
- data/ext/oj/intern.c +9 -2
- data/ext/oj/intern.h +1 -1
- data/ext/oj/mimic_json.c +26 -24
- data/ext/oj/odd.c +83 -63
- data/ext/oj/odd.h +13 -13
- data/ext/oj/oj.c +28 -16
- data/ext/oj/oj.h +20 -2
- data/ext/oj/parse.c +3 -2
- data/ext/oj/parser.c +10 -15
- data/ext/oj/rails.c +38 -57
- data/ext/oj/rails.h +1 -1
- data/ext/oj/reader.c +2 -0
- data/ext/oj/saj.c +11 -23
- data/ext/oj/stream_writer.c +3 -1
- data/ext/oj/string_writer.c +12 -5
- data/ext/oj/wab.c +8 -8
- data/lib/oj/version.rb +1 -1
- data/test/activesupport7/abstract_unit.rb +49 -0
- data/test/activesupport7/decoding_test.rb +125 -0
- data/test/activesupport7/encoding_test.rb +486 -0
- data/test/activesupport7/encoding_test_cases.rb +104 -0
- data/test/activesupport7/time_zone_test_helpers.rb +47 -0
- data/test/bar.rb +1 -8
- data/test/foo.rb +3 -3
- data/test/json_gem/json_generator_test.rb +2 -0
- data/test/perf_dump.rb +50 -0
- data/test/test_object.rb +12 -7
- metadata +15 -17
data/ext/oj/odd.c
CHANGED
@@ -5,28 +5,27 @@
|
|
5
5
|
|
6
6
|
#include <string.h>
|
7
7
|
|
8
|
-
static
|
9
|
-
static
|
10
|
-
static
|
11
|
-
static ID
|
12
|
-
static ID
|
13
|
-
static ID
|
14
|
-
static ID
|
15
|
-
static ID denominator_id;
|
16
|
-
static ID rational_id;
|
17
|
-
static VALUE rational_class;
|
8
|
+
static Odd odds = NULL;
|
9
|
+
static ID sec_id;
|
10
|
+
static ID sec_fraction_id;
|
11
|
+
static ID to_f_id;
|
12
|
+
static ID numerator_id;
|
13
|
+
static ID denominator_id;
|
14
|
+
static ID rational_id;
|
18
15
|
|
19
16
|
static void set_class(Odd odd, const char *classname) {
|
20
17
|
const char **np;
|
21
|
-
ID
|
18
|
+
ID *idp;
|
22
19
|
|
23
|
-
odd->classname
|
24
|
-
odd->clen
|
25
|
-
odd->clas
|
20
|
+
odd->classname = classname;
|
21
|
+
odd->clen = strlen(classname);
|
22
|
+
odd->clas = rb_const_get(rb_cObject, rb_intern(classname));
|
23
|
+
rb_gc_register_mark_object(odd->clas);
|
26
24
|
odd->create_obj = odd->clas;
|
27
|
-
odd->
|
28
|
-
odd->
|
29
|
-
odd->
|
25
|
+
rb_gc_register_mark_object(odd->create_obj);
|
26
|
+
odd->create_op = rb_intern("new");
|
27
|
+
odd->is_module = (T_MODULE == rb_type(odd->clas));
|
28
|
+
odd->raw = 0;
|
30
29
|
for (np = odd->attr_names, idp = odd->attrs; 0 != *np; np++, idp++) {
|
31
30
|
*idp = rb_intern(*np);
|
32
31
|
}
|
@@ -37,15 +36,48 @@ static VALUE get_datetime_secs(VALUE obj) {
|
|
37
36
|
volatile VALUE rsecs = rb_funcall(obj, sec_id, 0);
|
38
37
|
volatile VALUE rfrac = rb_funcall(obj, sec_fraction_id, 0);
|
39
38
|
long sec = NUM2LONG(rsecs);
|
40
|
-
long long num =
|
41
|
-
long long den =
|
39
|
+
long long num = NUM2LL(rb_funcall(rfrac, numerator_id, 0));
|
40
|
+
long long den = NUM2LL(rb_funcall(rfrac, denominator_id, 0));
|
42
41
|
|
43
42
|
num += sec * den;
|
44
43
|
|
45
44
|
return rb_funcall(rb_cObject, rational_id, 2, rb_ll2inum(num), rb_ll2inum(den));
|
46
45
|
}
|
47
46
|
|
48
|
-
void
|
47
|
+
static void print_odd(Odd odd) {
|
48
|
+
const char **np;
|
49
|
+
int i;
|
50
|
+
|
51
|
+
printf(" %s {\n", odd->classname);
|
52
|
+
printf(" attr_cnt: %d %p\n", odd->attr_cnt, (void *)odd->attr_names);
|
53
|
+
printf(" attr_names: %p\n", (void *)*odd->attr_names);
|
54
|
+
printf(" attr_names: %c\n", **odd->attr_names);
|
55
|
+
for (i = odd->attr_cnt, np = odd->attr_names; 0 < i; i--, np++) {
|
56
|
+
printf(" %d %s\n", i, *np);
|
57
|
+
}
|
58
|
+
printf(" }\n");
|
59
|
+
}
|
60
|
+
|
61
|
+
void print_all_odds(const char *label) {
|
62
|
+
Odd odd;
|
63
|
+
printf("@ %s {\n", label);
|
64
|
+
for (odd = odds; NULL != odd; odd = odd->next) {
|
65
|
+
print_odd(odd);
|
66
|
+
}
|
67
|
+
printf("}\n");
|
68
|
+
}
|
69
|
+
|
70
|
+
static Odd odd_create(void) {
|
71
|
+
Odd odd = ALLOC(struct _odd);
|
72
|
+
|
73
|
+
memset(odd, 0, sizeof(struct _odd));
|
74
|
+
odd->next = odds;
|
75
|
+
odds = odd;
|
76
|
+
|
77
|
+
return odd;
|
78
|
+
}
|
79
|
+
|
80
|
+
void oj_odd_init(void) {
|
49
81
|
Odd odd;
|
50
82
|
const char **np;
|
51
83
|
|
@@ -55,11 +87,9 @@ void oj_odd_init() {
|
|
55
87
|
numerator_id = rb_intern("numerator");
|
56
88
|
denominator_id = rb_intern("denominator");
|
57
89
|
rational_id = rb_intern("Rational");
|
58
|
-
rational_class = rb_const_get(rb_cObject, rational_id);
|
59
90
|
|
60
|
-
memset(_odds, 0, sizeof(_odds));
|
61
|
-
odd = odds;
|
62
91
|
// Rational
|
92
|
+
odd = odd_create();
|
63
93
|
np = odd->attr_names;
|
64
94
|
*np++ = "numerator";
|
65
95
|
*np++ = "denominator";
|
@@ -68,8 +98,9 @@ void oj_odd_init() {
|
|
68
98
|
odd->create_obj = rb_cObject;
|
69
99
|
odd->create_op = rational_id;
|
70
100
|
odd->attr_cnt = 2;
|
101
|
+
|
71
102
|
// Date
|
72
|
-
odd
|
103
|
+
odd = odd_create();
|
73
104
|
np = odd->attr_names;
|
74
105
|
*np++ = "year";
|
75
106
|
*np++ = "month";
|
@@ -78,8 +109,9 @@ void oj_odd_init() {
|
|
78
109
|
*np++ = 0;
|
79
110
|
set_class(odd, "Date");
|
80
111
|
odd->attr_cnt = 4;
|
112
|
+
|
81
113
|
// DateTime
|
82
|
-
odd
|
114
|
+
odd = odd_create();
|
83
115
|
np = odd->attr_names;
|
84
116
|
*np++ = "year";
|
85
117
|
*np++ = "month";
|
@@ -93,8 +125,9 @@ void oj_odd_init() {
|
|
93
125
|
set_class(odd, "DateTime");
|
94
126
|
odd->attr_cnt = 8;
|
95
127
|
odd->attrFuncs[5] = get_datetime_secs;
|
128
|
+
|
96
129
|
// Range
|
97
|
-
odd
|
130
|
+
odd = odd_create();
|
98
131
|
np = odd->attr_names;
|
99
132
|
*np++ = "begin";
|
100
133
|
*np++ = "end";
|
@@ -102,15 +135,13 @@ void oj_odd_init() {
|
|
102
135
|
*np++ = 0;
|
103
136
|
set_class(odd, "Range");
|
104
137
|
odd->attr_cnt = 3;
|
105
|
-
|
106
|
-
odd_cnt = odd - odds + 1;
|
107
138
|
}
|
108
139
|
|
109
140
|
Odd oj_get_odd(VALUE clas) {
|
110
141
|
Odd odd;
|
111
142
|
const char *classname = NULL;
|
112
143
|
|
113
|
-
for (odd = odds
|
144
|
+
for (odd = odds; NULL != odd; odd = odd->next) {
|
114
145
|
if (clas == odd->clas) {
|
115
146
|
return odd;
|
116
147
|
}
|
@@ -129,21 +160,20 @@ Odd oj_get_odd(VALUE clas) {
|
|
129
160
|
Odd oj_get_oddc(const char *classname, size_t len) {
|
130
161
|
Odd odd;
|
131
162
|
|
132
|
-
for (odd = odds
|
163
|
+
for (odd = odds; NULL != odd; odd = odd->next) {
|
133
164
|
if (len == odd->clen && 0 == strncmp(classname, odd->classname, len)) {
|
134
165
|
return odd;
|
135
166
|
}
|
136
|
-
if (odd->is_module && 0 == strncmp(odd->classname, classname, odd->clen) &&
|
137
|
-
':' == classname[odd->clen]) {
|
167
|
+
if (odd->is_module && 0 == strncmp(odd->classname, classname, odd->clen) && ':' == classname[odd->clen]) {
|
138
168
|
return odd;
|
139
169
|
}
|
140
170
|
}
|
141
|
-
return
|
171
|
+
return NULL;
|
142
172
|
}
|
143
173
|
|
144
174
|
OddArgs oj_odd_alloc_args(Odd odd) {
|
145
175
|
OddArgs oa = ALLOC_N(struct _oddArgs, 1);
|
146
|
-
VALUE
|
176
|
+
VALUE *a;
|
147
177
|
int i;
|
148
178
|
|
149
179
|
oa->odd = odd;
|
@@ -159,11 +189,10 @@ void oj_odd_free(OddArgs args) {
|
|
159
189
|
|
160
190
|
int oj_odd_set_arg(OddArgs args, const char *key, size_t klen, VALUE value) {
|
161
191
|
const char **np;
|
162
|
-
VALUE
|
192
|
+
VALUE *vp;
|
163
193
|
int i;
|
164
194
|
|
165
|
-
for (i = args->odd->attr_cnt, np = args->odd->attr_names, vp = args->args; 0 < i;
|
166
|
-
i--, np++, vp++) {
|
195
|
+
for (i = args->odd->attr_cnt, np = args->odd->attr_names, vp = args->args; 0 < i; i--, np++, vp++) {
|
167
196
|
if (0 == strncmp(key, *np, klen) && '\0' == *((*np) + klen)) {
|
168
197
|
*vp = value;
|
169
198
|
return 0;
|
@@ -172,37 +201,26 @@ int oj_odd_set_arg(OddArgs args, const char *key, size_t klen, VALUE value) {
|
|
172
201
|
return -1;
|
173
202
|
}
|
174
203
|
|
175
|
-
void oj_reg_odd(VALUE
|
176
|
-
VALUE create_object,
|
177
|
-
VALUE create_method,
|
178
|
-
int mcnt,
|
179
|
-
VALUE *members,
|
180
|
-
bool raw) {
|
204
|
+
void oj_reg_odd(VALUE clas, VALUE create_object, VALUE create_method, int mcnt, VALUE *members, bool raw) {
|
181
205
|
Odd odd;
|
182
206
|
const char **np;
|
183
|
-
ID
|
207
|
+
ID *ap;
|
184
208
|
AttrGetFunc *fp;
|
185
209
|
|
186
|
-
|
187
|
-
odds = ALLOC_N(struct _odd, odd_cnt + 1);
|
188
|
-
|
189
|
-
memcpy(odds, _odds, sizeof(struct _odd) * odd_cnt);
|
190
|
-
} else {
|
191
|
-
REALLOC_N(odds, struct _odd, odd_cnt + 1);
|
192
|
-
}
|
193
|
-
odd = odds + odd_cnt;
|
210
|
+
odd = odd_create();
|
194
211
|
odd->clas = clas;
|
212
|
+
rb_gc_register_mark_object(odd->clas);
|
195
213
|
if (NULL == (odd->classname = strdup(rb_class2name(clas)))) {
|
196
|
-
rb_raise(rb_eNoMemError, "for
|
214
|
+
rb_raise(rb_eNoMemError, "for class name.");
|
197
215
|
}
|
198
216
|
odd->clen = strlen(odd->classname);
|
199
217
|
odd->create_obj = create_object;
|
200
|
-
odd->
|
201
|
-
odd->
|
202
|
-
odd->
|
203
|
-
odd->
|
204
|
-
|
205
|
-
|
218
|
+
rb_gc_register_mark_object(odd->create_obj);
|
219
|
+
odd->create_op = SYM2ID(create_method);
|
220
|
+
odd->attr_cnt = mcnt;
|
221
|
+
odd->is_module = (T_MODULE == rb_type(clas));
|
222
|
+
odd->raw = raw;
|
223
|
+
for (ap = odd->attrs, np = odd->attr_names, fp = odd->attrFuncs; 0 < mcnt; mcnt--, ap++, np++, members++, fp++) {
|
206
224
|
*fp = 0;
|
207
225
|
switch (rb_type(*members)) {
|
208
226
|
case T_STRING:
|
@@ -210,14 +228,16 @@ void oj_reg_odd(VALUE clas,
|
|
210
228
|
rb_raise(rb_eNoMemError, "for attribute name.");
|
211
229
|
}
|
212
230
|
break;
|
213
|
-
case T_SYMBOL:
|
214
|
-
|
215
|
-
|
231
|
+
case T_SYMBOL:
|
232
|
+
// The symbol can move and invalidate the name so make a copy.
|
233
|
+
if (NULL == (*np = strdup(rb_id2name(SYM2ID(*members))))) {
|
234
|
+
rb_raise(rb_eNoMemError, "for attribute name.");
|
235
|
+
}
|
216
236
|
break;
|
237
|
+
default: rb_raise(rb_eArgError, "registered member identifiers must be Strings or Symbols."); break;
|
217
238
|
}
|
218
239
|
*ap = rb_intern(*np);
|
219
240
|
}
|
220
241
|
*np = 0;
|
221
242
|
*ap = 0;
|
222
|
-
odd_cnt++;
|
223
243
|
}
|
data/ext/oj/odd.h
CHANGED
@@ -13,17 +13,18 @@
|
|
13
13
|
typedef VALUE (*AttrGetFunc)(VALUE obj);
|
14
14
|
|
15
15
|
typedef struct _odd {
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
VALUE
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
bool
|
24
|
-
|
25
|
-
|
26
|
-
|
16
|
+
struct _odd *next;
|
17
|
+
const char * classname;
|
18
|
+
size_t clen;
|
19
|
+
VALUE clas; // Ruby class or module
|
20
|
+
VALUE create_obj;
|
21
|
+
ID create_op;
|
22
|
+
int attr_cnt;
|
23
|
+
bool is_module;
|
24
|
+
bool raw;
|
25
|
+
const char * attr_names[MAX_ODD_ARGS]; // NULL terminated attr names
|
26
|
+
ID attrs[MAX_ODD_ARGS]; // 0 terminated attr IDs
|
27
|
+
AttrGetFunc attrFuncs[MAX_ODD_ARGS];
|
27
28
|
} * Odd;
|
28
29
|
|
29
30
|
typedef struct _oddArgs {
|
@@ -37,7 +38,6 @@ extern Odd oj_get_oddc(const char *classname, size_t len);
|
|
37
38
|
extern OddArgs oj_odd_alloc_args(Odd odd);
|
38
39
|
extern void oj_odd_free(OddArgs args);
|
39
40
|
extern int oj_odd_set_arg(OddArgs args, const char *key, size_t klen, VALUE value);
|
40
|
-
extern void
|
41
|
-
oj_reg_odd(VALUE clas, VALUE create_object, VALUE create_method, int mcnt, VALUE *members, bool raw);
|
41
|
+
extern void oj_reg_odd(VALUE clas, VALUE create_object, VALUE create_method, int mcnt, VALUE *members, bool raw);
|
42
42
|
|
43
43
|
#endif /* OJ_ODD_H */
|
data/ext/oj/oj.c
CHANGED
@@ -153,6 +153,7 @@ static VALUE xmlschema_sym;
|
|
153
153
|
static VALUE xss_safe_sym;
|
154
154
|
|
155
155
|
rb_encoding *oj_utf8_encoding = 0;
|
156
|
+
int oj_utf8_encoding_index = 0;
|
156
157
|
|
157
158
|
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
158
159
|
pthread_mutex_t oj_cache_mutex;
|
@@ -1243,9 +1244,8 @@ static VALUE dump_body(VALUE a) {
|
|
1243
1244
|
static VALUE dump_ensure(VALUE a) {
|
1244
1245
|
volatile struct dump_arg *arg = (void *)a;
|
1245
1246
|
|
1246
|
-
|
1247
|
-
|
1248
|
-
}
|
1247
|
+
oj_out_free(arg->out);
|
1248
|
+
|
1249
1249
|
return Qnil;
|
1250
1250
|
}
|
1251
1251
|
|
@@ -1257,7 +1257,6 @@ static VALUE dump_ensure(VALUE a) {
|
|
1257
1257
|
* - *options* [_Hash_] same as default_options
|
1258
1258
|
*/
|
1259
1259
|
static VALUE dump(int argc, VALUE *argv, VALUE self) {
|
1260
|
-
char buf[4096];
|
1261
1260
|
struct dump_arg arg;
|
1262
1261
|
struct _out out;
|
1263
1262
|
struct _options copts = oj_default_options;
|
@@ -1279,9 +1278,8 @@ static VALUE dump(int argc, VALUE *argv, VALUE self) {
|
|
1279
1278
|
arg.argc = argc;
|
1280
1279
|
arg.argv = argv;
|
1281
1280
|
|
1282
|
-
arg.out
|
1283
|
-
|
1284
|
-
arg.out->allocated = false;
|
1281
|
+
oj_out_init(arg.out);
|
1282
|
+
|
1285
1283
|
arg.out->omit_nil = copts.dump_opts.omit_nil;
|
1286
1284
|
arg.out->caller = CALLER_DUMP;
|
1287
1285
|
|
@@ -1313,7 +1311,6 @@ static VALUE dump(int argc, VALUE *argv, VALUE self) {
|
|
1313
1311
|
* Returns [_String_] the encoded JSON.
|
1314
1312
|
*/
|
1315
1313
|
static VALUE to_json(int argc, VALUE *argv, VALUE self) {
|
1316
|
-
char buf[4096];
|
1317
1314
|
struct _out out;
|
1318
1315
|
struct _options copts = oj_default_options;
|
1319
1316
|
VALUE rstr;
|
@@ -1328,9 +1325,9 @@ static VALUE to_json(int argc, VALUE *argv, VALUE self) {
|
|
1328
1325
|
}
|
1329
1326
|
copts.mode = CompatMode;
|
1330
1327
|
copts.to_json = Yes;
|
1331
|
-
|
1332
|
-
out
|
1333
|
-
|
1328
|
+
|
1329
|
+
oj_out_init(&out);
|
1330
|
+
|
1334
1331
|
out.omit_nil = copts.dump_opts.omit_nil;
|
1335
1332
|
// For obj.to_json or generate nan is not allowed but if called from dump
|
1336
1333
|
// it is.
|
@@ -1341,9 +1338,9 @@ static VALUE to_json(int argc, VALUE *argv, VALUE self) {
|
|
1341
1338
|
}
|
1342
1339
|
rstr = rb_str_new2(out.buf);
|
1343
1340
|
rstr = oj_encode(rstr);
|
1344
|
-
|
1345
|
-
|
1346
|
-
|
1341
|
+
|
1342
|
+
oj_out_free(&out);
|
1343
|
+
|
1347
1344
|
return rstr;
|
1348
1345
|
}
|
1349
1346
|
|
@@ -1703,6 +1700,15 @@ static VALUE protect_require(VALUE x) {
|
|
1703
1700
|
return Qnil;
|
1704
1701
|
}
|
1705
1702
|
|
1703
|
+
extern void print_all_odds(const char *label);
|
1704
|
+
|
1705
|
+
static VALUE
|
1706
|
+
debug_odd(VALUE self, VALUE label) {
|
1707
|
+
print_all_odds(RSTRING_PTR(label));
|
1708
|
+
return Qnil;
|
1709
|
+
}
|
1710
|
+
|
1711
|
+
|
1706
1712
|
/* Document-module: Oj
|
1707
1713
|
*
|
1708
1714
|
* Optimized JSON (Oj), as the name implies was written to provide speed
|
@@ -1731,15 +1737,19 @@ static VALUE protect_require(VALUE x) {
|
|
1731
1737
|
*
|
1732
1738
|
* - *:wab* specifically for WAB data exchange.
|
1733
1739
|
*/
|
1734
|
-
void Init_oj() {
|
1740
|
+
void Init_oj(void) {
|
1735
1741
|
int err = 0;
|
1736
1742
|
|
1737
1743
|
#if HAVE_RB_EXT_RACTOR_SAFE
|
1738
1744
|
rb_ext_ractor_safe(true);
|
1739
1745
|
#endif
|
1740
1746
|
Oj = rb_define_module("Oj");
|
1747
|
+
rb_gc_register_address(&Oj);
|
1741
1748
|
|
1742
1749
|
oj_cstack_class = rb_define_class_under(Oj, "CStack", rb_cObject);
|
1750
|
+
rb_gc_register_address(&oj_cstack_class);
|
1751
|
+
|
1752
|
+
rb_undef_alloc_func(oj_cstack_class);
|
1743
1753
|
|
1744
1754
|
oj_string_writer_init();
|
1745
1755
|
oj_stream_writer_init();
|
@@ -1748,9 +1758,11 @@ void Init_oj() {
|
|
1748
1758
|
// On Rubinius the require fails but can be done from a ruby file.
|
1749
1759
|
rb_protect(protect_require, Qnil, &err);
|
1750
1760
|
rb_require("stringio");
|
1751
|
-
|
1761
|
+
oj_utf8_encoding_index = rb_enc_find_index("UTF-8");
|
1762
|
+
oj_utf8_encoding = rb_enc_from_index(oj_utf8_encoding_index);
|
1752
1763
|
|
1753
1764
|
// rb_define_module_function(Oj, "hash_test", hash_test, 0);
|
1765
|
+
rb_define_module_function(Oj, "debug_odd", debug_odd, 1);
|
1754
1766
|
|
1755
1767
|
rb_define_module_function(Oj, "default_options", get_def_opts, 0);
|
1756
1768
|
rb_define_module_function(Oj, "default_options=", set_def_opts, 1);
|
data/ext/oj/oj.h
CHANGED
@@ -39,6 +39,16 @@ enum st_retval { ST_CONTINUE = 0, ST_STOP = 1, ST_DELETE = 2, ST_CHECK };
|
|
39
39
|
#define NINF_VAL "-3.0e14159265358979323846"
|
40
40
|
#define NAN_VAL "3.3e14159265358979323846"
|
41
41
|
|
42
|
+
#if __STDC_VERSION__ >= 199901L
|
43
|
+
// To avoid using ruby_snprintf with C99.
|
44
|
+
#undef snprintf
|
45
|
+
#include <stdio.h>
|
46
|
+
#endif
|
47
|
+
|
48
|
+
// To avoid using ruby_nonempty_memcpy().
|
49
|
+
#undef memcpy
|
50
|
+
#include <string.h>
|
51
|
+
|
42
52
|
typedef enum { Yes = 'y', No = 'n', NotSet = 0 } YesNo;
|
43
53
|
|
44
54
|
typedef enum {
|
@@ -176,6 +186,7 @@ typedef struct _rOptTable {
|
|
176
186
|
} * ROptTable;
|
177
187
|
|
178
188
|
typedef struct _out {
|
189
|
+
char stack_buffer[4096];
|
179
190
|
char * buf;
|
180
191
|
char * end;
|
181
192
|
char * cur;
|
@@ -265,8 +276,8 @@ extern void oj_str_writer_pop(StrWriter sw);
|
|
265
276
|
extern void oj_str_writer_pop_all(StrWriter sw);
|
266
277
|
|
267
278
|
extern void oj_init_doc(void);
|
268
|
-
extern void oj_string_writer_init();
|
269
|
-
extern void oj_stream_writer_init();
|
279
|
+
extern void oj_string_writer_init(void);
|
280
|
+
extern void oj_stream_writer_init(void);
|
270
281
|
extern void oj_str_writer_init(StrWriter sw, int buf_size);
|
271
282
|
extern VALUE oj_define_mimic_json(int argc, VALUE *argv, VALUE self);
|
272
283
|
extern VALUE oj_mimic_generate(int argc, VALUE *argv, VALUE self);
|
@@ -282,6 +293,7 @@ extern VALUE oj_rails_encode(int argc, VALUE *argv, VALUE self);
|
|
282
293
|
extern VALUE Oj;
|
283
294
|
extern struct _options oj_default_options;
|
284
295
|
extern rb_encoding * oj_utf8_encoding;
|
296
|
+
extern int oj_utf8_encoding_index;
|
285
297
|
|
286
298
|
extern VALUE oj_bag_class;
|
287
299
|
extern VALUE oj_bigdecimal_class;
|
@@ -364,6 +376,12 @@ extern bool oj_use_hash_alt;
|
|
364
376
|
extern bool oj_use_array_alt;
|
365
377
|
extern bool string_writer_optimized;
|
366
378
|
|
379
|
+
#define APPEND_CHARS(buffer, chars, size) \
|
380
|
+
{ \
|
381
|
+
memcpy(buffer, chars, size); \
|
382
|
+
buffer += size; \
|
383
|
+
}
|
384
|
+
|
367
385
|
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
368
386
|
extern pthread_mutex_t oj_cache_mutex;
|
369
387
|
#else
|
data/ext/oj/parse.c
CHANGED
@@ -972,9 +972,10 @@ static VALUE protect_parse(VALUE pip) {
|
|
972
972
|
extern int oj_utf8_index;
|
973
973
|
|
974
974
|
static void oj_pi_set_input_str(ParseInfo pi, volatile VALUE *inputp) {
|
975
|
-
|
975
|
+
int idx = RB_ENCODING_GET(*inputp);
|
976
976
|
|
977
|
-
if (
|
977
|
+
if (oj_utf8_encoding_index != idx) {
|
978
|
+
rb_encoding *enc = rb_enc_from_index(idx);
|
978
979
|
*inputp = rb_str_conv_enc(*inputp, enc, oj_utf8_encoding);
|
979
980
|
}
|
980
981
|
pi->json = RSTRING_PTR(*inputp);
|
data/ext/oj/parser.c
CHANGED
@@ -11,8 +11,8 @@
|
|
11
11
|
#define USE_THREAD_LIMIT 0
|
12
12
|
// #define USE_THREAD_LIMIT 100000
|
13
13
|
#define MAX_EXP 4932
|
14
|
-
// max in the pow_map
|
15
|
-
#define MAX_POW
|
14
|
+
// max in the pow_map which is the limit for double
|
15
|
+
#define MAX_POW 308
|
16
16
|
|
17
17
|
#define MIN_SLEEP (1000000000LL / (double)CLOCKS_PER_SEC)
|
18
18
|
// 9,223,372,036,854,775,807
|
@@ -385,7 +385,7 @@ static const byte hex_map[256] = "\
|
|
385
385
|
................................\
|
386
386
|
................................";
|
387
387
|
|
388
|
-
static long double pow_map[
|
388
|
+
static long double pow_map[309] = {
|
389
389
|
1.0L, 1.0e1L, 1.0e2L, 1.0e3L, 1.0e4L, 1.0e5L, 1.0e6L, 1.0e7L, 1.0e8L, 1.0e9L, 1.0e10L,
|
390
390
|
1.0e11L, 1.0e12L, 1.0e13L, 1.0e14L, 1.0e15L, 1.0e16L, 1.0e17L, 1.0e18L, 1.0e19L, 1.0e20L, 1.0e21L,
|
391
391
|
1.0e22L, 1.0e23L, 1.0e24L, 1.0e25L, 1.0e26L, 1.0e27L, 1.0e28L, 1.0e29L, 1.0e30L, 1.0e31L, 1.0e32L,
|
@@ -414,15 +414,7 @@ static long double pow_map[401] = {
|
|
414
414
|
1.0e275L, 1.0e276L, 1.0e277L, 1.0e278L, 1.0e279L, 1.0e280L, 1.0e281L, 1.0e282L, 1.0e283L, 1.0e284L, 1.0e285L,
|
415
415
|
1.0e286L, 1.0e287L, 1.0e288L, 1.0e289L, 1.0e290L, 1.0e291L, 1.0e292L, 1.0e293L, 1.0e294L, 1.0e295L, 1.0e296L,
|
416
416
|
1.0e297L, 1.0e298L, 1.0e299L, 1.0e300L, 1.0e301L, 1.0e302L, 1.0e303L, 1.0e304L, 1.0e305L, 1.0e306L, 1.0e307L,
|
417
|
-
1.0e308L
|
418
|
-
1.0e319L, 1.0e320L, 1.0e321L, 1.0e322L, 1.0e323L, 1.0e324L, 1.0e325L, 1.0e326L, 1.0e327L, 1.0e328L, 1.0e329L,
|
419
|
-
1.0e330L, 1.0e331L, 1.0e332L, 1.0e333L, 1.0e334L, 1.0e335L, 1.0e336L, 1.0e337L, 1.0e338L, 1.0e339L, 1.0e340L,
|
420
|
-
1.0e341L, 1.0e342L, 1.0e343L, 1.0e344L, 1.0e345L, 1.0e346L, 1.0e347L, 1.0e348L, 1.0e349L, 1.0e350L, 1.0e351L,
|
421
|
-
1.0e352L, 1.0e353L, 1.0e354L, 1.0e355L, 1.0e356L, 1.0e357L, 1.0e358L, 1.0e359L, 1.0e360L, 1.0e361L, 1.0e362L,
|
422
|
-
1.0e363L, 1.0e364L, 1.0e365L, 1.0e366L, 1.0e367L, 1.0e368L, 1.0e369L, 1.0e370L, 1.0e371L, 1.0e372L, 1.0e373L,
|
423
|
-
1.0e374L, 1.0e375L, 1.0e376L, 1.0e377L, 1.0e378L, 1.0e379L, 1.0e380L, 1.0e381L, 1.0e382L, 1.0e383L, 1.0e384L,
|
424
|
-
1.0e385L, 1.0e386L, 1.0e387L, 1.0e388L, 1.0e389L, 1.0e390L, 1.0e391L, 1.0e392L, 1.0e393L, 1.0e394L, 1.0e395L,
|
425
|
-
1.0e396L, 1.0e397L, 1.0e398L, 1.0e399L, 1.0e400L};
|
417
|
+
1.0e308L};
|
426
418
|
|
427
419
|
static VALUE parser_class;
|
428
420
|
|
@@ -1190,7 +1182,7 @@ static VALUE parser_new(int argc, VALUE *argv, VALUE self) {
|
|
1190
1182
|
p->map = value_map;
|
1191
1183
|
|
1192
1184
|
if (argc < 1) {
|
1193
|
-
|
1185
|
+
oj_set_parser_validator(p);
|
1194
1186
|
} else {
|
1195
1187
|
VALUE mode = argv[0];
|
1196
1188
|
|
@@ -1284,7 +1276,7 @@ static VALUE parser_new(int argc, VALUE *argv, VALUE self) {
|
|
1284
1276
|
*/
|
1285
1277
|
static VALUE parser_missing(int argc, VALUE *argv, VALUE self) {
|
1286
1278
|
ojParser p = (ojParser)DATA_PTR(self);
|
1287
|
-
const char
|
1279
|
+
const char *key = NULL;
|
1288
1280
|
volatile VALUE rkey = *argv;
|
1289
1281
|
volatile VALUE rv = Qnil;
|
1290
1282
|
|
@@ -1515,8 +1507,11 @@ static VALUE parser_validate(VALUE self) {
|
|
1515
1507
|
* isolates options to just the parser so that other parts of the code are not
|
1516
1508
|
* forced to use the same options.
|
1517
1509
|
*/
|
1518
|
-
void oj_parser_init() {
|
1510
|
+
void oj_parser_init(void) {
|
1519
1511
|
parser_class = rb_define_class_under(Oj, "Parser", rb_cObject);
|
1512
|
+
rb_gc_register_address(&parser_class);
|
1513
|
+
rb_undef_alloc_func(parser_class);
|
1514
|
+
|
1520
1515
|
rb_define_module_function(parser_class, "new", parser_new, -1);
|
1521
1516
|
rb_define_method(parser_class, "parse", parser_parse, 1);
|
1522
1517
|
rb_define_method(parser_class, "load", parser_load, 1);
|