binyo 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,166 @@
1
+ /*
2
+ * binyo - Fast binary IO for Ruby
3
+ *
4
+ * Copyright (c) 2012-2013
5
+ * Martin Bosslet <martin.bosslet@gmail.com>
6
+ * All rights reserved.
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining
9
+ * a copy of this software and associated documentation files (the
10
+ * "Software"), to deal in the Software without restriction, including
11
+ * without limitation the rights to use, copy, modify, merge, publish,
12
+ * distribute, sublicense, and/or sell copies of the Software, and to
13
+ * permit persons to whom the Software is furnished to do so, subject to
14
+ * the following conditions:
15
+ *
16
+ * The above copyright notice and this permission notice shall be
17
+ * included in all copies or substantial portions of the Software.
18
+ *
19
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #include <unistd.h>
29
+ #include <errno.h>
30
+ #include "binyo.h"
31
+
32
+ typedef struct binyo_instream_fd_st {
33
+ binyo_instream_interface *methods;
34
+ int fd;
35
+ } binyo_instream_fd;
36
+
37
+ #define int_safe_cast(out, in) binyo_safe_cast_instream((out), (in), BINYO_INSTREAM_TYPE_FD, binyo_instream_fd)
38
+
39
+ static binyo_instream_fd *int_fd_alloc(void);
40
+ static ssize_t int_fd_read(binyo_instream *in, uint8_t *buf, size_t len);
41
+ static ssize_t int_fd_gets(binyo_instream *in, char *line, size_t len);
42
+ static int int_fd_seek(binyo_instream *in, off_t offset, int whence);
43
+ static void int_fd_free(binyo_instream *in);
44
+
45
+ static binyo_instream_interface binyo_interface_fd = {
46
+ BINYO_INSTREAM_TYPE_FD,
47
+ int_fd_read,
48
+ NULL,
49
+ int_fd_gets,
50
+ int_fd_seek,
51
+ NULL,
52
+ int_fd_free
53
+ };
54
+
55
+ binyo_instream *
56
+ binyo_instream_new_fd_io(VALUE value)
57
+ {
58
+ rb_io_t *fptr;
59
+ GetOpenFile(value, fptr);
60
+ rb_io_check_byte_readable(fptr);
61
+ return binyo_instream_new_fd(fptr->fd);
62
+ }
63
+
64
+ binyo_instream *
65
+ binyo_instream_new_fd(int fd)
66
+ {
67
+ binyo_instream_fd *in;
68
+
69
+ in = int_fd_alloc();
70
+ in->fd = fd;
71
+ return (binyo_instream *) in;
72
+ }
73
+
74
+ static binyo_instream_fd*
75
+ int_fd_alloc(void)
76
+ {
77
+ binyo_instream_fd *ret;
78
+ ret = ALLOC(binyo_instream_fd);
79
+ memset(ret, 0, sizeof(binyo_instream_fd));
80
+ ret->methods = &binyo_interface_fd;
81
+ return ret;
82
+ }
83
+
84
+ static ssize_t
85
+ int_fd_read(binyo_instream *instream, uint8_t *buf, size_t len)
86
+ {
87
+ int fd;
88
+ ssize_t r;
89
+ binyo_instream_fd *in;
90
+
91
+ int_safe_cast(in, instream);
92
+ if (!buf) return BINYO_ERR;
93
+
94
+ fd = in->fd;
95
+ binyo_clear_sys_error();
96
+ r = read(fd, buf, len);
97
+
98
+ if (r == -1) {
99
+ binyo_add_io_error();
100
+ return BINYO_ERR;
101
+ }
102
+ else if (r == 0) {
103
+ return BINYO_IO_EOF;
104
+ }
105
+ else {
106
+ return r;
107
+ }
108
+ }
109
+
110
+ static ssize_t
111
+ int_fd_gets(binyo_instream *instream, char *line, size_t len)
112
+ {
113
+ int fd;
114
+ binyo_instream_fd *in;
115
+ ssize_t ret = 0, r = 0;
116
+ char *p = line;
117
+ char *end = line + len;
118
+
119
+ int_safe_cast(in, instream);
120
+ if (!line) return BINYO_ERR;
121
+
122
+ fd = in->fd;
123
+ binyo_clear_sys_error();
124
+
125
+ while ( (p < end) &&
126
+ ((r = read(fd, p, 1)) == 1) &&
127
+ (*p != '\n') ) {
128
+ p++;
129
+ ret++;
130
+ }
131
+
132
+ if (r == -1) {
133
+ return BINYO_ERR;
134
+ }
135
+
136
+ if (ret == 0 && r == 0)
137
+ return BINYO_IO_EOF;
138
+
139
+ if (*p == '\n' && *(p - 1) == '\r')
140
+ ret--;
141
+
142
+ return ret;
143
+ }
144
+
145
+ static int
146
+ int_fd_seek(binyo_instream *instream, off_t offset, int whence)
147
+ {
148
+ int fd;
149
+ long off;
150
+ binyo_instream_fd *in;
151
+
152
+ int_safe_cast(in, instream);
153
+ fd = in->fd;
154
+ off = lseek(fd, offset, whence);
155
+
156
+ if (off == -1)
157
+ return BINYO_ERR;
158
+ return BINYO_OK;
159
+ }
160
+
161
+ static void
162
+ int_fd_free(binyo_instream *instream)
163
+ {
164
+ /* do not close the fd, should be done explicitly */
165
+ }
166
+
@@ -0,0 +1,182 @@
1
+ /*
2
+ * binyo - Fast binary IO for Ruby
3
+ *
4
+ * Copyright (c) 2012-2013
5
+ * Martin Bosslet <martin.bosslet@gmail.com>
6
+ * All rights reserved.
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining
9
+ * a copy of this software and associated documentation files (the
10
+ * "Software"), to deal in the Software without restriction, including
11
+ * without limitation the rights to use, copy, modify, merge, publish,
12
+ * distribute, sublicense, and/or sell copies of the Software, and to
13
+ * permit persons to whom the Software is furnished to do so, subject to
14
+ * the following conditions:
15
+ *
16
+ * The above copyright notice and this permission notice shall be
17
+ * included in all copies or substantial portions of the Software.
18
+ *
19
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #include "binyo.h"
29
+
30
+ typedef struct binyo_instream_io_st {
31
+ binyo_instream_interface *methods;
32
+ VALUE io;
33
+ } binyo_instream_io;
34
+
35
+ #define int_safe_cast(out, in) binyo_safe_cast_instream((out), (in), BINYO_INSTREAM_TYPE_IO_GENERIC, binyo_instream_io)
36
+
37
+ static binyo_instream_io* int_io_alloc(void);
38
+ static ssize_t int_io_read(binyo_instream *in, uint8_t *buf, size_t len);
39
+ static int int_io_rb_read(binyo_instream *in, VALUE vlen, VALUE vbuf, VALUE *out);
40
+ static int int_io_seek(binyo_instream *in, off_t offset, int whence);
41
+ static void int_io_mark(binyo_instream *in);
42
+ static void int_io_free(binyo_instream *in);
43
+
44
+ static binyo_instream_interface binyo_interface_io_generic = {
45
+ BINYO_INSTREAM_TYPE_IO_GENERIC,
46
+ int_io_read,
47
+ int_io_rb_read,
48
+ NULL,
49
+ int_io_seek,
50
+ int_io_mark,
51
+ int_io_free
52
+ };
53
+
54
+ binyo_instream *
55
+ binyo_instream_new_io_generic(VALUE io)
56
+ {
57
+ binyo_instream_io *in;
58
+
59
+ in = int_io_alloc();
60
+ in->io = io;
61
+ return (binyo_instream *) in;
62
+ }
63
+
64
+ static binyo_instream_io*
65
+ int_io_alloc(void)
66
+ {
67
+ binyo_instream_io *ret;
68
+ ret = ALLOC(binyo_instream_io);
69
+ memset(ret, 0, sizeof(binyo_instream_io));
70
+ ret->methods = &binyo_interface_io_generic;
71
+ return ret;
72
+ }
73
+
74
+ static VALUE
75
+ int_io_rb_protected_read(VALUE args)
76
+ {
77
+ VALUE io, vbuf, vlen;
78
+ io = rb_ary_entry(args, 0);
79
+ vlen = rb_ary_entry(args, 1);
80
+ vbuf = rb_ary_entry(args, 2);
81
+ return rb_funcall(io, sBinyo_ID_READ, 2, vlen, vbuf);
82
+ }
83
+
84
+ static int
85
+ int_io_rb_read_impl(binyo_instream_io *in, VALUE vlen, VALUE vbuf, VALUE *out)
86
+ {
87
+ VALUE args = rb_ary_new();
88
+ int state = 0;
89
+ rb_ary_push(args, in->io);
90
+ rb_ary_push(args, vlen);
91
+ rb_ary_push(args, vbuf);
92
+ *out = rb_protect(int_io_rb_protected_read, args, &state);
93
+ return state == 0 ? BINYO_OK : BINYO_ERR;
94
+ }
95
+
96
+ static ssize_t
97
+ int_io_read(binyo_instream *instream, uint8_t *buf, size_t len)
98
+ {
99
+ VALUE read, vlen, vbuf;
100
+ binyo_instream_io *in;
101
+
102
+ int_safe_cast(in, instream);
103
+
104
+ if (!buf) return BINYO_ERR;
105
+
106
+ vlen = LONG2NUM(len);
107
+ vbuf = rb_str_new2("");
108
+ rb_enc_associate(vbuf, rb_ascii8bit_encoding());
109
+
110
+ if (!int_io_rb_read_impl(in, vlen, vbuf, &read)) {
111
+ binyo_error_add("Error while reading from IO");
112
+ return BINYO_ERR;
113
+ }
114
+
115
+ if (NIL_P(read)) {
116
+ return BINYO_IO_EOF;
117
+ }
118
+ else {
119
+ ssize_t r = (ssize_t) RSTRING_LEN(read);
120
+ memcpy(buf, RSTRING_PTR(read), r);
121
+ return r;
122
+ }
123
+ }
124
+
125
+ static int
126
+ int_io_rb_read(binyo_instream *instream, VALUE vlen, VALUE vbuf, VALUE *out)
127
+ {
128
+ binyo_instream_io *in;
129
+
130
+ int_safe_cast(in, instream);
131
+ return int_io_rb_read_impl(in, vlen, vbuf, out);
132
+ }
133
+
134
+ static VALUE
135
+ int_whence_sym_for(int whence)
136
+ {
137
+ switch (whence) {
138
+ case SEEK_CUR:
139
+ return sBinyo_ID_SEEK_CUR;
140
+ case SEEK_SET:
141
+ return sBinyo_ID_SEEK_SET;
142
+ case SEEK_END:
143
+ return sBinyo_ID_SEEK_END;
144
+ default:
145
+ binyo_error_add("Unknown whence: %d", whence);
146
+ return Qnil;
147
+ }
148
+ }
149
+
150
+ /* TODO: rb_protect */
151
+ static int
152
+ int_io_seek(binyo_instream *instream, off_t offset, int whence)
153
+ {
154
+ VALUE io, whencesym;
155
+ binyo_instream_io *in;
156
+
157
+ int_safe_cast(in, instream);
158
+
159
+ io = in->io;
160
+ whencesym = int_whence_sym_for(whence);
161
+ if (NIL_P(whencesym)) return BINYO_ERR;
162
+ rb_funcall(io, sBinyo_ID_SEEK, 2, LONG2NUM(offset), whencesym);
163
+ return BINYO_OK;
164
+ }
165
+
166
+ static void
167
+ int_io_mark(binyo_instream *instream)
168
+ {
169
+ binyo_instream_io *in;
170
+
171
+ if (!instream) return;
172
+ int_safe_cast(in, instream);
173
+
174
+ rb_gc_mark(in->io);
175
+ }
176
+
177
+ static void
178
+ int_io_free(binyo_instream *instream)
179
+ {
180
+ /* do nothing */
181
+ }
182
+
@@ -0,0 +1,187 @@
1
+ /*
2
+ * binyo - Fast binary IO for Ruby
3
+ *
4
+ * Copyright (c) 2012-2013
5
+ * Martin Bosslet <martin.bosslet@gmail.com>
6
+ * All rights reserved.
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining
9
+ * a copy of this software and associated documentation files (the
10
+ * "Software"), to deal in the Software without restriction, including
11
+ * without limitation the rights to use, copy, modify, merge, publish,
12
+ * distribute, sublicense, and/or sell copies of the Software, and to
13
+ * permit persons to whom the Software is furnished to do so, subject to
14
+ * the following conditions:
15
+ *
16
+ * The above copyright notice and this permission notice shall be
17
+ * included in all copies or substantial portions of the Software.
18
+ *
19
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #include "binyo.h"
29
+ #include <stdarg.h>
30
+
31
+ typedef struct binyo_instream_seq_st {
32
+ binyo_instream_interface *methods;
33
+ binyo_instream *active;
34
+ int i;
35
+ binyo_instream **streams;
36
+ int num;
37
+ } binyo_instream_seq;
38
+
39
+ #define int_safe_cast(out, in) binyo_safe_cast_instream((out), (in), BINYO_INSTREAM_TYPE_SEQ, binyo_instream_seq)
40
+
41
+ static binyo_instream_seq* int_seq_alloc(void);
42
+ static ssize_t int_seq_read(binyo_instream *in, uint8_t *buf, size_t len);
43
+ static int int_seq_seek(binyo_instream *in, off_t offset, int whence);
44
+ static void int_seq_mark(binyo_instream *in);
45
+ static void int_seq_free(binyo_instream *in);
46
+
47
+ static binyo_instream_interface binyo_interface_seq = {
48
+ BINYO_INSTREAM_TYPE_SEQ,
49
+ int_seq_read,
50
+ NULL,
51
+ NULL,
52
+ int_seq_seek,
53
+ int_seq_mark,
54
+ int_seq_free
55
+ };
56
+
57
+ binyo_instream *
58
+ binyo_instream_new_seq(binyo_instream *in1, binyo_instream *in2)
59
+ {
60
+ return binyo_instream_new_seq_n(2, in1, in2);
61
+ }
62
+
63
+ binyo_instream *
64
+ binyo_instream_new_seq_n(int num, binyo_instream *in1, binyo_instream *in2, ...)
65
+ {
66
+ binyo_instream_seq *in;
67
+ va_list args;
68
+ int i = 0;
69
+
70
+ if (num < 2) {
71
+ binyo_error_add("At least two streams must be passed");
72
+ return NULL;
73
+ }
74
+
75
+ in = int_seq_alloc();
76
+ in->streams = ALLOC_N(binyo_instream *, num);
77
+ in->streams[i++] = in1;
78
+ in->streams[i++] = in2;
79
+ va_start(args, in2);
80
+
81
+ while (i < num) {
82
+ in->streams[i++] = va_arg(args, binyo_instream *);
83
+ }
84
+
85
+ va_end(args);
86
+ in->num = num;
87
+ in->i = 0;
88
+ in->active = in1;
89
+ return (binyo_instream *) in;
90
+ }
91
+
92
+ static binyo_instream_seq*
93
+ int_seq_alloc(void)
94
+ {
95
+ binyo_instream_seq *ret;
96
+ ret = ALLOC(binyo_instream_seq);
97
+ memset(ret, 0, sizeof(binyo_instream_seq));
98
+ ret->methods = &binyo_interface_seq;
99
+ return ret;
100
+ }
101
+
102
+ static ssize_t
103
+ int_do_read(binyo_instream_seq *in, uint8_t *buf, size_t len)
104
+ {
105
+ ssize_t read = 0;
106
+ size_t total = 0;
107
+
108
+ while (total < len && ((read = binyo_instream_read(in->active, buf, len - total)) >= 0)) {
109
+ total += read;
110
+ buf += read;
111
+ }
112
+
113
+ if (read == BINYO_ERR) return BINYO_ERR;
114
+ if (total == 0 && read == BINYO_IO_EOF) return BINYO_IO_EOF;
115
+ return total;
116
+ }
117
+
118
+ static ssize_t
119
+ int_seq_read(binyo_instream *instream, uint8_t *buf, size_t len)
120
+ {
121
+ ssize_t read;
122
+ binyo_instream_seq *in;
123
+ size_t total = 0;
124
+
125
+ int_safe_cast(in, instream);
126
+
127
+ if (!buf) return BINYO_ERR;
128
+
129
+ while (total < len) {
130
+ read = int_do_read(in, buf, len - total);
131
+ if (read == BINYO_ERR) return BINYO_ERR;
132
+ if (read == BINYO_IO_EOF) {
133
+ in->i++;
134
+ if (in->i == in->num) {
135
+ return BINYO_IO_EOF;
136
+ }
137
+ else {
138
+ in->active = in->streams[in->i];
139
+ }
140
+ }
141
+ else {
142
+ total += read;
143
+ buf += read;
144
+ }
145
+ }
146
+
147
+ return total;
148
+ }
149
+
150
+ static int
151
+ int_seq_seek(binyo_instream *instream, off_t offset, int whence)
152
+ {
153
+ binyo_instream_seq *in;
154
+
155
+ int_safe_cast(in, instream);
156
+ return binyo_instream_seek(in->active, offset, whence);
157
+ }
158
+
159
+ static void
160
+ int_seq_mark(binyo_instream *instream)
161
+ {
162
+ binyo_instream_seq *in;
163
+ int i;
164
+
165
+ if (!instream) return;
166
+ int_safe_cast(in, instream);
167
+
168
+ for(i=0; i < in->num; i++) {
169
+ binyo_instream_mark(in->streams[i]);
170
+ }
171
+ }
172
+
173
+ static void
174
+ int_seq_free(binyo_instream *instream)
175
+ {
176
+ binyo_instream_seq *in;
177
+ int i;
178
+
179
+ if (!instream) return;
180
+ int_safe_cast(in, instream);
181
+
182
+ for(i=0; i < in->num; i++) {
183
+ binyo_instream_free(in->streams[i]);
184
+ }
185
+ xfree(in->streams);
186
+ }
187
+