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.
- data/LICENSE +22 -0
- data/README.md +126 -0
- data/lib/beefcake.rb +203 -0
- data/lib/beefcake/buffer.rb +2 -0
- data/lib/beefcake/buffer/base.rb +92 -0
- data/lib/beefcake/buffer/decode.rb +101 -0
- data/lib/beefcake/buffer/encode.rb +115 -0
- data/test/buffer_decode_test.rb +114 -0
- data/test/buffer_encode_test.rb +222 -0
- data/test/buffer_test.rb +44 -0
- data/test/message_test.rb +280 -0
- metadata +122 -0
@@ -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
|