oj 3.9.1 → 3.16.11
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 +1452 -0
- data/README.md +21 -6
- data/RELEASE_NOTES.md +61 -0
- data/ext/oj/buf.h +50 -68
- data/ext/oj/cache.c +329 -0
- data/ext/oj/cache.h +22 -0
- data/ext/oj/cache8.c +60 -62
- data/ext/oj/cache8.h +9 -36
- data/ext/oj/circarray.c +38 -42
- data/ext/oj/circarray.h +12 -13
- data/ext/oj/code.c +158 -179
- data/ext/oj/code.h +20 -22
- data/ext/oj/compat.c +145 -205
- data/ext/oj/custom.c +740 -880
- data/ext/oj/debug.c +126 -0
- data/ext/oj/dump.c +1145 -844
- data/ext/oj/dump.h +71 -57
- data/ext/oj/dump_compat.c +575 -655
- data/ext/oj/dump_leaf.c +96 -186
- data/ext/oj/dump_object.c +533 -660
- data/ext/oj/dump_strict.c +306 -340
- data/ext/oj/encode.h +4 -33
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/err.c +28 -28
- data/ext/oj/err.h +39 -42
- data/ext/oj/extconf.rb +28 -7
- data/ext/oj/fast.c +1052 -1113
- data/ext/oj/intern.c +313 -0
- data/ext/oj/intern.h +22 -0
- data/ext/oj/mem.c +318 -0
- data/ext/oj/mem.h +53 -0
- data/ext/oj/mimic_json.c +471 -430
- data/ext/oj/object.c +532 -580
- data/ext/oj/odd.c +156 -142
- data/ext/oj/odd.h +25 -26
- data/ext/oj/oj.c +1346 -961
- data/ext/oj/oj.h +307 -290
- data/ext/oj/parse.c +954 -858
- data/ext/oj/parse.h +74 -72
- data/ext/oj/parser.c +1600 -0
- data/ext/oj/parser.h +103 -0
- data/ext/oj/rails.c +819 -836
- data/ext/oj/rails.h +8 -11
- data/ext/oj/reader.c +136 -147
- data/ext/oj/reader.h +69 -83
- data/ext/oj/resolve.c +41 -63
- data/ext/oj/resolve.h +4 -6
- data/ext/oj/rxclass.c +69 -72
- data/ext/oj/rxclass.h +12 -13
- data/ext/oj/saj.c +440 -485
- data/ext/oj/saj2.c +584 -0
- data/ext/oj/saj2.h +23 -0
- data/ext/oj/scp.c +79 -118
- data/ext/oj/simd.h +10 -0
- data/ext/oj/sparse.c +739 -709
- data/ext/oj/stream_writer.c +141 -175
- data/ext/oj/strict.c +103 -128
- data/ext/oj/string_writer.c +244 -261
- data/ext/oj/trace.c +34 -41
- data/ext/oj/trace.h +42 -15
- data/ext/oj/usual.c +1218 -0
- data/ext/oj/usual.h +69 -0
- data/ext/oj/util.c +107 -107
- data/ext/oj/util.h +4 -3
- data/ext/oj/val_stack.c +61 -78
- data/ext/oj/val_stack.h +80 -114
- data/ext/oj/validate.c +46 -0
- data/ext/oj/wab.c +316 -361
- data/lib/oj/active_support_helper.rb +1 -3
- data/lib/oj/bag.rb +8 -1
- data/lib/oj/easy_hash.rb +9 -9
- data/lib/oj/error.rb +1 -2
- data/lib/oj/json.rb +162 -150
- data/lib/oj/mimic.rb +54 -20
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/schandler.rb +5 -4
- data/lib/oj/state.rb +12 -8
- data/lib/oj/version.rb +1 -2
- data/lib/oj.rb +2 -8
- data/pages/Compatibility.md +1 -1
- data/pages/Encoding.md +1 -1
- data/pages/InstallOptions.md +20 -0
- data/pages/JsonGem.md +15 -0
- data/pages/Modes.md +9 -3
- data/pages/Options.md +62 -12
- data/pages/Parser.md +309 -0
- data/pages/Rails.md +73 -22
- metadata +68 -192
- data/ext/oj/hash.c +0 -163
- data/ext/oj/hash.h +0 -46
- data/ext/oj/hash_test.c +0 -512
- 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 -27
- 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/decoding_test.rb +0 -125
- data/test/activesupport5/encoding_test.rb +0 -485
- data/test/activesupport5/encoding_test_cases.rb +0 -90
- data/test/activesupport5/test_helper.rb +0 -50
- data/test/activesupport5/time_zone_test_helpers.rb +0 -24
- data/test/bar.rb +0 -25
- data/test/files.rb +0 -29
- data/test/foo.rb +0 -21
- data/test/helper.rb +0 -26
- 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 -148
- 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 -383
- data/test/json_gem/json_generic_object_test.rb +0 -90
- data/test/json_gem/json_parser_test.rb +0 -470
- data/test/json_gem/json_string_matching_test.rb +0 -42
- data/test/json_gem/test_helper.rb +0 -18
- data/test/perf.rb +0 -107
- data/test/perf_compat.rb +0 -130
- data/test/perf_fast.rb +0 -164
- data/test/perf_file.rb +0 -64
- data/test/perf_object.rb +0 -138
- data/test/perf_saj.rb +0 -109
- data/test/perf_scp.rb +0 -151
- data/test/perf_simple.rb +0 -287
- data/test/perf_strict.rb +0 -145
- data/test/perf_wab.rb +0 -131
- 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 -509
- data/test/test_custom.rb +0 -503
- data/test/test_debian.rb +0 -53
- data/test/test_fast.rb +0 -470
- data/test/test_file.rb +0 -239
- data/test/test_gc.rb +0 -49
- data/test/test_hash.rb +0 -29
- data/test/test_integer_range.rb +0 -73
- data/test/test_null.rb +0 -376
- data/test/test_object.rb +0 -1018
- data/test/test_saj.rb +0 -186
- data/test/test_scp.rb +0 -433
- data/test/test_strict.rb +0 -410
- data/test/test_various.rb +0 -741
- data/test/test_wab.rb +0 -307
- data/test/test_writer.rb +0 -380
- data/test/tests.rb +0 -24
- data/test/tests_mimic.rb +0 -14
- data/test/tests_mimic_addition.rb +0 -7
- data/test/zoo.rb +0 -13
data/ext/oj/string_writer.c
CHANGED
@@ -1,259 +1,259 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
1
|
+
// Copyright (c) 2012, 2017 Peter Ohler. All rights reserved.
|
2
|
+
// Licensed under the MIT License. See LICENSE file in the project root for license details.
|
5
3
|
|
6
4
|
#include "dump.h"
|
7
5
|
#include "encode.h"
|
6
|
+
#include "mem.h"
|
8
7
|
|
9
|
-
extern VALUE
|
8
|
+
extern VALUE Oj;
|
10
9
|
|
11
|
-
bool
|
10
|
+
bool string_writer_optimized = false;
|
12
11
|
|
13
|
-
static void
|
14
|
-
|
15
|
-
DumpType type = sw->types[sw->depth];
|
12
|
+
static void key_check(StrWriter sw, const char *key) {
|
13
|
+
DumpType type = sw->types[sw->depth];
|
16
14
|
|
17
15
|
if (0 == key && (ObjectNew == type || ObjectType == type)) {
|
18
|
-
|
16
|
+
rb_raise(rb_eStandardError, "Can not push onto an Object without a key.");
|
19
17
|
}
|
20
18
|
}
|
21
19
|
|
22
|
-
static void
|
23
|
-
push_type(StrWriter sw, DumpType type) {
|
20
|
+
static void push_type(StrWriter sw, DumpType type) {
|
24
21
|
if (sw->types_end <= sw->types + sw->depth + 1) {
|
25
|
-
|
22
|
+
size_t size = (sw->types_end - sw->types) * 2;
|
26
23
|
|
27
|
-
|
28
|
-
|
24
|
+
OJ_R_REALLOC_N(sw->types, char, size);
|
25
|
+
sw->types_end = sw->types + size;
|
29
26
|
}
|
30
27
|
sw->depth++;
|
31
28
|
sw->types[sw->depth] = type;
|
32
29
|
}
|
33
30
|
|
34
|
-
static void
|
35
|
-
maybe_comma(StrWriter sw) {
|
31
|
+
static void maybe_comma(StrWriter sw) {
|
36
32
|
switch (sw->types[sw->depth]) {
|
37
|
-
case ObjectNew:
|
38
|
-
|
39
|
-
break;
|
40
|
-
case ArrayNew:
|
41
|
-
sw->types[sw->depth] = ArrayType;
|
42
|
-
break;
|
33
|
+
case ObjectNew: sw->types[sw->depth] = ObjectType; break;
|
34
|
+
case ArrayNew: sw->types[sw->depth] = ArrayType; break;
|
43
35
|
case ObjectType:
|
44
36
|
case ArrayType:
|
45
|
-
|
46
|
-
|
47
|
-
|
37
|
+
// Always have a few characters available in the out.buf.
|
38
|
+
*sw->out.cur++ = ',';
|
39
|
+
break;
|
48
40
|
}
|
49
41
|
}
|
50
42
|
|
51
43
|
// Used by stream writer also.
|
52
|
-
void
|
53
|
-
|
54
|
-
sw->
|
55
|
-
sw->
|
56
|
-
sw->types
|
57
|
-
sw->
|
58
|
-
*sw->types = '\0';
|
44
|
+
void oj_str_writer_init(StrWriter sw, int buf_size) {
|
45
|
+
sw->opts = oj_default_options;
|
46
|
+
sw->depth = 0;
|
47
|
+
sw->types = OJ_R_ALLOC_N(char, 256);
|
48
|
+
sw->types_end = sw->types + 256;
|
49
|
+
*sw->types = '\0';
|
59
50
|
sw->keyWritten = 0;
|
60
51
|
|
61
52
|
if (0 == buf_size) {
|
62
|
-
|
53
|
+
buf_size = 4096;
|
63
54
|
} else if (buf_size < 1024) {
|
64
|
-
|
55
|
+
buf_size = 1024;
|
65
56
|
}
|
66
|
-
|
67
|
-
|
57
|
+
// Must be allocated. Using the out.stack_buffer results in double frees
|
58
|
+
// and I haven't figured out why yet.
|
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;
|
68
62
|
sw->out.allocated = true;
|
69
|
-
|
70
|
-
*sw->out.cur
|
63
|
+
|
64
|
+
*sw->out.cur = '\0';
|
71
65
|
sw->out.circ_cache = NULL;
|
72
|
-
sw->out.circ_cnt
|
73
|
-
sw->out.hash_cnt
|
74
|
-
sw->out.opts
|
75
|
-
sw->out.indent
|
76
|
-
sw->out.depth
|
77
|
-
sw->out.argc
|
78
|
-
sw->out.argv
|
79
|
-
sw->out.
|
80
|
-
sw->out.
|
81
|
-
sw->out.omit_nil = oj_default_options.dump_opts.omit_nil;
|
66
|
+
sw->out.circ_cnt = 0;
|
67
|
+
sw->out.hash_cnt = 0;
|
68
|
+
sw->out.opts = &sw->opts;
|
69
|
+
sw->out.indent = sw->opts.indent;
|
70
|
+
sw->out.depth = 0;
|
71
|
+
sw->out.argc = 0;
|
72
|
+
sw->out.argv = NULL;
|
73
|
+
sw->out.ropts = NULL;
|
74
|
+
sw->out.omit_nil = oj_default_options.dump_opts.omit_nil;
|
82
75
|
}
|
83
76
|
|
84
|
-
void
|
85
|
-
|
86
|
-
|
87
|
-
long size;
|
77
|
+
void oj_str_writer_push_key(StrWriter sw, const char *key) {
|
78
|
+
DumpType type = sw->types[sw->depth];
|
79
|
+
long size;
|
88
80
|
|
89
81
|
if (sw->keyWritten) {
|
90
|
-
|
82
|
+
rb_raise(rb_eStandardError, "Can not push more than one key before pushing a non-key.");
|
91
83
|
}
|
92
84
|
if (ObjectNew != type && ObjectType != type) {
|
93
|
-
|
85
|
+
rb_raise(rb_eStandardError, "Can only push a key onto an Object.");
|
94
86
|
}
|
95
87
|
size = sw->depth * sw->out.indent + 3;
|
96
88
|
assure_size(&sw->out, size);
|
97
89
|
maybe_comma(sw);
|
98
90
|
if (0 < sw->depth) {
|
99
|
-
|
91
|
+
fill_indent(&sw->out, sw->depth);
|
100
92
|
}
|
101
93
|
oj_dump_cstr(key, strlen(key), 0, 0, &sw->out);
|
102
94
|
*sw->out.cur++ = ':';
|
103
95
|
sw->keyWritten = 1;
|
104
96
|
}
|
105
97
|
|
106
|
-
void
|
107
|
-
oj_str_writer_push_object(StrWriter sw, const char *key) {
|
98
|
+
void oj_str_writer_push_object(StrWriter sw, const char *key) {
|
108
99
|
if (sw->keyWritten) {
|
109
|
-
|
110
|
-
|
100
|
+
sw->keyWritten = 0;
|
101
|
+
assure_size(&sw->out, 1);
|
111
102
|
} else {
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
103
|
+
long size;
|
104
|
+
|
105
|
+
key_check(sw, key);
|
106
|
+
size = sw->depth * sw->out.indent + 3;
|
107
|
+
assure_size(&sw->out, size);
|
108
|
+
maybe_comma(sw);
|
109
|
+
if (0 < sw->depth) {
|
110
|
+
fill_indent(&sw->out, sw->depth);
|
111
|
+
}
|
112
|
+
if (0 != key) {
|
113
|
+
oj_dump_cstr(key, strlen(key), 0, 0, &sw->out);
|
114
|
+
*sw->out.cur++ = ':';
|
115
|
+
}
|
125
116
|
}
|
126
117
|
*sw->out.cur++ = '{';
|
127
118
|
push_type(sw, ObjectNew);
|
128
119
|
}
|
129
120
|
|
130
|
-
void
|
131
|
-
oj_str_writer_push_array(StrWriter sw, const char *key) {
|
121
|
+
void oj_str_writer_push_array(StrWriter sw, const char *key) {
|
132
122
|
if (sw->keyWritten) {
|
133
|
-
|
134
|
-
|
123
|
+
sw->keyWritten = 0;
|
124
|
+
assure_size(&sw->out, 1);
|
135
125
|
} else {
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
126
|
+
long size;
|
127
|
+
|
128
|
+
key_check(sw, key);
|
129
|
+
size = sw->depth * sw->out.indent + 3;
|
130
|
+
assure_size(&sw->out, size);
|
131
|
+
maybe_comma(sw);
|
132
|
+
if (0 < sw->depth) {
|
133
|
+
fill_indent(&sw->out, sw->depth);
|
134
|
+
}
|
135
|
+
if (0 != key) {
|
136
|
+
oj_dump_cstr(key, strlen(key), 0, 0, &sw->out);
|
137
|
+
*sw->out.cur++ = ':';
|
138
|
+
}
|
149
139
|
}
|
150
140
|
*sw->out.cur++ = '[';
|
151
141
|
push_type(sw, ArrayNew);
|
152
142
|
}
|
153
143
|
|
154
|
-
void
|
155
|
-
|
156
|
-
Out out = &sw->out;
|
144
|
+
void oj_str_writer_push_value(StrWriter sw, VALUE val, const char *key) {
|
145
|
+
Out out = &sw->out;
|
157
146
|
|
158
147
|
if (sw->keyWritten) {
|
159
|
-
|
148
|
+
sw->keyWritten = 0;
|
160
149
|
} else {
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
150
|
+
long size;
|
151
|
+
|
152
|
+
key_check(sw, key);
|
153
|
+
size = sw->depth * out->indent + 3;
|
154
|
+
assure_size(out, size);
|
155
|
+
maybe_comma(sw);
|
156
|
+
if (0 < sw->depth) {
|
157
|
+
fill_indent(&sw->out, sw->depth);
|
158
|
+
}
|
159
|
+
if (0 != key) {
|
160
|
+
oj_dump_cstr(key, strlen(key), 0, 0, out);
|
161
|
+
*out->cur++ = ':';
|
162
|
+
}
|
174
163
|
}
|
175
164
|
switch (out->opts->mode) {
|
176
|
-
case StrictMode:
|
177
|
-
case NullMode:
|
178
|
-
case ObjectMode:
|
179
|
-
case CompatMode:
|
180
|
-
case RailsMode:
|
181
|
-
case CustomMode:
|
182
|
-
default:
|
165
|
+
case StrictMode: oj_dump_strict_val(val, sw->depth, out); break;
|
166
|
+
case NullMode: oj_dump_null_val(val, sw->depth, out); break;
|
167
|
+
case ObjectMode: oj_dump_obj_val(val, sw->depth, out); break;
|
168
|
+
case CompatMode: oj_dump_compat_val(val, sw->depth, out, Yes == out->opts->to_json); break;
|
169
|
+
case RailsMode: oj_dump_rails_val(val, sw->depth, out); break;
|
170
|
+
case CustomMode: oj_dump_custom_val(val, sw->depth, out, true); break;
|
171
|
+
default: oj_dump_custom_val(val, sw->depth, out, true); break;
|
183
172
|
}
|
184
173
|
}
|
185
174
|
|
186
|
-
void
|
187
|
-
oj_str_writer_push_json(StrWriter sw, const char *json, const char *key) {
|
175
|
+
void oj_str_writer_push_json(StrWriter sw, const char *json, const char *key) {
|
188
176
|
if (sw->keyWritten) {
|
189
|
-
|
177
|
+
sw->keyWritten = 0;
|
190
178
|
} else {
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
179
|
+
long size;
|
180
|
+
|
181
|
+
key_check(sw, key);
|
182
|
+
size = sw->depth * sw->out.indent + 3;
|
183
|
+
assure_size(&sw->out, size);
|
184
|
+
maybe_comma(sw);
|
185
|
+
if (0 < sw->depth) {
|
186
|
+
fill_indent(&sw->out, sw->depth);
|
187
|
+
}
|
188
|
+
if (0 != key) {
|
189
|
+
oj_dump_cstr(key, strlen(key), 0, 0, &sw->out);
|
190
|
+
*sw->out.cur++ = ':';
|
191
|
+
}
|
204
192
|
}
|
205
193
|
oj_dump_raw(json, strlen(json), &sw->out);
|
206
194
|
}
|
207
195
|
|
208
|
-
void
|
209
|
-
|
210
|
-
|
211
|
-
DumpType type = sw->types[sw->depth];
|
196
|
+
void oj_str_writer_pop(StrWriter sw) {
|
197
|
+
long size;
|
198
|
+
DumpType type = sw->types[sw->depth];
|
212
199
|
|
213
200
|
if (sw->keyWritten) {
|
214
|
-
|
215
|
-
|
201
|
+
sw->keyWritten = 0;
|
202
|
+
rb_raise(rb_eStandardError, "Can not pop after writing a key but no value.");
|
216
203
|
}
|
217
204
|
sw->depth--;
|
218
205
|
if (0 > sw->depth) {
|
219
|
-
|
206
|
+
rb_raise(rb_eStandardError, "Can not pop with no open array or object.");
|
220
207
|
}
|
221
208
|
size = sw->depth * sw->out.indent + 2;
|
222
209
|
assure_size(&sw->out, size);
|
223
210
|
fill_indent(&sw->out, sw->depth);
|
224
211
|
switch (type) {
|
225
212
|
case ObjectNew:
|
226
|
-
case ObjectType:
|
227
|
-
*sw->out.cur++ = '}';
|
228
|
-
break;
|
213
|
+
case ObjectType: *sw->out.cur++ = '}'; break;
|
229
214
|
case ArrayNew:
|
230
|
-
case ArrayType:
|
231
|
-
*sw->out.cur++ = ']';
|
232
|
-
break;
|
215
|
+
case ArrayType: *sw->out.cur++ = ']'; break;
|
233
216
|
}
|
234
217
|
if (0 == sw->depth && 0 <= sw->out.indent) {
|
235
|
-
|
218
|
+
*sw->out.cur++ = '\n';
|
236
219
|
}
|
237
220
|
}
|
238
221
|
|
239
|
-
void
|
240
|
-
oj_str_writer_pop_all(StrWriter sw) {
|
222
|
+
void oj_str_writer_pop_all(StrWriter sw) {
|
241
223
|
while (0 < sw->depth) {
|
242
|
-
|
224
|
+
oj_str_writer_pop(sw);
|
243
225
|
}
|
244
226
|
}
|
245
227
|
|
246
|
-
static void
|
247
|
-
|
248
|
-
StrWriter sw;
|
228
|
+
static void string_writer_free(void *ptr) {
|
229
|
+
StrWriter sw;
|
249
230
|
|
250
231
|
if (0 == ptr) {
|
251
|
-
|
232
|
+
return;
|
252
233
|
}
|
253
234
|
sw = (StrWriter)ptr;
|
254
|
-
|
255
|
-
|
256
|
-
|
235
|
+
|
236
|
+
oj_out_free(&sw->out);
|
237
|
+
|
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;
|
257
257
|
}
|
258
258
|
|
259
259
|
/* Document-method: new
|
@@ -270,21 +270,20 @@ str_writer_free(void *ptr) {
|
|
270
270
|
* should be.
|
271
271
|
*
|
272
272
|
* - *io* [_IO_] stream to write to
|
273
|
-
* - *options* [_Hash_]
|
273
|
+
* - *options* [_Hash_] formatting options
|
274
274
|
*/
|
275
|
-
static VALUE
|
276
|
-
|
277
|
-
StrWriter sw = ALLOC(struct _strWriter);
|
275
|
+
static VALUE str_writer_new(int argc, VALUE *argv, VALUE self) {
|
276
|
+
StrWriter sw = OJ_R_ALLOC(struct _strWriter);
|
278
277
|
|
279
278
|
oj_str_writer_init(sw, 0);
|
280
279
|
if (1 == argc) {
|
281
|
-
|
280
|
+
oj_parse_options(argv[0], &sw->opts);
|
282
281
|
}
|
283
|
-
sw->out.argc
|
284
|
-
sw->out.argv
|
282
|
+
sw->out.argc = argc - 1;
|
283
|
+
sw->out.argv = argv + 1;
|
285
284
|
sw->out.indent = sw->opts.indent;
|
286
285
|
|
287
|
-
return
|
286
|
+
return TypedData_Wrap_Struct(oj_string_writer_class, &oj_string_writer_type, sw);
|
288
287
|
}
|
289
288
|
|
290
289
|
/* Document-method: push_key
|
@@ -295,11 +294,10 @@ str_writer_new(int argc, VALUE *argv, VALUE self) {
|
|
295
294
|
* the next push then that new key will be ignored.
|
296
295
|
* - *key* [_String_] the key pending for the next push
|
297
296
|
*/
|
298
|
-
static VALUE
|
299
|
-
|
300
|
-
|
297
|
+
static VALUE str_writer_push_key(VALUE self, VALUE key) {
|
298
|
+
StrWriter sw;
|
299
|
+
TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
|
301
300
|
|
302
|
-
rb_check_type(key, T_STRING);
|
303
301
|
oj_str_writer_push_key(sw, StringValuePtr(key));
|
304
302
|
|
305
303
|
return Qnil;
|
@@ -312,29 +310,24 @@ str_writer_push_key(VALUE self, VALUE key) {
|
|
312
310
|
* until a pop() is called.
|
313
311
|
* - *key* [_String_] the key if adding to an object in the JSON document
|
314
312
|
*/
|
315
|
-
static VALUE
|
316
|
-
|
317
|
-
|
313
|
+
static VALUE str_writer_push_object(int argc, VALUE *argv, VALUE self) {
|
314
|
+
StrWriter sw;
|
315
|
+
TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
|
318
316
|
|
319
317
|
switch (argc) {
|
320
|
-
case 0:
|
321
|
-
oj_str_writer_push_object(sw, 0);
|
322
|
-
break;
|
318
|
+
case 0: oj_str_writer_push_object(sw, 0); break;
|
323
319
|
case 1:
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
default:
|
332
|
-
rb_raise(rb_eArgError, "Wrong number of argument to 'push_object'.");
|
333
|
-
break;
|
320
|
+
if (Qnil == argv[0]) {
|
321
|
+
oj_str_writer_push_object(sw, 0);
|
322
|
+
} else {
|
323
|
+
oj_str_writer_push_object(sw, StringValuePtr(argv[0]));
|
324
|
+
}
|
325
|
+
break;
|
326
|
+
default: rb_raise(rb_eArgError, "Wrong number of argument to 'push_object'."); break;
|
334
327
|
}
|
335
328
|
if (rb_block_given_p()) {
|
336
|
-
|
337
|
-
|
329
|
+
rb_yield(Qnil);
|
330
|
+
oj_str_writer_pop(sw);
|
338
331
|
}
|
339
332
|
return Qnil;
|
340
333
|
}
|
@@ -346,29 +339,24 @@ str_writer_push_object(int argc, VALUE *argv, VALUE self) {
|
|
346
339
|
* until a pop() is called.
|
347
340
|
* - *key* [_String_] the key if adding to an object in the JSON document
|
348
341
|
*/
|
349
|
-
static VALUE
|
350
|
-
|
351
|
-
|
342
|
+
static VALUE str_writer_push_array(int argc, VALUE *argv, VALUE self) {
|
343
|
+
StrWriter sw;
|
344
|
+
TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
|
352
345
|
|
353
346
|
switch (argc) {
|
354
|
-
case 0:
|
355
|
-
oj_str_writer_push_array(sw, 0);
|
356
|
-
break;
|
347
|
+
case 0: oj_str_writer_push_array(sw, 0); break;
|
357
348
|
case 1:
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
default:
|
366
|
-
rb_raise(rb_eArgError, "Wrong number of argument to 'push_object'.");
|
367
|
-
break;
|
349
|
+
if (Qnil == argv[0]) {
|
350
|
+
oj_str_writer_push_array(sw, 0);
|
351
|
+
} else {
|
352
|
+
oj_str_writer_push_array(sw, StringValuePtr(argv[0]));
|
353
|
+
}
|
354
|
+
break;
|
355
|
+
default: rb_raise(rb_eArgError, "Wrong number of argument to 'push_object'."); break;
|
368
356
|
}
|
369
357
|
if (rb_block_given_p()) {
|
370
|
-
|
371
|
-
|
358
|
+
rb_yield(Qnil);
|
359
|
+
oj_str_writer_pop(sw);
|
372
360
|
}
|
373
361
|
return Qnil;
|
374
362
|
}
|
@@ -380,23 +368,20 @@ str_writer_push_array(int argc, VALUE *argv, VALUE self) {
|
|
380
368
|
* - *value* [_Object_] value to add to the JSON document
|
381
369
|
* - *key* [_String_] the key if adding to an object in the JSON document
|
382
370
|
*/
|
383
|
-
static VALUE
|
384
|
-
|
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
|
+
|
385
375
|
switch (argc) {
|
386
|
-
case 1:
|
387
|
-
oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, 0);
|
388
|
-
break;
|
376
|
+
case 1: oj_str_writer_push_value(sw, *argv, 0); break;
|
389
377
|
case 2:
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
default:
|
398
|
-
rb_raise(rb_eArgError, "Wrong number of argument to 'push_value'.");
|
399
|
-
break;
|
378
|
+
if (Qnil == argv[1]) {
|
379
|
+
oj_str_writer_push_value(sw, *argv, 0);
|
380
|
+
} else {
|
381
|
+
oj_str_writer_push_value(sw, *argv, StringValuePtr(argv[1]));
|
382
|
+
}
|
383
|
+
break;
|
384
|
+
default: rb_raise(rb_eArgError, "Wrong number of argument to 'push_value'."); break;
|
400
385
|
}
|
401
386
|
return Qnil;
|
402
387
|
}
|
@@ -410,24 +395,20 @@ str_writer_push_value(int argc, VALUE *argv, VALUE self) {
|
|
410
395
|
* - *value* [_Object_] value to add to the JSON document
|
411
396
|
* - *key* [_String_] the key if adding to an object in the JSON document
|
412
397
|
*/
|
413
|
-
static VALUE
|
414
|
-
|
415
|
-
|
398
|
+
static VALUE str_writer_push_json(int argc, VALUE *argv, VALUE self) {
|
399
|
+
StrWriter sw;
|
400
|
+
TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
|
401
|
+
|
416
402
|
switch (argc) {
|
417
|
-
case 1:
|
418
|
-
oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), 0);
|
419
|
-
break;
|
403
|
+
case 1: oj_str_writer_push_json(sw, StringValuePtr(*argv), 0); break;
|
420
404
|
case 2:
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
default:
|
429
|
-
rb_raise(rb_eArgError, "Wrong number of argument to 'push_json'.");
|
430
|
-
break;
|
405
|
+
if (Qnil == argv[1]) {
|
406
|
+
oj_str_writer_push_json(sw, StringValuePtr(*argv), 0);
|
407
|
+
} else {
|
408
|
+
oj_str_writer_push_json(sw, StringValuePtr(*argv), StringValuePtr(argv[1]));
|
409
|
+
}
|
410
|
+
break;
|
411
|
+
default: rb_raise(rb_eArgError, "Wrong number of argument to 'push_json'."); break;
|
431
412
|
}
|
432
413
|
return Qnil;
|
433
414
|
}
|
@@ -437,9 +418,11 @@ str_writer_push_json(int argc, VALUE *argv, VALUE self) {
|
|
437
418
|
* Pops up a level in the JSON document closing the array or object that is
|
438
419
|
* currently open.
|
439
420
|
*/
|
440
|
-
static VALUE
|
441
|
-
|
442
|
-
|
421
|
+
static VALUE str_writer_pop(VALUE self) {
|
422
|
+
StrWriter sw;
|
423
|
+
TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
|
424
|
+
|
425
|
+
oj_str_writer_pop(sw);
|
443
426
|
return Qnil;
|
444
427
|
}
|
445
428
|
|
@@ -449,9 +432,11 @@ str_writer_pop(VALUE self) {
|
|
449
432
|
* Pops all level in the JSON document closing all the array or object that is
|
450
433
|
* currently open.
|
451
434
|
*/
|
452
|
-
static VALUE
|
453
|
-
|
454
|
-
|
435
|
+
static VALUE str_writer_pop_all(VALUE self) {
|
436
|
+
StrWriter sw;
|
437
|
+
TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
|
438
|
+
|
439
|
+
oj_str_writer_pop_all(sw);
|
455
440
|
|
456
441
|
return Qnil;
|
457
442
|
}
|
@@ -461,15 +446,15 @@ str_writer_pop_all(VALUE self) {
|
|
461
446
|
*
|
462
447
|
* Reset the writer back to the empty state.
|
463
448
|
*/
|
464
|
-
static VALUE
|
465
|
-
|
466
|
-
|
449
|
+
static VALUE str_writer_reset(VALUE self) {
|
450
|
+
StrWriter sw;
|
451
|
+
TypedData_Get_Struct(self, struct _strWriter, &oj_string_writer_type, sw);
|
467
452
|
|
468
|
-
sw->depth
|
469
|
-
*sw->types
|
453
|
+
sw->depth = 0;
|
454
|
+
*sw->types = '\0';
|
470
455
|
sw->keyWritten = 0;
|
471
|
-
sw->out.cur
|
472
|
-
*sw->out.cur
|
456
|
+
sw->out.cur = sw->out.buf;
|
457
|
+
*sw->out.cur = '\0';
|
473
458
|
|
474
459
|
return Qnil;
|
475
460
|
}
|
@@ -481,28 +466,25 @@ str_writer_reset(VALUE self) {
|
|
481
466
|
*
|
482
467
|
* *return* [_String_]
|
483
468
|
*/
|
484
|
-
static VALUE
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
return oj_encode(rstr);
|
469
|
+
static VALUE str_writer_to_s(VALUE self) {
|
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);
|
490
473
|
}
|
491
474
|
|
492
475
|
/* Document-method: as_json
|
493
|
-
* call-seq: as_json()
|
476
|
+
* call-seq: as_json(*)
|
494
477
|
*
|
495
478
|
* Returns the contents of the writer as a JSON element. If called from inside
|
496
479
|
* an array or hash by Oj the raw buffer will be used othersize a more
|
497
480
|
* inefficient parse of the contents and a return of the result is
|
498
|
-
* completed. The parse uses the
|
481
|
+
* completed. The parse uses the strict mode. Optional arguments are ignored.
|
499
482
|
*
|
500
483
|
* *return* [_Hash_|_Array_|_String_|_Integer_|_Float_|_True_|_False_|_nil|)
|
501
484
|
*/
|
502
|
-
static VALUE
|
503
|
-
str_writer_as_json(VALUE self) {
|
485
|
+
static VALUE str_writer_as_json(int argc, VALUE *argv, VALUE self) {
|
504
486
|
if (string_writer_optimized) {
|
505
|
-
|
487
|
+
return self;
|
506
488
|
}
|
507
489
|
return rb_hash_new();
|
508
490
|
}
|
@@ -513,12 +495,13 @@ str_writer_as_json(VALUE self) {
|
|
513
495
|
* by pushing values into the document. Pushing an array or an object will
|
514
496
|
* create that element in the JSON document and subsequent pushes will add the
|
515
497
|
* elements to that array or object until a pop() is called. When complete
|
516
|
-
* calling to_s() will return the JSON document. Note
|
498
|
+
* calling to_s() will return the JSON document. Note that calling to_s() before
|
517
499
|
* construction is complete will return the document in it's current state.
|
518
500
|
*/
|
519
|
-
void
|
520
|
-
oj_string_writer_init() {
|
501
|
+
void oj_string_writer_init(void) {
|
521
502
|
oj_string_writer_class = rb_define_class_under(Oj, "StringWriter", rb_cObject);
|
503
|
+
rb_gc_register_address(&oj_string_writer_class);
|
504
|
+
rb_undef_alloc_func(oj_string_writer_class);
|
522
505
|
rb_define_module_function(oj_string_writer_class, "new", str_writer_new, -1);
|
523
506
|
rb_define_method(oj_string_writer_class, "push_key", str_writer_push_key, 1);
|
524
507
|
rb_define_method(oj_string_writer_class, "push_object", str_writer_push_object, -1);
|
@@ -530,5 +513,5 @@ oj_string_writer_init() {
|
|
530
513
|
rb_define_method(oj_string_writer_class, "reset", str_writer_reset, 0);
|
531
514
|
rb_define_method(oj_string_writer_class, "to_s", str_writer_to_s, 0);
|
532
515
|
rb_define_method(oj_string_writer_class, "raw_json", str_writer_to_s, 0);
|
533
|
-
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);
|
534
517
|
}
|