binyo 0.0.1

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.
@@ -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
+