beefcake 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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