oj 2.18.3 → 3.13.14
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 +1324 -0
- data/README.md +51 -204
- data/RELEASE_NOTES.md +61 -0
- data/ext/oj/buf.h +49 -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 -68
- data/ext/oj/circarray.h +16 -42
- data/ext/oj/code.c +221 -0
- data/ext/oj/code.h +40 -0
- data/ext/oj/compat.c +231 -107
- data/ext/oj/custom.c +1125 -0
- data/ext/oj/debug.c +132 -0
- data/ext/oj/dump.c +935 -2513
- data/ext/oj/dump.h +108 -0
- data/ext/oj/dump_compat.c +936 -0
- data/ext/oj/dump_leaf.c +164 -0
- data/ext/oj/dump_object.c +761 -0
- data/ext/oj/dump_strict.c +410 -0
- data/ext/oj/encode.h +7 -42
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/err.c +40 -54
- data/ext/oj/err.h +52 -46
- data/ext/oj/extconf.rb +21 -30
- data/ext/oj/fast.c +1097 -1080
- data/ext/oj/intern.c +301 -0
- data/ext/oj/intern.h +26 -0
- data/ext/oj/mimic_json.c +893 -0
- data/ext/oj/object.c +549 -620
- data/ext/oj/odd.c +155 -167
- data/ext/oj/odd.h +37 -63
- data/ext/oj/oj.c +1661 -2063
- data/ext/oj/oj.h +341 -270
- data/ext/oj/parse.c +974 -737
- data/ext/oj/parse.h +105 -97
- data/ext/oj/parser.c +1526 -0
- data/ext/oj/parser.h +90 -0
- data/ext/oj/rails.c +1504 -0
- data/ext/oj/rails.h +18 -0
- data/ext/oj/reader.c +141 -163
- data/ext/oj/reader.h +75 -113
- data/ext/oj/resolve.c +45 -93
- data/ext/oj/resolve.h +7 -34
- data/ext/oj/rxclass.c +143 -0
- data/ext/oj/rxclass.h +26 -0
- data/ext/oj/saj.c +447 -511
- data/ext/oj/saj2.c +348 -0
- data/ext/oj/scp.c +91 -138
- data/ext/oj/sparse.c +793 -644
- data/ext/oj/stream_writer.c +331 -0
- data/ext/oj/strict.c +145 -109
- data/ext/oj/string_writer.c +493 -0
- data/ext/oj/trace.c +72 -0
- data/ext/oj/trace.h +28 -0
- 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 +62 -70
- data/ext/oj/val_stack.h +95 -129
- data/ext/oj/validate.c +51 -0
- data/ext/oj/wab.c +622 -0
- data/lib/oj/bag.rb +1 -0
- data/lib/oj/easy_hash.rb +17 -8
- data/lib/oj/error.rb +10 -11
- data/lib/oj/json.rb +176 -0
- data/lib/oj/mimic.rb +158 -19
- data/lib/oj/state.rb +132 -0
- data/lib/oj/version.rb +2 -2
- data/lib/oj.rb +1 -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/JsonGem.md +94 -0
- data/pages/Modes.md +161 -0
- data/pages/Options.md +327 -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
- data/test/activerecord/result_test.rb +32 -0
- data/test/activesupport4/decoding_test.rb +108 -0
- data/test/activesupport4/encoding_test.rb +531 -0
- data/test/activesupport4/test_helper.rb +41 -0
- data/test/activesupport5/abstract_unit.rb +45 -0
- data/test/activesupport5/decoding_test.rb +133 -0
- data/test/activesupport5/encoding_test.rb +500 -0
- data/test/activesupport5/encoding_test_cases.rb +98 -0
- data/test/activesupport5/test_helper.rb +72 -0
- data/test/activesupport5/time_zone_test_helpers.rb +39 -0
- 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 +9 -0
- data/test/baz.rb +16 -0
- data/test/bug.rb +11 -46
- data/test/foo.rb +69 -16
- data/test/helper.rb +10 -1
- data/test/isolated/shared.rb +12 -8
- data/test/isolated/test_mimic_rails_after.rb +3 -3
- data/test/isolated/test_mimic_rails_before.rb +3 -3
- data/test/json_gem/json_addition_test.rb +216 -0
- data/test/json_gem/json_common_interface_test.rb +153 -0
- data/test/json_gem/json_encoding_test.rb +107 -0
- data/test/json_gem/json_ext_parser_test.rb +20 -0
- data/test/json_gem/json_fixtures_test.rb +35 -0
- data/test/json_gem/json_generator_test.rb +397 -0
- data/test/json_gem/json_generic_object_test.rb +90 -0
- data/test/json_gem/json_parser_test.rb +470 -0
- data/test/json_gem/json_string_matching_test.rb +42 -0
- data/test/json_gem/test_helper.rb +26 -0
- data/test/mem.rb +33 -0
- data/test/perf.rb +1 -1
- data/test/perf_compat.rb +30 -28
- data/test/perf_dump.rb +50 -0
- data/test/perf_object.rb +1 -1
- 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 +30 -19
- data/test/perf_wab.rb +131 -0
- data/test/prec.rb +23 -0
- data/test/sample.rb +0 -1
- data/test/sample_json.rb +1 -1
- data/test/test_compat.rb +219 -102
- data/test/test_custom.rb +533 -0
- data/test/test_fast.rb +107 -35
- data/test/test_file.rb +19 -25
- data/test/test_generate.rb +21 -0
- data/test/test_hash.rb +11 -1
- data/test/test_integer_range.rb +72 -0
- data/test/test_null.rb +376 -0
- data/test/test_object.rb +357 -70
- data/test/test_parser.rb +27 -0
- data/test/test_parser_saj.rb +245 -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 +39 -2
- data/test/test_strict.rb +186 -7
- data/test/test_various.rb +160 -774
- data/test/test_wab.rb +307 -0
- data/test/test_writer.rb +90 -2
- data/test/tests.rb +24 -0
- data/test/tests_mimic.rb +14 -0
- data/test/tests_mimic_addition.rb +7 -0
- data/test/zoo.rb +13 -0
- metadata +194 -56
- data/ext/oj/hash.c +0 -163
- data/ext/oj/hash.h +0 -46
- data/ext/oj/hash_test.c +0 -512
- data/test/activesupport_datetime_test.rb +0 -23
- 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/io.rb +0 -48
- data/test/isolated/test_mimic_rails_datetime.rb +0 -27
- data/test/mod.rb +0 -16
- data/test/rails.rb +0 -50
- data/test/russian.rb +0 -18
- data/test/struct.rb +0 -29
- data/test/test_serializer.rb +0 -59
- 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,217 @@
|
|
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 "ruby.h"
|
43
17
|
#include "oj.h"
|
44
18
|
#include "reader.h"
|
19
|
+
#include "ruby.h"
|
45
20
|
|
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
|
21
|
+
#define BUF_PAD 4
|
22
|
+
|
23
|
+
static VALUE rescue_cb(VALUE rdr, VALUE err);
|
24
|
+
static VALUE io_cb(VALUE rdr);
|
25
|
+
static VALUE partial_io_cb(VALUE rdr);
|
26
|
+
static int read_from_io(Reader reader);
|
27
|
+
static int read_from_fd(Reader reader);
|
28
|
+
static int read_from_io_partial(Reader reader);
|
29
|
+
// static int read_from_str(Reader reader);
|
30
|
+
|
31
|
+
void oj_reader_init(Reader reader, VALUE io, int fd, bool to_s) {
|
32
|
+
VALUE io_class = rb_obj_class(io);
|
33
|
+
VALUE stat;
|
34
|
+
VALUE ftype;
|
35
|
+
|
36
|
+
reader->head = reader->base;
|
37
|
+
*((char *)reader->head) = '\0';
|
38
|
+
reader->end = reader->head + sizeof(reader->base) - BUF_PAD;
|
39
|
+
reader->tail = reader->head;
|
40
|
+
reader->read_end = reader->head;
|
41
|
+
reader->pro = 0;
|
42
|
+
reader->str = 0;
|
43
|
+
reader->pos = 0;
|
44
|
+
reader->line = 1;
|
45
|
+
reader->col = 0;
|
46
|
+
reader->free_head = 0;
|
72
47
|
|
73
48
|
if (0 != fd) {
|
74
|
-
|
75
|
-
|
49
|
+
reader->read_func = read_from_fd;
|
50
|
+
reader->fd = fd;
|
76
51
|
} else if (rb_cString == io_class) {
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
52
|
+
reader->read_func = 0;
|
53
|
+
reader->in_str = StringValuePtr(io);
|
54
|
+
reader->head = (char *)reader->in_str;
|
55
|
+
reader->tail = reader->head;
|
56
|
+
reader->read_end = reader->head + RSTRING_LEN(io);
|
82
57
|
} 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
|
-
|
96
|
-
reader->fd = FIX2INT(rb_funcall(io, oj_fileno_id, 0));
|
58
|
+
VALUE s = rb_funcall2(io, oj_string_id, 0, 0);
|
59
|
+
|
60
|
+
reader->read_func = 0;
|
61
|
+
reader->in_str = StringValuePtr(s);
|
62
|
+
reader->head = (char *)reader->in_str;
|
63
|
+
reader->tail = reader->head;
|
64
|
+
reader->read_end = reader->head + RSTRING_LEN(s);
|
65
|
+
} else if (rb_cFile == io_class && Qnil != (stat = rb_funcall(io, oj_stat_id, 0)) &&
|
66
|
+
Qnil != (ftype = rb_funcall(stat, oj_ftype_id, 0)) &&
|
67
|
+
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 = rb_funcall(io, oj_to_s_id, 0);
|
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,
|
87
|
+
"parser io argument must be a String or respond to readpartial() or read().\n");
|
105
88
|
}
|
106
89
|
}
|
107
90
|
|
108
|
-
int
|
109
|
-
|
110
|
-
|
111
|
-
size_t shift = 0;
|
91
|
+
int oj_reader_read(Reader reader) {
|
92
|
+
int err;
|
93
|
+
size_t shift = 0;
|
112
94
|
|
113
95
|
if (0 == reader->read_func) {
|
114
|
-
|
96
|
+
return -1;
|
115
97
|
}
|
116
98
|
// if there is not much room to read into, shift or realloc a larger buffer.
|
117
99
|
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
|
-
|
100
|
+
if (0 == reader->pro) {
|
101
|
+
shift = reader->tail - reader->head;
|
102
|
+
} else {
|
103
|
+
shift = reader->pro - reader->head - 1; // leave one character so we can backup one
|
104
|
+
}
|
105
|
+
if (0 >= shift) { /* no space left so allocate more */
|
106
|
+
const char *old = reader->head;
|
107
|
+
size_t size = reader->end - reader->head + BUF_PAD;
|
108
|
+
|
109
|
+
if (reader->head == reader->base) {
|
110
|
+
reader->head = ALLOC_N(char, size * 2);
|
111
|
+
memcpy((char *)reader->head, old, size);
|
112
|
+
} else {
|
113
|
+
REALLOC_N(reader->head, char, size * 2);
|
114
|
+
}
|
115
|
+
reader->free_head = 1;
|
116
|
+
reader->end = reader->head + size * 2 - BUF_PAD;
|
117
|
+
reader->tail = reader->head + (reader->tail - old);
|
118
|
+
reader->read_end = reader->head + (reader->read_end - old);
|
119
|
+
if (0 != reader->pro) {
|
120
|
+
reader->pro = reader->head + (reader->pro - old);
|
121
|
+
}
|
122
|
+
if (0 != reader->str) {
|
123
|
+
reader->str = reader->head + (reader->str - old);
|
124
|
+
}
|
125
|
+
} else {
|
126
|
+
memmove((char *)reader->head,
|
127
|
+
reader->head + shift,
|
128
|
+
reader->read_end - (reader->head + shift));
|
129
|
+
reader->tail -= shift;
|
130
|
+
reader->read_end -= shift;
|
131
|
+
if (0 != reader->pro) {
|
132
|
+
reader->pro -= shift;
|
133
|
+
}
|
134
|
+
if (0 != reader->str) {
|
135
|
+
reader->str -= shift;
|
136
|
+
}
|
137
|
+
}
|
154
138
|
}
|
155
|
-
err
|
156
|
-
*(char*)reader->read_end = '\0';
|
139
|
+
err = reader->read_func(reader);
|
140
|
+
*(char *)reader->read_end = '\0';
|
157
141
|
|
158
142
|
return err;
|
159
143
|
}
|
160
144
|
|
161
|
-
static VALUE
|
162
|
-
|
163
|
-
VALUE clas = rb_obj_class(err);
|
145
|
+
static VALUE rescue_cb(VALUE rbuf, VALUE err) {
|
146
|
+
VALUE clas = rb_obj_class(err);
|
164
147
|
|
165
148
|
if (rb_eTypeError != clas && rb_eEOFError != clas) {
|
166
|
-
|
149
|
+
Reader reader = (Reader)rbuf;
|
167
150
|
|
168
|
-
|
151
|
+
rb_raise(clas, "at line %d, column %d\n", reader->line, reader->col);
|
169
152
|
}
|
170
153
|
return Qfalse;
|
171
154
|
}
|
172
155
|
|
173
|
-
static VALUE
|
174
|
-
|
175
|
-
|
176
|
-
VALUE
|
177
|
-
|
178
|
-
|
179
|
-
size_t cnt;
|
156
|
+
static VALUE partial_io_cb(VALUE rbuf) {
|
157
|
+
Reader reader = (Reader)rbuf;
|
158
|
+
VALUE args[1];
|
159
|
+
VALUE rstr;
|
160
|
+
char * str;
|
161
|
+
size_t cnt;
|
180
162
|
|
181
163
|
args[0] = ULONG2NUM(reader->end - reader->tail);
|
182
|
-
rstr
|
164
|
+
rstr = rb_funcall2(reader->io, oj_readpartial_id, 1, args);
|
183
165
|
if (Qnil == rstr) {
|
184
|
-
|
166
|
+
return Qfalse;
|
185
167
|
}
|
186
168
|
str = StringValuePtr(rstr);
|
187
169
|
cnt = RSTRING_LEN(rstr);
|
188
|
-
//printf("*** partial read %lu bytes, str: '%s'\n", cnt, str);
|
170
|
+
// printf("*** partial read %lu bytes, str: '%s'\n", cnt, str);
|
189
171
|
strcpy(reader->tail, str);
|
190
172
|
reader->read_end = reader->tail + cnt;
|
191
173
|
|
192
174
|
return Qtrue;
|
193
175
|
}
|
194
176
|
|
195
|
-
static VALUE
|
196
|
-
|
197
|
-
|
198
|
-
VALUE
|
199
|
-
|
200
|
-
|
201
|
-
size_t cnt;
|
177
|
+
static VALUE io_cb(VALUE rbuf) {
|
178
|
+
Reader reader = (Reader)rbuf;
|
179
|
+
VALUE args[1];
|
180
|
+
VALUE rstr;
|
181
|
+
char * str;
|
182
|
+
size_t cnt;
|
202
183
|
|
203
184
|
args[0] = ULONG2NUM(reader->end - reader->tail);
|
204
|
-
rstr
|
185
|
+
rstr = rb_funcall2(reader->io, oj_read_id, 1, args);
|
205
186
|
if (Qnil == rstr) {
|
206
|
-
|
187
|
+
return Qfalse;
|
207
188
|
}
|
208
189
|
str = StringValuePtr(rstr);
|
209
190
|
cnt = RSTRING_LEN(rstr);
|
210
|
-
//printf("*** read %lu bytes, str: '%s'\n", cnt, str);
|
191
|
+
// printf("*** read %lu bytes, str: '%s'\n", cnt, str);
|
211
192
|
strcpy(reader->tail, str);
|
212
193
|
reader->read_end = reader->tail + cnt;
|
213
194
|
|
214
195
|
return Qtrue;
|
215
196
|
}
|
216
197
|
|
217
|
-
static int
|
218
|
-
read_from_io_partial(Reader reader) {
|
198
|
+
static int read_from_io_partial(Reader reader) {
|
219
199
|
return (Qfalse == rb_rescue(partial_io_cb, (VALUE)reader, rescue_cb, (VALUE)reader));
|
220
200
|
}
|
221
201
|
|
222
|
-
static int
|
223
|
-
read_from_io(Reader reader) {
|
202
|
+
static int read_from_io(Reader reader) {
|
224
203
|
return (Qfalse == rb_rescue(io_cb, (VALUE)reader, rescue_cb, (VALUE)reader));
|
225
204
|
}
|
226
205
|
|
227
|
-
static int
|
228
|
-
|
229
|
-
|
230
|
-
size_t max = reader->end - reader->tail;
|
206
|
+
static int read_from_fd(Reader reader) {
|
207
|
+
ssize_t cnt;
|
208
|
+
size_t max = reader->end - reader->tail;
|
231
209
|
|
232
210
|
cnt = read(reader->fd, reader->tail, max);
|
233
211
|
if (cnt <= 0) {
|
234
|
-
|
212
|
+
return -1;
|
235
213
|
} else if (0 != cnt) {
|
236
|
-
|
214
|
+
reader->read_end = reader->tail + cnt;
|
237
215
|
}
|
238
216
|
return 0;
|
239
217
|
}
|
data/ext/oj/reader.h
CHANGED
@@ -1,114 +1,84 @@
|
|
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
|
-
|
40
|
-
|
41
|
-
|
42
|
-
int
|
43
|
-
int
|
44
|
-
int free_head;
|
45
|
-
int (*read_func)(struct _Reader *reader);
|
7
|
+
typedef struct _reader {
|
8
|
+
char base[0x00001000];
|
9
|
+
char *head;
|
10
|
+
char *end;
|
11
|
+
char *tail;
|
12
|
+
char *read_end; /* one past last character read */
|
13
|
+
char *pro; /* protection start, buffer can not slide past this point */
|
14
|
+
char *str; /* start of current string being read */
|
15
|
+
long pos;
|
16
|
+
int line;
|
17
|
+
int col;
|
18
|
+
int free_head;
|
19
|
+
int (*read_func)(struct _reader *reader);
|
46
20
|
union {
|
47
|
-
|
48
|
-
|
49
|
-
|
21
|
+
int fd;
|
22
|
+
VALUE io;
|
23
|
+
const char *in_str;
|
50
24
|
};
|
51
|
-
} *Reader;
|
25
|
+
} * Reader;
|
52
26
|
|
53
|
-
extern void
|
54
|
-
extern int
|
27
|
+
extern void oj_reader_init(Reader reader, VALUE io, int fd, bool to_s);
|
28
|
+
extern int oj_reader_read(Reader reader);
|
55
29
|
|
56
|
-
static inline char
|
57
|
-
|
58
|
-
//
|
30
|
+
static inline char reader_get(Reader reader) {
|
31
|
+
// printf("*** drive get from '%s' from start: %ld buf: %p from read_end: %ld\n",
|
32
|
+
// reader->tail, reader->tail - reader->head, reader->head, reader->read_end - reader->tail);
|
59
33
|
if (reader->read_end <= reader->tail) {
|
60
|
-
|
61
|
-
|
62
|
-
|
34
|
+
if (0 != oj_reader_read(reader)) {
|
35
|
+
return '\0';
|
36
|
+
}
|
63
37
|
}
|
64
38
|
if ('\n' == *reader->tail) {
|
65
|
-
|
66
|
-
|
39
|
+
reader->line++;
|
40
|
+
reader->col = 0;
|
67
41
|
}
|
68
42
|
reader->col++;
|
69
|
-
|
43
|
+
reader->pos++;
|
44
|
+
|
70
45
|
return *reader->tail++;
|
71
46
|
}
|
72
47
|
|
73
|
-
static inline void
|
74
|
-
reader_backup(Reader reader) {
|
48
|
+
static inline void reader_backup(Reader reader) {
|
75
49
|
reader->tail--;
|
76
50
|
reader->col--;
|
51
|
+
reader->pos--;
|
77
52
|
if (0 >= reader->col) {
|
78
|
-
|
79
|
-
|
53
|
+
reader->line--;
|
54
|
+
// allow col to be negative since we never backup twice in a row
|
80
55
|
}
|
81
56
|
}
|
82
57
|
|
83
|
-
static inline void
|
84
|
-
reader_protect(Reader reader) {
|
58
|
+
static inline void reader_protect(Reader reader) {
|
85
59
|
reader->pro = reader->tail;
|
86
|
-
reader->str = reader->tail;
|
60
|
+
reader->str = reader->tail; // can't have str before pro
|
87
61
|
}
|
88
62
|
|
89
|
-
static inline void
|
90
|
-
reader_release(Reader reader) {
|
63
|
+
static inline void reader_release(Reader reader) {
|
91
64
|
reader->pro = 0;
|
92
65
|
}
|
93
66
|
|
94
67
|
/* Starts by reading a character so it is safe to use with an empty or
|
95
68
|
* compacted buffer.
|
96
69
|
*/
|
97
|
-
static inline char
|
98
|
-
|
99
|
-
char c;
|
70
|
+
static inline char reader_next_non_white(Reader reader) {
|
71
|
+
char c;
|
100
72
|
|
101
73
|
while ('\0' != (c = reader_get(reader))) {
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
return c;
|
111
|
-
}
|
74
|
+
switch (c) {
|
75
|
+
case ' ':
|
76
|
+
case '\t':
|
77
|
+
case '\f':
|
78
|
+
case '\n':
|
79
|
+
case '\r': break;
|
80
|
+
default: return c;
|
81
|
+
}
|
112
82
|
}
|
113
83
|
return '\0';
|
114
84
|
}
|
@@ -116,58 +86,50 @@ reader_next_non_white(Reader reader) {
|
|
116
86
|
/* Starts by reading a character so it is safe to use with an empty or
|
117
87
|
* compacted buffer.
|
118
88
|
*/
|
119
|
-
static inline char
|
120
|
-
|
121
|
-
char c;
|
89
|
+
static inline char reader_next_white(Reader reader) {
|
90
|
+
char c;
|
122
91
|
|
123
92
|
while ('\0' != (c = reader_get(reader))) {
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
break;
|
134
|
-
}
|
93
|
+
switch (c) {
|
94
|
+
case ' ':
|
95
|
+
case '\t':
|
96
|
+
case '\f':
|
97
|
+
case '\n':
|
98
|
+
case '\r':
|
99
|
+
case '\0': return c;
|
100
|
+
default: break;
|
101
|
+
}
|
135
102
|
}
|
136
103
|
return '\0';
|
137
104
|
}
|
138
105
|
|
139
|
-
static inline int
|
140
|
-
reader_expect(Reader reader, const char *s) {
|
106
|
+
static inline int reader_expect(Reader reader, const char *s) {
|
141
107
|
for (; '\0' != *s; s++) {
|
142
|
-
|
143
|
-
|
144
|
-
|
108
|
+
if (reader_get(reader) != *s) {
|
109
|
+
return -1;
|
110
|
+
}
|
145
111
|
}
|
146
112
|
return 0;
|
147
113
|
}
|
148
114
|
|
149
|
-
static inline void
|
150
|
-
reader_cleanup(Reader reader) {
|
115
|
+
static inline void reader_cleanup(Reader reader) {
|
151
116
|
if (reader->free_head && 0 != reader->head) {
|
152
|
-
|
153
|
-
|
154
|
-
|
117
|
+
xfree((char *)reader->head);
|
118
|
+
reader->head = 0;
|
119
|
+
reader->free_head = 0;
|
155
120
|
}
|
156
121
|
}
|
157
122
|
|
158
|
-
static inline int
|
159
|
-
|
160
|
-
switch(c) {
|
123
|
+
static inline int is_white(char c) {
|
124
|
+
switch (c) {
|
161
125
|
case ' ':
|
162
126
|
case '\t':
|
163
127
|
case '\f':
|
164
128
|
case '\n':
|
165
|
-
case '\r':
|
166
|
-
|
167
|
-
default:
|
168
|
-
break;
|
129
|
+
case '\r': return 1;
|
130
|
+
default: break;
|
169
131
|
}
|
170
132
|
return 0;
|
171
133
|
}
|
172
134
|
|
173
|
-
#endif /*
|
135
|
+
#endif /* OJ_READER_H */
|