oj 3.11.0 → 3.11.5
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/README.md +2 -1
- data/ext/oj/buf.h +34 -38
- data/ext/oj/cache8.c +59 -62
- data/ext/oj/cache8.h +8 -7
- data/ext/oj/circarray.c +33 -35
- data/ext/oj/circarray.h +11 -9
- data/ext/oj/code.c +170 -174
- data/ext/oj/code.h +21 -20
- data/ext/oj/compat.c +159 -166
- data/ext/oj/custom.c +802 -851
- data/ext/oj/dump.c +766 -778
- data/ext/oj/dump.h +49 -51
- data/ext/oj/dump_compat.c +1 -0
- data/ext/oj/dump_leaf.c +116 -157
- data/ext/oj/dump_object.c +609 -628
- data/ext/oj/dump_strict.c +318 -327
- data/ext/oj/encode.h +3 -4
- data/ext/oj/err.c +39 -25
- data/ext/oj/err.h +24 -15
- data/ext/oj/extconf.rb +2 -1
- data/ext/oj/fast.c +1008 -1038
- data/ext/oj/hash.c +62 -66
- data/ext/oj/hash.h +7 -6
- data/ext/oj/hash_test.c +450 -443
- data/ext/oj/mimic_json.c +413 -402
- data/ext/oj/object.c +559 -528
- data/ext/oj/odd.c +123 -128
- data/ext/oj/odd.h +27 -25
- data/ext/oj/oj.c +1131 -924
- data/ext/oj/oj.h +286 -298
- data/ext/oj/parse.c +938 -930
- data/ext/oj/parse.h +70 -69
- data/ext/oj/rails.c +836 -839
- data/ext/oj/rails.h +7 -7
- data/ext/oj/reader.c +135 -140
- data/ext/oj/reader.h +66 -79
- data/ext/oj/resolve.c +43 -43
- data/ext/oj/resolve.h +3 -2
- data/ext/oj/rxclass.c +67 -68
- data/ext/oj/rxclass.h +12 -10
- data/ext/oj/saj.c +451 -479
- data/ext/oj/scp.c +93 -103
- data/ext/oj/sparse.c +770 -730
- data/ext/oj/stream_writer.c +120 -149
- data/ext/oj/strict.c +71 -86
- data/ext/oj/string_writer.c +198 -243
- data/ext/oj/trace.c +29 -33
- data/ext/oj/trace.h +14 -11
- data/ext/oj/util.c +103 -103
- data/ext/oj/util.h +3 -2
- data/ext/oj/val_stack.c +47 -47
- data/ext/oj/val_stack.h +79 -86
- data/ext/oj/wab.c +291 -309
- data/lib/oj/bag.rb +1 -0
- data/lib/oj/easy_hash.rb +5 -4
- data/lib/oj/mimic.rb +0 -12
- data/lib/oj/version.rb +1 -1
- data/test/activerecord/result_test.rb +7 -2
- data/test/foo.rb +35 -32
- data/test/helper.rb +10 -0
- data/test/json_gem/json_generator_test.rb +15 -3
- data/test/json_gem/test_helper.rb +8 -0
- data/test/test_compat.rb +2 -2
- data/test/test_generate.rb +21 -0
- data/test/test_hash.rb +10 -0
- data/test/test_scp.rb +1 -1
- metadata +4 -2
data/ext/oj/odd.c
CHANGED
@@ -1,78 +1,76 @@
|
|
1
1
|
// Copyright (c) 2011 Peter Ohler. All rights reserved.
|
2
|
-
|
3
|
-
#include <string.h>
|
2
|
+
// Licensed under the MIT License. See LICENSE file in the project root for license details.
|
4
3
|
|
5
4
|
#include "odd.h"
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
static
|
10
|
-
static
|
11
|
-
static
|
12
|
-
static ID
|
13
|
-
static ID
|
14
|
-
static ID
|
15
|
-
static ID
|
16
|
-
static
|
17
|
-
|
18
|
-
static
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
odd->
|
25
|
-
odd->
|
6
|
+
#include <string.h>
|
7
|
+
|
8
|
+
static struct _odd _odds[4]; // bump up if new initial Odd classes are added
|
9
|
+
static struct _odd *odds = _odds;
|
10
|
+
static long odd_cnt = 0;
|
11
|
+
static ID sec_id;
|
12
|
+
static ID sec_fraction_id;
|
13
|
+
static ID to_f_id;
|
14
|
+
static ID numerator_id;
|
15
|
+
static ID denominator_id;
|
16
|
+
static ID rational_id;
|
17
|
+
static VALUE rational_class;
|
18
|
+
|
19
|
+
static void set_class(Odd odd, const char *classname) {
|
20
|
+
const char **np;
|
21
|
+
ID * idp;
|
22
|
+
|
23
|
+
odd->classname = classname;
|
24
|
+
odd->clen = strlen(classname);
|
25
|
+
odd->clas = rb_const_get(rb_cObject, rb_intern(classname));
|
26
26
|
odd->create_obj = odd->clas;
|
27
|
-
odd->create_op
|
28
|
-
odd->is_module
|
29
|
-
odd->raw
|
27
|
+
odd->create_op = rb_intern("new");
|
28
|
+
odd->is_module = (T_MODULE == rb_type(odd->clas));
|
29
|
+
odd->raw = 0;
|
30
30
|
for (np = odd->attr_names, idp = odd->attrs; 0 != *np; np++, idp++) {
|
31
|
-
|
31
|
+
*idp = rb_intern(*np);
|
32
32
|
}
|
33
33
|
*idp = 0;
|
34
34
|
}
|
35
35
|
|
36
|
-
static VALUE
|
37
|
-
|
38
|
-
volatile VALUE
|
39
|
-
|
40
|
-
long
|
41
|
-
long long
|
42
|
-
long long den = rb_num2ll(rb_funcall(rfrac, denominator_id, 0));
|
36
|
+
static VALUE get_datetime_secs(VALUE obj) {
|
37
|
+
volatile VALUE rsecs = rb_funcall(obj, sec_id, 0);
|
38
|
+
volatile VALUE rfrac = rb_funcall(obj, sec_fraction_id, 0);
|
39
|
+
long sec = NUM2LONG(rsecs);
|
40
|
+
long long num = rb_num2ll(rb_funcall(rfrac, numerator_id, 0));
|
41
|
+
long long den = rb_num2ll(rb_funcall(rfrac, denominator_id, 0));
|
43
42
|
|
44
43
|
num += sec * den;
|
45
44
|
|
46
45
|
return rb_funcall(rb_cObject, rational_id, 2, rb_ll2inum(num), rb_ll2inum(den));
|
47
46
|
}
|
48
47
|
|
49
|
-
void
|
50
|
-
|
51
|
-
|
52
|
-
const char **np;
|
48
|
+
void oj_odd_init() {
|
49
|
+
Odd odd;
|
50
|
+
const char **np;
|
53
51
|
|
54
|
-
sec_id
|
52
|
+
sec_id = rb_intern("sec");
|
55
53
|
sec_fraction_id = rb_intern("sec_fraction");
|
56
|
-
to_f_id
|
57
|
-
numerator_id
|
58
|
-
denominator_id
|
59
|
-
rational_id
|
60
|
-
rational_class
|
54
|
+
to_f_id = rb_intern("to_f");
|
55
|
+
numerator_id = rb_intern("numerator");
|
56
|
+
denominator_id = rb_intern("denominator");
|
57
|
+
rational_id = rb_intern("Rational");
|
58
|
+
rational_class = rb_const_get(rb_cObject, rational_id);
|
61
59
|
|
62
60
|
memset(_odds, 0, sizeof(_odds));
|
63
61
|
odd = odds;
|
64
62
|
// Rational
|
65
|
-
np
|
63
|
+
np = odd->attr_names;
|
66
64
|
*np++ = "numerator";
|
67
65
|
*np++ = "denominator";
|
68
|
-
*np
|
66
|
+
*np = 0;
|
69
67
|
set_class(odd, "Rational");
|
70
68
|
odd->create_obj = rb_cObject;
|
71
|
-
odd->create_op
|
72
|
-
odd->attr_cnt
|
69
|
+
odd->create_op = rational_id;
|
70
|
+
odd->attr_cnt = 2;
|
73
71
|
// Date
|
74
72
|
odd++;
|
75
|
-
np
|
73
|
+
np = odd->attr_names;
|
76
74
|
*np++ = "year";
|
77
75
|
*np++ = "month";
|
78
76
|
*np++ = "day";
|
@@ -82,7 +80,7 @@ oj_odd_init() {
|
|
82
80
|
odd->attr_cnt = 4;
|
83
81
|
// DateTime
|
84
82
|
odd++;
|
85
|
-
np
|
83
|
+
np = odd->attr_names;
|
86
84
|
*np++ = "year";
|
87
85
|
*np++ = "month";
|
88
86
|
*np++ = "day";
|
@@ -93,11 +91,11 @@ oj_odd_init() {
|
|
93
91
|
*np++ = "start";
|
94
92
|
*np++ = 0;
|
95
93
|
set_class(odd, "DateTime");
|
96
|
-
odd->attr_cnt
|
94
|
+
odd->attr_cnt = 8;
|
97
95
|
odd->attrFuncs[5] = get_datetime_secs;
|
98
96
|
// Range
|
99
97
|
odd++;
|
100
|
-
np
|
98
|
+
np = odd->attr_names;
|
101
99
|
*np++ = "begin";
|
102
100
|
*np++ = "end";
|
103
101
|
*np++ = "exclude_end?";
|
@@ -108,119 +106,116 @@ oj_odd_init() {
|
|
108
106
|
odd_cnt = odd - odds + 1;
|
109
107
|
}
|
110
108
|
|
111
|
-
Odd
|
112
|
-
|
113
|
-
|
114
|
-
const char *classname = NULL;
|
109
|
+
Odd oj_get_odd(VALUE clas) {
|
110
|
+
Odd odd;
|
111
|
+
const char *classname = NULL;
|
115
112
|
|
116
113
|
for (odd = odds + odd_cnt - 1; odds <= odd; odd--) {
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
}
|
114
|
+
if (clas == odd->clas) {
|
115
|
+
return odd;
|
116
|
+
}
|
117
|
+
if (odd->is_module) {
|
118
|
+
if (NULL == classname) {
|
119
|
+
classname = rb_class2name(clas);
|
120
|
+
}
|
121
|
+
if (0 == strncmp(odd->classname, classname, odd->clen) && ':' == classname[odd->clen]) {
|
122
|
+
return odd;
|
123
|
+
}
|
124
|
+
}
|
129
125
|
}
|
130
126
|
return NULL;
|
131
127
|
}
|
132
128
|
|
133
|
-
Odd
|
134
|
-
|
135
|
-
Odd odd;
|
129
|
+
Odd oj_get_oddc(const char *classname, size_t len) {
|
130
|
+
Odd odd;
|
136
131
|
|
137
132
|
for (odd = odds + odd_cnt - 1; odds <= odd; odd--) {
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
}
|
133
|
+
if (len == odd->clen && 0 == strncmp(classname, odd->classname, len)) {
|
134
|
+
return odd;
|
135
|
+
}
|
136
|
+
if (odd->is_module && 0 == strncmp(odd->classname, classname, odd->clen) &&
|
137
|
+
':' == classname[odd->clen]) {
|
138
|
+
return odd;
|
139
|
+
}
|
146
140
|
}
|
147
141
|
return 0;
|
148
142
|
}
|
149
143
|
|
150
|
-
OddArgs
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
int i;
|
144
|
+
OddArgs oj_odd_alloc_args(Odd odd) {
|
145
|
+
OddArgs oa = ALLOC_N(struct _oddArgs, 1);
|
146
|
+
VALUE * a;
|
147
|
+
int i;
|
155
148
|
|
156
149
|
oa->odd = odd;
|
157
150
|
for (i = odd->attr_cnt, a = oa->args; 0 < i; i--, a++) {
|
158
|
-
|
151
|
+
*a = Qnil;
|
159
152
|
}
|
160
153
|
return oa;
|
161
154
|
}
|
162
155
|
|
163
|
-
void
|
164
|
-
oj_odd_free(OddArgs args) {
|
156
|
+
void oj_odd_free(OddArgs args) {
|
165
157
|
xfree(args);
|
166
158
|
}
|
167
159
|
|
168
|
-
int
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
160
|
+
int oj_odd_set_arg(OddArgs args, const char *key, size_t klen, VALUE value) {
|
161
|
+
const char **np;
|
162
|
+
VALUE * vp;
|
163
|
+
int i;
|
164
|
+
|
165
|
+
for (i = args->odd->attr_cnt, np = args->odd->attr_names, vp = args->args; 0 < i;
|
166
|
+
i--, np++, vp++) {
|
167
|
+
if (0 == strncmp(key, *np, klen) && '\0' == *((*np) + klen)) {
|
168
|
+
*vp = value;
|
169
|
+
return 0;
|
170
|
+
}
|
179
171
|
}
|
180
172
|
return -1;
|
181
173
|
}
|
182
174
|
|
183
|
-
void
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
175
|
+
void oj_reg_odd(VALUE clas,
|
176
|
+
VALUE create_object,
|
177
|
+
VALUE create_method,
|
178
|
+
int mcnt,
|
179
|
+
VALUE *members,
|
180
|
+
bool raw) {
|
181
|
+
Odd odd;
|
182
|
+
const char **np;
|
183
|
+
ID * ap;
|
184
|
+
AttrGetFunc *fp;
|
189
185
|
|
190
186
|
if (_odds == odds) {
|
191
|
-
|
187
|
+
odds = ALLOC_N(struct _odd, odd_cnt + 1);
|
192
188
|
|
193
|
-
|
189
|
+
memcpy(odds, _odds, sizeof(struct _odd) * odd_cnt);
|
194
190
|
} else {
|
195
|
-
|
191
|
+
REALLOC_N(odds, struct _odd, odd_cnt + 1);
|
196
192
|
}
|
197
|
-
odd
|
193
|
+
odd = odds + odd_cnt;
|
198
194
|
odd->clas = clas;
|
199
195
|
if (NULL == (odd->classname = strdup(rb_class2name(clas)))) {
|
200
|
-
|
196
|
+
rb_raise(rb_eNoMemError, "for attribute name.");
|
201
197
|
}
|
202
|
-
odd->clen
|
198
|
+
odd->clen = strlen(odd->classname);
|
203
199
|
odd->create_obj = create_object;
|
204
|
-
odd->create_op
|
205
|
-
odd->attr_cnt
|
206
|
-
odd->is_module
|
207
|
-
odd->raw
|
208
|
-
for (ap = odd->attrs, np = odd->attr_names, fp = odd->attrFuncs; 0 < mcnt;
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
*ap = rb_intern(*np);
|
200
|
+
odd->create_op = SYM2ID(create_method);
|
201
|
+
odd->attr_cnt = mcnt;
|
202
|
+
odd->is_module = (T_MODULE == rb_type(clas));
|
203
|
+
odd->raw = raw;
|
204
|
+
for (ap = odd->attrs, np = odd->attr_names, fp = odd->attrFuncs; 0 < mcnt;
|
205
|
+
mcnt--, ap++, np++, members++, fp++) {
|
206
|
+
*fp = 0;
|
207
|
+
switch (rb_type(*members)) {
|
208
|
+
case T_STRING:
|
209
|
+
if (NULL == (*np = strdup(rb_string_value_ptr(members)))) {
|
210
|
+
rb_raise(rb_eNoMemError, "for attribute name.");
|
211
|
+
}
|
212
|
+
break;
|
213
|
+
case T_SYMBOL: *np = rb_id2name(SYM2ID(*members)); break;
|
214
|
+
default:
|
215
|
+
rb_raise(rb_eArgError, "registered member identifiers must be Strings or Symbols.");
|
216
|
+
break;
|
217
|
+
}
|
218
|
+
*ap = rb_intern(*np);
|
224
219
|
}
|
225
220
|
*np = 0;
|
226
221
|
*ap = 0;
|
data/ext/oj/odd.h
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
// Copyright (c) 2011 Peter Ohler. All rights reserved.
|
2
|
+
// Licensed under the MIT License. See LICENSE file in the project root for license details.
|
2
3
|
|
3
4
|
#ifndef OJ_ODD_H
|
4
5
|
#define OJ_ODD_H
|
@@ -7,35 +8,36 @@
|
|
7
8
|
|
8
9
|
#include "ruby.h"
|
9
10
|
|
10
|
-
#define MAX_ODD_ARGS
|
11
|
+
#define MAX_ODD_ARGS 10
|
11
12
|
|
12
|
-
typedef VALUE
|
13
|
+
typedef VALUE (*AttrGetFunc)(VALUE obj);
|
13
14
|
|
14
15
|
typedef struct _odd {
|
15
|
-
const char
|
16
|
-
size_t
|
17
|
-
VALUE
|
18
|
-
VALUE
|
19
|
-
ID
|
20
|
-
int
|
21
|
-
bool
|
22
|
-
bool
|
23
|
-
const char
|
24
|
-
ID
|
25
|
-
AttrGetFunc
|
26
|
-
} *Odd;
|
16
|
+
const char *classname;
|
17
|
+
size_t clen;
|
18
|
+
VALUE clas; // Ruby class or module
|
19
|
+
VALUE create_obj;
|
20
|
+
ID create_op;
|
21
|
+
int attr_cnt;
|
22
|
+
bool is_module;
|
23
|
+
bool raw;
|
24
|
+
const char *attr_names[MAX_ODD_ARGS]; // NULL terminated attr names
|
25
|
+
ID attrs[MAX_ODD_ARGS]; // 0 terminated attr IDs
|
26
|
+
AttrGetFunc attrFuncs[MAX_ODD_ARGS];
|
27
|
+
} * Odd;
|
27
28
|
|
28
29
|
typedef struct _oddArgs {
|
29
|
-
Odd
|
30
|
-
VALUE
|
31
|
-
} *OddArgs;
|
32
|
-
|
33
|
-
extern void
|
34
|
-
extern Odd
|
35
|
-
extern Odd
|
36
|
-
extern OddArgs
|
37
|
-
extern void
|
38
|
-
extern int
|
39
|
-
extern void
|
30
|
+
Odd odd;
|
31
|
+
VALUE args[MAX_ODD_ARGS];
|
32
|
+
} * OddArgs;
|
33
|
+
|
34
|
+
extern void oj_odd_init(void);
|
35
|
+
extern Odd oj_get_odd(VALUE clas);
|
36
|
+
extern Odd oj_get_oddc(const char *classname, size_t len);
|
37
|
+
extern OddArgs oj_odd_alloc_args(Odd odd);
|
38
|
+
extern void oj_odd_free(OddArgs args);
|
39
|
+
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);
|
40
42
|
|
41
43
|
#endif /* OJ_ODD_H */
|
data/ext/oj/oj.c
CHANGED
@@ -1,371 +1,491 @@
|
|
1
1
|
// Copyright (c) 2012 Peter Ohler. All rights reserved.
|
2
|
+
// Licensed under the MIT License. See LICENSE file in the project root for license details.
|
3
|
+
|
4
|
+
#include "oj.h"
|
2
5
|
|
3
|
-
#include <stdlib.h>
|
4
6
|
#include <errno.h>
|
7
|
+
#include <fcntl.h>
|
5
8
|
#include <stdio.h>
|
9
|
+
#include <stdlib.h>
|
6
10
|
#include <string.h>
|
7
11
|
#include <sys/types.h>
|
8
12
|
#include <unistd.h>
|
9
|
-
#include <fcntl.h>
|
10
13
|
|
11
|
-
#include "
|
12
|
-
#include "
|
14
|
+
#include "dump.h"
|
15
|
+
#include "encode.h"
|
13
16
|
#include "hash.h"
|
14
17
|
#include "odd.h"
|
15
|
-
#include "
|
18
|
+
#include "parse.h"
|
16
19
|
#include "rails.h"
|
17
|
-
#include "encode.h"
|
18
20
|
|
19
21
|
typedef struct _yesNoOpt {
|
20
|
-
VALUE
|
21
|
-
char
|
22
|
-
} *YesNoOpt;
|
22
|
+
VALUE sym;
|
23
|
+
char *attr;
|
24
|
+
} * YesNoOpt;
|
23
25
|
|
24
26
|
void Init_oj();
|
25
27
|
|
26
|
-
VALUE
|
27
|
-
|
28
|
-
ID
|
29
|
-
ID
|
30
|
-
ID
|
31
|
-
ID
|
32
|
-
ID
|
33
|
-
ID
|
34
|
-
ID
|
35
|
-
ID
|
36
|
-
ID
|
37
|
-
ID
|
38
|
-
ID
|
39
|
-
ID
|
40
|
-
ID
|
41
|
-
ID
|
42
|
-
ID
|
43
|
-
ID
|
44
|
-
ID
|
45
|
-
ID
|
46
|
-
ID
|
47
|
-
ID
|
48
|
-
ID
|
49
|
-
ID
|
50
|
-
ID
|
51
|
-
ID
|
52
|
-
ID
|
53
|
-
ID
|
54
|
-
ID
|
55
|
-
ID
|
56
|
-
ID
|
57
|
-
ID
|
58
|
-
ID
|
59
|
-
ID
|
60
|
-
ID
|
61
|
-
ID
|
62
|
-
ID
|
63
|
-
ID
|
64
|
-
ID
|
65
|
-
ID
|
66
|
-
ID
|
67
|
-
ID
|
68
|
-
ID
|
69
|
-
ID
|
70
|
-
ID
|
71
|
-
ID
|
72
|
-
|
73
|
-
|
74
|
-
VALUE
|
75
|
-
VALUE
|
76
|
-
VALUE
|
77
|
-
VALUE
|
78
|
-
VALUE
|
79
|
-
VALUE
|
80
|
-
VALUE
|
81
|
-
VALUE
|
82
|
-
VALUE
|
83
|
-
VALUE
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
VALUE
|
89
|
-
VALUE
|
90
|
-
VALUE
|
91
|
-
VALUE
|
92
|
-
VALUE
|
93
|
-
VALUE
|
94
|
-
VALUE
|
95
|
-
VALUE
|
96
|
-
VALUE
|
97
|
-
|
98
|
-
|
99
|
-
static VALUE
|
100
|
-
static VALUE
|
101
|
-
static VALUE
|
102
|
-
static VALUE
|
103
|
-
static VALUE
|
104
|
-
static VALUE
|
105
|
-
static VALUE
|
106
|
-
static VALUE
|
107
|
-
static VALUE
|
108
|
-
static VALUE
|
109
|
-
static VALUE
|
110
|
-
static VALUE
|
111
|
-
static VALUE
|
112
|
-
static VALUE
|
113
|
-
static VALUE
|
114
|
-
static VALUE
|
115
|
-
static VALUE
|
116
|
-
static VALUE
|
117
|
-
static VALUE
|
118
|
-
static VALUE
|
119
|
-
static VALUE
|
120
|
-
static VALUE
|
121
|
-
static VALUE
|
122
|
-
static VALUE
|
123
|
-
static VALUE
|
124
|
-
static VALUE
|
125
|
-
static VALUE
|
126
|
-
static VALUE
|
127
|
-
static VALUE
|
128
|
-
static VALUE
|
129
|
-
static VALUE
|
130
|
-
static VALUE
|
131
|
-
static VALUE
|
132
|
-
static VALUE
|
133
|
-
static VALUE
|
134
|
-
static VALUE
|
135
|
-
static VALUE
|
136
|
-
static VALUE
|
137
|
-
static VALUE
|
138
|
-
static VALUE
|
139
|
-
static VALUE
|
140
|
-
static VALUE
|
141
|
-
static VALUE
|
142
|
-
static VALUE
|
143
|
-
static VALUE
|
144
|
-
static VALUE
|
145
|
-
static VALUE
|
146
|
-
static VALUE
|
147
|
-
static VALUE
|
148
|
-
static VALUE
|
149
|
-
|
150
|
-
|
151
|
-
rb_encoding *oj_utf8_encoding = 0;
|
28
|
+
VALUE Oj = Qnil;
|
29
|
+
|
30
|
+
ID oj_add_value_id;
|
31
|
+
ID oj_array_append_id;
|
32
|
+
ID oj_array_end_id;
|
33
|
+
ID oj_array_start_id;
|
34
|
+
ID oj_as_json_id;
|
35
|
+
ID oj_begin_id;
|
36
|
+
ID oj_bigdecimal_id;
|
37
|
+
ID oj_end_id;
|
38
|
+
ID oj_exclude_end_id;
|
39
|
+
ID oj_error_id;
|
40
|
+
ID oj_file_id;
|
41
|
+
ID oj_fileno_id;
|
42
|
+
ID oj_ftype_id;
|
43
|
+
ID oj_has_key_id;
|
44
|
+
ID oj_hash_end_id;
|
45
|
+
ID oj_hash_key_id;
|
46
|
+
ID oj_hash_set_id;
|
47
|
+
ID oj_hash_start_id;
|
48
|
+
ID oj_iconv_id;
|
49
|
+
ID oj_instance_variables_id;
|
50
|
+
ID oj_json_create_id;
|
51
|
+
ID oj_length_id;
|
52
|
+
ID oj_new_id;
|
53
|
+
ID oj_parse_id;
|
54
|
+
ID oj_pos_id;
|
55
|
+
ID oj_raw_json_id;
|
56
|
+
ID oj_read_id;
|
57
|
+
ID oj_readpartial_id;
|
58
|
+
ID oj_replace_id;
|
59
|
+
ID oj_stat_id;
|
60
|
+
ID oj_string_id;
|
61
|
+
ID oj_to_h_id;
|
62
|
+
ID oj_to_hash_id;
|
63
|
+
ID oj_to_json_id;
|
64
|
+
ID oj_to_s_id;
|
65
|
+
ID oj_to_sym_id;
|
66
|
+
ID oj_to_time_id;
|
67
|
+
ID oj_tv_nsec_id;
|
68
|
+
ID oj_tv_sec_id;
|
69
|
+
ID oj_tv_usec_id;
|
70
|
+
ID oj_utc_id;
|
71
|
+
ID oj_utc_offset_id;
|
72
|
+
ID oj_utcq_id;
|
73
|
+
ID oj_write_id;
|
74
|
+
|
75
|
+
VALUE oj_bag_class;
|
76
|
+
VALUE oj_bigdecimal_class;
|
77
|
+
VALUE oj_cstack_class;
|
78
|
+
VALUE oj_date_class;
|
79
|
+
VALUE oj_datetime_class;
|
80
|
+
VALUE oj_enumerable_class;
|
81
|
+
VALUE oj_parse_error_class;
|
82
|
+
VALUE oj_stream_writer_class;
|
83
|
+
VALUE oj_string_writer_class;
|
84
|
+
VALUE oj_stringio_class;
|
85
|
+
VALUE oj_struct_class;
|
86
|
+
|
87
|
+
VALUE oj_slash_string;
|
88
|
+
|
89
|
+
VALUE oj_allow_nan_sym;
|
90
|
+
VALUE oj_array_class_sym;
|
91
|
+
VALUE oj_create_additions_sym;
|
92
|
+
VALUE oj_decimal_class_sym;
|
93
|
+
VALUE oj_hash_class_sym;
|
94
|
+
VALUE oj_indent_sym;
|
95
|
+
VALUE oj_object_class_sym;
|
96
|
+
VALUE oj_quirks_mode_sym;
|
97
|
+
VALUE oj_safe_sym;
|
98
|
+
VALUE oj_trace_sym;
|
99
|
+
|
100
|
+
static VALUE allow_blank_sym;
|
101
|
+
static VALUE allow_gc_sym;
|
102
|
+
static VALUE allow_invalid_unicode_sym;
|
103
|
+
static VALUE ascii_sym;
|
104
|
+
static VALUE auto_define_sym;
|
105
|
+
static VALUE auto_sym;
|
106
|
+
static VALUE bigdecimal_as_decimal_sym;
|
107
|
+
static VALUE bigdecimal_load_sym;
|
108
|
+
static VALUE bigdecimal_sym;
|
109
|
+
static VALUE circular_sym;
|
110
|
+
static VALUE class_cache_sym;
|
111
|
+
static VALUE compat_bigdecimal_sym;
|
112
|
+
static VALUE compat_sym;
|
113
|
+
static VALUE create_id_sym;
|
114
|
+
static VALUE custom_sym;
|
115
|
+
static VALUE empty_string_sym;
|
116
|
+
static VALUE escape_mode_sym;
|
117
|
+
static VALUE integer_range_sym;
|
118
|
+
static VALUE fast_sym;
|
119
|
+
static VALUE float_prec_sym;
|
120
|
+
static VALUE float_sym;
|
121
|
+
static VALUE huge_sym;
|
122
|
+
static VALUE ignore_sym;
|
123
|
+
static VALUE ignore_under_sym;
|
124
|
+
static VALUE json_sym;
|
125
|
+
static VALUE match_string_sym;
|
126
|
+
static VALUE mode_sym;
|
127
|
+
static VALUE nan_sym;
|
128
|
+
static VALUE newline_sym;
|
129
|
+
static VALUE nilnil_sym;
|
130
|
+
static VALUE null_sym;
|
131
|
+
static VALUE object_sym;
|
132
|
+
static VALUE omit_nil_sym;
|
133
|
+
static VALUE rails_sym;
|
134
|
+
static VALUE raise_sym;
|
135
|
+
static VALUE ruby_sym;
|
136
|
+
static VALUE sec_prec_sym;
|
137
|
+
static VALUE strict_sym;
|
138
|
+
static VALUE symbol_keys_sym;
|
139
|
+
static VALUE time_format_sym;
|
140
|
+
static VALUE unicode_xss_sym;
|
141
|
+
static VALUE unix_sym;
|
142
|
+
static VALUE unix_zone_sym;
|
143
|
+
static VALUE use_as_json_sym;
|
144
|
+
static VALUE use_raw_json_sym;
|
145
|
+
static VALUE use_to_hash_sym;
|
146
|
+
static VALUE use_to_json_sym;
|
147
|
+
static VALUE wab_sym;
|
148
|
+
static VALUE word_sym;
|
149
|
+
static VALUE xmlschema_sym;
|
150
|
+
static VALUE xss_safe_sym;
|
151
|
+
|
152
|
+
rb_encoding *oj_utf8_encoding = 0;
|
152
153
|
|
153
154
|
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
154
|
-
pthread_mutex_t
|
155
|
+
pthread_mutex_t oj_cache_mutex;
|
155
156
|
#else
|
156
157
|
VALUE oj_cache_mutex = Qnil;
|
157
158
|
#endif
|
158
159
|
|
159
|
-
const char
|
160
|
-
|
161
|
-
struct _options
|
162
|
-
0,
|
163
|
-
No,
|
164
|
-
No,
|
165
|
-
No,
|
166
|
-
JSONEsc,
|
167
|
-
ObjectMode,
|
168
|
-
Yes,
|
169
|
-
UnixTime,
|
170
|
-
NotSet,
|
171
|
-
AutoDec,
|
172
|
-
false,
|
173
|
-
No,
|
174
|
-
No,
|
175
|
-
No,
|
176
|
-
No,
|
177
|
-
No,
|
178
|
-
Yes,
|
179
|
-
Yes,
|
180
|
-
Yes,
|
181
|
-
No,
|
182
|
-
No,
|
183
|
-
Yes,
|
184
|
-
No,
|
185
|
-
No,
|
186
|
-
false,
|
187
|
-
No,
|
188
|
-
0,
|
189
|
-
0,
|
190
|
-
oj_json_class,
|
191
|
-
10,
|
192
|
-
9,
|
193
|
-
16,
|
194
|
-
"%0.15g",
|
195
|
-
Qnil,
|
196
|
-
Qnil,
|
197
|
-
{
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
160
|
+
const char oj_json_class[] = "json_class";
|
161
|
+
|
162
|
+
struct _options oj_default_options = {
|
163
|
+
0, // indent
|
164
|
+
No, // circular
|
165
|
+
No, // auto_define
|
166
|
+
No, // sym_key
|
167
|
+
JSONEsc, // escape_mode
|
168
|
+
ObjectMode, // mode
|
169
|
+
Yes, // class_cache
|
170
|
+
UnixTime, // time_format
|
171
|
+
NotSet, // bigdec_as_num
|
172
|
+
AutoDec, // bigdec_load
|
173
|
+
false, // compat_bigdec
|
174
|
+
No, // to_hash
|
175
|
+
No, // to_json
|
176
|
+
No, // as_json
|
177
|
+
No, // raw_json
|
178
|
+
No, // nilnil
|
179
|
+
Yes, // empty_string
|
180
|
+
Yes, // allow_gc
|
181
|
+
Yes, // quirks_mode
|
182
|
+
No, // allow_invalid
|
183
|
+
No, // create_ok
|
184
|
+
Yes, // allow_nan
|
185
|
+
No, // trace
|
186
|
+
No, // safe
|
187
|
+
false, // sec_prec_set
|
188
|
+
No, // ignore_under
|
189
|
+
0, // int_range_min
|
190
|
+
0, // int_range_max
|
191
|
+
oj_json_class, // create_id
|
192
|
+
10, // create_id_len
|
193
|
+
9, // sec_prec
|
194
|
+
16, // float_prec
|
195
|
+
"%0.15g", // float_fmt
|
196
|
+
Qnil, // hash_class
|
197
|
+
Qnil, // array_class
|
198
|
+
{
|
199
|
+
// dump_opts
|
200
|
+
false, // use
|
201
|
+
"", // indent
|
202
|
+
"", // before_sep
|
203
|
+
"", // after_sep
|
204
|
+
"", // hash_nl
|
205
|
+
"", // array_nl
|
206
|
+
0, // indent_size
|
207
|
+
0, // before_size
|
208
|
+
0, // after_size
|
209
|
+
0, // hash_size
|
210
|
+
0, // array_size
|
211
|
+
AutoNan, // nan_dump
|
212
|
+
false, // omit_nil
|
213
|
+
MAX_DEPTH, // max_depth
|
212
214
|
},
|
213
|
-
{
|
214
|
-
|
215
|
-
|
216
|
-
|
215
|
+
{
|
216
|
+
// str_rx
|
217
|
+
NULL, // head
|
218
|
+
NULL, // tail
|
219
|
+
{'\0'}, // err
|
217
220
|
},
|
218
|
-
NULL,
|
221
|
+
NULL, // ignore
|
219
222
|
};
|
220
223
|
|
221
224
|
/* Document-method: default_options()
|
222
225
|
* call-seq: default_options()
|
223
226
|
*
|
224
227
|
* Returns the default load and dump options as a Hash. The options are
|
225
|
-
* - *:indent* [_Fixnum_|_String_|_nil_] number of spaces to indent each element in an JSON
|
226
|
-
*
|
228
|
+
* - *:indent* [_Fixnum_|_String_|_nil_] number of spaces to indent each element in an JSON
|
229
|
+
*document, zero or nil is no newline between JSON elements, negative indicates no newline between
|
230
|
+
*top level JSON elements in a stream, a String indicates the string should be used for indentation
|
231
|
+
* - *:circular* [_Boolean_|_nil_] support circular references while dumping as well as shared
|
232
|
+
*references
|
227
233
|
* - *:auto_define* [_Boolean_|_nil_] automatically define classes if they do not exist
|
228
234
|
* - *:symbol_keys* [_Boolean_|_nil_] use symbols instead of strings for hash keys
|
229
|
-
* - *:escape_mode* [_:newline_|_:json_|_:xss_safe_|_:ascii_|_unicode_xss_|_nil_] determines the
|
230
|
-
*
|
231
|
-
* - *:
|
235
|
+
* - *:escape_mode* [_:newline_|_:json_|_:xss_safe_|_:ascii_|_unicode_xss_|_nil_] determines the
|
236
|
+
*characters to escape
|
237
|
+
* - *:class_cache* [_Boolean_|_nil_] cache classes for faster parsing (if dynamically modifying
|
238
|
+
*classes or reloading classes then don't use this)
|
239
|
+
* - *:mode* [_:object_|_:strict_|_:compat_|_:null_|_:custom_|_:rails_|_:wab_] load and dump modes
|
240
|
+
*to use for JSON
|
232
241
|
* - *:time_format* [_:unix_|_:unix_zone_|_:xmlschema_|_:ruby_] time format when dumping
|
233
242
|
* - *:bigdecimal_as_decimal* [_Boolean_|_nil_] dump BigDecimal as a decimal number or as a String
|
234
|
-
* - *:bigdecimal_load* [_:bigdecimal_|_:float_|_:auto_|_:fast_] load decimals as BigDecimal instead
|
235
|
-
*
|
236
|
-
*
|
237
|
-
* - *:
|
238
|
-
*
|
239
|
-
* - *:
|
243
|
+
* - *:bigdecimal_load* [_:bigdecimal_|_:float_|_:auto_|_:fast_] load decimals as BigDecimal instead
|
244
|
+
*of as a Float. :auto pick the most precise for the number of digits. :float should be the same as
|
245
|
+
*ruby. :fast may require rounding but is must faster.
|
246
|
+
* - *:compat_bigdecimal* [_true_|_false_] load decimals as BigDecimal instead of as a Float when in
|
247
|
+
*compat or rails mode.
|
248
|
+
* - *:create_id* [_String_|_nil_] create id for json compatible object encoding, default is
|
249
|
+
*'json_class'
|
250
|
+
* - *:create_additions* [_Boolean_|_nil_] if true allow creation of instances using create_id on
|
251
|
+
*load.
|
252
|
+
* - *:second_precision* [_Fixnum_|_nil_] number of digits after the decimal when dumping the
|
253
|
+
*seconds portion of time
|
254
|
+
* - *:float_precision* [_Fixnum_|_nil_] number of digits of precision when dumping floats, 0
|
255
|
+
*indicates use Ruby
|
240
256
|
* - *:use_to_json* [_Boolean_|_nil_] call to_json() methods on dump, default is false
|
241
257
|
* - *:use_as_json* [_Boolean_|_nil_] call as_json() methods on dump, default is false
|
242
258
|
* - *:use_raw_json* [_Boolean_|_nil_] call raw_json() methods on dump, default is false
|
243
|
-
* - *:nilnil* [_Boolean_|_nil_] if true a nil input to load will return nil and not raise an
|
259
|
+
* - *:nilnil* [_Boolean_|_nil_] if true a nil input to load will return nil and not raise an
|
260
|
+
*Exception
|
244
261
|
* - *:empty_string* [_Boolean_|_nil_] if true an empty input will not raise an Exception
|
245
262
|
* - *:allow_gc* [_Boolean_|_nil_] allow or prohibit GC during parsing, default is true (allow)
|
246
|
-
* - *:quirks_mode* [_true,_|_false_|_nil_] Allow single JSON values instead of documents, default
|
247
|
-
*
|
248
|
-
* - *:
|
249
|
-
*
|
263
|
+
* - *:quirks_mode* [_true,_|_false_|_nil_] Allow single JSON values instead of documents, default
|
264
|
+
*is true (allow)
|
265
|
+
* - *:allow_invalid_unicode* [_true,_|_false_|_nil_] Allow invalid unicode, default is false (don't
|
266
|
+
*allow)
|
267
|
+
* - *:allow_nan* [_true,_|_false_|_nil_] Allow Nan, Infinity, and -Infinity to be parsed, default
|
268
|
+
*is true (allow)
|
269
|
+
* - *:indent_str* [_String_|_nil_] String to use for indentation, overriding the indent option is
|
270
|
+
*not nil
|
250
271
|
* - *:space* [_String_|_nil_] String to use for the space after the colon in JSON object fields
|
251
272
|
* - *:space_before* [_String_|_nil_] String to use before the colon separator in JSON object fields
|
252
273
|
* - *:object_nl* [_String_|_nil_] String to use after a JSON object field value
|
253
274
|
* - *:array_nl* [_String_|_nil_] String to use after a JSON array value
|
254
|
-
* - *:nan* [_:null_|_:huge_|_:word_|_:raise_|_:auto_] how to dump Infinity and NaN. :null places a
|
255
|
-
*
|
275
|
+
* - *:nan* [_:null_|_:huge_|_:word_|_:raise_|_:auto_] how to dump Infinity and NaN. :null places a
|
276
|
+
*null, :huge places a huge number, :word places Infinity or NaN, :raise raises and exception, :auto
|
277
|
+
*uses default for each mode.
|
278
|
+
* - *:hash_class* [_Class_|_nil_] Class to use instead of Hash on load, :object_class can also be
|
279
|
+
*used
|
256
280
|
* - *:array_class* [_Class_|_nil_] Class to use instead of Array on load
|
257
281
|
* - *:omit_nil* [_true_|_false_] if true Hash and Object attributes with nil values are omitted
|
258
282
|
* - *:ignore* [_nil_|Array] either nil or an Array of classes to ignore when dumping
|
259
|
-
* - *:ignore_under* [Boolean] if true then attributes that start with _ are ignored when dumping in
|
283
|
+
* - *:ignore_under* [Boolean] if true then attributes that start with _ are ignored when dumping in
|
284
|
+
*object or custom mode.
|
260
285
|
* - *:integer_range* [_Range_] Dump integers outside range as strings.
|
261
286
|
* - *:trace* [_true,_|_false_] Trace all load and dump calls, default is false (trace is off)
|
262
|
-
* - *:safe* [_true,_|_false_] Safe mimic breaks JSON mimic to be safer, default is false (safe is
|
287
|
+
* - *:safe* [_true,_|_false_] Safe mimic breaks JSON mimic to be safer, default is false (safe is
|
288
|
+
*off)
|
263
289
|
*
|
264
290
|
* Return [_Hash_] all current option settings.
|
265
291
|
*/
|
266
|
-
static VALUE
|
267
|
-
|
268
|
-
VALUE opts = rb_hash_new();
|
292
|
+
static VALUE get_def_opts(VALUE self) {
|
293
|
+
VALUE opts = rb_hash_new();
|
269
294
|
|
270
295
|
if (0 == oj_default_options.dump_opts.indent_size) {
|
271
|
-
|
296
|
+
rb_hash_aset(opts, oj_indent_sym, INT2FIX(oj_default_options.indent));
|
272
297
|
} else {
|
273
|
-
|
298
|
+
rb_hash_aset(opts, oj_indent_sym, rb_str_new2(oj_default_options.dump_opts.indent_str));
|
274
299
|
}
|
275
300
|
rb_hash_aset(opts, sec_prec_sym, INT2FIX(oj_default_options.sec_prec));
|
276
|
-
rb_hash_aset(opts,
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
rb_hash_aset(opts,
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
rb_hash_aset(opts,
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
rb_hash_aset(opts,
|
292
|
-
|
293
|
-
|
301
|
+
rb_hash_aset(opts,
|
302
|
+
circular_sym,
|
303
|
+
(Yes == oj_default_options.circular)
|
304
|
+
? Qtrue
|
305
|
+
: ((No == oj_default_options.circular) ? Qfalse : Qnil));
|
306
|
+
rb_hash_aset(opts,
|
307
|
+
class_cache_sym,
|
308
|
+
(Yes == oj_default_options.class_cache)
|
309
|
+
? Qtrue
|
310
|
+
: ((No == oj_default_options.class_cache) ? Qfalse : Qnil));
|
311
|
+
rb_hash_aset(opts,
|
312
|
+
auto_define_sym,
|
313
|
+
(Yes == oj_default_options.auto_define)
|
314
|
+
? Qtrue
|
315
|
+
: ((No == oj_default_options.auto_define) ? Qfalse : Qnil));
|
316
|
+
rb_hash_aset(opts,
|
317
|
+
symbol_keys_sym,
|
318
|
+
(Yes == oj_default_options.sym_key)
|
319
|
+
? Qtrue
|
320
|
+
: ((No == oj_default_options.sym_key) ? Qfalse : Qnil));
|
321
|
+
rb_hash_aset(opts,
|
322
|
+
bigdecimal_as_decimal_sym,
|
323
|
+
(Yes == oj_default_options.bigdec_as_num)
|
324
|
+
? Qtrue
|
325
|
+
: ((No == oj_default_options.bigdec_as_num) ? Qfalse : Qnil));
|
326
|
+
rb_hash_aset(opts,
|
327
|
+
oj_create_additions_sym,
|
328
|
+
(Yes == oj_default_options.create_ok)
|
329
|
+
? Qtrue
|
330
|
+
: ((No == oj_default_options.create_ok) ? Qfalse : Qnil));
|
331
|
+
rb_hash_aset(opts,
|
332
|
+
use_to_json_sym,
|
333
|
+
(Yes == oj_default_options.to_json)
|
334
|
+
? Qtrue
|
335
|
+
: ((No == oj_default_options.to_json) ? Qfalse : Qnil));
|
336
|
+
rb_hash_aset(opts,
|
337
|
+
use_to_hash_sym,
|
338
|
+
(Yes == oj_default_options.to_hash)
|
339
|
+
? Qtrue
|
340
|
+
: ((No == oj_default_options.to_hash) ? Qfalse : Qnil));
|
341
|
+
rb_hash_aset(opts,
|
342
|
+
use_as_json_sym,
|
343
|
+
(Yes == oj_default_options.as_json)
|
344
|
+
? Qtrue
|
345
|
+
: ((No == oj_default_options.as_json) ? Qfalse : Qnil));
|
346
|
+
rb_hash_aset(opts,
|
347
|
+
use_raw_json_sym,
|
348
|
+
(Yes == oj_default_options.raw_json)
|
349
|
+
? Qtrue
|
350
|
+
: ((No == oj_default_options.raw_json) ? Qfalse : Qnil));
|
351
|
+
rb_hash_aset(opts,
|
352
|
+
nilnil_sym,
|
353
|
+
(Yes == oj_default_options.nilnil)
|
354
|
+
? Qtrue
|
355
|
+
: ((No == oj_default_options.nilnil) ? Qfalse : Qnil));
|
356
|
+
rb_hash_aset(opts,
|
357
|
+
empty_string_sym,
|
358
|
+
(Yes == oj_default_options.empty_string)
|
359
|
+
? Qtrue
|
360
|
+
: ((No == oj_default_options.empty_string) ? Qfalse : Qnil));
|
361
|
+
rb_hash_aset(opts,
|
362
|
+
allow_gc_sym,
|
363
|
+
(Yes == oj_default_options.allow_gc)
|
364
|
+
? Qtrue
|
365
|
+
: ((No == oj_default_options.allow_gc) ? Qfalse : Qnil));
|
366
|
+
rb_hash_aset(opts,
|
367
|
+
oj_quirks_mode_sym,
|
368
|
+
(Yes == oj_default_options.quirks_mode)
|
369
|
+
? Qtrue
|
370
|
+
: ((No == oj_default_options.quirks_mode) ? Qfalse : Qnil));
|
371
|
+
rb_hash_aset(opts,
|
372
|
+
allow_invalid_unicode_sym,
|
373
|
+
(Yes == oj_default_options.allow_invalid)
|
374
|
+
? Qtrue
|
375
|
+
: ((No == oj_default_options.allow_invalid) ? Qfalse : Qnil));
|
376
|
+
rb_hash_aset(opts,
|
377
|
+
oj_allow_nan_sym,
|
378
|
+
(Yes == oj_default_options.allow_nan)
|
379
|
+
? Qtrue
|
380
|
+
: ((No == oj_default_options.allow_nan) ? Qfalse : Qnil));
|
381
|
+
rb_hash_aset(opts,
|
382
|
+
oj_trace_sym,
|
383
|
+
(Yes == oj_default_options.trace)
|
384
|
+
? Qtrue
|
385
|
+
: ((No == oj_default_options.trace) ? Qfalse : Qnil));
|
386
|
+
rb_hash_aset(opts,
|
387
|
+
oj_safe_sym,
|
388
|
+
(Yes == oj_default_options.safe)
|
389
|
+
? Qtrue
|
390
|
+
: ((No == oj_default_options.safe) ? Qfalse : Qnil));
|
294
391
|
rb_hash_aset(opts, float_prec_sym, INT2FIX(oj_default_options.float_prec));
|
295
|
-
rb_hash_aset(opts,
|
392
|
+
rb_hash_aset(opts,
|
393
|
+
ignore_under_sym,
|
394
|
+
(Yes == oj_default_options.ignore_under)
|
395
|
+
? Qtrue
|
396
|
+
: ((No == oj_default_options.ignore_under) ? Qfalse : Qnil));
|
296
397
|
switch (oj_default_options.mode) {
|
297
|
-
case StrictMode:
|
298
|
-
case CompatMode:
|
299
|
-
case NullMode:
|
300
|
-
case ObjectMode:
|
301
|
-
case CustomMode:
|
302
|
-
case RailsMode:
|
303
|
-
case WabMode:
|
304
|
-
default:
|
398
|
+
case StrictMode: rb_hash_aset(opts, mode_sym, strict_sym); break;
|
399
|
+
case CompatMode: rb_hash_aset(opts, mode_sym, compat_sym); break;
|
400
|
+
case NullMode: rb_hash_aset(opts, mode_sym, null_sym); break;
|
401
|
+
case ObjectMode: rb_hash_aset(opts, mode_sym, object_sym); break;
|
402
|
+
case CustomMode: rb_hash_aset(opts, mode_sym, custom_sym); break;
|
403
|
+
case RailsMode: rb_hash_aset(opts, mode_sym, rails_sym); break;
|
404
|
+
case WabMode: rb_hash_aset(opts, mode_sym, wab_sym); break;
|
405
|
+
default: rb_hash_aset(opts, mode_sym, object_sym); break;
|
305
406
|
}
|
306
407
|
|
307
408
|
if (oj_default_options.int_range_max != 0 || oj_default_options.int_range_min != 0) {
|
308
|
-
|
309
|
-
|
310
|
-
|
409
|
+
VALUE range = rb_obj_alloc(rb_cRange);
|
410
|
+
VALUE min = LONG2FIX(oj_default_options.int_range_min);
|
411
|
+
VALUE max = LONG2FIX(oj_default_options.int_range_max);
|
311
412
|
|
312
|
-
|
313
|
-
|
314
|
-
|
413
|
+
rb_ivar_set(range, oj_begin_id, min);
|
414
|
+
rb_ivar_set(range, oj_end_id, max);
|
415
|
+
rb_hash_aset(opts, integer_range_sym, range);
|
315
416
|
} else {
|
316
|
-
|
417
|
+
rb_hash_aset(opts, integer_range_sym, Qnil);
|
317
418
|
}
|
318
419
|
switch (oj_default_options.escape_mode) {
|
319
|
-
case NLEsc:
|
320
|
-
case JSONEsc:
|
321
|
-
case XSSEsc:
|
322
|
-
case ASCIIEsc:
|
323
|
-
case JXEsc:
|
324
|
-
default:
|
420
|
+
case NLEsc: rb_hash_aset(opts, escape_mode_sym, newline_sym); break;
|
421
|
+
case JSONEsc: rb_hash_aset(opts, escape_mode_sym, json_sym); break;
|
422
|
+
case XSSEsc: rb_hash_aset(opts, escape_mode_sym, xss_safe_sym); break;
|
423
|
+
case ASCIIEsc: rb_hash_aset(opts, escape_mode_sym, ascii_sym); break;
|
424
|
+
case JXEsc: rb_hash_aset(opts, escape_mode_sym, unicode_xss_sym); break;
|
425
|
+
default: rb_hash_aset(opts, escape_mode_sym, json_sym); break;
|
325
426
|
}
|
326
427
|
switch (oj_default_options.time_format) {
|
327
|
-
case XmlTime:
|
328
|
-
case RubyTime:
|
329
|
-
case UnixZTime:
|
428
|
+
case XmlTime: rb_hash_aset(opts, time_format_sym, xmlschema_sym); break;
|
429
|
+
case RubyTime: rb_hash_aset(opts, time_format_sym, ruby_sym); break;
|
430
|
+
case UnixZTime: rb_hash_aset(opts, time_format_sym, unix_zone_sym); break;
|
330
431
|
case UnixTime:
|
331
|
-
default:
|
432
|
+
default: rb_hash_aset(opts, time_format_sym, unix_sym); break;
|
332
433
|
}
|
333
434
|
switch (oj_default_options.bigdec_load) {
|
334
|
-
case BigDec:
|
335
|
-
case FloatDec:
|
336
|
-
case FastDec:
|
435
|
+
case BigDec: rb_hash_aset(opts, bigdecimal_load_sym, bigdecimal_sym); break;
|
436
|
+
case FloatDec: rb_hash_aset(opts, bigdecimal_load_sym, float_sym); break;
|
437
|
+
case FastDec: rb_hash_aset(opts, bigdecimal_load_sym, fast_sym); break;
|
337
438
|
case AutoDec:
|
338
|
-
default:
|
439
|
+
default: rb_hash_aset(opts, bigdecimal_load_sym, auto_sym); break;
|
339
440
|
}
|
340
441
|
rb_hash_aset(opts, compat_bigdecimal_sym, oj_default_options.compat_bigdec ? Qtrue : Qfalse);
|
341
|
-
rb_hash_aset(
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
rb_hash_aset(opts,
|
442
|
+
rb_hash_aset(
|
443
|
+
opts,
|
444
|
+
create_id_sym,
|
445
|
+
(NULL == oj_default_options.create_id) ? Qnil : rb_str_new2(oj_default_options.create_id));
|
446
|
+
rb_hash_aset(opts,
|
447
|
+
oj_space_sym,
|
448
|
+
(0 == oj_default_options.dump_opts.after_size)
|
449
|
+
? Qnil
|
450
|
+
: rb_str_new2(oj_default_options.dump_opts.after_sep));
|
451
|
+
rb_hash_aset(opts,
|
452
|
+
oj_space_before_sym,
|
453
|
+
(0 == oj_default_options.dump_opts.before_size)
|
454
|
+
? Qnil
|
455
|
+
: rb_str_new2(oj_default_options.dump_opts.before_sep));
|
456
|
+
rb_hash_aset(opts,
|
457
|
+
oj_object_nl_sym,
|
458
|
+
(0 == oj_default_options.dump_opts.hash_size)
|
459
|
+
? Qnil
|
460
|
+
: rb_str_new2(oj_default_options.dump_opts.hash_nl));
|
461
|
+
rb_hash_aset(opts,
|
462
|
+
oj_array_nl_sym,
|
463
|
+
(0 == oj_default_options.dump_opts.array_size)
|
464
|
+
? Qnil
|
465
|
+
: rb_str_new2(oj_default_options.dump_opts.array_nl));
|
346
466
|
|
347
467
|
switch (oj_default_options.dump_opts.nan_dump) {
|
348
|
-
case NullNan:
|
349
|
-
case RaiseNan:
|
350
|
-
case WordNan:
|
351
|
-
case HugeNan:
|
468
|
+
case NullNan: rb_hash_aset(opts, nan_sym, null_sym); break;
|
469
|
+
case RaiseNan: rb_hash_aset(opts, nan_sym, raise_sym); break;
|
470
|
+
case WordNan: rb_hash_aset(opts, nan_sym, word_sym); break;
|
471
|
+
case HugeNan: rb_hash_aset(opts, nan_sym, huge_sym); break;
|
352
472
|
case AutoNan:
|
353
|
-
default:
|
473
|
+
default: rb_hash_aset(opts, nan_sym, auto_sym); break;
|
354
474
|
}
|
355
475
|
rb_hash_aset(opts, omit_nil_sym, oj_default_options.dump_opts.omit_nil ? Qtrue : Qfalse);
|
356
476
|
rb_hash_aset(opts, oj_hash_class_sym, oj_default_options.hash_class);
|
357
477
|
rb_hash_aset(opts, oj_array_class_sym, oj_default_options.array_class);
|
358
478
|
|
359
479
|
if (NULL == oj_default_options.ignore) {
|
360
|
-
|
480
|
+
rb_hash_aset(opts, ignore_sym, Qnil);
|
361
481
|
} else {
|
362
|
-
|
363
|
-
|
482
|
+
VALUE * vp;
|
483
|
+
volatile VALUE a = rb_ary_new();
|
364
484
|
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
485
|
+
for (vp = oj_default_options.ignore; Qnil != *vp; vp++) {
|
486
|
+
rb_ary_push(a, *vp);
|
487
|
+
}
|
488
|
+
rb_hash_aset(opts, ignore_sym, a);
|
369
489
|
}
|
370
490
|
return opts;
|
371
491
|
}
|
@@ -375,452 +495,479 @@ get_def_opts(VALUE self) {
|
|
375
495
|
*
|
376
496
|
* Sets the default options for load and dump.
|
377
497
|
* - *opts* [_Hash_] options to change
|
378
|
-
* - *:indent* [_Fixnum_|_String_|_nil_] number of spaces to indent each element in a JSON
|
498
|
+
* - *:indent* [_Fixnum_|_String_|_nil_] number of spaces to indent each element in a JSON
|
499
|
+
*document or the String to use for identation.
|
379
500
|
* - :circular [_Boolean_|_nil_] support circular references while dumping.
|
380
501
|
* - *:auto_define* [_Boolean_|_nil_] automatically define classes if they do not exist.
|
381
502
|
* - *:symbol_keys* [_Boolean_|_nil_] convert hash keys to symbols.
|
382
503
|
* - *:class_cache* [_Boolean_|_nil_] cache classes for faster parsing.
|
383
|
-
* - *:escape* [_:newline_|_:json_|_:xss_safe_|_:ascii_|_unicode_xss_|_nil_] mode encodes all
|
384
|
-
*
|
385
|
-
|
386
|
-
*
|
387
|
-
*
|
388
|
-
* - *:
|
504
|
+
* - *:escape* [_:newline_|_:json_|_:xss_safe_|_:ascii_|_unicode_xss_|_nil_] mode encodes all
|
505
|
+
*high-bit characters as escaped sequences if :ascii, :json is standand UTF-8 JSON encoding,
|
506
|
+
*:newline is the same as :json but newlines are not escaped, :unicode_xss allows unicode but
|
507
|
+
*escapes &, <, and >, and any \u20xx characters along with some others, and :xss_safe escapes &, <,
|
508
|
+
*and >, and some others.
|
509
|
+
* - *:bigdecimal_as_decimal* [_Boolean_|_nil_] dump BigDecimal as a decimal number or as a
|
510
|
+
*String.
|
511
|
+
* - *:bigdecimal_load* [_:bigdecimal_|_:float_|_:auto_|_nil_] load decimals as BigDecimal instead
|
512
|
+
*of as a Float. :auto pick the most precise for the number of digits.
|
513
|
+
* - *:compat_bigdecimal* [_true_|_false_] load decimals as BigDecimal instead of as a Float in
|
514
|
+
*compat mode.
|
515
|
+
* - *:mode* [_:object_|_:strict_|_:compat_|_:null_|_:custom_|_:rails_|_:wab_] load and dump mode
|
516
|
+
*to use for JSON :strict raises an exception when a non-supported Object is encountered. :compat
|
517
|
+
*attempts to extract variable values from an Object using to_json() or to_hash() then it walks the
|
518
|
+
*Object's variables if neither is found. The :object mode ignores to_hash() and to_json() methods
|
519
|
+
*and encodes variables using code internal to the Oj gem. The :null mode ignores non-supported
|
520
|
+
*Objects and replaces them with a null. The :custom mode honors all dump options. The :rails more
|
521
|
+
*mimics rails and Active behavior.
|
522
|
+
* - *:time_format* [_:unix_|_:xmlschema_|_:ruby_] time format when dumping in :compat mode :unix
|
523
|
+
*decimal number denoting the number of seconds since 1/1/1970, :unix_zone decimal number denoting
|
524
|
+
*the number of seconds since 1/1/1970 plus the utc_offset in the exponent, :xmlschema date-time
|
525
|
+
*format taken from XML Schema as a String, :ruby Time.to_s formatted String.
|
389
526
|
* - *:create_id* [_String_|_nil_] create id for json compatible object encoding
|
390
|
-
* - *:create_additions* [_Boolean_|_nil_] if true allow creation of instances using create_id on
|
391
|
-
*
|
392
|
-
* - *:
|
527
|
+
* - *:create_additions* [_Boolean_|_nil_] if true allow creation of instances using create_id on
|
528
|
+
*load.
|
529
|
+
* - *:second_precision* [_Fixnum_|_nil_] number of digits after the decimal when dumping the
|
530
|
+
*seconds portion of time.
|
531
|
+
* - *:float_precision* [_Fixnum_|_nil_] number of digits of precision when dumping floats, 0
|
532
|
+
*indicates use Ruby.
|
393
533
|
* - *:use_to_json* [_Boolean_|_nil_] call to_json() methods on dump, default is false.
|
394
534
|
* - *:use_as_json* [_Boolean_|_nil_] call as_json() methods on dump, default is false.
|
395
535
|
* - *:use_to_hash* [_Boolean_|_nil_] call to_hash() methods on dump, default is false.
|
396
536
|
* - *:use_raw_json* [_Boolean_|_nil_] call raw_json() methods on dump, default is false.
|
397
|
-
* - *:nilnil* [_Boolean_|_nil_] if true a nil input to load will return nil and not raise an
|
537
|
+
* - *:nilnil* [_Boolean_|_nil_] if true a nil input to load will return nil and not raise an
|
538
|
+
*Exception.
|
398
539
|
* - *:allow_gc* [_Boolean_|_nil_] allow or prohibit GC during parsing, default is true (allow).
|
399
|
-
* - *:quirks_mode* [_Boolean_|_nil_] allow single JSON values instead of documents, default is
|
400
|
-
*
|
540
|
+
* - *:quirks_mode* [_Boolean_|_nil_] allow single JSON values instead of documents, default is
|
541
|
+
*true (allow).
|
542
|
+
* - *:allow_invalid_unicode* [_Boolean_|_nil_] allow invalid unicode, default is false (don't
|
543
|
+
*allow).
|
401
544
|
* - *:allow_nan* [_Boolean_|_nil_] allow Nan, Infinity, and -Infinity, default is true (allow).
|
402
545
|
* - *:space* [_String_|_nil_] String to use for the space after the colon in JSON object fields.
|
403
|
-
* - *:space_before* [_String_|_nil_] String to use before the colon separator in JSON object
|
546
|
+
* - *:space_before* [_String_|_nil_] String to use before the colon separator in JSON object
|
547
|
+
*fields.
|
404
548
|
* - *:object_nl* [_String_|_nil_] String to use after a JSON object field value.
|
405
549
|
* - *:array_nl* [_String_|_nil_] String to use after a JSON array value
|
406
|
-
* - *:nan* [_:null_|_:huge_|_:word_|_:raise_] how to dump Infinity and NaN in null, strict, and
|
407
|
-
*
|
550
|
+
* - *:nan* [_:null_|_:huge_|_:word_|_:raise_] how to dump Infinity and NaN in null, strict, and
|
551
|
+
*compat mode. :null places a null, :huge places a huge number, :word places Infinity or NaN, :raise
|
552
|
+
*raises and exception, :auto uses default for each mode.
|
553
|
+
* - *:hash_class* [_Class_|_nil_] Class to use instead of Hash on load, :object_class can also be
|
554
|
+
*used.
|
408
555
|
* - *:array_class* [_Class_|_nil_] Class to use instead of Array on load.
|
409
556
|
* - *:omit_nil* [_true_|_false_] if true Hash and Object attributes with nil values are omitted.
|
410
557
|
* - *:ignore* [_nil_|Array] either nil or an Array of classes to ignore when dumping
|
411
|
-
* - *:ignore_under* [_Boolean_] if true then attributes that start with _ are ignored when
|
558
|
+
* - *:ignore_under* [_Boolean_] if true then attributes that start with _ are ignored when
|
559
|
+
*dumping in object or custom mode.
|
412
560
|
* - *:integer_range* [_Range_] Dump integers outside range as strings.
|
413
561
|
* - *:trace* [_Boolean_] turn trace on or off.
|
414
562
|
* - *:safe* [_Boolean_] turn safe mimic on or off.
|
415
563
|
*/
|
416
|
-
static VALUE
|
417
|
-
set_def_opts(VALUE self, VALUE opts) {
|
564
|
+
static VALUE set_def_opts(VALUE self, VALUE opts) {
|
418
565
|
Check_Type(opts, T_HASH);
|
419
566
|
oj_parse_options(opts, &oj_default_options);
|
420
567
|
|
421
568
|
return Qnil;
|
422
569
|
}
|
423
570
|
|
424
|
-
void
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
YesNoOpt o;
|
450
|
-
volatile VALUE v;
|
451
|
-
size_t len;
|
571
|
+
void oj_parse_options(VALUE ropts, Options copts) {
|
572
|
+
struct _yesNoOpt ynos[] = {{circular_sym, &copts->circular},
|
573
|
+
{auto_define_sym, &copts->auto_define},
|
574
|
+
{symbol_keys_sym, &copts->sym_key},
|
575
|
+
{class_cache_sym, &copts->class_cache},
|
576
|
+
{bigdecimal_as_decimal_sym, &copts->bigdec_as_num},
|
577
|
+
{use_to_hash_sym, &copts->to_hash},
|
578
|
+
{use_to_json_sym, &copts->to_json},
|
579
|
+
{use_as_json_sym, &copts->as_json},
|
580
|
+
{use_raw_json_sym, &copts->raw_json},
|
581
|
+
{nilnil_sym, &copts->nilnil},
|
582
|
+
{allow_blank_sym, &copts->nilnil}, // same as nilnil
|
583
|
+
{empty_string_sym, &copts->empty_string},
|
584
|
+
{allow_gc_sym, &copts->allow_gc},
|
585
|
+
{oj_quirks_mode_sym, &copts->quirks_mode},
|
586
|
+
{allow_invalid_unicode_sym, &copts->allow_invalid},
|
587
|
+
{oj_allow_nan_sym, &copts->allow_nan},
|
588
|
+
{oj_trace_sym, &copts->trace},
|
589
|
+
{oj_safe_sym, &copts->safe},
|
590
|
+
{ignore_under_sym, &copts->ignore_under},
|
591
|
+
{oj_create_additions_sym, &copts->create_ok},
|
592
|
+
{Qnil, 0}};
|
593
|
+
YesNoOpt o;
|
594
|
+
volatile VALUE v;
|
595
|
+
size_t len;
|
452
596
|
|
453
597
|
if (T_HASH != rb_type(ropts)) {
|
454
|
-
|
598
|
+
return;
|
455
599
|
}
|
456
600
|
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_indent_sym)) {
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
601
|
+
v = rb_hash_lookup(ropts, oj_indent_sym);
|
602
|
+
switch (rb_type(v)) {
|
603
|
+
case T_NIL:
|
604
|
+
copts->dump_opts.indent_size = 0;
|
605
|
+
*copts->dump_opts.indent_str = '\0';
|
606
|
+
copts->indent = 0;
|
607
|
+
break;
|
608
|
+
case T_FIXNUM:
|
609
|
+
copts->dump_opts.indent_size = 0;
|
610
|
+
*copts->dump_opts.indent_str = '\0';
|
611
|
+
copts->indent = FIX2INT(v);
|
612
|
+
break;
|
613
|
+
case T_STRING:
|
614
|
+
if (sizeof(copts->dump_opts.indent_str) <= (len = RSTRING_LEN(v))) {
|
615
|
+
rb_raise(rb_eArgError,
|
616
|
+
"indent string is limited to %lu characters.",
|
617
|
+
(unsigned long)sizeof(copts->dump_opts.indent_str));
|
618
|
+
}
|
619
|
+
strcpy(copts->dump_opts.indent_str, StringValuePtr(v));
|
620
|
+
copts->dump_opts.indent_size = (uint8_t)len;
|
621
|
+
copts->indent = 0;
|
622
|
+
break;
|
623
|
+
default: rb_raise(rb_eTypeError, "indent must be a Fixnum, String, or nil."); break;
|
624
|
+
}
|
481
625
|
}
|
482
626
|
if (Qnil != (v = rb_hash_lookup(ropts, float_prec_sym))) {
|
483
|
-
|
627
|
+
int n;
|
484
628
|
|
485
629
|
#ifdef RUBY_INTEGER_UNIFICATION
|
486
|
-
|
487
|
-
|
488
|
-
|
630
|
+
if (rb_cInteger != rb_obj_class(v)) {
|
631
|
+
rb_raise(rb_eArgError, ":float_precision must be a Integer.");
|
632
|
+
}
|
489
633
|
#else
|
490
|
-
|
491
|
-
|
492
|
-
|
634
|
+
if (T_FIXNUM != rb_type(v)) {
|
635
|
+
rb_raise(rb_eArgError, ":float_precision must be a Fixnum.");
|
636
|
+
}
|
493
637
|
#endif
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
638
|
+
n = FIX2INT(v);
|
639
|
+
if (0 >= n) {
|
640
|
+
*copts->float_fmt = '\0';
|
641
|
+
copts->float_prec = 0;
|
642
|
+
} else {
|
643
|
+
if (20 < n) {
|
644
|
+
n = 20;
|
645
|
+
}
|
646
|
+
sprintf(copts->float_fmt, "%%0.%dg", n);
|
647
|
+
copts->float_prec = n;
|
648
|
+
}
|
505
649
|
}
|
506
650
|
if (Qnil != (v = rb_hash_lookup(ropts, sec_prec_sym))) {
|
507
|
-
|
651
|
+
int n;
|
508
652
|
|
509
653
|
#ifdef RUBY_INTEGER_UNIFICATION
|
510
|
-
|
511
|
-
|
512
|
-
|
654
|
+
if (rb_cInteger != rb_obj_class(v)) {
|
655
|
+
rb_raise(rb_eArgError, ":second_precision must be a Integer.");
|
656
|
+
}
|
513
657
|
#else
|
514
|
-
|
515
|
-
|
516
|
-
|
658
|
+
if (T_FIXNUM != rb_type(v)) {
|
659
|
+
rb_raise(rb_eArgError, ":second_precision must be a Fixnum.");
|
660
|
+
}
|
517
661
|
#endif
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
662
|
+
n = NUM2INT(v);
|
663
|
+
if (0 > n) {
|
664
|
+
n = 0;
|
665
|
+
copts->sec_prec_set = false;
|
666
|
+
} else if (9 < n) {
|
667
|
+
n = 9;
|
668
|
+
copts->sec_prec_set = true;
|
669
|
+
} else {
|
670
|
+
copts->sec_prec_set = true;
|
671
|
+
}
|
672
|
+
copts->sec_prec = n;
|
529
673
|
}
|
530
674
|
if (Qnil != (v = rb_hash_lookup(ropts, mode_sym))) {
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
675
|
+
if (wab_sym == v) {
|
676
|
+
copts->mode = WabMode;
|
677
|
+
} else if (object_sym == v) {
|
678
|
+
copts->mode = ObjectMode;
|
679
|
+
} else if (strict_sym == v) {
|
680
|
+
copts->mode = StrictMode;
|
681
|
+
} else if (compat_sym == v || json_sym == v) {
|
682
|
+
copts->mode = CompatMode;
|
683
|
+
} else if (null_sym == v) {
|
684
|
+
copts->mode = NullMode;
|
685
|
+
} else if (custom_sym == v) {
|
686
|
+
copts->mode = CustomMode;
|
687
|
+
} else if (rails_sym == v) {
|
688
|
+
copts->mode = RailsMode;
|
689
|
+
} else {
|
690
|
+
rb_raise(rb_eArgError,
|
691
|
+
":mode must be :object, :strict, :compat, :null, :custom, :rails, or :wab.");
|
692
|
+
}
|
548
693
|
}
|
549
694
|
if (Qnil != (v = rb_hash_lookup(ropts, time_format_sym))) {
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
695
|
+
if (unix_sym == v) {
|
696
|
+
copts->time_format = UnixTime;
|
697
|
+
} else if (unix_zone_sym == v) {
|
698
|
+
copts->time_format = UnixZTime;
|
699
|
+
} else if (xmlschema_sym == v) {
|
700
|
+
copts->time_format = XmlTime;
|
701
|
+
} else if (ruby_sym == v) {
|
702
|
+
copts->time_format = RubyTime;
|
703
|
+
} else {
|
704
|
+
rb_raise(rb_eArgError, ":time_format must be :unix, :unix_zone, :xmlschema, or :ruby.");
|
705
|
+
}
|
561
706
|
}
|
562
707
|
if (Qnil != (v = rb_hash_lookup(ropts, escape_mode_sym))) {
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
708
|
+
if (newline_sym == v) {
|
709
|
+
copts->escape_mode = NLEsc;
|
710
|
+
} else if (json_sym == v) {
|
711
|
+
copts->escape_mode = JSONEsc;
|
712
|
+
} else if (xss_safe_sym == v) {
|
713
|
+
copts->escape_mode = XSSEsc;
|
714
|
+
} else if (ascii_sym == v) {
|
715
|
+
copts->escape_mode = ASCIIEsc;
|
716
|
+
} else if (unicode_xss_sym == v) {
|
717
|
+
copts->escape_mode = JXEsc;
|
718
|
+
} else {
|
719
|
+
rb_raise(rb_eArgError,
|
720
|
+
":encoding must be :newline, :json, :xss_safe, :unicode_xss, or :ascii.");
|
721
|
+
}
|
576
722
|
}
|
577
723
|
if (Qnil != (v = rb_hash_lookup(ropts, bigdecimal_load_sym))) {
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
724
|
+
if (bigdecimal_sym == v || Qtrue == v) {
|
725
|
+
copts->bigdec_load = BigDec;
|
726
|
+
} else if (float_sym == v) {
|
727
|
+
copts->bigdec_load = FloatDec;
|
728
|
+
} else if (fast_sym == v) {
|
729
|
+
copts->bigdec_load = FastDec;
|
730
|
+
} else if (auto_sym == v || Qfalse == v) {
|
731
|
+
copts->bigdec_load = AutoDec;
|
732
|
+
} else {
|
733
|
+
rb_raise(rb_eArgError, ":bigdecimal_load must be :bigdecimal, :float, or :auto.");
|
734
|
+
}
|
589
735
|
}
|
590
736
|
if (Qnil != (v = rb_hash_lookup(ropts, compat_bigdecimal_sym))) {
|
591
|
-
|
737
|
+
copts->compat_bigdec = (Qtrue == v);
|
592
738
|
}
|
593
739
|
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_decimal_class_sym)) {
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
}
|
604
|
-
}
|
740
|
+
v = rb_hash_lookup(ropts, oj_decimal_class_sym);
|
741
|
+
if (rb_cFloat == v) {
|
742
|
+
copts->compat_bigdec = false;
|
743
|
+
} else if (oj_bigdecimal_class == v) {
|
744
|
+
copts->compat_bigdec = true;
|
745
|
+
} else {
|
746
|
+
rb_raise(rb_eArgError, ":decimal_class must be BigDecimal or Float.");
|
747
|
+
}
|
748
|
+
}
|
605
749
|
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, create_id_sym)) {
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
}
|
750
|
+
v = rb_hash_lookup(ropts, create_id_sym);
|
751
|
+
if (Qnil == v) {
|
752
|
+
if (oj_json_class != oj_default_options.create_id && NULL != copts->create_id) {
|
753
|
+
xfree((char *)oj_default_options.create_id);
|
754
|
+
}
|
755
|
+
copts->create_id = NULL;
|
756
|
+
copts->create_id_len = 0;
|
757
|
+
} else if (T_STRING == rb_type(v)) {
|
758
|
+
const char *str = StringValuePtr(v);
|
759
|
+
|
760
|
+
len = RSTRING_LEN(v);
|
761
|
+
if (len != copts->create_id_len || 0 != strcmp(copts->create_id, str)) {
|
762
|
+
copts->create_id = ALLOC_N(char, len + 1);
|
763
|
+
strcpy((char *)copts->create_id, str);
|
764
|
+
copts->create_id_len = len;
|
765
|
+
}
|
766
|
+
} else {
|
767
|
+
rb_raise(rb_eArgError, ":create_id must be string.");
|
768
|
+
}
|
626
769
|
}
|
627
770
|
for (o = ynos; 0 != o->attr; o++) {
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
771
|
+
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, o->sym)) {
|
772
|
+
v = rb_hash_lookup(ropts, o->sym);
|
773
|
+
if (Qnil == v) {
|
774
|
+
*o->attr = NotSet;
|
775
|
+
} else if (Qtrue == v) {
|
776
|
+
*o->attr = Yes;
|
777
|
+
} else if (Qfalse == v) {
|
778
|
+
*o->attr = No;
|
779
|
+
} else {
|
780
|
+
rb_raise(rb_eArgError,
|
781
|
+
"%s must be true, false, or nil.",
|
782
|
+
rb_id2name(SYM2ID(o->sym)));
|
783
|
+
}
|
784
|
+
}
|
640
785
|
}
|
641
786
|
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_space_sym)) {
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
787
|
+
if (Qnil == (v = rb_hash_lookup(ropts, oj_space_sym))) {
|
788
|
+
copts->dump_opts.after_size = 0;
|
789
|
+
*copts->dump_opts.after_sep = '\0';
|
790
|
+
} else {
|
791
|
+
rb_check_type(v, T_STRING);
|
792
|
+
if (sizeof(copts->dump_opts.after_sep) <= (len = RSTRING_LEN(v))) {
|
793
|
+
rb_raise(rb_eArgError,
|
794
|
+
"space string is limited to %lu characters.",
|
795
|
+
(unsigned long)sizeof(copts->dump_opts.after_sep));
|
796
|
+
}
|
797
|
+
strcpy(copts->dump_opts.after_sep, StringValuePtr(v));
|
798
|
+
copts->dump_opts.after_size = (uint8_t)len;
|
799
|
+
}
|
653
800
|
}
|
654
801
|
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_space_before_sym)) {
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
802
|
+
if (Qnil == (v = rb_hash_lookup(ropts, oj_space_before_sym))) {
|
803
|
+
copts->dump_opts.before_size = 0;
|
804
|
+
*copts->dump_opts.before_sep = '\0';
|
805
|
+
} else {
|
806
|
+
rb_check_type(v, T_STRING);
|
807
|
+
if (sizeof(copts->dump_opts.before_sep) <= (len = RSTRING_LEN(v))) {
|
808
|
+
rb_raise(rb_eArgError,
|
809
|
+
"sapce_before string is limited to %lu characters.",
|
810
|
+
(unsigned long)sizeof(copts->dump_opts.before_sep));
|
811
|
+
}
|
812
|
+
strcpy(copts->dump_opts.before_sep, StringValuePtr(v));
|
813
|
+
copts->dump_opts.before_size = (uint8_t)len;
|
814
|
+
}
|
666
815
|
}
|
667
816
|
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_object_nl_sym)) {
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
817
|
+
if (Qnil == (v = rb_hash_lookup(ropts, oj_object_nl_sym))) {
|
818
|
+
copts->dump_opts.hash_size = 0;
|
819
|
+
*copts->dump_opts.hash_nl = '\0';
|
820
|
+
} else {
|
821
|
+
rb_check_type(v, T_STRING);
|
822
|
+
if (sizeof(copts->dump_opts.hash_nl) <= (len = RSTRING_LEN(v))) {
|
823
|
+
rb_raise(rb_eArgError,
|
824
|
+
"object_nl string is limited to %lu characters.",
|
825
|
+
(unsigned long)sizeof(copts->dump_opts.hash_nl));
|
826
|
+
}
|
827
|
+
strcpy(copts->dump_opts.hash_nl, StringValuePtr(v));
|
828
|
+
copts->dump_opts.hash_size = (uint8_t)len;
|
829
|
+
}
|
679
830
|
}
|
680
831
|
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_array_nl_sym)) {
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
832
|
+
if (Qnil == (v = rb_hash_lookup(ropts, oj_array_nl_sym))) {
|
833
|
+
copts->dump_opts.array_size = 0;
|
834
|
+
*copts->dump_opts.array_nl = '\0';
|
835
|
+
} else {
|
836
|
+
rb_check_type(v, T_STRING);
|
837
|
+
if (sizeof(copts->dump_opts.array_nl) <= (len = RSTRING_LEN(v))) {
|
838
|
+
rb_raise(rb_eArgError,
|
839
|
+
"array_nl string is limited to %lu characters.",
|
840
|
+
(unsigned long)sizeof(copts->dump_opts.array_nl));
|
841
|
+
}
|
842
|
+
strcpy(copts->dump_opts.array_nl, StringValuePtr(v));
|
843
|
+
copts->dump_opts.array_size = (uint8_t)len;
|
844
|
+
}
|
692
845
|
}
|
693
846
|
if (Qnil != (v = rb_hash_lookup(ropts, nan_sym))) {
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
847
|
+
if (null_sym == v) {
|
848
|
+
copts->dump_opts.nan_dump = NullNan;
|
849
|
+
} else if (huge_sym == v) {
|
850
|
+
copts->dump_opts.nan_dump = HugeNan;
|
851
|
+
} else if (word_sym == v) {
|
852
|
+
copts->dump_opts.nan_dump = WordNan;
|
853
|
+
} else if (raise_sym == v) {
|
854
|
+
copts->dump_opts.nan_dump = RaiseNan;
|
855
|
+
} else if (auto_sym == v) {
|
856
|
+
copts->dump_opts.nan_dump = AutoNan;
|
857
|
+
} else {
|
858
|
+
rb_raise(rb_eArgError, ":nan must be :null, :huge, :word, :raise, or :auto.");
|
859
|
+
}
|
707
860
|
}
|
708
|
-
copts->dump_opts.use = (0 < copts->dump_opts.indent_size ||
|
709
|
-
|
710
|
-
|
711
|
-
0 < copts->dump_opts.hash_size ||
|
712
|
-
0 < copts->dump_opts.array_size);
|
861
|
+
copts->dump_opts.use = (0 < copts->dump_opts.indent_size || 0 < copts->dump_opts.after_size ||
|
862
|
+
0 < copts->dump_opts.before_size || 0 < copts->dump_opts.hash_size ||
|
863
|
+
0 < copts->dump_opts.array_size);
|
713
864
|
if (Qnil != (v = rb_hash_lookup(ropts, omit_nil_sym))) {
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
865
|
+
if (Qtrue == v) {
|
866
|
+
copts->dump_opts.omit_nil = true;
|
867
|
+
} else if (Qfalse == v) {
|
868
|
+
copts->dump_opts.omit_nil = false;
|
869
|
+
} else {
|
870
|
+
rb_raise(rb_eArgError, ":omit_nil must be true or false.");
|
871
|
+
}
|
721
872
|
}
|
722
873
|
// This is here only for backwards compatibility with the original Oj.
|
723
874
|
v = rb_hash_lookup(ropts, oj_ascii_only_sym);
|
724
875
|
if (Qtrue == v) {
|
725
|
-
|
876
|
+
copts->escape_mode = ASCIIEsc;
|
726
877
|
} else if (Qfalse == v) {
|
727
|
-
|
878
|
+
copts->escape_mode = JSONEsc;
|
728
879
|
}
|
729
880
|
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_hash_class_sym)) {
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
881
|
+
if (Qnil == (v = rb_hash_lookup(ropts, oj_hash_class_sym))) {
|
882
|
+
copts->hash_class = Qnil;
|
883
|
+
} else {
|
884
|
+
rb_check_type(v, T_CLASS);
|
885
|
+
copts->hash_class = v;
|
886
|
+
}
|
736
887
|
}
|
737
888
|
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_object_class_sym)) {
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
889
|
+
if (Qnil == (v = rb_hash_lookup(ropts, oj_object_class_sym))) {
|
890
|
+
copts->hash_class = Qnil;
|
891
|
+
} else {
|
892
|
+
rb_check_type(v, T_CLASS);
|
893
|
+
copts->hash_class = v;
|
894
|
+
}
|
744
895
|
}
|
745
896
|
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_array_class_sym)) {
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
897
|
+
if (Qnil == (v = rb_hash_lookup(ropts, oj_array_class_sym))) {
|
898
|
+
copts->array_class = Qnil;
|
899
|
+
} else {
|
900
|
+
rb_check_type(v, T_CLASS);
|
901
|
+
copts->array_class = v;
|
902
|
+
}
|
752
903
|
}
|
753
904
|
oj_parse_opt_match_string(&copts->str_rx, ropts);
|
754
905
|
if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, ignore_sym)) {
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
906
|
+
xfree(copts->ignore);
|
907
|
+
copts->ignore = NULL;
|
908
|
+
if (Qnil != (v = rb_hash_lookup(ropts, ignore_sym))) {
|
909
|
+
int cnt;
|
910
|
+
|
911
|
+
rb_check_type(v, T_ARRAY);
|
912
|
+
cnt = (int)RARRAY_LEN(v);
|
913
|
+
if (0 < cnt) {
|
914
|
+
int i;
|
915
|
+
|
916
|
+
copts->ignore = ALLOC_N(VALUE, cnt + 1);
|
917
|
+
for (i = 0; i < cnt; i++) {
|
918
|
+
copts->ignore[i] = rb_ary_entry(v, i);
|
919
|
+
}
|
920
|
+
copts->ignore[i] = Qnil;
|
921
|
+
}
|
922
|
+
}
|
772
923
|
}
|
773
924
|
if (Qnil != (v = rb_hash_lookup(ropts, integer_range_sym))) {
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
925
|
+
if (TYPE(v) == T_STRUCT && rb_obj_class(v) == rb_cRange) {
|
926
|
+
VALUE min = rb_funcall(v, oj_begin_id, 0);
|
927
|
+
VALUE max = rb_funcall(v, oj_end_id, 0);
|
928
|
+
|
929
|
+
if (TYPE(min) != T_FIXNUM || TYPE(max) != T_FIXNUM) {
|
930
|
+
rb_raise(rb_eArgError, ":integer_range range bounds is not Fixnum.");
|
931
|
+
}
|
932
|
+
|
933
|
+
copts->int_range_min = FIX2LONG(min);
|
934
|
+
copts->int_range_max = FIX2LONG(max);
|
935
|
+
} else if (Qfalse != v) {
|
936
|
+
rb_raise(rb_eArgError, ":integer_range must be a range of Fixnum.");
|
937
|
+
}
|
787
938
|
}
|
788
939
|
}
|
789
940
|
|
790
|
-
static int
|
791
|
-
|
792
|
-
RxClass rc = (RxClass)rx;
|
941
|
+
static int match_string_cb(VALUE key, VALUE value, VALUE rx) {
|
942
|
+
RxClass rc = (RxClass)rx;
|
793
943
|
|
794
944
|
if (T_CLASS != rb_type(value)) {
|
795
|
-
|
945
|
+
rb_raise(rb_eArgError, "for :match_string, the hash values must be a Class.");
|
796
946
|
}
|
797
947
|
switch (rb_type(key)) {
|
798
|
-
case T_REGEXP:
|
799
|
-
oj_rxclass_rappend(rc, key, value);
|
800
|
-
break;
|
948
|
+
case T_REGEXP: oj_rxclass_rappend(rc, key, value); break;
|
801
949
|
case T_STRING:
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
950
|
+
if (0 != oj_rxclass_append(rc, StringValuePtr(key), value)) {
|
951
|
+
rb_raise(rb_eArgError, "%s", rc->err);
|
952
|
+
}
|
953
|
+
break;
|
806
954
|
default:
|
807
|
-
|
808
|
-
|
955
|
+
rb_raise(rb_eArgError, "for :match_string, keys must either a String or RegExp.");
|
956
|
+
break;
|
809
957
|
}
|
810
958
|
return ST_CONTINUE;
|
811
959
|
}
|
812
960
|
|
813
|
-
void
|
814
|
-
|
815
|
-
VALUE v;
|
961
|
+
void oj_parse_opt_match_string(RxClass rc, VALUE ropts) {
|
962
|
+
VALUE v;
|
816
963
|
|
817
964
|
if (Qnil != (v = rb_hash_lookup(ropts, match_string_sym))) {
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
965
|
+
rb_check_type(v, T_HASH);
|
966
|
+
// Zero out rc. Pattern are not appended but override.
|
967
|
+
rc->head = NULL;
|
968
|
+
rc->tail = NULL;
|
969
|
+
*rc->err = '\0';
|
970
|
+
rb_hash_foreach(v, match_string_cb, (VALUE)rc);
|
824
971
|
}
|
825
972
|
}
|
826
973
|
|
@@ -856,54 +1003,50 @@ oj_parse_opt_match_string(RxClass rc, VALUE ropts) {
|
|
856
1003
|
*
|
857
1004
|
* Returns [_Hash_|_Array_|_String_|_Fixnum_|_Float_|_Boolean_|_nil_]
|
858
1005
|
*/
|
859
|
-
static VALUE
|
860
|
-
|
861
|
-
Mode mode = oj_default_options.mode;
|
1006
|
+
static VALUE load(int argc, VALUE *argv, VALUE self) {
|
1007
|
+
Mode mode = oj_default_options.mode;
|
862
1008
|
|
863
1009
|
if (1 > argc) {
|
864
|
-
|
1010
|
+
rb_raise(rb_eArgError, "Wrong number of arguments to load().");
|
865
1011
|
}
|
866
1012
|
if (2 <= argc) {
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
1013
|
+
VALUE ropts = argv[1];
|
1014
|
+
VALUE v;
|
1015
|
+
|
1016
|
+
if (Qnil != ropts || CompatMode != mode) {
|
1017
|
+
Check_Type(ropts, T_HASH);
|
1018
|
+
if (Qnil != (v = rb_hash_lookup(ropts, mode_sym))) {
|
1019
|
+
if (object_sym == v) {
|
1020
|
+
mode = ObjectMode;
|
1021
|
+
} else if (strict_sym == v) {
|
1022
|
+
mode = StrictMode;
|
1023
|
+
} else if (compat_sym == v || json_sym == v) {
|
1024
|
+
mode = CompatMode;
|
1025
|
+
} else if (null_sym == v) {
|
1026
|
+
mode = NullMode;
|
1027
|
+
} else if (custom_sym == v) {
|
1028
|
+
mode = CustomMode;
|
1029
|
+
} else if (rails_sym == v) {
|
1030
|
+
mode = RailsMode;
|
1031
|
+
} else if (wab_sym == v) {
|
1032
|
+
mode = WabMode;
|
1033
|
+
} else {
|
1034
|
+
rb_raise(rb_eArgError,
|
1035
|
+
":mode must be :object, :strict, :compat, :null, :custom, :rails, or "
|
1036
|
+
":wab.");
|
1037
|
+
}
|
1038
|
+
}
|
1039
|
+
}
|
892
1040
|
}
|
893
1041
|
switch (mode) {
|
894
1042
|
case StrictMode:
|
895
|
-
case NullMode:
|
896
|
-
return oj_strict_parse(argc, argv, self);
|
1043
|
+
case NullMode: return oj_strict_parse(argc, argv, self);
|
897
1044
|
case CompatMode:
|
898
|
-
case RailsMode:
|
899
|
-
|
900
|
-
case
|
901
|
-
return oj_custom_parse(argc, argv, self);
|
902
|
-
case WabMode:
|
903
|
-
return oj_wab_parse(argc, argv, self);
|
1045
|
+
case RailsMode: return oj_compat_parse(argc, argv, self);
|
1046
|
+
case CustomMode: return oj_custom_parse(argc, argv, self);
|
1047
|
+
case WabMode: return oj_wab_parse(argc, argv, self);
|
904
1048
|
case ObjectMode:
|
905
|
-
default:
|
906
|
-
break;
|
1049
|
+
default: break;
|
907
1050
|
}
|
908
1051
|
return oj_object_parse(argc, argv, self);
|
909
1052
|
}
|
@@ -942,69 +1085,61 @@ load(int argc, VALUE *argv, VALUE self) {
|
|
942
1085
|
*
|
943
1086
|
* Returns [_Object_|_Hash_|_Array_|_String_|_Fixnum_|_Float_|_Boolean_|_nil_]
|
944
1087
|
*/
|
945
|
-
static VALUE
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
struct _parseInfo pi;
|
1088
|
+
static VALUE load_file(int argc, VALUE *argv, VALUE self) {
|
1089
|
+
char * path;
|
1090
|
+
int fd;
|
1091
|
+
Mode mode = oj_default_options.mode;
|
1092
|
+
struct _parseInfo pi;
|
951
1093
|
|
952
1094
|
if (1 > argc) {
|
953
|
-
|
1095
|
+
rb_raise(rb_eArgError, "Wrong number of arguments to load().");
|
954
1096
|
}
|
955
1097
|
Check_Type(*argv, T_STRING);
|
956
1098
|
parse_info_init(&pi);
|
957
|
-
pi.options
|
958
|
-
pi.handler
|
1099
|
+
pi.options = oj_default_options;
|
1100
|
+
pi.handler = Qnil;
|
959
1101
|
pi.err_class = Qnil;
|
960
1102
|
pi.max_depth = 0;
|
961
1103
|
if (2 <= argc) {
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
1104
|
+
VALUE ropts = argv[1];
|
1105
|
+
VALUE v;
|
1106
|
+
|
1107
|
+
Check_Type(ropts, T_HASH);
|
1108
|
+
if (Qnil != (v = rb_hash_lookup(ropts, mode_sym))) {
|
1109
|
+
if (object_sym == v) {
|
1110
|
+
mode = ObjectMode;
|
1111
|
+
} else if (strict_sym == v) {
|
1112
|
+
mode = StrictMode;
|
1113
|
+
} else if (compat_sym == v || json_sym == v) {
|
1114
|
+
mode = CompatMode;
|
1115
|
+
} else if (null_sym == v) {
|
1116
|
+
mode = NullMode;
|
1117
|
+
} else if (custom_sym == v) {
|
1118
|
+
mode = CustomMode;
|
1119
|
+
} else if (rails_sym == v) {
|
1120
|
+
mode = RailsMode;
|
1121
|
+
} else if (wab_sym == v) {
|
1122
|
+
mode = WabMode;
|
1123
|
+
} else {
|
1124
|
+
rb_raise(
|
1125
|
+
rb_eArgError,
|
1126
|
+
":mode must be :object, :strict, :compat, :null, :custom, :rails, or :wab.");
|
1127
|
+
}
|
1128
|
+
}
|
985
1129
|
}
|
986
1130
|
path = StringValuePtr(*argv);
|
987
1131
|
if (0 == (fd = open(path, O_RDONLY))) {
|
988
|
-
|
1132
|
+
rb_raise(rb_eIOError, "%s", strerror(errno));
|
989
1133
|
}
|
990
1134
|
switch (mode) {
|
991
1135
|
case StrictMode:
|
992
|
-
case NullMode:
|
993
|
-
|
994
|
-
return oj_pi_sparse(argc, argv, &pi, fd);
|
995
|
-
case CustomMode:
|
996
|
-
oj_set_custom_callbacks(&pi);
|
997
|
-
return oj_pi_sparse(argc, argv, &pi, fd);
|
1136
|
+
case NullMode: oj_set_strict_callbacks(&pi); return oj_pi_sparse(argc, argv, &pi, fd);
|
1137
|
+
case CustomMode: oj_set_custom_callbacks(&pi); return oj_pi_sparse(argc, argv, &pi, fd);
|
998
1138
|
case CompatMode:
|
999
|
-
case RailsMode:
|
1000
|
-
|
1001
|
-
return oj_pi_sparse(argc, argv, &pi, fd);
|
1002
|
-
case WabMode:
|
1003
|
-
oj_set_wab_callbacks(&pi);
|
1004
|
-
return oj_pi_sparse(argc, argv, &pi, fd);
|
1139
|
+
case RailsMode: oj_set_compat_callbacks(&pi); return oj_pi_sparse(argc, argv, &pi, fd);
|
1140
|
+
case WabMode: oj_set_wab_callbacks(&pi); return oj_pi_sparse(argc, argv, &pi, fd);
|
1005
1141
|
case ObjectMode:
|
1006
|
-
default:
|
1007
|
-
break;
|
1142
|
+
default: break;
|
1008
1143
|
}
|
1009
1144
|
oj_set_object_callbacks(&pi);
|
1010
1145
|
|
@@ -1022,18 +1157,17 @@ load_file(int argc, VALUE *argv, VALUE self) {
|
|
1022
1157
|
*
|
1023
1158
|
* Returns [_Hash_|_Array_|_String_|_Fixnum_|_Bignum_|_BigDecimal_|_nil_|_True_|_False_]
|
1024
1159
|
*/
|
1025
|
-
static VALUE
|
1026
|
-
|
1027
|
-
|
1028
|
-
VALUE args[1];
|
1160
|
+
static VALUE safe_load(VALUE self, VALUE doc) {
|
1161
|
+
struct _parseInfo pi;
|
1162
|
+
VALUE args[1];
|
1029
1163
|
|
1030
1164
|
parse_info_init(&pi);
|
1031
|
-
pi.err_class
|
1032
|
-
pi.max_depth
|
1033
|
-
pi.options
|
1165
|
+
pi.err_class = Qnil;
|
1166
|
+
pi.max_depth = 0;
|
1167
|
+
pi.options = oj_default_options;
|
1034
1168
|
pi.options.auto_define = No;
|
1035
|
-
pi.options.sym_key
|
1036
|
-
pi.options.mode
|
1169
|
+
pi.options.sym_key = No;
|
1170
|
+
pi.options.mode = StrictMode;
|
1037
1171
|
oj_set_strict_callbacks(&pi);
|
1038
1172
|
*args = doc;
|
1039
1173
|
|
@@ -1073,38 +1207,37 @@ safe_load(VALUE self, VALUE doc) {
|
|
1073
1207
|
* - *obj* [_Object_] Object to serialize as an JSON document String
|
1074
1208
|
* - *options* [_Hash_] same as default_options
|
1075
1209
|
*/
|
1076
|
-
static VALUE
|
1077
|
-
|
1078
|
-
|
1079
|
-
struct
|
1080
|
-
|
1081
|
-
VALUE rstr;
|
1210
|
+
static VALUE dump(int argc, VALUE *argv, VALUE self) {
|
1211
|
+
char buf[4096];
|
1212
|
+
struct _out out;
|
1213
|
+
struct _options copts = oj_default_options;
|
1214
|
+
VALUE rstr;
|
1082
1215
|
|
1083
1216
|
if (1 > argc) {
|
1084
|
-
|
1217
|
+
rb_raise(rb_eArgError, "wrong number of arguments (0 for 1).");
|
1085
1218
|
}
|
1086
1219
|
if (CompatMode == copts.mode) {
|
1087
|
-
|
1220
|
+
copts.dump_opts.nan_dump = WordNan;
|
1088
1221
|
}
|
1089
1222
|
if (2 == argc) {
|
1090
|
-
|
1223
|
+
oj_parse_options(argv[1], &copts);
|
1091
1224
|
}
|
1092
1225
|
if (CompatMode == copts.mode && copts.escape_mode != ASCIIEsc) {
|
1093
|
-
|
1226
|
+
copts.escape_mode = JSONEsc;
|
1094
1227
|
}
|
1095
|
-
out.buf
|
1096
|
-
out.end
|
1228
|
+
out.buf = buf;
|
1229
|
+
out.end = buf + sizeof(buf) - 10;
|
1097
1230
|
out.allocated = false;
|
1098
|
-
out.omit_nil
|
1099
|
-
out.caller
|
1100
|
-
oj_dump_obj_to_json_using_params(*argv, &copts, &out, argc - 1,argv + 1);
|
1231
|
+
out.omit_nil = copts.dump_opts.omit_nil;
|
1232
|
+
out.caller = CALLER_DUMP;
|
1233
|
+
oj_dump_obj_to_json_using_params(*argv, &copts, &out, argc - 1, argv + 1);
|
1101
1234
|
if (0 == out.buf) {
|
1102
|
-
|
1235
|
+
rb_raise(rb_eNoMemError, "Not enough memory.");
|
1103
1236
|
}
|
1104
1237
|
rstr = rb_str_new2(out.buf);
|
1105
1238
|
rstr = oj_encode(rstr);
|
1106
1239
|
if (out.allocated) {
|
1107
|
-
|
1240
|
+
xfree(out.buf);
|
1108
1241
|
}
|
1109
1242
|
return rstr;
|
1110
1243
|
}
|
@@ -1116,50 +1249,54 @@ dump(int argc, VALUE *argv, VALUE self) {
|
|
1116
1249
|
* will be called. The mode is set to :compat.
|
1117
1250
|
* - *obj* [_Object_] Object to serialize as an JSON document String
|
1118
1251
|
* - *options* [_Hash_]
|
1119
|
-
* - *:max_nesting* [_boolean_] It true nesting is limited to 100. The option to detect circular
|
1120
|
-
*
|
1121
|
-
* - *:
|
1122
|
-
*
|
1252
|
+
* - *:max_nesting* [_boolean_] It true nesting is limited to 100. The option to detect circular
|
1253
|
+
* references is available but is not compatible with the json gem., default is false
|
1254
|
+
* - *:allow_nan* [_boolean_] If true non JSON compliant words such as Nan and Infinity will be
|
1255
|
+
* used as appropriate, default is true.
|
1256
|
+
* - *:quirks_mode* [_boolean_] Allow single JSON values instead of documents, default is true
|
1257
|
+
* (allow).
|
1258
|
+
* - *:indent* [_String_|_nil_] String to use for indentation, overriding the indent option if not
|
1259
|
+
* nil.
|
1123
1260
|
* - *:space* [_String_|_nil_] String to use for the space after the colon in JSON object fields.
|
1124
|
-
* - *:space_before* [_String_|_nil_] String to use before the colon separator in JSON object
|
1261
|
+
* - *:space_before* [_String_|_nil_] String to use before the colon separator in JSON object
|
1262
|
+
* fields.
|
1125
1263
|
* - *:object_nl* [_String_|_nil_] String to use after a JSON object field value.
|
1126
1264
|
* - *:array_nl* [_String_|_nil_] String to use after a JSON array value.
|
1127
1265
|
* - *:trace* [_Boolean_] If true trace is turned on.
|
1128
1266
|
*
|
1129
1267
|
* Returns [_String_] the encoded JSON.
|
1130
1268
|
*/
|
1131
|
-
static VALUE
|
1132
|
-
|
1133
|
-
|
1134
|
-
struct
|
1135
|
-
|
1136
|
-
VALUE rstr;
|
1269
|
+
static VALUE to_json(int argc, VALUE *argv, VALUE self) {
|
1270
|
+
char buf[4096];
|
1271
|
+
struct _out out;
|
1272
|
+
struct _options copts = oj_default_options;
|
1273
|
+
VALUE rstr;
|
1137
1274
|
|
1138
1275
|
if (1 > argc) {
|
1139
|
-
|
1276
|
+
rb_raise(rb_eArgError, "wrong number of arguments (0 for 1).");
|
1140
1277
|
}
|
1141
|
-
copts.escape_mode
|
1278
|
+
copts.escape_mode = JXEsc;
|
1142
1279
|
copts.dump_opts.nan_dump = RaiseNan;
|
1143
1280
|
if (2 == argc) {
|
1144
|
-
|
1281
|
+
oj_parse_mimic_dump_options(argv[1], &copts);
|
1145
1282
|
}
|
1146
|
-
copts.mode
|
1283
|
+
copts.mode = CompatMode;
|
1147
1284
|
copts.to_json = Yes;
|
1148
|
-
out.buf
|
1149
|
-
out.end
|
1285
|
+
out.buf = buf;
|
1286
|
+
out.end = buf + sizeof(buf) - 10;
|
1150
1287
|
out.allocated = false;
|
1151
|
-
out.omit_nil
|
1288
|
+
out.omit_nil = copts.dump_opts.omit_nil;
|
1152
1289
|
// For obj.to_json or generate nan is not allowed but if called from dump
|
1153
1290
|
// it is.
|
1154
1291
|
oj_dump_obj_to_json_using_params(*argv, &copts, &out, argc - 1, argv + 1);
|
1155
1292
|
|
1156
1293
|
if (0 == out.buf) {
|
1157
|
-
|
1294
|
+
rb_raise(rb_eNoMemError, "Not enough memory.");
|
1158
1295
|
}
|
1159
1296
|
rstr = rb_str_new2(out.buf);
|
1160
1297
|
rstr = oj_encode(rstr);
|
1161
1298
|
if (out.allocated) {
|
1162
|
-
|
1299
|
+
xfree(out.buf);
|
1163
1300
|
}
|
1164
1301
|
return rstr;
|
1165
1302
|
}
|
@@ -1174,12 +1311,11 @@ to_json(int argc, VALUE *argv, VALUE self) {
|
|
1174
1311
|
* - *:indent* [_Fixnum_] format expected
|
1175
1312
|
* - *:circular* [_Boolean_] allow circular references, default: false
|
1176
1313
|
*/
|
1177
|
-
static VALUE
|
1178
|
-
|
1179
|
-
struct _options copts = oj_default_options;
|
1314
|
+
static VALUE to_file(int argc, VALUE *argv, VALUE self) {
|
1315
|
+
struct _options copts = oj_default_options;
|
1180
1316
|
|
1181
1317
|
if (3 == argc) {
|
1182
|
-
|
1318
|
+
oj_parse_options(argv[2], &copts);
|
1183
1319
|
}
|
1184
1320
|
Check_Type(*argv, T_STRING);
|
1185
1321
|
oj_write_obj_to_file(argv[1], StringValuePtr(*argv), &copts);
|
@@ -1197,12 +1333,11 @@ to_file(int argc, VALUE *argv, VALUE self) {
|
|
1197
1333
|
* - *:indent* [_Fixnum_] format expected
|
1198
1334
|
* - *:circular* [_Boolean_] allow circular references, default: false
|
1199
1335
|
*/
|
1200
|
-
static VALUE
|
1201
|
-
|
1202
|
-
struct _options copts = oj_default_options;
|
1336
|
+
static VALUE to_stream(int argc, VALUE *argv, VALUE self) {
|
1337
|
+
struct _options copts = oj_default_options;
|
1203
1338
|
|
1204
1339
|
if (3 == argc) {
|
1205
|
-
|
1340
|
+
oj_parse_options(argv[2], &copts);
|
1206
1341
|
}
|
1207
1342
|
oj_write_obj_to_stream(argv[1], *argv, &copts);
|
1208
1343
|
|
@@ -1220,25 +1355,23 @@ to_stream(int argc, VALUE *argv, VALUE self) {
|
|
1220
1355
|
*
|
1221
1356
|
* - *clas* [_Class__|_Module_] Class or Module to be made special
|
1222
1357
|
* - *create_object* [_Object_] object to call the create method on
|
1223
|
-
* - *create_method* [_Symbol_] method on the clas that will create a new instance of the clas when
|
1224
|
-
*
|
1358
|
+
* - *create_method* [_Symbol_] method on the clas that will create a new instance of the clas when
|
1359
|
+
* given all the member values in the order specified.
|
1360
|
+
* - *members* [_Symbol__|_String_] methods used to get the member values from instances of the
|
1361
|
+
* clas.
|
1225
1362
|
*/
|
1226
|
-
static VALUE
|
1227
|
-
register_odd(int argc, VALUE *argv, VALUE self) {
|
1363
|
+
static VALUE register_odd(int argc, VALUE *argv, VALUE self) {
|
1228
1364
|
if (3 > argc) {
|
1229
|
-
|
1365
|
+
rb_raise(rb_eArgError, "incorrect number of arguments.");
|
1230
1366
|
}
|
1231
1367
|
switch (rb_type(*argv)) {
|
1232
1368
|
case T_CLASS:
|
1233
|
-
case T_MODULE:
|
1234
|
-
|
1235
|
-
default:
|
1236
|
-
rb_raise(rb_eTypeError, "expected a class or module.");
|
1237
|
-
break;
|
1369
|
+
case T_MODULE: break;
|
1370
|
+
default: rb_raise(rb_eTypeError, "expected a class or module."); break;
|
1238
1371
|
}
|
1239
1372
|
Check_Type(argv[2], T_SYMBOL);
|
1240
1373
|
if (MAX_ODD_ARGS < argc - 2) {
|
1241
|
-
|
1374
|
+
rb_raise(rb_eArgError, "too many members.");
|
1242
1375
|
}
|
1243
1376
|
oj_reg_odd(argv[0], argv[1], argv[2], argc - 3, argv + 3, false);
|
1244
1377
|
|
@@ -1258,25 +1391,23 @@ register_odd(int argc, VALUE *argv, VALUE self) {
|
|
1258
1391
|
*
|
1259
1392
|
* - *clas* [_Class_|_Module_] Class or Module to be made special
|
1260
1393
|
* - *create_object* [_Object_] object to call the create method on
|
1261
|
-
* - *create_method* [_Symbol_] method on the clas that will create a new instance of the clas when
|
1262
|
-
*
|
1394
|
+
* - *create_method* [_Symbol_] method on the clas that will create a new instance of the clas when
|
1395
|
+
*given all the member values in the order specified.
|
1396
|
+
* - *dump_method* [_Symbol_|_String_] method to call on the object being serialized to generate the
|
1397
|
+
*raw JSON.
|
1263
1398
|
*/
|
1264
|
-
static VALUE
|
1265
|
-
register_odd_raw(int argc, VALUE *argv, VALUE self) {
|
1399
|
+
static VALUE register_odd_raw(int argc, VALUE *argv, VALUE self) {
|
1266
1400
|
if (3 > argc) {
|
1267
|
-
|
1401
|
+
rb_raise(rb_eArgError, "incorrect number of arguments.");
|
1268
1402
|
}
|
1269
1403
|
switch (rb_type(*argv)) {
|
1270
1404
|
case T_CLASS:
|
1271
|
-
case T_MODULE:
|
1272
|
-
|
1273
|
-
default:
|
1274
|
-
rb_raise(rb_eTypeError, "expected a class or module.");
|
1275
|
-
break;
|
1405
|
+
case T_MODULE: break;
|
1406
|
+
default: rb_raise(rb_eTypeError, "expected a class or module."); break;
|
1276
1407
|
}
|
1277
1408
|
Check_Type(argv[2], T_SYMBOL);
|
1278
1409
|
if (MAX_ODD_ARGS < argc - 2) {
|
1279
|
-
|
1410
|
+
rb_raise(rb_eArgError, "too many members.");
|
1280
1411
|
}
|
1281
1412
|
oj_reg_odd(argv[0], argv[1], argv[2], 1, argv + 3, true);
|
1282
1413
|
|
@@ -1322,7 +1453,7 @@ register_odd_raw(int argc, VALUE *argv, VALUE self) {
|
|
1322
1453
|
*
|
1323
1454
|
* Returns [_Hash_|_Array_|_String_|_Fixnum_|_Float_|_Boolean_|_nil_]
|
1324
1455
|
*/
|
1325
|
-
extern VALUE
|
1456
|
+
extern VALUE oj_strict_parse(int argc, VALUE *argv, VALUE self);
|
1326
1457
|
|
1327
1458
|
/* Document-method: compat_load
|
1328
1459
|
* call-seq: compat_load(json, options) { _|_obj, start, len_|_ }
|
@@ -1356,7 +1487,7 @@ extern VALUE oj_strict_parse(int argc, VALUE *argv, VALUE self);
|
|
1356
1487
|
*
|
1357
1488
|
* Returns [_Hash_|_Array_|_String_|_Fixnum_|_Float_|_Boolean_|_nil_]
|
1358
1489
|
*/
|
1359
|
-
extern VALUE
|
1490
|
+
extern VALUE oj_compat_parse(int argc, VALUE *argv, VALUE self);
|
1360
1491
|
|
1361
1492
|
/* Document-method: object_load
|
1362
1493
|
* call-seq: object_load(json, options) { _|_obj, start, len_|_ }
|
@@ -1386,7 +1517,7 @@ extern VALUE oj_compat_parse(int argc, VALUE *argv, VALUE self);
|
|
1386
1517
|
*
|
1387
1518
|
* Returns [_Hash_|_Array_|_String_|_Fixnum_|_Float_|_Boolean_|_nil_]
|
1388
1519
|
*/
|
1389
|
-
extern VALUE
|
1520
|
+
extern VALUE oj_object_parse(int argc, VALUE *argv, VALUE self);
|
1390
1521
|
|
1391
1522
|
/* Document-method: wab_load
|
1392
1523
|
* call-seq: wab_load(json, options) { _|_obj, start, len_|_ }
|
@@ -1421,7 +1552,7 @@ extern VALUE oj_object_parse(int argc, VALUE *argv, VALUE self);
|
|
1421
1552
|
*
|
1422
1553
|
* Returns [_Hash_|_Array_|_String_|_Fixnum_|_Float_|_Boolean_|_nil_]
|
1423
1554
|
*/
|
1424
|
-
extern VALUE
|
1555
|
+
extern VALUE oj_wab_parse(int argc, VALUE *argv, VALUE self);
|
1425
1556
|
|
1426
1557
|
/* Document-method: add_to_json
|
1427
1558
|
* call-seq: add_to_json(*args)
|
@@ -1438,7 +1569,7 @@ extern VALUE oj_wab_parse(int argc, VALUE *argv, VALUE self);
|
|
1438
1569
|
*
|
1439
1570
|
* - *args( [_Class_] zero or more classes to optimize.
|
1440
1571
|
*/
|
1441
|
-
extern VALUE
|
1572
|
+
extern VALUE oj_add_to_json(int argc, VALUE *argv, VALUE self);
|
1442
1573
|
|
1443
1574
|
/* @!method remove_to_json(*args)
|
1444
1575
|
*
|
@@ -1454,7 +1585,7 @@ extern VALUE oj_add_to_json(int argc, VALUE *argv, VALUE self);
|
|
1454
1585
|
*
|
1455
1586
|
* - *args* [_Class_] zero or more classes to optimize.
|
1456
1587
|
*/
|
1457
|
-
extern VALUE
|
1588
|
+
extern VALUE oj_remove_to_json(int argc, VALUE *argv, VALUE self);
|
1458
1589
|
|
1459
1590
|
/* Document-method: mimic_JSON
|
1460
1591
|
* call-seq: mimic_JSON()
|
@@ -1472,14 +1603,15 @@ extern VALUE oj_remove_to_json(int argc, VALUE *argv, VALUE self);
|
|
1472
1603
|
*
|
1473
1604
|
* Returns [_Module_] the JSON module.
|
1474
1605
|
*/
|
1475
|
-
extern VALUE
|
1606
|
+
extern VALUE oj_define_mimic_json(int argc, VALUE *argv, VALUE self);
|
1476
1607
|
|
1477
1608
|
/* Document-method: generate
|
1478
1609
|
* call-seq: generate(obj, opts=nil)
|
1479
1610
|
*
|
1480
1611
|
* Encode obj as a JSON String. The obj argument must be a Hash, Array, or
|
1481
1612
|
* respond to to_h or to_json. Options other than those listed such as
|
1482
|
-
* +:allow_nan+ or +:max_nesting+ are ignored.
|
1613
|
+
* +:allow_nan+ or +:max_nesting+ are ignored. Calling this method will call
|
1614
|
+
* Oj.mimic_JSON if it is not already called.
|
1483
1615
|
*
|
1484
1616
|
* - *obj* [_Object__|_Hash_|_Array_] object to convert to a JSON String
|
1485
1617
|
* - *opts* [_Hash_] options
|
@@ -1488,18 +1620,19 @@ extern VALUE oj_define_mimic_json(int argc, VALUE *argv, VALUE self);
|
|
1488
1620
|
* - *:space_before* [_String_] String placed before a : delimiter
|
1489
1621
|
* - *:object_nl* [_String_] String placed after a JSON object
|
1490
1622
|
* - *:array_nl* [_String_] String placed after a JSON array
|
1491
|
-
* - *:ascii_only* [_Boolean_] if not nil or false then use only ascii characters in the output.
|
1623
|
+
* - *:ascii_only* [_Boolean_] if not nil or false then use only ascii characters in the output.
|
1624
|
+
* Note JSON.generate does support this even if it is not documented.
|
1492
1625
|
*
|
1493
1626
|
* Returns [_String_]generated JSON.
|
1494
1627
|
*/
|
1495
|
-
extern VALUE
|
1628
|
+
extern VALUE oj_mimic_generate(int argc, VALUE *argv, VALUE self);
|
1496
1629
|
|
1497
1630
|
/* Document-module: Oj.optimize_rails()
|
1498
1631
|
*
|
1499
1632
|
* Sets the Oj as the Rails encoder and decoder. Oj::Rails.optimize is also
|
1500
1633
|
* called.
|
1501
1634
|
*/
|
1502
|
-
extern VALUE
|
1635
|
+
extern VALUE oj_optimize_rails(VALUE self);
|
1503
1636
|
|
1504
1637
|
/*
|
1505
1638
|
extern void oj_hash_test();
|
@@ -1511,8 +1644,7 @@ hash_test(VALUE self) {
|
|
1511
1644
|
}
|
1512
1645
|
*/
|
1513
1646
|
|
1514
|
-
static VALUE
|
1515
|
-
protect_require(VALUE x) {
|
1647
|
+
static VALUE protect_require(VALUE x) {
|
1516
1648
|
rb_require("time");
|
1517
1649
|
rb_require("bigdecimal");
|
1518
1650
|
return Qnil;
|
@@ -1546,9 +1678,8 @@ protect_require(VALUE x) {
|
|
1546
1678
|
*
|
1547
1679
|
* - *:wab* specifically for WAB data exchange.
|
1548
1680
|
*/
|
1549
|
-
void
|
1550
|
-
|
1551
|
-
int err = 0;
|
1681
|
+
void Init_oj() {
|
1682
|
+
int err = 0;
|
1552
1683
|
|
1553
1684
|
Oj = rb_define_module("Oj");
|
1554
1685
|
|
@@ -1563,7 +1694,7 @@ Init_oj() {
|
|
1563
1694
|
rb_require("stringio");
|
1564
1695
|
oj_utf8_encoding = rb_enc_find("UTF-8");
|
1565
1696
|
|
1566
|
-
//rb_define_module_function(Oj, "hash_test", hash_test, 0);
|
1697
|
+
// rb_define_module_function(Oj, "hash_test", hash_test, 0);
|
1567
1698
|
|
1568
1699
|
rb_define_module_function(Oj, "default_options", get_def_opts, 0);
|
1569
1700
|
rb_define_module_function(Oj, "default_options=", set_def_opts, 1);
|
@@ -1597,50 +1728,50 @@ Init_oj() {
|
|
1597
1728
|
|
1598
1729
|
rb_define_module_function(Oj, "optimize_rails", oj_optimize_rails, 0);
|
1599
1730
|
|
1600
|
-
oj_add_value_id
|
1601
|
-
oj_array_append_id
|
1602
|
-
oj_array_end_id
|
1603
|
-
oj_array_start_id
|
1604
|
-
oj_as_json_id
|
1605
|
-
oj_begin_id
|
1606
|
-
oj_bigdecimal_id
|
1607
|
-
oj_end_id
|
1608
|
-
oj_error_id
|
1609
|
-
oj_exclude_end_id
|
1610
|
-
oj_file_id
|
1611
|
-
oj_fileno_id
|
1612
|
-
oj_ftype_id
|
1613
|
-
oj_has_key_id
|
1614
|
-
oj_hash_end_id
|
1615
|
-
oj_hash_key_id
|
1616
|
-
oj_hash_set_id
|
1617
|
-
oj_hash_start_id
|
1618
|
-
oj_iconv_id
|
1731
|
+
oj_add_value_id = rb_intern("add_value");
|
1732
|
+
oj_array_append_id = rb_intern("array_append");
|
1733
|
+
oj_array_end_id = rb_intern("array_end");
|
1734
|
+
oj_array_start_id = rb_intern("array_start");
|
1735
|
+
oj_as_json_id = rb_intern("as_json");
|
1736
|
+
oj_begin_id = rb_intern("begin");
|
1737
|
+
oj_bigdecimal_id = rb_intern("BigDecimal");
|
1738
|
+
oj_end_id = rb_intern("end");
|
1739
|
+
oj_error_id = rb_intern("error");
|
1740
|
+
oj_exclude_end_id = rb_intern("exclude_end?");
|
1741
|
+
oj_file_id = rb_intern("file?");
|
1742
|
+
oj_fileno_id = rb_intern("fileno");
|
1743
|
+
oj_ftype_id = rb_intern("ftype");
|
1744
|
+
oj_has_key_id = rb_intern("has_key?");
|
1745
|
+
oj_hash_end_id = rb_intern("hash_end");
|
1746
|
+
oj_hash_key_id = rb_intern("hash_key");
|
1747
|
+
oj_hash_set_id = rb_intern("hash_set");
|
1748
|
+
oj_hash_start_id = rb_intern("hash_start");
|
1749
|
+
oj_iconv_id = rb_intern("iconv");
|
1619
1750
|
oj_instance_variables_id = rb_intern("instance_variables");
|
1620
|
-
oj_json_create_id
|
1621
|
-
oj_length_id
|
1622
|
-
oj_new_id
|
1623
|
-
oj_parse_id
|
1624
|
-
oj_pos_id
|
1625
|
-
oj_raw_json_id
|
1626
|
-
oj_read_id
|
1627
|
-
oj_readpartial_id
|
1628
|
-
oj_replace_id
|
1629
|
-
oj_stat_id
|
1630
|
-
oj_string_id
|
1631
|
-
oj_to_h_id
|
1632
|
-
oj_to_hash_id
|
1633
|
-
oj_to_json_id
|
1634
|
-
oj_to_s_id
|
1635
|
-
oj_to_sym_id
|
1636
|
-
oj_to_time_id
|
1637
|
-
oj_tv_nsec_id
|
1638
|
-
oj_tv_sec_id
|
1639
|
-
oj_tv_usec_id
|
1640
|
-
oj_utc_id
|
1641
|
-
oj_utc_offset_id
|
1642
|
-
oj_utcq_id
|
1643
|
-
oj_write_id
|
1751
|
+
oj_json_create_id = rb_intern("json_create");
|
1752
|
+
oj_length_id = rb_intern("length");
|
1753
|
+
oj_new_id = rb_intern("new");
|
1754
|
+
oj_parse_id = rb_intern("parse");
|
1755
|
+
oj_pos_id = rb_intern("pos");
|
1756
|
+
oj_raw_json_id = rb_intern("raw_json");
|
1757
|
+
oj_read_id = rb_intern("read");
|
1758
|
+
oj_readpartial_id = rb_intern("readpartial");
|
1759
|
+
oj_replace_id = rb_intern("replace");
|
1760
|
+
oj_stat_id = rb_intern("stat");
|
1761
|
+
oj_string_id = rb_intern("string");
|
1762
|
+
oj_to_h_id = rb_intern("to_h");
|
1763
|
+
oj_to_hash_id = rb_intern("to_hash");
|
1764
|
+
oj_to_json_id = rb_intern("to_json");
|
1765
|
+
oj_to_s_id = rb_intern("to_s");
|
1766
|
+
oj_to_sym_id = rb_intern("to_sym");
|
1767
|
+
oj_to_time_id = rb_intern("to_time");
|
1768
|
+
oj_tv_nsec_id = rb_intern("tv_nsec");
|
1769
|
+
oj_tv_sec_id = rb_intern("tv_sec");
|
1770
|
+
oj_tv_usec_id = rb_intern("tv_usec");
|
1771
|
+
oj_utc_id = rb_intern("utc");
|
1772
|
+
oj_utc_offset_id = rb_intern("utc_offset");
|
1773
|
+
oj_utcq_id = rb_intern("utc?");
|
1774
|
+
oj_write_id = rb_intern("write");
|
1644
1775
|
|
1645
1776
|
rb_require("oj/bag");
|
1646
1777
|
rb_require("oj/error");
|
@@ -1649,85 +1780,161 @@ Init_oj() {
|
|
1649
1780
|
rb_require("oj/schandler");
|
1650
1781
|
|
1651
1782
|
oj_bag_class = rb_const_get_at(Oj, rb_intern("Bag"));
|
1783
|
+
rb_gc_register_mark_object(oj_bag_class);
|
1652
1784
|
oj_bigdecimal_class = rb_const_get(rb_cObject, rb_intern("BigDecimal"));
|
1785
|
+
rb_gc_register_mark_object(oj_bigdecimal_class);
|
1653
1786
|
oj_date_class = rb_const_get(rb_cObject, rb_intern("Date"));
|
1787
|
+
rb_gc_register_mark_object(oj_date_class);
|
1654
1788
|
oj_datetime_class = rb_const_get(rb_cObject, rb_intern("DateTime"));
|
1789
|
+
rb_gc_register_mark_object(oj_datetime_class);
|
1655
1790
|
oj_enumerable_class = rb_const_get(rb_cObject, rb_intern("Enumerable"));
|
1791
|
+
rb_gc_register_mark_object(oj_enumerable_class);
|
1656
1792
|
oj_parse_error_class = rb_const_get_at(Oj, rb_intern("ParseError"));
|
1793
|
+
rb_gc_register_mark_object(oj_parse_error_class);
|
1657
1794
|
oj_stringio_class = rb_const_get(rb_cObject, rb_intern("StringIO"));
|
1795
|
+
rb_gc_register_mark_object(oj_stringio_class);
|
1658
1796
|
oj_struct_class = rb_const_get(rb_cObject, rb_intern("Struct"));
|
1659
|
-
|
1660
|
-
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1665
|
-
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1669
|
-
|
1670
|
-
|
1671
|
-
|
1672
|
-
|
1673
|
-
|
1674
|
-
|
1675
|
-
|
1676
|
-
|
1677
|
-
|
1678
|
-
|
1679
|
-
|
1680
|
-
|
1681
|
-
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1689
|
-
|
1690
|
-
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
|
1713
|
-
|
1714
|
-
|
1715
|
-
|
1716
|
-
|
1717
|
-
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
|
1726
|
-
|
1727
|
-
|
1728
|
-
|
1729
|
-
|
1730
|
-
|
1797
|
+
rb_gc_register_mark_object(oj_struct_class);
|
1798
|
+
oj_json_parser_error_class = rb_eEncodingError; // replaced if mimic is called
|
1799
|
+
oj_json_generator_error_class = rb_eEncodingError; // replaced if mimic is called
|
1800
|
+
|
1801
|
+
allow_blank_sym = ID2SYM(rb_intern("allow_blank"));
|
1802
|
+
rb_gc_register_address(&allow_blank_sym);
|
1803
|
+
allow_gc_sym = ID2SYM(rb_intern("allow_gc"));
|
1804
|
+
rb_gc_register_address(&allow_gc_sym);
|
1805
|
+
allow_invalid_unicode_sym = ID2SYM(rb_intern("allow_invalid_unicode"));
|
1806
|
+
rb_gc_register_address(&allow_invalid_unicode_sym);
|
1807
|
+
ascii_sym = ID2SYM(rb_intern("ascii"));
|
1808
|
+
rb_gc_register_address(&ascii_sym);
|
1809
|
+
auto_define_sym = ID2SYM(rb_intern("auto_define"));
|
1810
|
+
rb_gc_register_address(&auto_define_sym);
|
1811
|
+
auto_sym = ID2SYM(rb_intern("auto"));
|
1812
|
+
rb_gc_register_address(&auto_sym);
|
1813
|
+
bigdecimal_as_decimal_sym = ID2SYM(rb_intern("bigdecimal_as_decimal"));
|
1814
|
+
rb_gc_register_address(&bigdecimal_as_decimal_sym);
|
1815
|
+
bigdecimal_load_sym = ID2SYM(rb_intern("bigdecimal_load"));
|
1816
|
+
rb_gc_register_address(&bigdecimal_load_sym);
|
1817
|
+
bigdecimal_sym = ID2SYM(rb_intern("bigdecimal"));
|
1818
|
+
rb_gc_register_address(&bigdecimal_sym);
|
1819
|
+
circular_sym = ID2SYM(rb_intern("circular"));
|
1820
|
+
rb_gc_register_address(&circular_sym);
|
1821
|
+
class_cache_sym = ID2SYM(rb_intern("class_cache"));
|
1822
|
+
rb_gc_register_address(&class_cache_sym);
|
1823
|
+
compat_bigdecimal_sym = ID2SYM(rb_intern("compat_bigdecimal"));
|
1824
|
+
rb_gc_register_address(&compat_bigdecimal_sym);
|
1825
|
+
compat_sym = ID2SYM(rb_intern("compat"));
|
1826
|
+
rb_gc_register_address(&compat_sym);
|
1827
|
+
create_id_sym = ID2SYM(rb_intern("create_id"));
|
1828
|
+
rb_gc_register_address(&create_id_sym);
|
1829
|
+
custom_sym = ID2SYM(rb_intern("custom"));
|
1830
|
+
rb_gc_register_address(&custom_sym);
|
1831
|
+
empty_string_sym = ID2SYM(rb_intern("empty_string"));
|
1832
|
+
rb_gc_register_address(&empty_string_sym);
|
1833
|
+
escape_mode_sym = ID2SYM(rb_intern("escape_mode"));
|
1834
|
+
rb_gc_register_address(&escape_mode_sym);
|
1835
|
+
integer_range_sym = ID2SYM(rb_intern("integer_range"));
|
1836
|
+
rb_gc_register_address(&integer_range_sym);
|
1837
|
+
fast_sym = ID2SYM(rb_intern("fast"));
|
1838
|
+
rb_gc_register_address(&fast_sym);
|
1839
|
+
float_prec_sym = ID2SYM(rb_intern("float_precision"));
|
1840
|
+
rb_gc_register_address(&float_prec_sym);
|
1841
|
+
float_sym = ID2SYM(rb_intern("float"));
|
1842
|
+
rb_gc_register_address(&float_sym);
|
1843
|
+
huge_sym = ID2SYM(rb_intern("huge"));
|
1844
|
+
rb_gc_register_address(&huge_sym);
|
1845
|
+
ignore_sym = ID2SYM(rb_intern("ignore"));
|
1846
|
+
rb_gc_register_address(&ignore_sym);
|
1847
|
+
ignore_under_sym = ID2SYM(rb_intern("ignore_under"));
|
1848
|
+
rb_gc_register_address(&ignore_under_sym);
|
1849
|
+
json_sym = ID2SYM(rb_intern("json"));
|
1850
|
+
rb_gc_register_address(&json_sym);
|
1851
|
+
match_string_sym = ID2SYM(rb_intern("match_string"));
|
1852
|
+
rb_gc_register_address(&match_string_sym);
|
1853
|
+
mode_sym = ID2SYM(rb_intern("mode"));
|
1854
|
+
rb_gc_register_address(&mode_sym);
|
1855
|
+
nan_sym = ID2SYM(rb_intern("nan"));
|
1856
|
+
rb_gc_register_address(&nan_sym);
|
1857
|
+
newline_sym = ID2SYM(rb_intern("newline"));
|
1858
|
+
rb_gc_register_address(&newline_sym);
|
1859
|
+
nilnil_sym = ID2SYM(rb_intern("nilnil"));
|
1860
|
+
rb_gc_register_address(&nilnil_sym);
|
1861
|
+
null_sym = ID2SYM(rb_intern("null"));
|
1862
|
+
rb_gc_register_address(&null_sym);
|
1863
|
+
object_sym = ID2SYM(rb_intern("object"));
|
1864
|
+
rb_gc_register_address(&object_sym);
|
1865
|
+
oj_allow_nan_sym = ID2SYM(rb_intern("allow_nan"));
|
1866
|
+
rb_gc_register_address(&oj_allow_nan_sym);
|
1867
|
+
oj_array_class_sym = ID2SYM(rb_intern("array_class"));
|
1868
|
+
rb_gc_register_address(&oj_array_class_sym);
|
1869
|
+
oj_array_nl_sym = ID2SYM(rb_intern("array_nl"));
|
1870
|
+
rb_gc_register_address(&oj_array_nl_sym);
|
1871
|
+
oj_ascii_only_sym = ID2SYM(rb_intern("ascii_only"));
|
1872
|
+
rb_gc_register_address(&oj_ascii_only_sym);
|
1873
|
+
oj_create_additions_sym = ID2SYM(rb_intern("create_additions"));
|
1874
|
+
rb_gc_register_address(&oj_create_additions_sym);
|
1875
|
+
oj_decimal_class_sym = ID2SYM(rb_intern("decimal_class"));
|
1876
|
+
rb_gc_register_address(&oj_decimal_class_sym);
|
1877
|
+
oj_hash_class_sym = ID2SYM(rb_intern("hash_class"));
|
1878
|
+
rb_gc_register_address(&oj_hash_class_sym);
|
1879
|
+
oj_indent_sym = ID2SYM(rb_intern("indent"));
|
1880
|
+
rb_gc_register_address(&oj_indent_sym);
|
1881
|
+
oj_max_nesting_sym = ID2SYM(rb_intern("max_nesting"));
|
1882
|
+
rb_gc_register_address(&oj_max_nesting_sym);
|
1883
|
+
oj_object_class_sym = ID2SYM(rb_intern("object_class"));
|
1884
|
+
rb_gc_register_address(&oj_object_class_sym);
|
1885
|
+
oj_object_nl_sym = ID2SYM(rb_intern("object_nl"));
|
1886
|
+
rb_gc_register_address(&oj_object_nl_sym);
|
1887
|
+
oj_quirks_mode_sym = ID2SYM(rb_intern("quirks_mode"));
|
1888
|
+
rb_gc_register_address(&oj_quirks_mode_sym);
|
1889
|
+
oj_safe_sym = ID2SYM(rb_intern("safe"));
|
1890
|
+
rb_gc_register_address(&oj_safe_sym);
|
1891
|
+
oj_space_before_sym = ID2SYM(rb_intern("space_before"));
|
1892
|
+
rb_gc_register_address(&oj_space_before_sym);
|
1893
|
+
oj_space_sym = ID2SYM(rb_intern("space"));
|
1894
|
+
rb_gc_register_address(&oj_space_sym);
|
1895
|
+
oj_trace_sym = ID2SYM(rb_intern("trace"));
|
1896
|
+
rb_gc_register_address(&oj_trace_sym);
|
1897
|
+
omit_nil_sym = ID2SYM(rb_intern("omit_nil"));
|
1898
|
+
rb_gc_register_address(&omit_nil_sym);
|
1899
|
+
rails_sym = ID2SYM(rb_intern("rails"));
|
1900
|
+
rb_gc_register_address(&rails_sym);
|
1901
|
+
raise_sym = ID2SYM(rb_intern("raise"));
|
1902
|
+
rb_gc_register_address(&raise_sym);
|
1903
|
+
ruby_sym = ID2SYM(rb_intern("ruby"));
|
1904
|
+
rb_gc_register_address(&ruby_sym);
|
1905
|
+
sec_prec_sym = ID2SYM(rb_intern("second_precision"));
|
1906
|
+
rb_gc_register_address(&sec_prec_sym);
|
1907
|
+
strict_sym = ID2SYM(rb_intern("strict"));
|
1908
|
+
rb_gc_register_address(&strict_sym);
|
1909
|
+
symbol_keys_sym = ID2SYM(rb_intern("symbol_keys"));
|
1910
|
+
rb_gc_register_address(&symbol_keys_sym);
|
1911
|
+
time_format_sym = ID2SYM(rb_intern("time_format"));
|
1912
|
+
rb_gc_register_address(&time_format_sym);
|
1913
|
+
unicode_xss_sym = ID2SYM(rb_intern("unicode_xss"));
|
1914
|
+
rb_gc_register_address(&unicode_xss_sym);
|
1915
|
+
unix_sym = ID2SYM(rb_intern("unix"));
|
1916
|
+
rb_gc_register_address(&unix_sym);
|
1917
|
+
unix_zone_sym = ID2SYM(rb_intern("unix_zone"));
|
1918
|
+
rb_gc_register_address(&unix_zone_sym);
|
1919
|
+
use_as_json_sym = ID2SYM(rb_intern("use_as_json"));
|
1920
|
+
rb_gc_register_address(&use_as_json_sym);
|
1921
|
+
use_raw_json_sym = ID2SYM(rb_intern("use_raw_json"));
|
1922
|
+
rb_gc_register_address(&use_raw_json_sym);
|
1923
|
+
use_to_hash_sym = ID2SYM(rb_intern("use_to_hash"));
|
1924
|
+
rb_gc_register_address(&use_to_hash_sym);
|
1925
|
+
use_to_json_sym = ID2SYM(rb_intern("use_to_json"));
|
1926
|
+
rb_gc_register_address(&use_to_json_sym);
|
1927
|
+
wab_sym = ID2SYM(rb_intern("wab"));
|
1928
|
+
rb_gc_register_address(&wab_sym);
|
1929
|
+
word_sym = ID2SYM(rb_intern("word"));
|
1930
|
+
rb_gc_register_address(&word_sym);
|
1931
|
+
xmlschema_sym = ID2SYM(rb_intern("xmlschema"));
|
1932
|
+
rb_gc_register_address(&xmlschema_sym);
|
1933
|
+
xss_safe_sym = ID2SYM(rb_intern("xss_safe"));
|
1934
|
+
rb_gc_register_address(&xss_safe_sym);
|
1935
|
+
|
1936
|
+
oj_slash_string = rb_str_new2("/");
|
1937
|
+
rb_gc_register_address(&oj_slash_string);
|
1731
1938
|
OBJ_FREEZE(oj_slash_string);
|
1732
1939
|
|
1733
1940
|
oj_default_options.mode = ObjectMode;
|
@@ -1738,7 +1945,7 @@ Init_oj() {
|
|
1738
1945
|
|
1739
1946
|
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
1740
1947
|
if (0 != (err = pthread_mutex_init(&oj_cache_mutex, 0))) {
|
1741
|
-
|
1948
|
+
rb_raise(rb_eException, "failed to initialize a mutex. %s", strerror(err));
|
1742
1949
|
}
|
1743
1950
|
#else
|
1744
1951
|
oj_cache_mutex = rb_mutex_new();
|