oj 3.7.4 → 3.13.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1352 -0
- data/README.md +29 -8
- data/RELEASE_NOTES.md +61 -0
- data/ext/oj/buf.h +53 -72
- data/ext/oj/cache.c +326 -0
- data/ext/oj/cache.h +21 -0
- data/ext/oj/cache8.c +61 -64
- data/ext/oj/cache8.h +12 -39
- data/ext/oj/circarray.c +37 -43
- data/ext/oj/circarray.h +16 -17
- data/ext/oj/code.c +165 -179
- data/ext/oj/code.h +27 -29
- data/ext/oj/compat.c +174 -194
- data/ext/oj/custom.c +809 -866
- data/ext/oj/debug.c +132 -0
- data/ext/oj/dump.c +848 -863
- data/ext/oj/dump.h +81 -67
- data/ext/oj/dump_compat.c +85 -123
- data/ext/oj/dump_leaf.c +100 -188
- data/ext/oj/dump_object.c +527 -656
- data/ext/oj/dump_strict.c +315 -338
- data/ext/oj/encode.h +7 -34
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/err.c +40 -29
- data/ext/oj/err.h +48 -48
- data/ext/oj/extconf.rb +17 -4
- data/ext/oj/fast.c +1070 -1087
- data/ext/oj/intern.c +301 -0
- data/ext/oj/intern.h +26 -0
- data/ext/oj/mimic_json.c +469 -436
- data/ext/oj/object.c +525 -593
- data/ext/oj/odd.c +154 -138
- data/ext/oj/odd.h +37 -38
- data/ext/oj/oj.c +1325 -986
- data/ext/oj/oj.h +333 -316
- data/ext/oj/parse.c +1002 -846
- data/ext/oj/parse.h +92 -87
- data/ext/oj/parser.c +1557 -0
- data/ext/oj/parser.h +91 -0
- data/ext/oj/rails.c +888 -878
- data/ext/oj/rails.h +11 -14
- data/ext/oj/reader.c +141 -147
- data/ext/oj/reader.h +73 -89
- data/ext/oj/resolve.c +41 -62
- data/ext/oj/resolve.h +7 -9
- data/ext/oj/rxclass.c +71 -75
- data/ext/oj/rxclass.h +18 -19
- data/ext/oj/saj.c +443 -486
- data/ext/oj/saj2.c +602 -0
- data/ext/oj/scp.c +88 -113
- data/ext/oj/sparse.c +787 -709
- data/ext/oj/stream_writer.c +133 -159
- data/ext/oj/strict.c +127 -118
- data/ext/oj/string_writer.c +230 -249
- data/ext/oj/trace.c +34 -41
- data/ext/oj/trace.h +19 -19
- data/ext/oj/usual.c +1254 -0
- data/ext/oj/util.c +136 -0
- data/ext/oj/util.h +20 -0
- data/ext/oj/val_stack.c +59 -67
- data/ext/oj/val_stack.h +91 -129
- data/ext/oj/validate.c +46 -0
- data/ext/oj/wab.c +342 -353
- data/lib/oj/bag.rb +1 -0
- data/lib/oj/easy_hash.rb +5 -4
- data/lib/oj/error.rb +1 -1
- data/lib/oj/json.rb +1 -1
- data/lib/oj/mimic.rb +48 -14
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/state.rb +8 -7
- data/lib/oj/version.rb +2 -2
- data/lib/oj.rb +0 -8
- data/pages/Compatibility.md +1 -1
- data/pages/JsonGem.md +15 -0
- data/pages/Modes.md +53 -46
- data/pages/Options.md +72 -11
- data/pages/Parser.md +309 -0
- data/pages/Rails.md +73 -22
- data/pages/Security.md +1 -1
- data/test/activerecord/result_test.rb +7 -2
- data/test/activesupport5/abstract_unit.rb +45 -0
- data/test/activesupport5/decoding_test.rb +68 -60
- data/test/activesupport5/encoding_test.rb +111 -96
- data/test/activesupport5/encoding_test_cases.rb +33 -25
- data/test/activesupport5/test_helper.rb +43 -21
- data/test/activesupport5/time_zone_test_helpers.rb +18 -3
- data/test/activesupport6/abstract_unit.rb +44 -0
- data/test/activesupport6/decoding_test.rb +133 -0
- data/test/activesupport6/encoding_test.rb +507 -0
- data/test/activesupport6/encoding_test_cases.rb +98 -0
- data/test/activesupport6/test_common.rb +17 -0
- data/test/activesupport6/test_helper.rb +163 -0
- data/test/activesupport6/time_zone_test_helpers.rb +39 -0
- data/test/activesupport7/abstract_unit.rb +49 -0
- data/test/activesupport7/decoding_test.rb +125 -0
- data/test/activesupport7/encoding_test.rb +486 -0
- data/test/activesupport7/encoding_test_cases.rb +104 -0
- data/test/activesupport7/time_zone_test_helpers.rb +47 -0
- data/test/bar.rb +6 -12
- data/test/baz.rb +16 -0
- data/test/bug.rb +16 -0
- data/test/foo.rb +69 -75
- data/test/helper.rb +16 -0
- data/test/json_gem/json_common_interface_test.rb +8 -3
- data/test/json_gem/json_generator_test.rb +18 -4
- data/test/json_gem/json_parser_test.rb +9 -0
- data/test/json_gem/test_helper.rb +12 -0
- data/test/mem.rb +33 -0
- data/test/perf.rb +1 -1
- data/test/perf_dump.rb +50 -0
- data/test/perf_once.rb +58 -0
- data/test/perf_parser.rb +189 -0
- data/test/perf_scp.rb +11 -10
- data/test/perf_strict.rb +17 -23
- data/test/prec.rb +23 -0
- data/test/sample_json.rb +1 -1
- data/test/test_compat.rb +46 -10
- data/test/test_custom.rb +147 -8
- data/test/test_fast.rb +62 -2
- data/test/test_file.rb +25 -2
- data/test/test_gc.rb +13 -0
- data/test/test_generate.rb +21 -0
- data/test/test_hash.rb +11 -1
- data/test/test_integer_range.rb +7 -2
- data/test/test_object.rb +85 -9
- data/test/test_parser.rb +27 -0
- data/test/test_parser_saj.rb +335 -0
- data/test/test_parser_usual.rb +217 -0
- data/test/test_rails.rb +35 -0
- data/test/test_saj.rb +1 -1
- data/test/test_scp.rb +5 -5
- data/test/test_strict.rb +26 -1
- data/test/test_various.rb +87 -65
- data/test/test_wab.rb +2 -0
- data/test/test_writer.rb +19 -2
- data/test/tests.rb +1 -1
- data/test/zoo.rb +13 -0
- metadata +60 -110
- data/ext/oj/hash.c +0 -163
- data/ext/oj/hash.h +0 -46
- data/ext/oj/hash_test.c +0 -512
data/ext/oj/rails.h
CHANGED
|
@@ -1,21 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* All rights reserved.
|
|
4
|
-
*/
|
|
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.
|
|
5
3
|
|
|
6
|
-
#ifndef
|
|
7
|
-
#define
|
|
4
|
+
#ifndef OJ_RAILS_H
|
|
5
|
+
#define OJ_RAILS_H
|
|
8
6
|
|
|
9
7
|
#include "dump.h"
|
|
10
8
|
|
|
11
|
-
extern void
|
|
12
|
-
extern ROpt
|
|
9
|
+
extern void oj_mimic_rails_init(void);
|
|
10
|
+
extern ROpt oj_rails_get_opt(ROptTable rot, VALUE clas);
|
|
13
11
|
|
|
14
|
-
extern bool
|
|
15
|
-
extern bool
|
|
16
|
-
extern bool
|
|
12
|
+
extern bool oj_rails_hash_opt;
|
|
13
|
+
extern bool oj_rails_array_opt;
|
|
14
|
+
extern bool oj_rails_float_opt;
|
|
17
15
|
|
|
18
|
-
extern VALUE
|
|
16
|
+
extern VALUE oj_optimize_rails(VALUE self);
|
|
19
17
|
|
|
20
|
-
|
|
21
|
-
#endif /* __OJ_RAILS_H__ */
|
|
18
|
+
#endif /* OJ_RAILS_H */
|
data/ext/oj/reader.c
CHANGED
|
@@ -1,223 +1,217 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* All rights reserved.
|
|
4
|
-
*/
|
|
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.
|
|
5
3
|
|
|
6
|
-
#include <stdlib.h>
|
|
7
4
|
#include <errno.h>
|
|
8
5
|
#include <stdio.h>
|
|
6
|
+
#include <stdlib.h>
|
|
9
7
|
#include <strings.h>
|
|
10
8
|
#include <sys/types.h>
|
|
9
|
+
#ifdef NEEDS_UIO
|
|
11
10
|
#if NEEDS_UIO
|
|
12
|
-
#include <sys/uio.h>
|
|
11
|
+
#include <sys/uio.h>
|
|
12
|
+
#endif
|
|
13
13
|
#endif
|
|
14
|
-
#include <unistd.h>
|
|
15
14
|
#include <time.h>
|
|
15
|
+
#include <unistd.h>
|
|
16
16
|
|
|
17
|
-
#include "ruby.h"
|
|
18
17
|
#include "oj.h"
|
|
19
18
|
#include "reader.h"
|
|
19
|
+
#include "ruby.h"
|
|
20
20
|
|
|
21
|
-
#define BUF_PAD
|
|
22
|
-
|
|
23
|
-
static VALUE
|
|
24
|
-
static VALUE
|
|
25
|
-
static VALUE
|
|
26
|
-
static int
|
|
27
|
-
static int
|
|
28
|
-
static int
|
|
29
|
-
//static int read_from_str(Reader reader);
|
|
30
|
-
|
|
31
|
-
void
|
|
32
|
-
|
|
33
|
-
VALUE
|
|
34
|
-
VALUE
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
reader->head =
|
|
38
|
-
|
|
39
|
-
reader->
|
|
40
|
-
reader->
|
|
41
|
-
reader->
|
|
42
|
-
reader->
|
|
43
|
-
reader->
|
|
44
|
-
reader->
|
|
45
|
-
reader->
|
|
46
|
-
reader->
|
|
47
|
-
reader->free_head = 0;
|
|
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;
|
|
48
47
|
|
|
49
48
|
if (0 != fd) {
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
reader->read_func = read_from_fd;
|
|
50
|
+
reader->fd = fd;
|
|
52
51
|
} else if (rb_cString == io_class) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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);
|
|
58
57
|
} else if (oj_stringio_class == io_class) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
} else if (rb_cFile == io_class &&
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
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));
|
|
73
71
|
} else if (rb_respond_to(io, oj_readpartial_id)) {
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
reader->read_func = read_from_io_partial;
|
|
73
|
+
reader->io = io;
|
|
76
74
|
} else if (rb_respond_to(io, oj_read_id)) {
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
reader->read_func = read_from_io;
|
|
76
|
+
reader->io = io;
|
|
79
77
|
} else if (to_s) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
} else {
|
|
88
|
-
|
|
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);
|
|
85
|
+
} else {
|
|
86
|
+
rb_raise(rb_eArgError,
|
|
87
|
+
"parser io argument must be a String or respond to readpartial() or read().\n");
|
|
89
88
|
}
|
|
90
89
|
}
|
|
91
90
|
|
|
92
|
-
int
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
size_t shift = 0;
|
|
91
|
+
int oj_reader_read(Reader reader) {
|
|
92
|
+
int err;
|
|
93
|
+
size_t shift = 0;
|
|
96
94
|
|
|
97
95
|
if (0 == reader->read_func) {
|
|
98
|
-
|
|
96
|
+
return -1;
|
|
99
97
|
}
|
|
100
98
|
// if there is not much room to read into, shift or realloc a larger buffer.
|
|
101
99
|
if (reader->head < reader->tail && 4096 > reader->end - reader->tail) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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
|
+
}
|
|
138
138
|
}
|
|
139
|
-
err
|
|
140
|
-
*(char*)reader->read_end = '\0';
|
|
139
|
+
err = reader->read_func(reader);
|
|
140
|
+
*(char *)reader->read_end = '\0';
|
|
141
141
|
|
|
142
142
|
return err;
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
static VALUE
|
|
146
|
-
|
|
147
|
-
VALUE clas = rb_obj_class(err);
|
|
145
|
+
static VALUE rescue_cb(VALUE rbuf, VALUE err) {
|
|
146
|
+
VALUE clas = rb_obj_class(err);
|
|
148
147
|
|
|
149
148
|
if (rb_eTypeError != clas && rb_eEOFError != clas) {
|
|
150
|
-
|
|
149
|
+
Reader reader = (Reader)rbuf;
|
|
151
150
|
|
|
152
|
-
|
|
151
|
+
rb_raise(clas, "at line %d, column %d\n", reader->line, reader->col);
|
|
153
152
|
}
|
|
154
153
|
return Qfalse;
|
|
155
154
|
}
|
|
156
155
|
|
|
157
|
-
static VALUE
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
VALUE
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
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;
|
|
164
162
|
|
|
165
163
|
args[0] = ULONG2NUM(reader->end - reader->tail);
|
|
166
|
-
rstr
|
|
164
|
+
rstr = rb_funcall2(reader->io, oj_readpartial_id, 1, args);
|
|
167
165
|
if (Qnil == rstr) {
|
|
168
|
-
|
|
166
|
+
return Qfalse;
|
|
169
167
|
}
|
|
170
168
|
str = StringValuePtr(rstr);
|
|
171
169
|
cnt = RSTRING_LEN(rstr);
|
|
172
|
-
//printf("*** partial read %lu bytes, str: '%s'\n", cnt, str);
|
|
170
|
+
// printf("*** partial read %lu bytes, str: '%s'\n", cnt, str);
|
|
173
171
|
strcpy(reader->tail, str);
|
|
174
172
|
reader->read_end = reader->tail + cnt;
|
|
175
173
|
|
|
176
174
|
return Qtrue;
|
|
177
175
|
}
|
|
178
176
|
|
|
179
|
-
static VALUE
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
VALUE
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
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;
|
|
186
183
|
|
|
187
184
|
args[0] = ULONG2NUM(reader->end - reader->tail);
|
|
188
|
-
rstr
|
|
185
|
+
rstr = rb_funcall2(reader->io, oj_read_id, 1, args);
|
|
189
186
|
if (Qnil == rstr) {
|
|
190
|
-
|
|
187
|
+
return Qfalse;
|
|
191
188
|
}
|
|
192
189
|
str = StringValuePtr(rstr);
|
|
193
190
|
cnt = RSTRING_LEN(rstr);
|
|
194
|
-
//printf("*** read %lu bytes, str: '%s'\n", cnt, str);
|
|
191
|
+
// printf("*** read %lu bytes, str: '%s'\n", cnt, str);
|
|
195
192
|
strcpy(reader->tail, str);
|
|
196
193
|
reader->read_end = reader->tail + cnt;
|
|
197
194
|
|
|
198
195
|
return Qtrue;
|
|
199
196
|
}
|
|
200
197
|
|
|
201
|
-
static int
|
|
202
|
-
read_from_io_partial(Reader reader) {
|
|
198
|
+
static int read_from_io_partial(Reader reader) {
|
|
203
199
|
return (Qfalse == rb_rescue(partial_io_cb, (VALUE)reader, rescue_cb, (VALUE)reader));
|
|
204
200
|
}
|
|
205
201
|
|
|
206
|
-
static int
|
|
207
|
-
read_from_io(Reader reader) {
|
|
202
|
+
static int read_from_io(Reader reader) {
|
|
208
203
|
return (Qfalse == rb_rescue(io_cb, (VALUE)reader, rescue_cb, (VALUE)reader));
|
|
209
204
|
}
|
|
210
205
|
|
|
211
|
-
static int
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
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;
|
|
215
209
|
|
|
216
210
|
cnt = read(reader->fd, reader->tail, max);
|
|
217
211
|
if (cnt <= 0) {
|
|
218
|
-
|
|
212
|
+
return -1;
|
|
219
213
|
} else if (0 != cnt) {
|
|
220
|
-
|
|
214
|
+
reader->read_end = reader->tail + cnt;
|
|
221
215
|
}
|
|
222
216
|
return 0;
|
|
223
217
|
}
|
data/ext/oj/reader.h
CHANGED
|
@@ -1,92 +1,84 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
char
|
|
11
|
-
char
|
|
12
|
-
char
|
|
13
|
-
char
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
int
|
|
19
|
-
int col;
|
|
20
|
-
int free_head;
|
|
21
|
-
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);
|
|
22
20
|
union {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
int fd;
|
|
22
|
+
VALUE io;
|
|
23
|
+
const char *in_str;
|
|
26
24
|
};
|
|
27
|
-
} *Reader;
|
|
25
|
+
} * Reader;
|
|
28
26
|
|
|
29
|
-
extern void
|
|
30
|
-
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);
|
|
31
29
|
|
|
32
|
-
static inline char
|
|
33
|
-
|
|
34
|
-
//
|
|
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);
|
|
35
33
|
if (reader->read_end <= reader->tail) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
if (0 != oj_reader_read(reader)) {
|
|
35
|
+
return '\0';
|
|
36
|
+
}
|
|
39
37
|
}
|
|
40
38
|
if ('\n' == *reader->tail) {
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
reader->line++;
|
|
40
|
+
reader->col = 0;
|
|
43
41
|
}
|
|
44
42
|
reader->col++;
|
|
45
43
|
reader->pos++;
|
|
46
|
-
|
|
44
|
+
|
|
47
45
|
return *reader->tail++;
|
|
48
46
|
}
|
|
49
47
|
|
|
50
|
-
static inline void
|
|
51
|
-
reader_backup(Reader reader) {
|
|
48
|
+
static inline void reader_backup(Reader reader) {
|
|
52
49
|
reader->tail--;
|
|
53
50
|
reader->col--;
|
|
54
51
|
reader->pos--;
|
|
55
52
|
if (0 >= reader->col) {
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
reader->line--;
|
|
54
|
+
// allow col to be negative since we never backup twice in a row
|
|
58
55
|
}
|
|
59
56
|
}
|
|
60
57
|
|
|
61
|
-
static inline void
|
|
62
|
-
reader_protect(Reader reader) {
|
|
58
|
+
static inline void reader_protect(Reader reader) {
|
|
63
59
|
reader->pro = reader->tail;
|
|
64
|
-
reader->str = reader->tail;
|
|
60
|
+
reader->str = reader->tail; // can't have str before pro
|
|
65
61
|
}
|
|
66
62
|
|
|
67
|
-
static inline void
|
|
68
|
-
reader_release(Reader reader) {
|
|
63
|
+
static inline void reader_release(Reader reader) {
|
|
69
64
|
reader->pro = 0;
|
|
70
65
|
}
|
|
71
66
|
|
|
72
67
|
/* Starts by reading a character so it is safe to use with an empty or
|
|
73
68
|
* compacted buffer.
|
|
74
69
|
*/
|
|
75
|
-
static inline char
|
|
76
|
-
|
|
77
|
-
char c;
|
|
70
|
+
static inline char reader_next_non_white(Reader reader) {
|
|
71
|
+
char c;
|
|
78
72
|
|
|
79
73
|
while ('\0' != (c = reader_get(reader))) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
return c;
|
|
89
|
-
}
|
|
74
|
+
switch (c) {
|
|
75
|
+
case ' ':
|
|
76
|
+
case '\t':
|
|
77
|
+
case '\f':
|
|
78
|
+
case '\n':
|
|
79
|
+
case '\r': break;
|
|
80
|
+
default: return c;
|
|
81
|
+
}
|
|
90
82
|
}
|
|
91
83
|
return '\0';
|
|
92
84
|
}
|
|
@@ -94,58 +86,50 @@ reader_next_non_white(Reader reader) {
|
|
|
94
86
|
/* Starts by reading a character so it is safe to use with an empty or
|
|
95
87
|
* compacted buffer.
|
|
96
88
|
*/
|
|
97
|
-
static inline char
|
|
98
|
-
|
|
99
|
-
char c;
|
|
89
|
+
static inline char reader_next_white(Reader reader) {
|
|
90
|
+
char c;
|
|
100
91
|
|
|
101
92
|
while ('\0' != (c = reader_get(reader))) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
break;
|
|
112
|
-
}
|
|
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
|
+
}
|
|
113
102
|
}
|
|
114
103
|
return '\0';
|
|
115
104
|
}
|
|
116
105
|
|
|
117
|
-
static inline int
|
|
118
|
-
reader_expect(Reader reader, const char *s) {
|
|
106
|
+
static inline int reader_expect(Reader reader, const char *s) {
|
|
119
107
|
for (; '\0' != *s; s++) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
108
|
+
if (reader_get(reader) != *s) {
|
|
109
|
+
return -1;
|
|
110
|
+
}
|
|
123
111
|
}
|
|
124
112
|
return 0;
|
|
125
113
|
}
|
|
126
114
|
|
|
127
|
-
static inline void
|
|
128
|
-
reader_cleanup(Reader reader) {
|
|
115
|
+
static inline void reader_cleanup(Reader reader) {
|
|
129
116
|
if (reader->free_head && 0 != reader->head) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
117
|
+
xfree((char *)reader->head);
|
|
118
|
+
reader->head = 0;
|
|
119
|
+
reader->free_head = 0;
|
|
133
120
|
}
|
|
134
121
|
}
|
|
135
122
|
|
|
136
|
-
static inline int
|
|
137
|
-
|
|
138
|
-
switch(c) {
|
|
123
|
+
static inline int is_white(char c) {
|
|
124
|
+
switch (c) {
|
|
139
125
|
case ' ':
|
|
140
126
|
case '\t':
|
|
141
127
|
case '\f':
|
|
142
128
|
case '\n':
|
|
143
|
-
case '\r':
|
|
144
|
-
|
|
145
|
-
default:
|
|
146
|
-
break;
|
|
129
|
+
case '\r': return 1;
|
|
130
|
+
default: break;
|
|
147
131
|
}
|
|
148
132
|
return 0;
|
|
149
133
|
}
|
|
150
134
|
|
|
151
|
-
#endif /*
|
|
135
|
+
#endif /* OJ_READER_H */
|