oj 3.13.23 → 3.16.10
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 +86 -0
- data/README.md +2 -2
- data/ext/oj/buf.h +7 -6
- data/ext/oj/cache.c +29 -26
- data/ext/oj/cache.h +3 -2
- data/ext/oj/cache8.c +10 -9
- data/ext/oj/circarray.c +7 -5
- data/ext/oj/circarray.h +2 -2
- data/ext/oj/code.c +5 -12
- data/ext/oj/code.h +2 -2
- data/ext/oj/compat.c +20 -60
- data/ext/oj/custom.c +26 -59
- data/ext/oj/debug.c +3 -9
- data/ext/oj/dump.c +103 -53
- data/ext/oj/dump.h +1 -4
- data/ext/oj/dump_compat.c +557 -592
- data/ext/oj/dump_leaf.c +3 -5
- data/ext/oj/dump_object.c +42 -48
- data/ext/oj/dump_strict.c +10 -22
- data/ext/oj/encoder.c +1 -1
- data/ext/oj/err.c +2 -13
- data/ext/oj/err.h +9 -12
- data/ext/oj/extconf.rb +16 -7
- data/ext/oj/fast.c +63 -98
- data/ext/oj/intern.c +62 -47
- data/ext/oj/intern.h +3 -7
- data/ext/oj/mem.c +318 -0
- data/ext/oj/mem.h +53 -0
- data/ext/oj/mimic_json.c +54 -38
- data/ext/oj/object.c +33 -43
- data/ext/oj/odd.c +8 -6
- data/ext/oj/odd.h +4 -4
- data/ext/oj/oj.c +245 -216
- data/ext/oj/oj.h +83 -81
- data/ext/oj/parse.c +109 -153
- data/ext/oj/parse.h +21 -24
- data/ext/oj/parser.c +80 -67
- data/ext/oj/parser.h +9 -8
- data/ext/oj/rails.c +71 -94
- data/ext/oj/reader.c +9 -14
- data/ext/oj/reader.h +4 -2
- data/ext/oj/resolve.c +3 -4
- data/ext/oj/rxclass.c +6 -5
- data/ext/oj/rxclass.h +1 -1
- data/ext/oj/saj.c +13 -15
- data/ext/oj/saj2.c +37 -49
- data/ext/oj/saj2.h +1 -1
- data/ext/oj/scp.c +6 -20
- data/ext/oj/sparse.c +22 -70
- data/ext/oj/stream_writer.c +46 -48
- data/ext/oj/strict.c +22 -56
- data/ext/oj/string_writer.c +64 -40
- data/ext/oj/trace.h +31 -4
- data/ext/oj/usual.c +125 -114
- data/ext/oj/usual.h +7 -6
- data/ext/oj/util.h +1 -1
- data/ext/oj/val_stack.c +13 -2
- data/ext/oj/val_stack.h +8 -7
- data/ext/oj/wab.c +25 -57
- data/lib/oj/active_support_helper.rb +1 -3
- data/lib/oj/bag.rb +7 -1
- data/lib/oj/easy_hash.rb +4 -5
- data/lib/oj/error.rb +0 -1
- data/lib/oj/json.rb +162 -150
- data/lib/oj/mimic.rb +7 -7
- data/lib/oj/schandler.rb +5 -4
- data/lib/oj/state.rb +8 -5
- data/lib/oj/version.rb +1 -2
- data/lib/oj.rb +2 -0
- data/pages/InstallOptions.md +20 -0
- data/pages/Options.md +4 -0
- metadata +46 -121
- data/test/_test_active.rb +0 -76
- data/test/_test_active_mimic.rb +0 -96
- data/test/_test_mimic_rails.rb +0 -126
- data/test/activerecord/result_test.rb +0 -32
- data/test/activesupport4/decoding_test.rb +0 -108
- data/test/activesupport4/encoding_test.rb +0 -531
- data/test/activesupport4/test_helper.rb +0 -41
- data/test/activesupport5/abstract_unit.rb +0 -45
- data/test/activesupport5/decoding_test.rb +0 -133
- data/test/activesupport5/encoding_test.rb +0 -500
- data/test/activesupport5/encoding_test_cases.rb +0 -98
- data/test/activesupport5/test_helper.rb +0 -72
- data/test/activesupport5/time_zone_test_helpers.rb +0 -39
- data/test/activesupport6/abstract_unit.rb +0 -44
- data/test/activesupport6/decoding_test.rb +0 -133
- data/test/activesupport6/encoding_test.rb +0 -507
- data/test/activesupport6/encoding_test_cases.rb +0 -98
- data/test/activesupport6/test_common.rb +0 -17
- data/test/activesupport6/test_helper.rb +0 -163
- data/test/activesupport6/time_zone_test_helpers.rb +0 -39
- data/test/activesupport7/abstract_unit.rb +0 -49
- data/test/activesupport7/decoding_test.rb +0 -125
- data/test/activesupport7/encoding_test.rb +0 -486
- data/test/activesupport7/encoding_test_cases.rb +0 -104
- data/test/activesupport7/time_zone_test_helpers.rb +0 -47
- data/test/bar.rb +0 -11
- data/test/baz.rb +0 -16
- data/test/bug.rb +0 -16
- data/test/files.rb +0 -29
- data/test/foo.rb +0 -77
- data/test/helper.rb +0 -42
- data/test/isolated/shared.rb +0 -308
- data/test/isolated/test_mimic_after.rb +0 -13
- data/test/isolated/test_mimic_alone.rb +0 -12
- data/test/isolated/test_mimic_as_json.rb +0 -45
- data/test/isolated/test_mimic_before.rb +0 -13
- data/test/isolated/test_mimic_define.rb +0 -28
- data/test/isolated/test_mimic_rails_after.rb +0 -22
- data/test/isolated/test_mimic_rails_before.rb +0 -21
- data/test/isolated/test_mimic_redefine.rb +0 -15
- data/test/json_gem/json_addition_test.rb +0 -216
- data/test/json_gem/json_common_interface_test.rb +0 -153
- data/test/json_gem/json_encoding_test.rb +0 -107
- data/test/json_gem/json_ext_parser_test.rb +0 -20
- data/test/json_gem/json_fixtures_test.rb +0 -35
- data/test/json_gem/json_generator_test.rb +0 -396
- data/test/json_gem/json_generic_object_test.rb +0 -90
- data/test/json_gem/json_parser_test.rb +0 -477
- data/test/json_gem/json_string_matching_test.rb +0 -42
- data/test/json_gem/test_helper.rb +0 -30
- data/test/mem.rb +0 -33
- data/test/perf.rb +0 -107
- data/test/perf_compat.rb +0 -130
- data/test/perf_dump.rb +0 -50
- data/test/perf_fast.rb +0 -164
- data/test/perf_file.rb +0 -64
- data/test/perf_object.rb +0 -138
- data/test/perf_once.rb +0 -58
- data/test/perf_parser.rb +0 -189
- data/test/perf_saj.rb +0 -109
- data/test/perf_scp.rb +0 -152
- data/test/perf_simple.rb +0 -287
- data/test/perf_strict.rb +0 -139
- data/test/perf_wab.rb +0 -131
- data/test/prec.rb +0 -23
- data/test/sample/change.rb +0 -14
- data/test/sample/dir.rb +0 -19
- data/test/sample/doc.rb +0 -36
- data/test/sample/file.rb +0 -48
- data/test/sample/group.rb +0 -16
- data/test/sample/hasprops.rb +0 -16
- data/test/sample/layer.rb +0 -12
- data/test/sample/line.rb +0 -20
- data/test/sample/oval.rb +0 -10
- data/test/sample/rect.rb +0 -10
- data/test/sample/shape.rb +0 -35
- data/test/sample/text.rb +0 -20
- data/test/sample.rb +0 -54
- data/test/sample_json.rb +0 -37
- data/test/test_compat.rb +0 -540
- data/test/test_custom.rb +0 -544
- data/test/test_debian.rb +0 -53
- data/test/test_fast.rb +0 -530
- data/test/test_file.rb +0 -255
- data/test/test_gc.rb +0 -60
- data/test/test_generate.rb +0 -21
- data/test/test_hash.rb +0 -39
- data/test/test_integer_range.rb +0 -72
- data/test/test_null.rb +0 -376
- data/test/test_object.rb +0 -1025
- data/test/test_parser.rb +0 -11
- data/test/test_parser_debug.rb +0 -27
- data/test/test_parser_saj.rb +0 -335
- data/test/test_parser_usual.rb +0 -217
- data/test/test_rails.rb +0 -35
- data/test/test_saj.rb +0 -186
- data/test/test_scp.rb +0 -431
- data/test/test_strict.rb +0 -435
- data/test/test_various.rb +0 -752
- data/test/test_wab.rb +0 -309
- data/test/test_writer.rb +0 -380
- data/test/tests.rb +0 -33
- data/test/tests_mimic.rb +0 -23
- data/test/tests_mimic_addition.rb +0 -16
- data/test/zoo.rb +0 -13
data/ext/oj/stream_writer.c
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
#include <ruby.h>
|
6
6
|
|
7
7
|
#include "encode.h"
|
8
|
+
#include "mem.h"
|
8
9
|
|
9
10
|
extern VALUE Oj;
|
10
11
|
|
@@ -15,11 +16,22 @@ static void stream_writer_free(void *ptr) {
|
|
15
16
|
return;
|
16
17
|
}
|
17
18
|
sw = (StreamWriter)ptr;
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
OJ_R_FREE(sw->sw.out.buf);
|
20
|
+
OJ_R_FREE(sw->sw.types);
|
21
|
+
OJ_R_FREE(ptr);
|
21
22
|
}
|
22
23
|
|
24
|
+
static const rb_data_type_t oj_stream_writer_type = {
|
25
|
+
"Oj/stream_writer",
|
26
|
+
{
|
27
|
+
NULL,
|
28
|
+
stream_writer_free,
|
29
|
+
NULL,
|
30
|
+
},
|
31
|
+
0,
|
32
|
+
0,
|
33
|
+
};
|
34
|
+
|
23
35
|
static void stream_writer_reset_buf(StreamWriter sw) {
|
24
36
|
sw->sw.out.cur = sw->sw.out.buf;
|
25
37
|
*sw->sw.out.cur = '\0';
|
@@ -30,22 +42,12 @@ static void stream_writer_write(StreamWriter sw) {
|
|
30
42
|
|
31
43
|
switch (sw->type) {
|
32
44
|
case STRING_IO:
|
33
|
-
case STREAM_IO:
|
34
|
-
|
35
|
-
|
36
|
-
// Oddly enough, when pushing ASCII characters with UTF-8 encoding or
|
37
|
-
// even ASCII-8BIT does not change the output encoding. Pushing any
|
38
|
-
// non-ASCII no matter what the encoding changes the output encoding
|
39
|
-
// to ASCII-8BIT if it the string is not forced to UTF-8 here.
|
40
|
-
rs = oj_encode(rs);
|
45
|
+
case STREAM_IO:
|
46
|
+
case FILE_IO: {
|
47
|
+
volatile VALUE rs = rb_utf8_str_new(sw->sw.out.buf, size);
|
41
48
|
rb_funcall(sw->stream, oj_write_id, 1, rs);
|
42
49
|
break;
|
43
50
|
}
|
44
|
-
case FILE_IO:
|
45
|
-
if (size != write(sw->fd, sw->sw.out.buf, size)) {
|
46
|
-
rb_raise(rb_eIOError, "Write failed. [_%d_:%s]\n", errno, strerror(errno));
|
47
|
-
}
|
48
|
-
break;
|
49
51
|
default: rb_raise(rb_eArgError, "expected an IO Object.");
|
50
52
|
}
|
51
53
|
stream_writer_reset_buf(sw);
|
@@ -82,8 +84,8 @@ static VALUE stream_writer_new(int argc, VALUE *argv, VALUE self) {
|
|
82
84
|
if (oj_stringio_class == clas) {
|
83
85
|
type = STRING_IO;
|
84
86
|
#if !IS_WINDOWS
|
85
|
-
} else if (rb_respond_to(stream, oj_fileno_id) &&
|
86
|
-
|
87
|
+
} else if (rb_respond_to(stream, oj_fileno_id) && Qnil != (s = rb_funcall(stream, oj_fileno_id, 0)) &&
|
88
|
+
0 != (fd = FIX2INT(s))) {
|
87
89
|
type = FILE_IO;
|
88
90
|
#endif
|
89
91
|
} else if (rb_respond_to(stream, oj_write_id)) {
|
@@ -91,7 +93,7 @@ static VALUE stream_writer_new(int argc, VALUE *argv, VALUE self) {
|
|
91
93
|
} else {
|
92
94
|
rb_raise(rb_eArgError, "expected an IO Object.");
|
93
95
|
}
|
94
|
-
sw =
|
96
|
+
sw = OJ_R_ALLOC(struct _streamWriter);
|
95
97
|
if (2 == argc && T_HASH == rb_type(argv[1])) {
|
96
98
|
volatile VALUE v;
|
97
99
|
int buf_size = 0;
|
@@ -101,15 +103,10 @@ static VALUE stream_writer_new(int argc, VALUE *argv, VALUE self) {
|
|
101
103
|
rb_gc_register_address(&buffer_size_sym);
|
102
104
|
}
|
103
105
|
if (Qnil != (v = rb_hash_lookup(argv[1], buffer_size_sym))) {
|
104
|
-
#ifdef RUBY_INTEGER_UNIFICATION
|
105
106
|
if (rb_cInteger != rb_obj_class(v)) {
|
107
|
+
OJ_R_FREE(sw);
|
106
108
|
rb_raise(rb_eArgError, ":buffer size must be a Integer.");
|
107
109
|
}
|
108
|
-
#else
|
109
|
-
if (T_FIXNUM != rb_type(v)) {
|
110
|
-
rb_raise(rb_eArgError, ":buffer size must be a Integer.");
|
111
|
-
}
|
112
|
-
#endif
|
113
110
|
buf_size = FIX2INT(v);
|
114
111
|
}
|
115
112
|
oj_str_writer_init(&sw->sw, buf_size);
|
@@ -124,7 +121,7 @@ static VALUE stream_writer_new(int argc, VALUE *argv, VALUE self) {
|
|
124
121
|
sw->type = type;
|
125
122
|
sw->fd = fd;
|
126
123
|
|
127
|
-
return
|
124
|
+
return TypedData_Wrap_Struct(oj_stream_writer_class, &oj_stream_writer_type, sw);
|
128
125
|
}
|
129
126
|
|
130
127
|
/* Document-method: push_key
|
@@ -137,9 +134,9 @@ static VALUE stream_writer_new(int argc, VALUE *argv, VALUE self) {
|
|
137
134
|
* - *key* [_String_] the key pending for the next push
|
138
135
|
*/
|
139
136
|
static VALUE stream_writer_push_key(VALUE self, VALUE key) {
|
140
|
-
StreamWriter sw
|
137
|
+
StreamWriter sw;
|
138
|
+
TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw);
|
141
139
|
|
142
|
-
rb_check_type(key, T_STRING);
|
143
140
|
oj_str_writer_push_key(&sw->sw, StringValuePtr(key));
|
144
141
|
if (sw->flush_limit < sw->sw.out.cur - sw->sw.out.buf) {
|
145
142
|
stream_writer_write(sw);
|
@@ -156,7 +153,8 @@ static VALUE stream_writer_push_key(VALUE self, VALUE key) {
|
|
156
153
|
* - *key* [_String_] the key if adding to an object in the JSON document
|
157
154
|
*/
|
158
155
|
static VALUE stream_writer_push_object(int argc, VALUE *argv, VALUE self) {
|
159
|
-
StreamWriter sw
|
156
|
+
StreamWriter sw;
|
157
|
+
TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw);
|
160
158
|
|
161
159
|
switch (argc) {
|
162
160
|
case 0: oj_str_writer_push_object(&sw->sw, 0); break;
|
@@ -164,7 +162,6 @@ static VALUE stream_writer_push_object(int argc, VALUE *argv, VALUE self) {
|
|
164
162
|
if (Qnil == argv[0]) {
|
165
163
|
oj_str_writer_push_object(&sw->sw, 0);
|
166
164
|
} else {
|
167
|
-
rb_check_type(argv[0], T_STRING);
|
168
165
|
oj_str_writer_push_object(&sw->sw, StringValuePtr(argv[0]));
|
169
166
|
}
|
170
167
|
break;
|
@@ -185,7 +182,8 @@ static VALUE stream_writer_push_object(int argc, VALUE *argv, VALUE self) {
|
|
185
182
|
* - *key* [_String_] the key if adding to an object in the JSON document
|
186
183
|
*/
|
187
184
|
static VALUE stream_writer_push_array(int argc, VALUE *argv, VALUE self) {
|
188
|
-
StreamWriter sw
|
185
|
+
StreamWriter sw;
|
186
|
+
TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw);
|
189
187
|
|
190
188
|
switch (argc) {
|
191
189
|
case 0: oj_str_writer_push_array(&sw->sw, 0); break;
|
@@ -193,7 +191,6 @@ static VALUE stream_writer_push_array(int argc, VALUE *argv, VALUE self) {
|
|
193
191
|
if (Qnil == argv[0]) {
|
194
192
|
oj_str_writer_push_array(&sw->sw, 0);
|
195
193
|
} else {
|
196
|
-
rb_check_type(argv[0], T_STRING);
|
197
194
|
oj_str_writer_push_array(&sw->sw, StringValuePtr(argv[0]));
|
198
195
|
}
|
199
196
|
break;
|
@@ -213,16 +210,16 @@ static VALUE stream_writer_push_array(int argc, VALUE *argv, VALUE self) {
|
|
213
210
|
* - *key* [_String_] the key if adding to an object in the JSON document
|
214
211
|
*/
|
215
212
|
static VALUE stream_writer_push_value(int argc, VALUE *argv, VALUE self) {
|
216
|
-
StreamWriter sw
|
213
|
+
StreamWriter sw;
|
214
|
+
TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw);
|
217
215
|
|
218
216
|
switch (argc) {
|
219
|
-
case 1: oj_str_writer_push_value((StrWriter)
|
217
|
+
case 1: oj_str_writer_push_value((StrWriter)sw, *argv, 0); break;
|
220
218
|
case 2:
|
221
219
|
if (Qnil == argv[1]) {
|
222
|
-
oj_str_writer_push_value((StrWriter)
|
220
|
+
oj_str_writer_push_value((StrWriter)sw, *argv, 0);
|
223
221
|
} else {
|
224
|
-
|
225
|
-
oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, StringValuePtr(argv[1]));
|
222
|
+
oj_str_writer_push_value((StrWriter)sw, *argv, StringValuePtr(argv[1]));
|
226
223
|
}
|
227
224
|
break;
|
228
225
|
default: rb_raise(rb_eArgError, "Wrong number of argument to 'push_value'."); break;
|
@@ -243,19 +240,16 @@ static VALUE stream_writer_push_value(int argc, VALUE *argv, VALUE self) {
|
|
243
240
|
* - *key* [_String_] the key if adding to an object in the JSON document
|
244
241
|
*/
|
245
242
|
static VALUE stream_writer_push_json(int argc, VALUE *argv, VALUE self) {
|
246
|
-
StreamWriter sw
|
243
|
+
StreamWriter sw;
|
244
|
+
TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw);
|
247
245
|
|
248
|
-
rb_check_type(argv[0], T_STRING);
|
249
246
|
switch (argc) {
|
250
|
-
case 1: oj_str_writer_push_json((StrWriter)
|
247
|
+
case 1: oj_str_writer_push_json((StrWriter)sw, StringValuePtr(*argv), 0); break;
|
251
248
|
case 2:
|
252
249
|
if (Qnil == argv[1]) {
|
253
|
-
oj_str_writer_push_json((StrWriter)
|
250
|
+
oj_str_writer_push_json((StrWriter)sw, StringValuePtr(*argv), 0);
|
254
251
|
} else {
|
255
|
-
|
256
|
-
oj_str_writer_push_json((StrWriter)DATA_PTR(self),
|
257
|
-
StringValuePtr(*argv),
|
258
|
-
StringValuePtr(argv[1]));
|
252
|
+
oj_str_writer_push_json((StrWriter)sw, StringValuePtr(*argv), StringValuePtr(argv[1]));
|
259
253
|
}
|
260
254
|
break;
|
261
255
|
default: rb_raise(rb_eArgError, "Wrong number of argument to 'push_json'."); break;
|
@@ -273,7 +267,8 @@ static VALUE stream_writer_push_json(int argc, VALUE *argv, VALUE self) {
|
|
273
267
|
* currently open.
|
274
268
|
*/
|
275
269
|
static VALUE stream_writer_pop(VALUE self) {
|
276
|
-
StreamWriter sw
|
270
|
+
StreamWriter sw;
|
271
|
+
TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw);
|
277
272
|
|
278
273
|
oj_str_writer_pop(&sw->sw);
|
279
274
|
if (sw->flush_limit < sw->sw.out.cur - sw->sw.out.buf) {
|
@@ -289,7 +284,8 @@ static VALUE stream_writer_pop(VALUE self) {
|
|
289
284
|
* currently open.
|
290
285
|
*/
|
291
286
|
static VALUE stream_writer_pop_all(VALUE self) {
|
292
|
-
StreamWriter sw
|
287
|
+
StreamWriter sw;
|
288
|
+
TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw);
|
293
289
|
|
294
290
|
oj_str_writer_pop_all(&sw->sw);
|
295
291
|
stream_writer_write(sw);
|
@@ -303,7 +299,9 @@ static VALUE stream_writer_pop_all(VALUE self) {
|
|
303
299
|
* Flush any remaining characters in the buffer.
|
304
300
|
*/
|
305
301
|
static VALUE stream_writer_flush(VALUE self) {
|
306
|
-
|
302
|
+
StreamWriter sw;
|
303
|
+
TypedData_Get_Struct(self, struct _streamWriter, &oj_stream_writer_type, sw);
|
304
|
+
stream_writer_write(sw);
|
307
305
|
|
308
306
|
return Qnil;
|
309
307
|
}
|
data/ext/oj/strict.c
CHANGED
@@ -17,10 +17,9 @@ VALUE oj_cstr_to_value(const char *str, size_t len, size_t cache_str) {
|
|
17
17
|
volatile VALUE rstr = Qnil;
|
18
18
|
|
19
19
|
if (len < cache_str) {
|
20
|
-
|
20
|
+
rstr = oj_str_intern(str, len);
|
21
21
|
} else {
|
22
|
-
rstr =
|
23
|
-
rstr = oj_encode(rstr);
|
22
|
+
rstr = rb_utf8_str_new(str, len);
|
24
23
|
}
|
25
24
|
return rstr;
|
26
25
|
}
|
@@ -35,30 +34,25 @@ VALUE oj_calc_hash_key(ParseInfo pi, Val parent) {
|
|
35
34
|
if (Yes == pi->options.sym_key) {
|
36
35
|
rkey = ID2SYM(rb_intern3(parent->key, parent->klen, oj_utf8_encoding));
|
37
36
|
} else {
|
38
|
-
rkey =
|
39
|
-
|
40
|
-
OBJ_FREEZE(rkey); // frozen when used as a Hash key anyway
|
37
|
+
rkey = rb_utf8_str_new(parent->key, parent->klen);
|
38
|
+
OBJ_FREEZE(rkey); // frozen when used as a Hash key anyway
|
41
39
|
}
|
42
40
|
return rkey;
|
43
41
|
}
|
44
42
|
if (Yes == pi->options.sym_key) {
|
45
|
-
|
43
|
+
rkey = oj_sym_intern(parent->key, parent->klen);
|
46
44
|
} else {
|
47
|
-
|
45
|
+
rkey = oj_str_intern(parent->key, parent->klen);
|
48
46
|
}
|
49
47
|
return rkey;
|
50
48
|
}
|
51
49
|
|
52
50
|
static void hash_end(ParseInfo pi) {
|
53
|
-
|
54
|
-
oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
|
55
|
-
}
|
51
|
+
TRACE_PARSE_HASH_END(pi->options.trace, pi);
|
56
52
|
}
|
57
53
|
|
58
54
|
static void array_end(ParseInfo pi) {
|
59
|
-
|
60
|
-
oj_trace_parse_array_end(pi, __FILE__, __LINE__);
|
61
|
-
}
|
55
|
+
TRACE_PARSE_ARRAY_END(pi->options.trace, pi);
|
62
56
|
}
|
63
57
|
|
64
58
|
static VALUE noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
|
@@ -66,9 +60,7 @@ static VALUE noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
|
|
66
60
|
}
|
67
61
|
|
68
62
|
static void add_value(ParseInfo pi, VALUE val) {
|
69
|
-
|
70
|
-
oj_trace_parse_call("add_value", pi, __FILE__, __LINE__, val);
|
71
|
-
}
|
63
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_value", pi, val);
|
72
64
|
pi->stack.head->val = val;
|
73
65
|
}
|
74
66
|
|
@@ -76,9 +68,7 @@ static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig
|
|
76
68
|
volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
|
77
69
|
|
78
70
|
pi->stack.head->val = rstr;
|
79
|
-
|
80
|
-
oj_trace_parse_call("add_string", pi, __FILE__, __LINE__, rstr);
|
81
|
-
}
|
71
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_string", pi, rstr);
|
82
72
|
}
|
83
73
|
|
84
74
|
static void add_num(ParseInfo pi, NumInfo ni) {
|
@@ -86,30 +76,22 @@ static void add_num(ParseInfo pi, NumInfo ni) {
|
|
86
76
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
|
87
77
|
}
|
88
78
|
pi->stack.head->val = oj_num_as_value(ni);
|
89
|
-
|
90
|
-
oj_trace_parse_call("add_number", pi, __FILE__, __LINE__, pi->stack.head->val);
|
91
|
-
}
|
79
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_number", pi, pi->stack.head->val);
|
92
80
|
}
|
93
81
|
|
94
82
|
static VALUE start_hash(ParseInfo pi) {
|
95
83
|
if (Qnil != pi->options.hash_class) {
|
96
84
|
return rb_class_new_instance(0, NULL, pi->options.hash_class);
|
97
85
|
}
|
98
|
-
|
99
|
-
oj_trace_parse_in("start_hash", pi, __FILE__, __LINE__);
|
100
|
-
}
|
86
|
+
TRACE_PARSE_IN(pi->options.trace, "start_hash", pi);
|
101
87
|
return rb_hash_new();
|
102
88
|
}
|
103
89
|
|
104
90
|
static void hash_set_cstr(ParseInfo pi, Val parent, const char *str, size_t len, const char *orig) {
|
105
91
|
volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
|
106
92
|
|
107
|
-
rb_hash_aset(stack_peek(&pi->stack)->val,
|
108
|
-
|
109
|
-
rstr);
|
110
|
-
if (RB_UNLIKELY(Yes == pi->options.trace)) {
|
111
|
-
oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rstr);
|
112
|
-
}
|
93
|
+
rb_hash_aset(stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, parent), rstr);
|
94
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_string", pi, rstr);
|
113
95
|
}
|
114
96
|
|
115
97
|
static void hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
|
@@ -119,27 +101,17 @@ static void hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
|
|
119
101
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
|
120
102
|
}
|
121
103
|
v = oj_num_as_value(ni);
|
122
|
-
rb_hash_aset(stack_peek(&pi->stack)->val,
|
123
|
-
|
124
|
-
v);
|
125
|
-
if (RB_UNLIKELY(Yes == pi->options.trace)) {
|
126
|
-
oj_trace_parse_call("set_number", pi, __FILE__, __LINE__, v);
|
127
|
-
}
|
104
|
+
rb_hash_aset(stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, parent), v);
|
105
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_number", pi, v);
|
128
106
|
}
|
129
107
|
|
130
108
|
static void hash_set_value(ParseInfo pi, Val parent, VALUE value) {
|
131
|
-
rb_hash_aset(stack_peek(&pi->stack)->val,
|
132
|
-
|
133
|
-
value);
|
134
|
-
if (RB_UNLIKELY(Yes == pi->options.trace)) {
|
135
|
-
oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
|
136
|
-
}
|
109
|
+
rb_hash_aset(stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, parent), value);
|
110
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_value", pi, value);
|
137
111
|
}
|
138
112
|
|
139
113
|
static VALUE start_array(ParseInfo pi) {
|
140
|
-
|
141
|
-
oj_trace_parse_in("start_array", pi, __FILE__, __LINE__);
|
142
|
-
}
|
114
|
+
TRACE_PARSE_IN(pi->options.trace, "start_array", pi);
|
143
115
|
return rb_ary_new();
|
144
116
|
}
|
145
117
|
|
@@ -147,9 +119,7 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
|
|
147
119
|
volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
|
148
120
|
|
149
121
|
rb_ary_push(stack_peek(&pi->stack)->val, rstr);
|
150
|
-
|
151
|
-
oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rstr);
|
152
|
-
}
|
122
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_string", pi, rstr);
|
153
123
|
}
|
154
124
|
|
155
125
|
static void array_append_num(ParseInfo pi, NumInfo ni) {
|
@@ -160,16 +130,12 @@ static void array_append_num(ParseInfo pi, NumInfo ni) {
|
|
160
130
|
}
|
161
131
|
v = oj_num_as_value(ni);
|
162
132
|
rb_ary_push(stack_peek(&pi->stack)->val, v);
|
163
|
-
|
164
|
-
oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, v);
|
165
|
-
}
|
133
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_number", pi, v);
|
166
134
|
}
|
167
135
|
|
168
136
|
static void array_append_value(ParseInfo pi, VALUE value) {
|
169
137
|
rb_ary_push(stack_peek(&pi->stack)->val, value);
|
170
|
-
|
171
|
-
oj_trace_parse_call("append_value", pi, __FILE__, __LINE__, value);
|
172
|
-
}
|
138
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_value", pi, value);
|
173
139
|
}
|
174
140
|
|
175
141
|
void oj_set_strict_callbacks(ParseInfo pi) {
|
data/ext/oj/string_writer.c
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
#include "dump.h"
|
5
5
|
#include "encode.h"
|
6
|
+
#include "mem.h"
|
6
7
|
|
7
8
|
extern VALUE Oj;
|
8
9
|
|
@@ -20,7 +21,7 @@ static void push_type(StrWriter sw, DumpType type) {
|
|
20
21
|
if (sw->types_end <= sw->types + sw->depth + 1) {
|
21
22
|
size_t size = (sw->types_end - sw->types) * 2;
|
22
23
|
|
23
|
-
|
24
|
+
OJ_R_REALLOC_N(sw->types, char, size);
|
24
25
|
sw->types_end = sw->types + size;
|
25
26
|
}
|
26
27
|
sw->depth++;
|
@@ -43,7 +44,7 @@ static void maybe_comma(StrWriter sw) {
|
|
43
44
|
void oj_str_writer_init(StrWriter sw, int buf_size) {
|
44
45
|
sw->opts = oj_default_options;
|
45
46
|
sw->depth = 0;
|
46
|
-
sw->types =
|
47
|
+
sw->types = OJ_R_ALLOC_N(char, 256);
|
47
48
|
sw->types_end = sw->types + 256;
|
48
49
|
*sw->types = '\0';
|
49
50
|
sw->keyWritten = 0;
|
@@ -55,10 +56,10 @@ void oj_str_writer_init(StrWriter sw, int buf_size) {
|
|
55
56
|
}
|
56
57
|
// Must be allocated. Using the out.stack_buffer results in double frees
|
57
58
|
// and I haven't figured out why yet.
|
58
|
-
sw->out.buf
|
59
|
-
sw->out.cur
|
60
|
-
sw->out.end
|
61
|
-
sw->out.allocated
|
59
|
+
sw->out.buf = OJ_R_ALLOC_N(char, buf_size);
|
60
|
+
sw->out.cur = sw->out.buf;
|
61
|
+
sw->out.end = sw->out.buf + buf_size - BUFFER_EXTRA;
|
62
|
+
sw->out.allocated = true;
|
62
63
|
|
63
64
|
*sw->out.cur = '\0';
|
64
65
|
sw->out.circ_cache = NULL;
|
@@ -69,7 +70,6 @@ void oj_str_writer_init(StrWriter sw, int buf_size) {
|
|
69
70
|
sw->out.depth = 0;
|
70
71
|
sw->out.argc = 0;
|
71
72
|
sw->out.argv = NULL;
|
72
|
-
sw->out.caller = 0;
|
73
73
|
sw->out.ropts = NULL;
|
74
74
|
sw->out.omit_nil = oj_default_options.dump_opts.omit_nil;
|
75
75
|
}
|
@@ -225,7 +225,7 @@ void oj_str_writer_pop_all(StrWriter sw) {
|
|
225
225
|
}
|
226
226
|
}
|
227
227
|
|
228
|
-
static void
|
228
|
+
static void string_writer_free(void *ptr) {
|
229
229
|
StrWriter sw;
|
230
230
|
|
231
231
|
if (0 == ptr) {
|
@@ -235,8 +235,25 @@ static void str_writer_free(void *ptr) {
|
|
235
235
|
|
236
236
|
oj_out_free(&sw->out);
|
237
237
|
|
238
|
-
|
239
|
-
|
238
|
+
OJ_R_FREE(sw->types);
|
239
|
+
OJ_R_FREE(ptr);
|
240
|
+
}
|
241
|
+
|
242
|
+
static const rb_data_type_t oj_string_writer_type = {
|
243
|
+
"Oj/string_writer",
|
244
|
+
{
|
245
|
+
NULL,
|
246
|
+
string_writer_free,
|
247
|
+
NULL,
|
248
|
+
},
|
249
|
+
0,
|
250
|
+
0,
|
251
|
+
};
|
252
|
+
|
253
|
+
StrWriter oj_str_writer_unwrap(VALUE writer) {
|
254
|
+
StrWriter sw;
|
255
|
+
TypedData_Get_Struct(writer, struct _strWriter, &oj_string_writer_type, sw);
|
256
|
+
return sw;
|
240
257
|
}
|
241
258
|
|
242
259
|
/* Document-method: new
|
@@ -256,7 +273,7 @@ static void str_writer_free(void *ptr) {
|
|
256
273
|
* - *options* [_Hash_] formatting options
|
257
274
|
*/
|
258
275
|
static VALUE str_writer_new(int argc, VALUE *argv, VALUE self) {
|
259
|
-
StrWriter sw =
|
276
|
+
StrWriter sw = OJ_R_ALLOC(struct _strWriter);
|
260
277
|
|
261
278
|
oj_str_writer_init(sw, 0);
|
262
279
|
if (1 == argc) {
|
@@ -266,7 +283,7 @@ static VALUE str_writer_new(int argc, VALUE *argv, VALUE self) {
|
|
266
283
|
sw->out.argv = argv + 1;
|
267
284
|
sw->out.indent = sw->opts.indent;
|
268
285
|
|
269
|
-
return
|
286
|
+
return TypedData_Wrap_Struct(oj_string_writer_class, &oj_string_writer_type, sw);
|
270
287
|
}
|
271
288
|
|
272
289
|
/* Document-method: push_key
|
@@ -278,9 +295,9 @@ static VALUE str_writer_new(int argc, VALUE *argv, VALUE self) {
|
|
278
295
|
* - *key* [_String_] the key pending for the next push
|
279
296
|
*/
|
280
297
|
static VALUE str_writer_push_key(VALUE self, VALUE key) {
|
281
|
-
StrWriter sw
|
298
|
+
StrWriter sw;
|
299
|
+
TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
|
282
300
|
|
283
|
-
rb_check_type(key, T_STRING);
|
284
301
|
oj_str_writer_push_key(sw, StringValuePtr(key));
|
285
302
|
|
286
303
|
return Qnil;
|
@@ -294,7 +311,8 @@ static VALUE str_writer_push_key(VALUE self, VALUE key) {
|
|
294
311
|
* - *key* [_String_] the key if adding to an object in the JSON document
|
295
312
|
*/
|
296
313
|
static VALUE str_writer_push_object(int argc, VALUE *argv, VALUE self) {
|
297
|
-
StrWriter sw
|
314
|
+
StrWriter sw;
|
315
|
+
TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
|
298
316
|
|
299
317
|
switch (argc) {
|
300
318
|
case 0: oj_str_writer_push_object(sw, 0); break;
|
@@ -302,7 +320,6 @@ static VALUE str_writer_push_object(int argc, VALUE *argv, VALUE self) {
|
|
302
320
|
if (Qnil == argv[0]) {
|
303
321
|
oj_str_writer_push_object(sw, 0);
|
304
322
|
} else {
|
305
|
-
rb_check_type(argv[0], T_STRING);
|
306
323
|
oj_str_writer_push_object(sw, StringValuePtr(argv[0]));
|
307
324
|
}
|
308
325
|
break;
|
@@ -323,7 +340,8 @@ static VALUE str_writer_push_object(int argc, VALUE *argv, VALUE self) {
|
|
323
340
|
* - *key* [_String_] the key if adding to an object in the JSON document
|
324
341
|
*/
|
325
342
|
static VALUE str_writer_push_array(int argc, VALUE *argv, VALUE self) {
|
326
|
-
StrWriter sw
|
343
|
+
StrWriter sw;
|
344
|
+
TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
|
327
345
|
|
328
346
|
switch (argc) {
|
329
347
|
case 0: oj_str_writer_push_array(sw, 0); break;
|
@@ -331,7 +349,6 @@ static VALUE str_writer_push_array(int argc, VALUE *argv, VALUE self) {
|
|
331
349
|
if (Qnil == argv[0]) {
|
332
350
|
oj_str_writer_push_array(sw, 0);
|
333
351
|
} else {
|
334
|
-
rb_check_type(argv[0], T_STRING);
|
335
352
|
oj_str_writer_push_array(sw, StringValuePtr(argv[0]));
|
336
353
|
}
|
337
354
|
break;
|
@@ -352,14 +369,16 @@ static VALUE str_writer_push_array(int argc, VALUE *argv, VALUE self) {
|
|
352
369
|
* - *key* [_String_] the key if adding to an object in the JSON document
|
353
370
|
*/
|
354
371
|
static VALUE str_writer_push_value(int argc, VALUE *argv, VALUE self) {
|
372
|
+
StrWriter sw;
|
373
|
+
TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
|
374
|
+
|
355
375
|
switch (argc) {
|
356
|
-
case 1: oj_str_writer_push_value(
|
376
|
+
case 1: oj_str_writer_push_value(sw, *argv, 0); break;
|
357
377
|
case 2:
|
358
378
|
if (Qnil == argv[1]) {
|
359
|
-
oj_str_writer_push_value(
|
379
|
+
oj_str_writer_push_value(sw, *argv, 0);
|
360
380
|
} else {
|
361
|
-
|
362
|
-
oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, StringValuePtr(argv[1]));
|
381
|
+
oj_str_writer_push_value(sw, *argv, StringValuePtr(argv[1]));
|
363
382
|
}
|
364
383
|
break;
|
365
384
|
default: rb_raise(rb_eArgError, "Wrong number of argument to 'push_value'."); break;
|
@@ -377,17 +396,16 @@ static VALUE str_writer_push_value(int argc, VALUE *argv, VALUE self) {
|
|
377
396
|
* - *key* [_String_] the key if adding to an object in the JSON document
|
378
397
|
*/
|
379
398
|
static VALUE str_writer_push_json(int argc, VALUE *argv, VALUE self) {
|
380
|
-
|
399
|
+
StrWriter sw;
|
400
|
+
TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
|
401
|
+
|
381
402
|
switch (argc) {
|
382
|
-
case 1: oj_str_writer_push_json(
|
403
|
+
case 1: oj_str_writer_push_json(sw, StringValuePtr(*argv), 0); break;
|
383
404
|
case 2:
|
384
405
|
if (Qnil == argv[1]) {
|
385
|
-
oj_str_writer_push_json(
|
406
|
+
oj_str_writer_push_json(sw, StringValuePtr(*argv), 0);
|
386
407
|
} else {
|
387
|
-
|
388
|
-
oj_str_writer_push_json((StrWriter)DATA_PTR(self),
|
389
|
-
StringValuePtr(*argv),
|
390
|
-
StringValuePtr(argv[1]));
|
408
|
+
oj_str_writer_push_json(sw, StringValuePtr(*argv), StringValuePtr(argv[1]));
|
391
409
|
}
|
392
410
|
break;
|
393
411
|
default: rb_raise(rb_eArgError, "Wrong number of argument to 'push_json'."); break;
|
@@ -401,7 +419,10 @@ static VALUE str_writer_push_json(int argc, VALUE *argv, VALUE self) {
|
|
401
419
|
* currently open.
|
402
420
|
*/
|
403
421
|
static VALUE str_writer_pop(VALUE self) {
|
404
|
-
|
422
|
+
StrWriter sw;
|
423
|
+
TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
|
424
|
+
|
425
|
+
oj_str_writer_pop(sw);
|
405
426
|
return Qnil;
|
406
427
|
}
|
407
428
|
|
@@ -412,7 +433,10 @@ static VALUE str_writer_pop(VALUE self) {
|
|
412
433
|
* currently open.
|
413
434
|
*/
|
414
435
|
static VALUE str_writer_pop_all(VALUE self) {
|
415
|
-
|
436
|
+
StrWriter sw;
|
437
|
+
TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
|
438
|
+
|
439
|
+
oj_str_writer_pop_all(sw);
|
416
440
|
|
417
441
|
return Qnil;
|
418
442
|
}
|
@@ -423,7 +447,8 @@ static VALUE str_writer_pop_all(VALUE self) {
|
|
423
447
|
* Reset the writer back to the empty state.
|
424
448
|
*/
|
425
449
|
static VALUE str_writer_reset(VALUE self) {
|
426
|
-
StrWriter sw
|
450
|
+
StrWriter sw;
|
451
|
+
TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
|
427
452
|
|
428
453
|
sw->depth = 0;
|
429
454
|
*sw->types = '\0';
|
@@ -442,23 +467,22 @@ static VALUE str_writer_reset(VALUE self) {
|
|
442
467
|
* *return* [_String_]
|
443
468
|
*/
|
444
469
|
static VALUE str_writer_to_s(VALUE self) {
|
445
|
-
StrWriter sw
|
446
|
-
|
447
|
-
|
448
|
-
return oj_encode(rstr);
|
470
|
+
StrWriter sw;
|
471
|
+
TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
|
472
|
+
return rb_utf8_str_new(sw->out.buf, sw->out.cur - sw->out.buf);
|
449
473
|
}
|
450
474
|
|
451
475
|
/* Document-method: as_json
|
452
|
-
* call-seq: as_json()
|
476
|
+
* call-seq: as_json(*)
|
453
477
|
*
|
454
478
|
* Returns the contents of the writer as a JSON element. If called from inside
|
455
479
|
* an array or hash by Oj the raw buffer will be used othersize a more
|
456
480
|
* inefficient parse of the contents and a return of the result is
|
457
|
-
* completed. The parse uses the strict mode.
|
481
|
+
* completed. The parse uses the strict mode. Optional arguments are ignored.
|
458
482
|
*
|
459
483
|
* *return* [_Hash_|_Array_|_String_|_Integer_|_Float_|_True_|_False_|_nil|)
|
460
484
|
*/
|
461
|
-
static VALUE str_writer_as_json(VALUE self) {
|
485
|
+
static VALUE str_writer_as_json(int argc, VALUE *argv, VALUE self) {
|
462
486
|
if (string_writer_optimized) {
|
463
487
|
return self;
|
464
488
|
}
|
@@ -489,5 +513,5 @@ void oj_string_writer_init(void) {
|
|
489
513
|
rb_define_method(oj_string_writer_class, "reset", str_writer_reset, 0);
|
490
514
|
rb_define_method(oj_string_writer_class, "to_s", str_writer_to_s, 0);
|
491
515
|
rb_define_method(oj_string_writer_class, "raw_json", str_writer_to_s, 0);
|
492
|
-
rb_define_method(oj_string_writer_class, "as_json", str_writer_as_json,
|
516
|
+
rb_define_method(oj_string_writer_class, "as_json", str_writer_as_json, -1);
|
493
517
|
}
|