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