mochilo 1.3.0 → 2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -4
- data/Gemfile.lock +1 -1
- data/LICENSE +21 -0
- data/README.md +12 -26
- data/docs/format-spec.md +63 -44
- data/docs/why-banana-pack.md +5 -3
- data/ext/mochilo/buffer.c +11 -14
- data/ext/mochilo/buffer.h +4 -5
- data/ext/mochilo/mochilo.h +33 -27
- data/ext/mochilo/mochilo.rb.c +15 -42
- data/ext/mochilo/mochilo_api.h +2 -15
- data/ext/mochilo/mochilo_pack.c +103 -95
- data/ext/mochilo/mochilo_unpack.c +125 -32
- data/lib/mochilo/version.rb +1 -1
- data/mochilo.gemspec +2 -1
- data/script/bootstrap +1 -0
- data/test/pack_test.rb +169 -64
- data/test/setup.rb +4 -9
- data/test/unpack_test.rb +243 -48
- metadata +5 -8
- data/MIT-LICENSE +0 -20
data/test/pack_test.rb
CHANGED
@@ -4,7 +4,7 @@ require File.expand_path('../setup', __FILE__)
|
|
4
4
|
require 'mochilo'
|
5
5
|
require 'stringio'
|
6
6
|
|
7
|
-
class MochiloPackTest <
|
7
|
+
class MochiloPackTest < Minitest::Test
|
8
8
|
|
9
9
|
OBJECTS = [
|
10
10
|
{"hello" => "world"},
|
@@ -52,122 +52,222 @@ class MochiloPackTest < MiniTest::Unit::TestCase
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def test_pack_positive_fixed
|
55
|
-
|
55
|
+
[0,127].each do |int|
|
56
|
+
assert_equal int.chr, Mochilo.pack(int)
|
57
|
+
end
|
56
58
|
end
|
57
59
|
|
58
60
|
def test_pack_negative_fixed
|
59
|
-
assert_equal "\
|
61
|
+
assert_equal "\xFF", Mochilo.pack(-1)
|
62
|
+
assert_equal "\xE0", Mochilo.pack(-32)
|
60
63
|
end
|
61
64
|
|
62
65
|
def test_pack_uint8
|
63
|
-
|
66
|
+
[128,255].each do |int|
|
67
|
+
assert_equal "\xCC#{int.chr}", Mochilo.pack(int)
|
68
|
+
end
|
64
69
|
end
|
65
70
|
|
66
71
|
def test_pack_uint16
|
67
|
-
|
72
|
+
[256,((2**16)-1)].each do |int|
|
73
|
+
packed = [int].pack("n")
|
74
|
+
assert_equal "\xCD#{packed}", Mochilo.pack(int)
|
75
|
+
end
|
68
76
|
end
|
69
77
|
|
70
78
|
def test_pack_uint32
|
71
|
-
|
79
|
+
[(2**16),((2**32)-1)].each do |int|
|
80
|
+
packed = [int].pack("N")
|
81
|
+
assert_equal "\xCE#{packed}", Mochilo.pack(int)
|
82
|
+
end
|
72
83
|
end
|
73
84
|
|
74
85
|
def test_pack_uint64
|
75
|
-
|
86
|
+
[(2**32),((2**64)-1)].each do |int|
|
87
|
+
packed = [int].pack("Q>")
|
88
|
+
assert_equal "\xCF#{packed}", Mochilo.pack(int)
|
89
|
+
end
|
76
90
|
end
|
77
91
|
|
78
92
|
def test_pack_int8
|
79
|
-
assert_equal "\xD0\
|
93
|
+
assert_equal "\xD0\xDF", Mochilo.pack(-33)
|
94
|
+
assert_equal "\xD0\x80", Mochilo.pack(-128)
|
80
95
|
end
|
81
96
|
|
82
97
|
def test_pack_int16
|
83
|
-
assert_equal "\xD1\
|
98
|
+
assert_equal "\xD1\xFF\x7F", Mochilo.pack(-129)
|
99
|
+
assert_equal "\xD1\x80\x00", Mochilo.pack(-32768)
|
84
100
|
end
|
85
101
|
|
86
102
|
def test_pack_int32
|
87
|
-
assert_equal "\xD2\
|
103
|
+
assert_equal "\xD2\xFF\xFF\x7F\xFF", Mochilo.pack(-32769)
|
104
|
+
assert_equal "\xD2\x80\x00\x00\x00", Mochilo.pack(-2147483648)
|
88
105
|
end
|
89
106
|
|
90
107
|
def test_pack_int64
|
91
|
-
assert_equal "\xD3\xFF\xFF\xFF\
|
108
|
+
assert_equal "\xD3\xFF\xFF\xFF\xFF\x7F\xFF\xFF\xFF", Mochilo.pack(-2147483649)
|
109
|
+
assert_equal "\xD3\x80\x00\x00\x00\x00\x00\x00\x00", Mochilo.pack(-9223372036854775808)
|
92
110
|
end
|
93
111
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
112
|
+
def test_pack_fixed_str
|
113
|
+
str = "a".force_encoding('UTF-8')
|
114
|
+
assert_equal "\xA1#{str}", Mochilo.pack(str)
|
115
|
+
|
116
|
+
str = ("a"*31).force_encoding('UTF-8')
|
117
|
+
assert_equal "\xBF#{str}", Mochilo.pack(str)
|
99
118
|
end
|
100
119
|
|
101
|
-
def
|
102
|
-
|
120
|
+
def test_pack_str8
|
121
|
+
str = ("a"*32).force_encoding('UTF-8')
|
122
|
+
assert_equal "\xD9#{str.bytesize.chr}#{str}", Mochilo.pack(str)
|
123
|
+
|
124
|
+
str = ("a"*255).force_encoding('UTF-8')
|
125
|
+
assert_equal "\xD9#{str.bytesize.chr}#{str}", Mochilo.pack(str)
|
103
126
|
end
|
104
127
|
|
105
|
-
def
|
106
|
-
str = "
|
107
|
-
assert_equal "\
|
128
|
+
def test_pack_str16
|
129
|
+
str = ("a"*256).force_encoding('UTF-8')
|
130
|
+
assert_equal "\xDA\x01\x00#{str}", Mochilo.pack(str)
|
131
|
+
|
132
|
+
str = ("a"*(2**16-1)).force_encoding('UTF-8')
|
133
|
+
assert_equal "\xDA\xFF\xFF#{str}", Mochilo.pack(str)
|
108
134
|
end
|
109
135
|
|
110
|
-
def
|
111
|
-
str = ("a"*
|
112
|
-
assert_equal "\
|
136
|
+
def test_pack_str32
|
137
|
+
str = ("a"*(2**16)).force_encoding('UTF-8')
|
138
|
+
assert_equal "\xDB\x00\x01\x00\x00#{str}", Mochilo.pack(str)
|
139
|
+
|
140
|
+
# This will create a 4GB string, so let's just skip that ;)
|
141
|
+
# str = ("a"*(2**32-1)).force_encoding('UTF-8')
|
142
|
+
# assert_equal "\xDB\x00\x01\x00\x00#{str}", Mochilo.pack(str)
|
113
143
|
end
|
114
144
|
|
115
|
-
def
|
116
|
-
|
145
|
+
def test_pack_enc8
|
146
|
+
str = ("a"*32).force_encoding('ISO-8859-1')
|
147
|
+
assert_equal "\xC7#{str.bytesize.chr}\x0C#{str}", Mochilo.pack(str)
|
148
|
+
|
149
|
+
str = ("a"*255).force_encoding('ISO-8859-1')
|
150
|
+
assert_equal "\xC7#{str.bytesize.chr}\x0C#{str}", Mochilo.pack(str)
|
117
151
|
end
|
118
152
|
|
119
|
-
def
|
120
|
-
|
121
|
-
assert_equal "\
|
153
|
+
def test_pack_enc16
|
154
|
+
str = ("a"*256).force_encoding('ISO-8859-1')
|
155
|
+
assert_equal "\xC8\x01\x00\x0C#{str}", Mochilo.pack(str)
|
156
|
+
|
157
|
+
str = ("a"*(2**16-1)).force_encoding('ISO-8859-1')
|
158
|
+
assert_equal "\xC8\xFF\xFF\x0C#{str}", Mochilo.pack(str)
|
122
159
|
end
|
123
160
|
|
124
|
-
def
|
125
|
-
|
126
|
-
assert_equal "\
|
161
|
+
def test_pack_enc32
|
162
|
+
str = ("a"*(2**16)).force_encoding('ISO-8859-1')
|
163
|
+
assert_equal "\xC9\x00\x01\x00\x00\x0C#{str}", Mochilo.pack(str)
|
164
|
+
|
165
|
+
# This would create a 4GB string, so let's just skip that ;)
|
166
|
+
# str = ("a"*(2**32-1)).force_encoding('ISO-8859-1')
|
167
|
+
# assert_equal "\xC9\x00\x01\x00\x00\x0C#{str}", Mochilo.pack(str)
|
127
168
|
end
|
128
169
|
|
129
|
-
def
|
130
|
-
|
170
|
+
def test_pack_bin8
|
171
|
+
str = ("a"*32).force_encoding('binary')
|
172
|
+
assert_equal "\xC4#{str.bytesize.chr}#{str}", Mochilo.pack(str)
|
173
|
+
|
174
|
+
str = ("a"*255).force_encoding('binary')
|
175
|
+
assert_equal "\xC4#{str.bytesize.chr}#{str}", Mochilo.pack(str)
|
131
176
|
end
|
132
177
|
|
133
|
-
def
|
134
|
-
|
135
|
-
assert_equal "\
|
178
|
+
def test_pack_bin16
|
179
|
+
str = ("a"*256).force_encoding('binary')
|
180
|
+
assert_equal "\xC5\x01\x00#{str}", Mochilo.pack(str)
|
181
|
+
|
182
|
+
str = ("a"*(2**16-1)).force_encoding('binary')
|
183
|
+
assert_equal "\xC5\xFF\xFF#{str}", Mochilo.pack(str)
|
136
184
|
end
|
137
185
|
|
138
|
-
def
|
139
|
-
|
140
|
-
assert_equal "\
|
186
|
+
def test_pack_bin32
|
187
|
+
str = ("a"*(2**16)).force_encoding('binary')
|
188
|
+
assert_equal "\xC6\x00\x01\x00\x00#{str}", Mochilo.pack(str)
|
189
|
+
|
190
|
+
# This would create a 4GB string, so let's just skip that ;)
|
191
|
+
# str = ("a"*(2**32-1)).force_encoding('UTF-8')
|
192
|
+
# assert_equal "\xC6\x00\x01\x00\x00#{str}", Mochilo.pack(str)
|
141
193
|
end
|
142
194
|
|
143
|
-
def
|
144
|
-
|
145
|
-
fine = ("a"*0xff).to_sym
|
195
|
+
def test_pack_fixed_array
|
196
|
+
assert_equal "\x90", Mochilo.pack([])
|
146
197
|
|
147
|
-
|
148
|
-
|
149
|
-
|
198
|
+
arr = (1..15).to_a
|
199
|
+
expected = "\x9F"
|
200
|
+
arr.each {|i| expected << Mochilo.pack(i)}
|
201
|
+
assert_equal expected, Mochilo.pack(arr)
|
202
|
+
end
|
150
203
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
204
|
+
def test_pack_array16
|
205
|
+
arr = (1..16).to_a
|
206
|
+
expected = "\xDC\x00\x10"
|
207
|
+
arr.each {|i| expected << Mochilo.pack(i)}
|
208
|
+
assert_equal expected, Mochilo.pack(arr)
|
209
|
+
|
210
|
+
arr = (1..2**16-1).to_a
|
211
|
+
expected = "\xDC\xFF\xFF"
|
212
|
+
arr.each {|i| expected << Mochilo.pack(i)}
|
213
|
+
assert_equal expected, Mochilo.pack(arr)
|
156
214
|
end
|
157
215
|
|
158
|
-
def
|
159
|
-
|
160
|
-
|
216
|
+
def test_pack_array32
|
217
|
+
arr = (1..2**16).to_a
|
218
|
+
expected = "\xDD\x00\x01\x00\x00"
|
219
|
+
arr.each {|i| expected << Mochilo.pack(i)}
|
220
|
+
assert_equal expected, Mochilo.pack(arr)
|
221
|
+
|
222
|
+
# This would create an array with 4294967295 entries in it, so let's not
|
223
|
+
# arr = (1..2**32-1).to_a
|
224
|
+
# expected = "\xDD\xFF\xFF\xFF\xFF"
|
225
|
+
# arr.each {|i| expected << Mochilo.pack(i)}
|
226
|
+
# assert_equal expected, Mochilo.pack(arr)
|
161
227
|
end
|
162
228
|
|
163
|
-
def
|
164
|
-
|
229
|
+
def test_pack_fixed_map
|
230
|
+
assert_equal "\x80", Mochilo.pack({})
|
231
|
+
|
232
|
+
arr = (1..15).to_a
|
233
|
+
hash = {}
|
234
|
+
arr.each {|i| hash[i] = i }
|
235
|
+
expected = "\x8F"
|
236
|
+
arr.each {|i| expected << (Mochilo.pack(i) + Mochilo.pack(i))}
|
237
|
+
assert_equal expected, Mochilo.pack(hash)
|
165
238
|
end
|
166
239
|
|
167
|
-
def
|
168
|
-
|
240
|
+
def test_pack_map16
|
241
|
+
arr = (1..16).to_a
|
242
|
+
hash = {}
|
243
|
+
arr.each {|i| hash[i] = i }
|
244
|
+
expected = "\xDE\x00\x10"
|
245
|
+
arr.each {|i| expected << (Mochilo.pack(i) + Mochilo.pack(i))}
|
246
|
+
assert_equal expected, Mochilo.pack(hash)
|
247
|
+
|
248
|
+
arr = (1..2**16-1).to_a
|
249
|
+
hash = {}
|
250
|
+
arr.each {|i| hash[i] = i }
|
251
|
+
expected = "\xDE\xFF\xFF"
|
252
|
+
arr.each {|i| expected << (Mochilo.pack(i) + Mochilo.pack(i))}
|
253
|
+
assert_equal expected, Mochilo.pack(hash)
|
254
|
+
end
|
169
255
|
|
170
|
-
|
256
|
+
def test_pack_map32
|
257
|
+
arr = (1..2**16).to_a
|
258
|
+
hash = {}
|
259
|
+
arr.each {|i| hash[i] = i }
|
260
|
+
expected = "\xDF\x00\x01\x00\x00"
|
261
|
+
arr.each {|i| expected << (Mochilo.pack(i) + Mochilo.pack(i))}
|
262
|
+
assert_equal expected, Mochilo.pack(hash)
|
263
|
+
|
264
|
+
# This would create a hash with 4294967295 entries in it, so let's not
|
265
|
+
# arr = (1..2**32-1).to_a
|
266
|
+
# hash = {}
|
267
|
+
# arr.each {|i| hash[i] = i }
|
268
|
+
# expected = "\xDF\xFF\xFF\xFF\xFF"
|
269
|
+
# arr.each {|i| expected << (Mochilo.pack(i) + Mochilo.pack(i))}
|
270
|
+
# assert_equal expected, Mochilo.pack(hash)
|
171
271
|
end
|
172
272
|
|
173
273
|
def test_pack_unsupported_type
|
@@ -176,8 +276,14 @@ class MochiloPackTest < MiniTest::Unit::TestCase
|
|
176
276
|
end
|
177
277
|
end
|
178
278
|
|
279
|
+
def test_pack_symbol
|
280
|
+
expected = "\xC7\x07\xFF\x00symbol"
|
281
|
+
assert_equal expected, Mochilo.pack(:symbol)
|
282
|
+
assert_equal :symbol, Mochilo.unpack(expected)
|
283
|
+
end
|
284
|
+
|
179
285
|
def test_pack_regexp
|
180
|
-
expected = "\
|
286
|
+
expected = "\xC7\x0D\xFF\x01\x00\x00\x00\x00\x01pa.tern"
|
181
287
|
assert_equal expected, Mochilo.pack(/pa.tern/)
|
182
288
|
[
|
183
289
|
/pa.tern/,
|
@@ -190,13 +296,12 @@ class MochiloPackTest < MiniTest::Unit::TestCase
|
|
190
296
|
def test_time
|
191
297
|
offset = -13*60*60 # I don't know if this is possible. There shouldn't be anything with a greater absolute value.
|
192
298
|
t = Time.gm(2042, 7, 21, 3, 32, 37, 974010).getlocal(offset)
|
193
|
-
expected = "\
|
299
|
+
expected = "\xC7\x15\xFF\x02" +
|
194
300
|
"\x00\x00\x00\x00\x88\x77\x66\x55" + # sec
|
195
301
|
"\x00\x00\x00\x00\x00\x0E\xDC\xBA" + # usec
|
196
302
|
"\xFF\xFF\x49\x30" # utc_offset
|
197
303
|
assert_equal expected, Mochilo.pack(t)
|
198
|
-
|
199
|
-
assert_equal
|
200
|
-
assert_equal t.utc_offset, unpacked.utc_offset
|
304
|
+
assert_equal t, Mochilo.unpack(expected)
|
305
|
+
assert_equal offset, Mochilo.unpack(expected).utc_offset
|
201
306
|
end
|
202
307
|
end
|
data/test/setup.rb
CHANGED
@@ -10,16 +10,11 @@ require 'bundler/setup'
|
|
10
10
|
# bring in minitest
|
11
11
|
require 'minitest/autorun'
|
12
12
|
|
13
|
+
if !defined?(MiniTest::Test)
|
14
|
+
MiniTest::Test = MiniTest::Unit::TestCase
|
15
|
+
end
|
16
|
+
|
13
17
|
# put lib and test dirs directly on load path
|
14
18
|
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
15
19
|
$LOAD_PATH.unshift File.expand_path('..', __FILE__)
|
16
20
|
|
17
|
-
class CustomType
|
18
|
-
def initialize(str)
|
19
|
-
@str = str
|
20
|
-
end
|
21
|
-
|
22
|
-
def to_bpack
|
23
|
-
Mochilo.pack(@str)
|
24
|
-
end
|
25
|
-
end
|