oj 2.18.5 → 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 +5 -5
- data/CHANGELOG.md +1452 -0
- data/README.md +53 -221
- data/RELEASE_NOTES.md +61 -0
- data/ext/oj/buf.h +54 -72
- data/ext/oj/cache.c +329 -0
- data/ext/oj/cache.h +22 -0
- data/ext/oj/cache8.c +61 -63
- data/ext/oj/cache8.h +12 -39
- data/ext/oj/circarray.c +38 -67
- data/ext/oj/circarray.h +16 -42
- data/ext/oj/code.c +214 -0
- data/ext/oj/code.h +40 -0
- data/ext/oj/compat.c +194 -110
- data/ext/oj/custom.c +1074 -0
- data/ext/oj/debug.c +126 -0
- data/ext/oj/dump.c +1276 -2494
- data/ext/oj/dump.h +110 -0
- data/ext/oj/dump_compat.c +897 -0
- data/ext/oj/dump_leaf.c +162 -0
- data/ext/oj/dump_object.c +710 -0
- data/ext/oj/dump_strict.c +399 -0
- data/ext/oj/encode.h +7 -42
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/err.c +28 -53
- data/ext/oj/err.h +49 -46
- data/ext/oj/extconf.rb +33 -32
- data/ext/oj/fast.c +1082 -1098
- 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 +919 -0
- data/ext/oj/object.c +545 -625
- data/ext/oj/odd.c +158 -168
- data/ext/oj/odd.h +32 -58
- data/ext/oj/oj.c +1727 -2080
- data/ext/oj/oj.h +334 -259
- data/ext/oj/parse.c +974 -753
- data/ext/oj/parse.h +97 -90
- data/ext/oj/parser.c +1600 -0
- data/ext/oj/parser.h +103 -0
- data/ext/oj/rails.c +1478 -0
- data/ext/oj/rails.h +18 -0
- data/ext/oj/reader.c +136 -163
- data/ext/oj/reader.h +76 -112
- data/ext/oj/resolve.c +45 -94
- data/ext/oj/resolve.h +7 -34
- data/ext/oj/rxclass.c +144 -0
- data/ext/oj/rxclass.h +26 -0
- data/ext/oj/saj.c +445 -511
- data/ext/oj/saj2.c +584 -0
- data/ext/oj/saj2.h +23 -0
- data/ext/oj/scp.c +82 -143
- data/ext/oj/simd.h +10 -0
- data/ext/oj/sparse.c +749 -644
- data/ext/oj/stream_writer.c +329 -0
- data/ext/oj/strict.c +114 -112
- data/ext/oj/string_writer.c +517 -0
- data/ext/oj/trace.c +72 -0
- data/ext/oj/trace.h +55 -0
- data/ext/oj/usual.c +1218 -0
- data/ext/oj/usual.h +69 -0
- data/ext/oj/util.c +136 -0
- data/ext/oj/util.h +20 -0
- data/ext/oj/val_stack.c +75 -72
- data/ext/oj/val_stack.h +94 -127
- data/ext/oj/validate.c +46 -0
- data/ext/oj/wab.c +586 -0
- data/lib/oj/active_support_helper.rb +1 -3
- data/lib/oj/bag.rb +8 -1
- data/lib/oj/easy_hash.rb +21 -13
- data/lib/oj/error.rb +10 -12
- data/lib/oj/json.rb +188 -0
- data/lib/oj/mimic.rb +165 -26
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/schandler.rb +5 -4
- data/lib/oj/state.rb +135 -0
- data/lib/oj/version.rb +2 -3
- data/lib/oj.rb +3 -31
- data/pages/Advanced.md +22 -0
- data/pages/Compatibility.md +25 -0
- data/pages/Custom.md +23 -0
- data/pages/Encoding.md +65 -0
- data/pages/InstallOptions.md +20 -0
- data/pages/JsonGem.md +94 -0
- data/pages/Modes.md +161 -0
- data/pages/Options.md +337 -0
- data/pages/Parser.md +309 -0
- data/pages/Rails.md +167 -0
- data/pages/Security.md +20 -0
- data/pages/WAB.md +13 -0
- metadata +126 -163
- 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/activesupport_datetime_test.rb +0 -23
- data/test/bug.rb +0 -51
- data/test/bug2.rb +0 -10
- data/test/bug3.rb +0 -46
- data/test/bug_fast.rb +0 -32
- data/test/bug_load.rb +0 -24
- data/test/crash.rb +0 -111
- data/test/curl/curl_oj.rb +0 -46
- data/test/curl/get_oj.rb +0 -24
- data/test/curl/just_curl.rb +0 -31
- data/test/curl/just_oj.rb +0 -51
- data/test/example.rb +0 -11
- data/test/files.rb +0 -29
- data/test/foo.rb +0 -24
- data/test/helper.rb +0 -27
- data/test/io.rb +0 -48
- data/test/isolated/shared.rb +0 -310
- 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_rails_datetime.rb +0 -27
- data/test/isolated/test_mimic_redefine.rb +0 -15
- data/test/mod.rb +0 -16
- data/test/perf.rb +0 -107
- data/test/perf_compat.rb +0 -128
- 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 -128
- data/test/rails.rb +0 -50
- data/test/russian.rb +0 -18
- 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 -55
- data/test/sample_json.rb +0 -37
- data/test/struct.rb +0 -29
- data/test/test_compat.rb +0 -398
- data/test/test_debian.rb +0 -53
- data/test/test_fast.rb +0 -458
- data/test/test_file.rb +0 -245
- data/test/test_gc.rb +0 -49
- data/test/test_hash.rb +0 -29
- data/test/test_object.rb +0 -745
- data/test/test_saj.rb +0 -186
- data/test/test_scp.rb +0 -396
- data/test/test_serializer.rb +0 -59
- data/test/test_strict.rb +0 -254
- data/test/test_various.rb +0 -1383
- data/test/test_writer.rb +0 -308
- data/test/write_timebars.rb +0 -31
data/ext/oj/rails.h
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
// Copyright (c) 2017 Peter Ohler. All rights reserved.
|
2
|
+
// Licensed under the MIT License. See LICENSE file in the project root for license details.
|
3
|
+
|
4
|
+
#ifndef OJ_RAILS_H
|
5
|
+
#define OJ_RAILS_H
|
6
|
+
|
7
|
+
#include "dump.h"
|
8
|
+
|
9
|
+
extern void oj_mimic_rails_init(void);
|
10
|
+
extern ROpt oj_rails_get_opt(ROptTable rot, VALUE clas);
|
11
|
+
|
12
|
+
extern bool oj_rails_hash_opt;
|
13
|
+
extern bool oj_rails_array_opt;
|
14
|
+
extern bool oj_rails_float_opt;
|
15
|
+
|
16
|
+
extern VALUE oj_optimize_rails(VALUE self);
|
17
|
+
|
18
|
+
#endif /* OJ_RAILS_H */
|
data/ext/oj/reader.c
CHANGED
@@ -1,239 +1,212 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
* All rights reserved.
|
4
|
-
*
|
5
|
-
* Redistribution and use in source and binary forms, with or without
|
6
|
-
* modification, are permitted provided that the following conditions are met:
|
7
|
-
*
|
8
|
-
* - Redistributions of source code must retain the above copyright notice, this
|
9
|
-
* list of conditions and the following disclaimer.
|
10
|
-
*
|
11
|
-
* - Redistributions in binary form must reproduce the above copyright notice,
|
12
|
-
* this list of conditions and the following disclaimer in the documentation
|
13
|
-
* and/or other materials provided with the distribution.
|
14
|
-
*
|
15
|
-
* - Neither the name of Peter Ohler nor the names of its contributors may be
|
16
|
-
* used to endorse or promote products derived from this software without
|
17
|
-
* specific prior written permission.
|
18
|
-
*
|
19
|
-
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
-
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
-
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
22
|
-
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
23
|
-
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
24
|
-
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
25
|
-
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
26
|
-
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
27
|
-
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
|
-
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
-
*/
|
1
|
+
// Copyright (c) 2011 Peter Ohler. All rights reserved.
|
2
|
+
// Licensed under the MIT License. See LICENSE file in the project root for license details.
|
30
3
|
|
31
|
-
#include <stdlib.h>
|
32
4
|
#include <errno.h>
|
33
5
|
#include <stdio.h>
|
6
|
+
#include <stdlib.h>
|
34
7
|
#include <strings.h>
|
35
8
|
#include <sys/types.h>
|
9
|
+
#ifdef NEEDS_UIO
|
36
10
|
#if NEEDS_UIO
|
37
|
-
#include <sys/uio.h>
|
11
|
+
#include <sys/uio.h>
|
12
|
+
#endif
|
38
13
|
#endif
|
39
|
-
#include <unistd.h>
|
40
14
|
#include <time.h>
|
15
|
+
#include <unistd.h>
|
41
16
|
|
42
|
-
#include "
|
17
|
+
#include "mem.h"
|
43
18
|
#include "oj.h"
|
44
19
|
#include "reader.h"
|
20
|
+
#include "ruby.h"
|
45
21
|
|
46
|
-
#define BUF_PAD
|
47
|
-
|
48
|
-
static VALUE
|
49
|
-
static VALUE
|
50
|
-
static VALUE
|
51
|
-
static int
|
52
|
-
static int
|
53
|
-
static int
|
54
|
-
//static int read_from_str(Reader reader);
|
55
|
-
|
56
|
-
void
|
57
|
-
|
58
|
-
VALUE
|
59
|
-
VALUE
|
60
|
-
|
61
|
-
|
62
|
-
reader->head =
|
63
|
-
|
64
|
-
reader->
|
65
|
-
reader->
|
66
|
-
reader->
|
67
|
-
reader->
|
68
|
-
reader->
|
69
|
-
reader->line
|
70
|
-
reader->col
|
71
|
-
reader->free_head
|
22
|
+
#define BUF_PAD 4
|
23
|
+
|
24
|
+
static VALUE rescue_cb(VALUE rdr, VALUE err);
|
25
|
+
static VALUE io_cb(VALUE rdr);
|
26
|
+
static VALUE partial_io_cb(VALUE rdr);
|
27
|
+
static int read_from_io(Reader reader);
|
28
|
+
static int read_from_fd(Reader reader);
|
29
|
+
static int read_from_io_partial(Reader reader);
|
30
|
+
// static int read_from_str(Reader reader);
|
31
|
+
|
32
|
+
void oj_reader_init(Reader reader, VALUE io, int fd, bool to_s) {
|
33
|
+
VALUE io_class = rb_obj_class(io);
|
34
|
+
VALUE stat;
|
35
|
+
VALUE ftype;
|
36
|
+
|
37
|
+
reader->head = reader->base;
|
38
|
+
*((char *)reader->head) = '\0';
|
39
|
+
reader->end = reader->head + sizeof(reader->base) - BUF_PAD;
|
40
|
+
reader->tail = reader->head;
|
41
|
+
reader->read_end = reader->head;
|
42
|
+
reader->pro = 0;
|
43
|
+
reader->str = 0;
|
44
|
+
reader->pos = 0;
|
45
|
+
reader->line = 1;
|
46
|
+
reader->col = 0;
|
47
|
+
reader->free_head = 0;
|
72
48
|
|
73
49
|
if (0 != fd) {
|
74
|
-
|
75
|
-
|
50
|
+
reader->read_func = read_from_fd;
|
51
|
+
reader->fd = fd;
|
76
52
|
} else if (rb_cString == io_class) {
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
53
|
+
reader->read_func = 0;
|
54
|
+
reader->in_str = StringValuePtr(io);
|
55
|
+
reader->head = (char *)reader->in_str;
|
56
|
+
reader->tail = reader->head;
|
57
|
+
reader->read_end = reader->head + RSTRING_LEN(io);
|
82
58
|
} else if (oj_stringio_class == io_class) {
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
} else if (rb_cFile == io_class &&
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
reader->read_func = read_from_fd;
|
96
|
-
reader->fd = FIX2INT(rb_funcall(io, oj_fileno_id, 0));
|
59
|
+
VALUE s = rb_funcall2(io, oj_string_id, 0, 0);
|
60
|
+
|
61
|
+
reader->read_func = 0;
|
62
|
+
reader->in_str = StringValuePtr(s);
|
63
|
+
reader->head = (char *)reader->in_str;
|
64
|
+
reader->tail = reader->head;
|
65
|
+
reader->read_end = reader->head + RSTRING_LEN(s);
|
66
|
+
} else if (rb_cFile == io_class && Qnil != (stat = rb_funcall(io, oj_stat_id, 0)) &&
|
67
|
+
Qnil != (ftype = rb_funcall(stat, oj_ftype_id, 0)) && 0 == strcmp("file", StringValuePtr(ftype)) &&
|
68
|
+
0 == FIX2INT(rb_funcall(io, oj_pos_id, 0))) {
|
69
|
+
reader->read_func = read_from_fd;
|
70
|
+
reader->fd = FIX2INT(rb_funcall(io, oj_fileno_id, 0));
|
97
71
|
} else if (rb_respond_to(io, oj_readpartial_id)) {
|
98
|
-
|
99
|
-
|
72
|
+
reader->read_func = read_from_io_partial;
|
73
|
+
reader->io = io;
|
100
74
|
} else if (rb_respond_to(io, oj_read_id)) {
|
101
|
-
|
102
|
-
|
75
|
+
reader->read_func = read_from_io;
|
76
|
+
reader->io = io;
|
77
|
+
} else if (to_s) {
|
78
|
+
volatile VALUE rstr = oj_safe_string_convert(io);
|
79
|
+
|
80
|
+
reader->read_func = 0;
|
81
|
+
reader->in_str = StringValuePtr(rstr);
|
82
|
+
reader->head = (char *)reader->in_str;
|
83
|
+
reader->tail = reader->head;
|
84
|
+
reader->read_end = reader->head + RSTRING_LEN(rstr);
|
103
85
|
} else {
|
104
|
-
|
86
|
+
rb_raise(rb_eArgError, "parser io argument must be a String or respond to readpartial() or read().\n");
|
105
87
|
}
|
106
88
|
}
|
107
89
|
|
108
|
-
int
|
109
|
-
|
110
|
-
|
111
|
-
size_t shift = 0;
|
90
|
+
int oj_reader_read(Reader reader) {
|
91
|
+
int err;
|
92
|
+
size_t shift = 0;
|
112
93
|
|
113
94
|
if (0 == reader->read_func) {
|
114
|
-
|
95
|
+
return -1;
|
115
96
|
}
|
116
97
|
// if there is not much room to read into, shift or realloc a larger buffer.
|
117
98
|
if (reader->head < reader->tail && 4096 > reader->end - reader->tail) {
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
99
|
+
if (0 == reader->pro) {
|
100
|
+
shift = reader->tail - reader->head;
|
101
|
+
} else {
|
102
|
+
shift = reader->pro - reader->head - 1; // leave one character so we can backup one
|
103
|
+
}
|
104
|
+
if (0 >= shift) { /* no space left so allocate more */
|
105
|
+
const char *old = reader->head;
|
106
|
+
size_t size = reader->end - reader->head + BUF_PAD;
|
107
|
+
|
108
|
+
if (reader->head == reader->base) {
|
109
|
+
reader->head = OJ_R_ALLOC_N(char, size * 2);
|
110
|
+
memcpy((char *)reader->head, old, size);
|
111
|
+
} else {
|
112
|
+
OJ_R_REALLOC_N(reader->head, char, size * 2);
|
113
|
+
}
|
114
|
+
reader->free_head = 1;
|
115
|
+
reader->end = reader->head + size * 2 - BUF_PAD;
|
116
|
+
reader->tail = reader->head + (reader->tail - old);
|
117
|
+
reader->read_end = reader->head + (reader->read_end - old);
|
118
|
+
if (0 != reader->pro) {
|
119
|
+
reader->pro = reader->head + (reader->pro - old);
|
120
|
+
}
|
121
|
+
if (0 != reader->str) {
|
122
|
+
reader->str = reader->head + (reader->str - old);
|
123
|
+
}
|
124
|
+
} else {
|
125
|
+
memmove((char *)reader->head, reader->head + shift, reader->read_end - (reader->head + shift));
|
126
|
+
reader->tail -= shift;
|
127
|
+
reader->read_end -= shift;
|
128
|
+
if (0 != reader->pro) {
|
129
|
+
reader->pro -= shift;
|
130
|
+
}
|
131
|
+
if (0 != reader->str) {
|
132
|
+
reader->str -= shift;
|
133
|
+
}
|
134
|
+
}
|
154
135
|
}
|
155
|
-
err
|
156
|
-
*(char*)reader->read_end = '\0';
|
136
|
+
err = reader->read_func(reader);
|
137
|
+
*(char *)reader->read_end = '\0';
|
157
138
|
|
158
139
|
return err;
|
159
140
|
}
|
160
141
|
|
161
|
-
static VALUE
|
162
|
-
|
163
|
-
VALUE clas = rb_obj_class(err);
|
142
|
+
static VALUE rescue_cb(VALUE rbuf, VALUE err) {
|
143
|
+
VALUE clas = rb_obj_class(err);
|
164
144
|
|
165
145
|
if (rb_eTypeError != clas && rb_eEOFError != clas) {
|
166
|
-
|
146
|
+
Reader reader = (Reader)rbuf;
|
167
147
|
|
168
|
-
|
148
|
+
rb_raise(clas, "at line %d, column %d\n", reader->line, reader->col);
|
169
149
|
}
|
170
150
|
return Qfalse;
|
171
151
|
}
|
172
152
|
|
173
|
-
static VALUE
|
174
|
-
|
175
|
-
|
176
|
-
VALUE
|
177
|
-
|
178
|
-
|
179
|
-
size_t cnt;
|
153
|
+
static VALUE partial_io_cb(VALUE rbuf) {
|
154
|
+
Reader reader = (Reader)rbuf;
|
155
|
+
VALUE args[1];
|
156
|
+
VALUE rstr;
|
157
|
+
char *str;
|
158
|
+
size_t cnt;
|
180
159
|
|
181
160
|
args[0] = ULONG2NUM(reader->end - reader->tail);
|
182
|
-
rstr
|
161
|
+
rstr = rb_funcall2(reader->io, oj_readpartial_id, 1, args);
|
183
162
|
if (Qnil == rstr) {
|
184
|
-
|
163
|
+
return Qfalse;
|
185
164
|
}
|
186
165
|
str = StringValuePtr(rstr);
|
187
166
|
cnt = RSTRING_LEN(rstr);
|
188
|
-
//printf("*** partial read %lu bytes, str: '%s'\n", cnt, str);
|
189
167
|
strcpy(reader->tail, str);
|
190
168
|
reader->read_end = reader->tail + cnt;
|
191
169
|
|
192
170
|
return Qtrue;
|
193
171
|
}
|
194
172
|
|
195
|
-
static VALUE
|
196
|
-
|
197
|
-
|
198
|
-
VALUE
|
199
|
-
|
200
|
-
|
201
|
-
size_t cnt;
|
173
|
+
static VALUE io_cb(VALUE rbuf) {
|
174
|
+
Reader reader = (Reader)rbuf;
|
175
|
+
VALUE args[1];
|
176
|
+
VALUE rstr;
|
177
|
+
char *str;
|
178
|
+
size_t cnt;
|
202
179
|
|
203
180
|
args[0] = ULONG2NUM(reader->end - reader->tail);
|
204
|
-
rstr
|
181
|
+
rstr = rb_funcall2(reader->io, oj_read_id, 1, args);
|
205
182
|
if (Qnil == rstr) {
|
206
|
-
|
183
|
+
return Qfalse;
|
207
184
|
}
|
208
185
|
str = StringValuePtr(rstr);
|
209
186
|
cnt = RSTRING_LEN(rstr);
|
210
|
-
//printf("*** read %lu bytes, str: '%s'\n", cnt, str);
|
211
187
|
strcpy(reader->tail, str);
|
212
188
|
reader->read_end = reader->tail + cnt;
|
213
189
|
|
214
190
|
return Qtrue;
|
215
191
|
}
|
216
192
|
|
217
|
-
static int
|
218
|
-
read_from_io_partial(Reader reader) {
|
193
|
+
static int read_from_io_partial(Reader reader) {
|
219
194
|
return (Qfalse == rb_rescue(partial_io_cb, (VALUE)reader, rescue_cb, (VALUE)reader));
|
220
195
|
}
|
221
196
|
|
222
|
-
static int
|
223
|
-
read_from_io(Reader reader) {
|
197
|
+
static int read_from_io(Reader reader) {
|
224
198
|
return (Qfalse == rb_rescue(io_cb, (VALUE)reader, rescue_cb, (VALUE)reader));
|
225
199
|
}
|
226
200
|
|
227
|
-
static int
|
228
|
-
|
229
|
-
|
230
|
-
size_t max = reader->end - reader->tail;
|
201
|
+
static int read_from_fd(Reader reader) {
|
202
|
+
ssize_t cnt;
|
203
|
+
size_t max = reader->end - reader->tail;
|
231
204
|
|
232
205
|
cnt = read(reader->fd, reader->tail, max);
|
233
206
|
if (cnt <= 0) {
|
234
|
-
|
207
|
+
return -1;
|
235
208
|
} else if (0 != cnt) {
|
236
|
-
|
209
|
+
reader->read_end = reader->tail + cnt;
|
237
210
|
}
|
238
211
|
return 0;
|
239
212
|
}
|
data/ext/oj/reader.h
CHANGED
@@ -1,114 +1,86 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
* modification, are permitted provided that the following conditions are met:
|
7
|
-
*
|
8
|
-
* - Redistributions of source code must retain the above copyright notice, this
|
9
|
-
* list of conditions and the following disclaimer.
|
10
|
-
*
|
11
|
-
* - Redistributions in binary form must reproduce the above copyright notice,
|
12
|
-
* this list of conditions and the following disclaimer in the documentation
|
13
|
-
* and/or other materials provided with the distribution.
|
14
|
-
*
|
15
|
-
* - Neither the name of Peter Ohler nor the names of its contributors may be
|
16
|
-
* used to endorse or promote products derived from this software without
|
17
|
-
* specific prior written permission.
|
18
|
-
*
|
19
|
-
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
-
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
-
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
22
|
-
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
23
|
-
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
24
|
-
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
25
|
-
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
26
|
-
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
27
|
-
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
|
-
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
-
*/
|
1
|
+
// Copyright (c) 2011 Peter Ohler. All rights reserved.
|
2
|
+
// Licensed under the MIT License. See LICENSE file in the project root for license details.
|
3
|
+
|
4
|
+
#ifndef OJ_READER_H
|
5
|
+
#define OJ_READER_H
|
30
6
|
|
31
|
-
#
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
char
|
36
|
-
char
|
37
|
-
char
|
38
|
-
char
|
39
|
-
char
|
40
|
-
char
|
41
|
-
|
42
|
-
int
|
43
|
-
int
|
44
|
-
int
|
45
|
-
int
|
7
|
+
#include "mem.h"
|
8
|
+
|
9
|
+
typedef struct _reader {
|
10
|
+
char base[0x00001000];
|
11
|
+
char *head;
|
12
|
+
char *end;
|
13
|
+
char *tail;
|
14
|
+
char *read_end; /* one past last character read */
|
15
|
+
char *pro; /* protection start, buffer can not slide past this point */
|
16
|
+
char *str; /* start of current string being read */
|
17
|
+
long pos;
|
18
|
+
int line;
|
19
|
+
int col;
|
20
|
+
int free_head;
|
21
|
+
int (*read_func)(struct _reader *reader);
|
46
22
|
union {
|
47
|
-
|
48
|
-
|
49
|
-
|
23
|
+
int fd;
|
24
|
+
VALUE io;
|
25
|
+
const char *in_str;
|
50
26
|
};
|
51
27
|
} *Reader;
|
52
28
|
|
53
|
-
extern void
|
54
|
-
extern int
|
29
|
+
extern void oj_reader_init(Reader reader, VALUE io, int fd, bool to_s);
|
30
|
+
extern int oj_reader_read(Reader reader);
|
55
31
|
|
56
|
-
static inline char
|
57
|
-
|
58
|
-
//
|
32
|
+
static inline char reader_get(Reader reader) {
|
33
|
+
// printf("*** drive get from '%s' from start: %ld buf: %p from read_end: %ld\n",
|
34
|
+
// reader->tail, reader->tail - reader->head, reader->head, reader->read_end - reader->tail);
|
59
35
|
if (reader->read_end <= reader->tail) {
|
60
|
-
|
61
|
-
|
62
|
-
|
36
|
+
if (0 != oj_reader_read(reader)) {
|
37
|
+
return '\0';
|
38
|
+
}
|
63
39
|
}
|
64
40
|
if ('\n' == *reader->tail) {
|
65
|
-
|
66
|
-
|
41
|
+
reader->line++;
|
42
|
+
reader->col = 0;
|
67
43
|
}
|
68
44
|
reader->col++;
|
69
|
-
|
45
|
+
reader->pos++;
|
46
|
+
|
70
47
|
return *reader->tail++;
|
71
48
|
}
|
72
49
|
|
73
|
-
static inline void
|
74
|
-
reader_backup(Reader reader) {
|
50
|
+
static inline void reader_backup(Reader reader) {
|
75
51
|
reader->tail--;
|
76
52
|
reader->col--;
|
53
|
+
reader->pos--;
|
77
54
|
if (0 >= reader->col) {
|
78
|
-
|
79
|
-
|
55
|
+
reader->line--;
|
56
|
+
// allow col to be negative since we never backup twice in a row
|
80
57
|
}
|
81
58
|
}
|
82
59
|
|
83
|
-
static inline void
|
84
|
-
reader_protect(Reader reader) {
|
60
|
+
static inline void reader_protect(Reader reader) {
|
85
61
|
reader->pro = reader->tail;
|
86
|
-
reader->str = reader->tail;
|
62
|
+
reader->str = reader->tail; // can't have str before pro
|
87
63
|
}
|
88
64
|
|
89
|
-
static inline void
|
90
|
-
reader_release(Reader reader) {
|
65
|
+
static inline void reader_release(Reader reader) {
|
91
66
|
reader->pro = 0;
|
92
67
|
}
|
93
68
|
|
94
69
|
/* Starts by reading a character so it is safe to use with an empty or
|
95
70
|
* compacted buffer.
|
96
71
|
*/
|
97
|
-
static inline char
|
98
|
-
|
99
|
-
char c;
|
72
|
+
static inline char reader_next_non_white(Reader reader) {
|
73
|
+
char c;
|
100
74
|
|
101
75
|
while ('\0' != (c = reader_get(reader))) {
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
return c;
|
111
|
-
}
|
76
|
+
switch (c) {
|
77
|
+
case ' ':
|
78
|
+
case '\t':
|
79
|
+
case '\f':
|
80
|
+
case '\n':
|
81
|
+
case '\r': break;
|
82
|
+
default: return c;
|
83
|
+
}
|
112
84
|
}
|
113
85
|
return '\0';
|
114
86
|
}
|
@@ -116,58 +88,50 @@ reader_next_non_white(Reader reader) {
|
|
116
88
|
/* Starts by reading a character so it is safe to use with an empty or
|
117
89
|
* compacted buffer.
|
118
90
|
*/
|
119
|
-
static inline char
|
120
|
-
|
121
|
-
char c;
|
91
|
+
static inline char reader_next_white(Reader reader) {
|
92
|
+
char c;
|
122
93
|
|
123
94
|
while ('\0' != (c = reader_get(reader))) {
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
break;
|
134
|
-
}
|
95
|
+
switch (c) {
|
96
|
+
case ' ':
|
97
|
+
case '\t':
|
98
|
+
case '\f':
|
99
|
+
case '\n':
|
100
|
+
case '\r':
|
101
|
+
case '\0': return c;
|
102
|
+
default: break;
|
103
|
+
}
|
135
104
|
}
|
136
105
|
return '\0';
|
137
106
|
}
|
138
107
|
|
139
|
-
static inline int
|
140
|
-
reader_expect(Reader reader, const char *s) {
|
108
|
+
static inline int reader_expect(Reader reader, const char *s) {
|
141
109
|
for (; '\0' != *s; s++) {
|
142
|
-
|
143
|
-
|
144
|
-
|
110
|
+
if (reader_get(reader) != *s) {
|
111
|
+
return -1;
|
112
|
+
}
|
145
113
|
}
|
146
114
|
return 0;
|
147
115
|
}
|
148
116
|
|
149
|
-
static inline void
|
150
|
-
reader_cleanup(Reader reader) {
|
117
|
+
static inline void reader_cleanup(Reader reader) {
|
151
118
|
if (reader->free_head && 0 != reader->head) {
|
152
|
-
|
153
|
-
|
154
|
-
|
119
|
+
OJ_R_FREE((char *)reader->head);
|
120
|
+
reader->head = 0;
|
121
|
+
reader->free_head = 0;
|
155
122
|
}
|
156
123
|
}
|
157
124
|
|
158
|
-
static inline int
|
159
|
-
|
160
|
-
switch(c) {
|
125
|
+
static inline int is_white(char c) {
|
126
|
+
switch (c) {
|
161
127
|
case ' ':
|
162
128
|
case '\t':
|
163
129
|
case '\f':
|
164
130
|
case '\n':
|
165
|
-
case '\r':
|
166
|
-
|
167
|
-
default:
|
168
|
-
break;
|
131
|
+
case '\r': return 1;
|
132
|
+
default: break;
|
169
133
|
}
|
170
134
|
return 0;
|
171
135
|
}
|
172
136
|
|
173
|
-
#endif /*
|
137
|
+
#endif /* OJ_READER_H */
|