binyo 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,120 @@
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_outstream_bytes_st {
31
+ binyo_outstream_interface *methods;
32
+ binyo_byte_buffer *buffer;
33
+ } binyo_outstream_bytes;
34
+
35
+ #define int_safe_cast(out, in) binyo_safe_cast_outstream((out), (in), BINYO_OUTSTREAM_TYPE_BYTES, binyo_outstream_bytes)
36
+
37
+ static binyo_outstream_bytes* int_bytes_alloc(void);
38
+ static ssize_t int_bytes_write(binyo_outstream *out, uint8_t *buf, size_t len);
39
+ static void int_bytes_free(binyo_outstream *out);
40
+
41
+ static binyo_outstream_interface binyo_interface_bytes = {
42
+ BINYO_OUTSTREAM_TYPE_BYTES,
43
+ int_bytes_write,
44
+ NULL,
45
+ NULL,
46
+ int_bytes_free
47
+ };
48
+
49
+ binyo_outstream *
50
+ binyo_outstream_new_bytes(void)
51
+ {
52
+ binyo_outstream_bytes *out;
53
+
54
+ out = int_bytes_alloc();
55
+ out->buffer = binyo_buffer_new();
56
+ return (binyo_outstream *) out;
57
+ }
58
+
59
+ binyo_outstream *
60
+ binyo_outstream_new_bytes_size(size_t size)
61
+ {
62
+ binyo_outstream_bytes *out;
63
+
64
+ out = int_bytes_alloc();
65
+ out->buffer = binyo_buffer_new_size(size);
66
+ return (binyo_outstream *) out;
67
+ }
68
+
69
+ binyo_outstream *
70
+ binyo_outstream_new_bytes_prealloc(uint8_t *b, size_t len)
71
+ {
72
+ binyo_outstream_bytes *out;
73
+
74
+ out = int_bytes_alloc();
75
+ out->buffer = binyo_buffer_new_prealloc(b, len);
76
+ return (binyo_outstream *) out;
77
+ }
78
+
79
+ size_t
80
+ binyo_outstream_bytes_get_bytes_free(binyo_outstream *outstream, uint8_t **bytes)
81
+ {
82
+ binyo_outstream_bytes *out;
83
+ size_t len;
84
+
85
+ int_safe_cast(out, outstream);
86
+ len = binyo_buffer_get_bytes_free(out->buffer, bytes);
87
+ xfree(out);
88
+ return len;
89
+ }
90
+
91
+ static binyo_outstream_bytes *
92
+ int_bytes_alloc(void)
93
+ {
94
+ binyo_outstream_bytes *ret;
95
+ ret = ALLOC(binyo_outstream_bytes);
96
+ memset(ret, 0, sizeof(binyo_outstream_bytes));
97
+ ret->methods = &binyo_interface_bytes;
98
+ return ret;
99
+ }
100
+
101
+ static ssize_t
102
+ int_bytes_write(binyo_outstream *outstream, uint8_t *buf, size_t len)
103
+ {
104
+ binyo_outstream_bytes *out;
105
+
106
+ int_safe_cast(out, outstream);
107
+ return binyo_buffer_write(out->buffer, buf, len);
108
+ }
109
+
110
+ static void
111
+ int_bytes_free(binyo_outstream *outstream)
112
+ {
113
+ binyo_outstream_bytes *out;
114
+
115
+ if (!outstream) return;
116
+ int_safe_cast(out, outstream);
117
+ if (out->buffer)
118
+ binyo_buffer_free(out->buffer);
119
+ }
120
+
@@ -0,0 +1,110 @@
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_outstream_fd_st {
33
+ binyo_outstream_interface *methods;
34
+ int fd;
35
+ } binyo_outstream_fd;
36
+
37
+ #define int_safe_cast(out, in) binyo_safe_cast_outstream((out), (in), BINYO_OUTSTREAM_TYPE_FD, binyo_outstream_fd)
38
+
39
+ static binyo_outstream_fd* int_fd_alloc(void);
40
+ static ssize_t int_fd_write(binyo_outstream *out, uint8_t *buf, size_t len);
41
+ static void int_fd_free(binyo_outstream *out);
42
+
43
+ static binyo_outstream_interface binyo_interface_fd = {
44
+ BINYO_OUTSTREAM_TYPE_FD,
45
+ int_fd_write,
46
+ NULL,
47
+ NULL,
48
+ int_fd_free
49
+ };
50
+
51
+ binyo_outstream *
52
+ binyo_outstream_new_fd_io(VALUE value)
53
+ {
54
+ rb_io_t *fptr;
55
+ GetOpenFile(value, fptr);
56
+ rb_io_check_writable(fptr);
57
+ return binyo_outstream_new_fd(fptr->fd);
58
+ }
59
+
60
+ binyo_outstream *
61
+ binyo_outstream_new_fd(int fd)
62
+ {
63
+ binyo_outstream_fd *out;
64
+
65
+ out = int_fd_alloc();
66
+ out->fd = fd;
67
+ return (binyo_outstream *) out;
68
+ }
69
+
70
+ static binyo_outstream_fd*
71
+ int_fd_alloc(void)
72
+ {
73
+ binyo_outstream_fd *ret;
74
+ ret = ALLOC(binyo_outstream_fd);
75
+ memset(ret, 0, sizeof(binyo_outstream_fd));
76
+ ret->methods = &binyo_interface_fd;
77
+ return ret;
78
+ }
79
+
80
+ static ssize_t
81
+ int_fd_write(binyo_outstream *outstream, uint8_t *buf, size_t len)
82
+ {
83
+ int fd;
84
+ ssize_t w;
85
+ binyo_outstream_fd *out;
86
+
87
+ int_safe_cast(out, outstream);
88
+
89
+ if (!buf) return BINYO_ERR;
90
+
91
+ fd = out->fd;
92
+ binyo_clear_sys_error();
93
+ /* no need to increase out->num_written */
94
+ w = write(fd, buf, len);
95
+
96
+ if (w < 0) {
97
+ binyo_add_io_error();
98
+ return BINYO_ERR;
99
+ }
100
+ else {
101
+ return w;
102
+ }
103
+ }
104
+
105
+ static void
106
+ int_fd_free(binyo_outstream *out)
107
+ {
108
+ /* do not close the fd, should be done explicitly */
109
+ }
110
+
@@ -0,0 +1,125 @@
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_outstream_io_st {
31
+ binyo_outstream_interface *methods;
32
+ VALUE io;
33
+ } binyo_outstream_io;
34
+
35
+ #define int_safe_cast(out, in) binyo_safe_cast_outstream((out), (in), BINYO_OUTSTREAM_TYPE_IO_GENERIC, binyo_outstream_io)
36
+
37
+ static binyo_outstream_io* int_io_alloc(void);
38
+ static ssize_t int_io_write(binyo_outstream *out, uint8_t *buf, size_t len);
39
+ static int int_io_rb_write(binyo_outstream *out, VALUE vbuf, VALUE *ret);
40
+ static void int_io_mark(binyo_outstream *out);
41
+ static void int_io_free(binyo_outstream *out);
42
+
43
+ static binyo_outstream_interface binyo_interface_io = {
44
+ BINYO_OUTSTREAM_TYPE_IO_GENERIC,
45
+ int_io_write,
46
+ int_io_rb_write,
47
+ int_io_mark,
48
+ int_io_free
49
+ };
50
+
51
+ binyo_outstream *
52
+ binyo_outstream_new_io_generic(VALUE io)
53
+ {
54
+ binyo_outstream_io *out;
55
+
56
+ out = int_io_alloc();
57
+ out->io = io;
58
+ return (binyo_outstream *) out;
59
+ }
60
+
61
+ static binyo_outstream_io *
62
+ int_io_alloc(void)
63
+ {
64
+ binyo_outstream_io *ret;
65
+ ret = ALLOC(binyo_outstream_io);
66
+ memset(ret, 0, sizeof(binyo_outstream_io));
67
+ ret->methods = &binyo_interface_io;
68
+ return ret;
69
+ }
70
+
71
+ static ssize_t
72
+ int_io_write(binyo_outstream *outstream, uint8_t *buf, size_t len)
73
+ {
74
+ VALUE vbuf, ret;
75
+
76
+ if (!buf) return BINYO_ERR;
77
+
78
+ vbuf = rb_str_new((const char *)buf, len);
79
+ if(int_io_rb_write(outstream, vbuf, &ret) == BINYO_ERR) {
80
+ binyo_error_add("Error while writing to IO");
81
+ return BINYO_ERR;
82
+ }
83
+ return NUM2LONG(ret);
84
+ }
85
+
86
+ static VALUE
87
+ int_io_rb_protected_write(VALUE args)
88
+ {
89
+ VALUE io, vbuf;
90
+ io = rb_ary_entry(args, 0);
91
+ vbuf = rb_ary_entry(args, 1);
92
+ return rb_funcall(io, sBinyo_ID_WRITE, 1, vbuf);
93
+ }
94
+
95
+ static int
96
+ int_io_rb_write(binyo_outstream *outstream, VALUE vbuf, VALUE *ret)
97
+ {
98
+ binyo_outstream_io *out;
99
+ VALUE args;
100
+ int state = 0;
101
+
102
+ int_safe_cast(out, outstream);
103
+ args = rb_ary_new();
104
+ rb_ary_push(args, out->io);
105
+ rb_ary_push(args, vbuf);
106
+ *ret = rb_protect(int_io_rb_protected_write, args, &state);
107
+ return state == 0 ? BINYO_OK : BINYO_ERR;
108
+ }
109
+
110
+ static void
111
+ int_io_mark(binyo_outstream *outstream)
112
+ {
113
+ binyo_outstream_io *out;
114
+
115
+ if (!outstream) return;
116
+ int_safe_cast(out, outstream);
117
+ rb_gc_mark(out->io);
118
+ }
119
+
120
+ static void
121
+ int_io_free(binyo_outstream *outstream)
122
+ {
123
+ /* do nothing */
124
+ }
125
+
@@ -0,0 +1,32 @@
1
+ =begin
2
+
3
+ = Info
4
+
5
+ binyo - Fast binary IO for Ruby
6
+
7
+ Copyright (C) 2012-2013
8
+ Martin Bosslet <martin.bosslet@gmail.com>
9
+ All rights reserved.
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining
12
+ a copy of this software and associated documentation files (the
13
+ "Software"), to deal in the Software without restriction, including
14
+ without limitation the rights to use, copy, modify, merge, publish,
15
+ distribute, sublicense, and/or sell copies of the Software, and to
16
+ permit persons to whom the Software is furnished to do so, subject to
17
+ the following conditions:
18
+
19
+ The above copyright notice and this permission notice shall be
20
+ included in all copies or substantial portions of the Software.
21
+
22
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
+
30
+ =end
31
+
32
+ require 'binyo.so'
Binary file
@@ -0,0 +1,135 @@
1
+ require 'binyo'
2
+ require 'benchmark'
3
+
4
+ HEX_TABLE = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102]
5
+ HEX_TABLE_INV = [
6
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
7
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
8
+ -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1,
9
+ -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
10
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12,
11
+ 13, 14, 15
12
+ ] #102
13
+ HEX_INV_MAX = 102
14
+
15
+ module Hex
16
+
17
+ def self.encode(data)
18
+ ("\0" * (data.size * 2)).tap do |ret|
19
+ data.each_byte.each_with_index do |b, i|
20
+ ret.setbyte(i * 2, HEX_TABLE[b >> 4])
21
+ ret.setbyte(i * 2 + 1, HEX_TABLE[b & 0x0f])
22
+ end
23
+ end
24
+ end
25
+
26
+ def self.decode(data)
27
+ len = data.size
28
+ raise RuntimeError.new("Hex-encoded data length must be a multiple of 2") unless len % 2 == 0
29
+ "".tap do |ret|
30
+ (len / 2).times do |i|
31
+ dbl_i = i * 2
32
+ c = data[dbl_i].ord
33
+ d = data[dbl_i + 1].ord
34
+ if c > HEX_INV_MAX || d > HEX_INV_MAX
35
+ raise RuntimeError.new("Illegal hex character detected: #{c}|#{d}")
36
+ end
37
+ b = HEX_TABLE_INV[c]
38
+ raise illegal_hex_char(c) if b < 0
39
+ b = b << 4
40
+ bb = HEX_TABLE_INV[d]
41
+ raise illegal_hex_char(d) if bb < 0
42
+ ret << (b | bb)
43
+ end
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ def self.illegal_hex_char(c)
50
+ RuntimeError.new("Illegal hex character detected: #{c}")
51
+ end
52
+
53
+ end
54
+
55
+ module BinyoHex
56
+
57
+ def self.encode(data)
58
+ input = Binyo::ByteList.new(data)
59
+ bl = Binyo::ByteList.new(data.size * 2)
60
+ input.each do |b|
61
+ bl << HEX_TABLE[b >> 4]
62
+ bl << HEX_TABLE[b & 0x0f]
63
+ end
64
+ bl.to_s
65
+ end
66
+
67
+ def self.decode(data)
68
+ raise RuntimeError.new("Hex-encoded data length must be a multiple of 2") unless data.size % 2 == 0
69
+ input = Binyo::ByteList.new(data)
70
+ half_len = data.size / 2
71
+ bl = Binyo::ByteList.new(half_len)
72
+ half_len.times do |i|
73
+ dbl_i = i * 2
74
+ c = input[dbl_i]
75
+ d = input[dbl_i + 1]
76
+ if c > HEX_INV_MAX || d > HEX_INV_MAX
77
+ raise RuntimeError.new("Illegal hex character detected: #{c}|#{d}")
78
+ end
79
+ b = HEX_TABLE_INV[c]
80
+ raise illegal_hex_char(c) if b < 0
81
+ b = b << 4
82
+ bb = HEX_TABLE_INV[d]
83
+ raise illegal_hex_char(d) if bb < 0
84
+ bl << (b | bb)
85
+ end
86
+ bl.to_s
87
+ end
88
+
89
+ end
90
+
91
+ Benchmark.bm do |bm|
92
+ n = 1000
93
+
94
+ data = "test" * 10000
95
+
96
+ bm.report("unpack('H*')") do
97
+ n.times do
98
+ data.unpack("H*")[0]
99
+ end
100
+ end
101
+
102
+ bm.report("Hex.encode") do
103
+ n.times do
104
+ Hex.encode(data)
105
+ end
106
+ end
107
+
108
+ bm.report("BinyoHex.encode") do
109
+ n.times do
110
+ BinyoHex.encode(data)
111
+ end
112
+ end
113
+
114
+ enc = data.unpack("H*")[0]
115
+
116
+ bm.report("pack('H*')") do
117
+ n.times do
118
+ [enc].pack("H*")
119
+ end
120
+ end
121
+
122
+ bm.report("Hex.decode") do
123
+ n.times do
124
+ Hex.decode(enc)
125
+ end
126
+ end
127
+
128
+ bm.report("BinyoHex.decode") do
129
+ n.times do
130
+ BinyoHex.decode(enc)
131
+ end
132
+ end
133
+
134
+ end
135
+