beefcake 0.1.0

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,101 @@
1
+ require 'beefcake/buffer/base'
2
+
3
+ module Beefcake
4
+
5
+ class Buffer
6
+
7
+ def read_info
8
+ n = read_uint64
9
+ fn = n >> 3
10
+ wire = n & 0x7
11
+
12
+ [fn, wire]
13
+ end
14
+
15
+ def read_string
16
+ read(read_uint64)
17
+ end
18
+ alias :read_bytes :read_string
19
+
20
+ def read_fixed32
21
+ bytes = read(4)
22
+ bytes.unpack("V").first
23
+ end
24
+
25
+ def read_fixed64
26
+ bytes = read(8)
27
+ x, y = bytes.unpack("VV")
28
+ x + (y << 32)
29
+ end
30
+
31
+ def read_int64
32
+ n = read_uint64
33
+ if n > MaxInt64
34
+ n -= (1 << 64)
35
+ end
36
+ n
37
+ end
38
+ alias :read_int32 :read_int64
39
+
40
+ def read_uint64
41
+ n = shift = 0
42
+ while true
43
+ if shift >= 64
44
+ raise BufferOverflowError, "varint"
45
+ end
46
+ b = buf.slice!(0).ord
47
+ n |= ((b & 0x7F) << shift)
48
+ shift += 7
49
+ if (b & 0x80) == 0
50
+ return n
51
+ end
52
+ end
53
+ end
54
+ alias :read_uint32 :read_uint64
55
+
56
+ def read_sint64
57
+ decode_zigzag(read_uint64)
58
+ end
59
+ alias :read_sint32 :read_sint64
60
+
61
+ def read_sfixed32
62
+ decode_zigzag(read_fixed32)
63
+ end
64
+
65
+ def read_sfixed64
66
+ decode_zigzag(read_fixed64)
67
+ end
68
+
69
+ def read_float
70
+ bytes = read(4)
71
+ bytes.unpack("e").first
72
+ end
73
+
74
+ def read_double
75
+ bytes = read(8)
76
+ bytes.unpack("E").first
77
+ end
78
+
79
+ def read_bool
80
+ read_int32 != 0
81
+ end
82
+
83
+ def skip(wire)
84
+ case wire
85
+ when 0 then read_uint64
86
+ when 1 then read_fixed64
87
+ when 2 then read_string
88
+ when 5 then read_fixed32
89
+ end
90
+ end
91
+
92
+
93
+ private
94
+
95
+ def decode_zigzag(n)
96
+ (n >> 1) ^ -(n & 1)
97
+ end
98
+
99
+ end
100
+
101
+ end
@@ -0,0 +1,115 @@
1
+ require 'beefcake/buffer/base'
2
+
3
+ module Beefcake
4
+
5
+ class Buffer
6
+
7
+ def append(type, val, fn)
8
+ if fn != 0
9
+ wire = Buffer.wire_for(type)
10
+ append_info(fn, wire)
11
+ end
12
+
13
+ __send__("append_#{type}", val)
14
+ end
15
+
16
+ def append_info(fn, wire)
17
+ self << ((fn << 3) | wire)
18
+ end
19
+
20
+ def append_fixed32(n, tag=false)
21
+ if n < MinUint32 or n > MaxUint32
22
+ raise OutOfRangeError, n
23
+ end
24
+
25
+ self << [n].pack("V")
26
+ end
27
+
28
+ def append_fixed64(n)
29
+ if n < MinUint64 or n > MaxUint64
30
+ raise OutOfRangeError, n
31
+ end
32
+
33
+ self << [n & 0xFFFFFFFF, n >> 32].pack("VV")
34
+ end
35
+
36
+ def append_int32(n)
37
+ if n < MinInt32 or n > MaxInt32
38
+ raise OutOfRangeError, n
39
+ end
40
+
41
+ append_int64(n)
42
+ end
43
+
44
+ def append_uint32(n)
45
+ if n < MinUint32 or n > MaxUint32
46
+ raise OutOfRangeError, n
47
+ end
48
+
49
+ append_uint64(n)
50
+ end
51
+
52
+ def append_int64(n)
53
+ if n < MinInt64 or n > MaxInt64
54
+ raise OutOfRangeError, n
55
+ end
56
+
57
+ if n < 0
58
+ n += (1 << 64)
59
+ end
60
+
61
+ append_uint64(n)
62
+ end
63
+
64
+ def append_sint32(n)
65
+ append_uint32((n << 1) ^ (n >> 31))
66
+ end
67
+
68
+ def append_sfixed32(n)
69
+ append_fixed32((n << 1) ^ (n >> 31))
70
+ end
71
+
72
+ def append_sint64(n)
73
+ append_uint64((n << 1) ^ (n >> 63))
74
+ end
75
+
76
+ def append_sfixed64(n)
77
+ append_fixed64((n << 1) ^ (n >> 63))
78
+ end
79
+
80
+ def append_uint64(n)
81
+ if n < MinUint64 or n > MaxUint64
82
+ raise OutOfRangeError, n
83
+ end
84
+
85
+ while true
86
+ bits = n & 0x7F
87
+ n >>= 7
88
+ if n == 0
89
+ return self << bits
90
+ end
91
+ self << (bits | 0x80)
92
+ end
93
+ end
94
+
95
+ def append_float(n)
96
+ self << [n].pack("e")
97
+ end
98
+
99
+ def append_double(n)
100
+ self << [n].pack("E")
101
+ end
102
+
103
+ def append_bool(n)
104
+ append_int64(n ? 1 : 0)
105
+ end
106
+
107
+ def append_string(s)
108
+ append_uint64(s.length)
109
+ self << s
110
+ end
111
+ alias :append_bytes :append_string
112
+
113
+ end
114
+
115
+ end
@@ -0,0 +1,114 @@
1
+ require 'beefcake/buffer'
2
+
3
+ class BufferDecodeTest < Test::Unit::TestCase
4
+
5
+ B = Beefcake::Buffer
6
+
7
+ def setup
8
+ @buf = B.new
9
+ end
10
+
11
+ def test_read_info
12
+ @buf.append_info(1, 2)
13
+ assert_equal [1, 2], @buf.read_info
14
+
15
+ @buf.append_info(2, 5)
16
+ assert_equal [2, 5], @buf.read_info
17
+ end
18
+
19
+ def test_read_string
20
+ @buf.append_string("testing")
21
+ assert_equal "testing", @buf.read_string
22
+ end
23
+
24
+ def test_read_fixed32
25
+ @buf.append_fixed32(123)
26
+ assert_equal 123, @buf.read_fixed32
27
+ end
28
+
29
+ def test_read_fixed64
30
+ @buf.append_fixed64(456)
31
+ assert_equal 456, @buf.read_fixed64
32
+ end
33
+
34
+ def test_read_uint32
35
+ @buf.append_uint32(1)
36
+ assert_equal 1, @buf.read_uint32
37
+ end
38
+
39
+ def test_read_int32
40
+ @buf.append_int32(999)
41
+ assert_equal 999, @buf.read_int32
42
+
43
+ @buf.append_int32(-999)
44
+ assert_equal -999, @buf.read_int32
45
+ end
46
+
47
+ def test_read_int64
48
+ @buf.append_int64(999)
49
+ assert_equal 999, @buf.read_int64
50
+
51
+ @buf.append_int64(-999)
52
+ assert_equal -999, @buf.read_int64
53
+ end
54
+
55
+ def test_read_uint64
56
+ @buf.append_uint64(1)
57
+ assert_equal 1, @buf.read_uint64
58
+ end
59
+
60
+ def test_read_float
61
+ @buf.append_float(0.5)
62
+ assert_equal 0.5, @buf.read_float
63
+ end
64
+
65
+ def test_read_double
66
+ @buf.append_double(Math::PI)
67
+ assert_equal Math::PI, @buf.read_double
68
+ end
69
+
70
+ def test_read_bool
71
+ @buf.append_bool(true)
72
+ assert_equal true, @buf.read_bool
73
+
74
+ @buf.append_bool(false)
75
+ assert_equal false, @buf.read_bool
76
+ end
77
+
78
+ def test_read_sint32
79
+ @buf.append_sint32(B::MinInt32)
80
+ assert_equal B::MinInt32, @buf.read_sint32
81
+
82
+ @buf.buf = ""
83
+ @buf.append_sint32(B::MaxInt32)
84
+ assert_equal B::MaxInt32, @buf.read_sint32
85
+ end
86
+
87
+ def test_read_sfixed32
88
+ @buf.append_sfixed32(B::MinInt32)
89
+ assert_equal B::MinInt32, @buf.read_sfixed32
90
+
91
+ @buf.buf = ""
92
+ @buf.append_sfixed32(B::MaxInt32)
93
+ assert_equal B::MaxInt32, @buf.read_sfixed32
94
+ end
95
+
96
+ def test_read_sint64
97
+ @buf.append_sint64(B::MinInt64)
98
+ assert_equal B::MinInt64, @buf.read_sint64
99
+
100
+ @buf.buf = ""
101
+ @buf.append_sint64(B::MaxInt64)
102
+ assert_equal B::MaxInt64, @buf.read_sint64
103
+ end
104
+
105
+ def test_read_sfixed64
106
+ @buf.append_sfixed64(B::MinInt64)
107
+ assert_equal B::MinInt64, @buf.read_sfixed64
108
+
109
+ @buf.buf = ""
110
+ @buf.append_sfixed64(B::MaxInt64)
111
+ assert_equal B::MaxInt64, @buf.read_sfixed64
112
+ end
113
+
114
+ end
@@ -0,0 +1,222 @@
1
+ require 'beefcake/buffer/encode'
2
+
3
+ class BufferEncodeTest < Test::Unit::TestCase
4
+
5
+ B = Beefcake::Buffer
6
+
7
+ def setup
8
+ @buf = B.new
9
+ end
10
+
11
+ def test_append_info
12
+ @buf.append_info(1, 0)
13
+ assert_equal "\010", @buf.to_s
14
+
15
+ @buf.buf = ""
16
+ @buf.append_info(2, 1)
17
+ assert_equal "\021", @buf.to_s
18
+ end
19
+
20
+ def test_append_string
21
+ @buf.append_string("testing")
22
+ assert_equal "\007testing", @buf.to_s
23
+ end
24
+
25
+ def test_append_fixed32
26
+ @buf.append_fixed32(1)
27
+ assert_equal "\001\0\0\0", @buf.to_s
28
+
29
+ @buf.buf = ""
30
+ @buf.append_fixed32(B::MinUint32)
31
+ assert_equal "\0\0\0\0", @buf.to_s
32
+
33
+ @buf.buf = ""
34
+ @buf.append_fixed32(B::MaxUint32)
35
+ assert_equal "\377\377\377\377", @buf.to_s
36
+
37
+ assert_raises B::OutOfRangeError do
38
+ @buf.append_fixed32(B::MinUint32 - 1)
39
+ end
40
+
41
+ assert_raises B::OutOfRangeError do
42
+ @buf.append_fixed32(B::MaxUint32 + 1)
43
+ end
44
+ end
45
+
46
+ def test_append_fixed64
47
+ @buf.append_fixed64(1)
48
+ assert_equal "\001\0\0\0\0\0\0\0", @buf.to_s
49
+
50
+ @buf.buf = ""
51
+ @buf.append_fixed64(B::MinUint64)
52
+ assert_equal "\000\0\0\0\0\0\0\0", @buf.to_s
53
+
54
+ @buf.buf = ""
55
+ @buf.append_fixed64(B::MaxUint64)
56
+ assert_equal "\377\377\377\377\377\377\377\377", @buf.to_s
57
+
58
+ assert_raises B::OutOfRangeError do
59
+ @buf.append_fixed64(B::MinUint64 - 1)
60
+ end
61
+
62
+ assert_raises B::OutOfRangeError do
63
+ @buf.append_fixed64(B::MaxUint64 + 1)
64
+ end
65
+ end
66
+
67
+ def test_append_uint32
68
+ @buf.append_uint32(1)
69
+ assert_equal "\001", @buf.to_s
70
+
71
+ @buf.buf = ""
72
+ @buf.append_uint32(B::MinUint32)
73
+ assert_equal "\000", @buf.to_s
74
+
75
+ @buf.buf = ""
76
+ @buf.append_uint32(B::MaxUint32)
77
+ assert_equal "\377\377\377\377\017", @buf.to_s
78
+
79
+ assert_raises B::OutOfRangeError do
80
+ @buf.append_uint32(B::MinUint32 - 1)
81
+ end
82
+
83
+ assert_raises B::OutOfRangeError do
84
+ @buf.append_uint32(B::MaxUint32 + 1)
85
+ end
86
+ end
87
+
88
+ def test_append_int32
89
+ @buf.append_int32(1)
90
+ assert_equal "\001", @buf.to_s
91
+
92
+ @buf.buf = ""
93
+ @buf.append_int32(-1)
94
+ assert_equal "\377\377\377\377\377\377\377\377\377\001", @buf.to_s
95
+
96
+ @buf.buf = ""
97
+ @buf.append_int32(B::MinInt32)
98
+ assert_equal "\200\200\200\200\370\377\377\377\377\001", @buf.to_s
99
+
100
+ @buf.buf = ""
101
+ @buf.append_int32(B::MaxInt32)
102
+ assert_equal "\377\377\377\377\007", @buf.to_s
103
+
104
+ assert_raises B::OutOfRangeError do
105
+ @buf.append_int32(B::MinInt32 - 1)
106
+ end
107
+
108
+ assert_raises B::OutOfRangeError do
109
+ @buf.append_int32(B::MaxInt32 + 1)
110
+ end
111
+ end
112
+
113
+ def test_append_int64
114
+ @buf.append_int64(1)
115
+ assert_equal "\001", @buf.to_s
116
+
117
+ @buf.buf = ""
118
+ @buf.append_int64(-1)
119
+ assert_equal "\377\377\377\377\377\377\377\377\377\001", @buf.to_s
120
+
121
+ @buf.buf = ""
122
+ @buf.append_int64(B::MinInt64)
123
+ assert_equal "\200\200\200\200\200\200\200\200\200\001", @buf.to_s
124
+
125
+ @buf.buf = ""
126
+ @buf.append_int64(B::MaxInt64)
127
+ assert_equal "\377\377\377\377\377\377\377\377\177", @buf.to_s
128
+
129
+ assert_raises B::OutOfRangeError do
130
+ @buf.append_int64(B::MinInt64 - 1)
131
+ end
132
+
133
+ assert_raises B::OutOfRangeError do
134
+ @buf.append_int64(B::MaxInt64 + 1)
135
+ end
136
+ end
137
+
138
+ def test_append_uint64
139
+ @buf.append_uint64(1)
140
+ assert_equal "\001", @buf.to_s
141
+
142
+ @buf.buf = ""
143
+ @buf.append_uint64(B::MinUint64)
144
+ assert_equal "\000", @buf.to_s
145
+
146
+ @buf.buf = ""
147
+ @buf.append_uint64(B::MaxUint64)
148
+ assert_equal "\377\377\377\377\377\377\377\377\377\001", @buf.to_s
149
+
150
+ assert_raises B::OutOfRangeError do
151
+ @buf.append_uint64(B::MinUint64 - 1)
152
+ end
153
+
154
+ assert_raises B::OutOfRangeError do
155
+ @buf.append_uint64(B::MaxUint64 + 1)
156
+ end
157
+ end
158
+
159
+ def test_append_float
160
+ @buf.append_float(3.14)
161
+ assert_equal "\303\365H@", @buf.to_s
162
+ end
163
+
164
+ def test_append_double
165
+ @buf.buf = ""
166
+ @buf.append_float(Math::PI)
167
+ assert_equal "\333\017I@", @buf.to_s
168
+ end
169
+
170
+ def test_append_bool
171
+ @buf.append_bool(true)
172
+ @buf.append_bool(false)
173
+ assert_equal "\001\000", @buf.to_s
174
+ end
175
+
176
+ def test_append_sint32
177
+ @buf.append_sint32(-2)
178
+ assert_equal "\003", @buf.to_s
179
+
180
+ @buf.buf = ""
181
+ @buf.append_sint32(B::MaxInt32)
182
+ assert_equal "\376\377\377\377\017", @buf.to_s
183
+
184
+ @buf.buf = ""
185
+ @buf.append_sint32(B::MinInt32)
186
+ assert_equal "\377\377\377\377\017", @buf.to_s
187
+ end
188
+
189
+ def test_append_sfixed32
190
+ @buf.append_sfixed32(-2)
191
+ assert_equal "\003\000\000\000", @buf.to_s
192
+ end
193
+
194
+ def test_append_sint64
195
+ @buf.append_sint64(-2)
196
+ assert_equal "\003", @buf.to_s
197
+
198
+ @buf.buf = ""
199
+ @buf.append_sint64(B::MaxInt64)
200
+ assert_equal "\376\377\377\377\377\377\377\377\377\001", @buf.to_s
201
+
202
+ @buf.buf = ""
203
+ @buf.append_sint64(B::MinInt64)
204
+ assert_equal "\377\377\377\377\377\377\377\377\377\001", @buf.to_s
205
+ end
206
+
207
+ def test_append_sfixed64
208
+ @buf.append_sfixed64(B::MaxInt64)
209
+ assert_equal "\376\377\377\377\377\377\377\377", @buf.to_s
210
+ end
211
+
212
+ def test_append_string
213
+ @buf.append_string("testing")
214
+ assert_equal "\007testing", @buf.to_s
215
+ end
216
+
217
+ def test_append_bytes
218
+ @buf.append_bytes("testing")
219
+ assert_equal "\007testing", @buf.to_s
220
+ end
221
+
222
+ end