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/unpack_test.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
# encoding:
|
1
|
+
# encoding: ascii-8bit
|
2
2
|
require File.expand_path('../setup', __FILE__)
|
3
3
|
|
4
4
|
require 'mochilo'
|
5
5
|
|
6
|
-
class MochiloUnpackTest <
|
6
|
+
class MochiloUnpackTest < Minitest::Test
|
7
7
|
BUFFERS = [
|
8
8
|
"\xCC\x80",
|
9
9
|
"\xCD\x04\xD2",
|
@@ -39,14 +39,14 @@ class MochiloUnpackTest < MiniTest::Unit::TestCase
|
|
39
39
|
assert_equal nil, Mochilo.unpack("\xC0")
|
40
40
|
end
|
41
41
|
|
42
|
-
def test_unpack_true
|
43
|
-
assert_equal true, Mochilo.unpack("\xC3")
|
44
|
-
end
|
45
|
-
|
46
42
|
def test_unpack_false
|
47
43
|
assert_equal false, Mochilo.unpack("\xC2")
|
48
44
|
end
|
49
45
|
|
46
|
+
def test_unpack_true
|
47
|
+
assert_equal true, Mochilo.unpack("\xC3")
|
48
|
+
end
|
49
|
+
|
50
50
|
def xtest_unpack_float
|
51
51
|
# ruby uses double's internally so we can't reliably
|
52
52
|
# test for a float without some hacks
|
@@ -57,103 +57,298 @@ class MochiloUnpackTest < MiniTest::Unit::TestCase
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def test_unpack_positive_fixed
|
60
|
-
|
60
|
+
(0..127).each do |int|
|
61
|
+
assert_equal int, Mochilo.unpack(int.chr)
|
62
|
+
end
|
61
63
|
end
|
62
64
|
|
63
65
|
def test_unpack_negative_fixed
|
64
|
-
assert_equal -
|
66
|
+
assert_equal -1, Mochilo.unpack("\xFF")
|
67
|
+
assert_equal -32, Mochilo.unpack("\xE0")
|
65
68
|
end
|
66
69
|
|
67
70
|
def test_unpack_uint8
|
68
|
-
|
71
|
+
[128,255].each do |int|
|
72
|
+
assert_equal int, Mochilo.unpack("\xCC#{int.chr}")
|
73
|
+
end
|
69
74
|
end
|
70
75
|
|
71
76
|
def test_unpack_uint16
|
72
|
-
|
77
|
+
[256,((2**16)-1)].each do |int|
|
78
|
+
packed = [int].pack("n")
|
79
|
+
assert_equal int, Mochilo.unpack("\xCD#{packed}")
|
80
|
+
end
|
73
81
|
end
|
74
82
|
|
75
83
|
def test_unpack_uint32
|
76
|
-
|
84
|
+
[(2**16),((2**32)-1)].each do |int|
|
85
|
+
packed = [int].pack("N")
|
86
|
+
assert_equal int, Mochilo.unpack("\xCE#{packed}")
|
87
|
+
end
|
77
88
|
end
|
78
89
|
|
79
90
|
def test_unpack_uint64
|
80
|
-
|
91
|
+
[(2**32),((2**64)-1)].each do |int|
|
92
|
+
packed = [int].pack("Q>")
|
93
|
+
assert_equal int, Mochilo.unpack("\xCF#{packed}")
|
94
|
+
end
|
81
95
|
end
|
82
96
|
|
83
97
|
def test_unpack_int8
|
84
|
-
assert_equal -
|
98
|
+
assert_equal -33, Mochilo.unpack("\xD0\xDF")
|
99
|
+
assert_equal -128, Mochilo.unpack("\xD0\x80")
|
85
100
|
end
|
86
101
|
|
87
102
|
def test_unpack_int16
|
88
|
-
assert_equal -
|
103
|
+
assert_equal -129, Mochilo.unpack("\xD1\xFF\x7F")
|
104
|
+
assert_equal -32768, Mochilo.unpack("\xD1\x80\x00")
|
89
105
|
end
|
90
106
|
|
91
107
|
def test_unpack_int32
|
92
|
-
assert_equal -
|
108
|
+
assert_equal -32769, Mochilo.unpack("\xD2\xFF\xFF\x7F\xFF")
|
109
|
+
assert_equal -2147483648, Mochilo.unpack("\xD2\x80\x00\x00\x00")
|
93
110
|
end
|
94
111
|
|
95
112
|
def test_unpack_int64
|
96
|
-
assert_equal -
|
113
|
+
assert_equal -2147483649, Mochilo.unpack("\xD3\xFF\xFF\xFF\xFF\x7F\xFF\xFF\xFF")
|
114
|
+
assert_equal -9223372036854775808, Mochilo.unpack("\xD3\x80\x00\x00\x00\x00\x00\x00\x00")
|
97
115
|
end
|
98
116
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
117
|
+
def test_unpack_fixed_str
|
118
|
+
str = "a".force_encoding('UTF-8')
|
119
|
+
val = Mochilo.unpack("\xA1#{str}")
|
120
|
+
assert_equal str, val
|
121
|
+
assert_equal Encoding::UTF_8, val.encoding
|
122
|
+
|
123
|
+
str = ("a"*31).force_encoding('UTF-8')
|
124
|
+
val = Mochilo.unpack("\xBF#{str}")
|
125
|
+
assert_equal str, val
|
126
|
+
assert_equal Encoding::UTF_8, val.encoding
|
104
127
|
end
|
105
128
|
|
106
|
-
def
|
107
|
-
|
129
|
+
def test_unpack_str8
|
130
|
+
str = ("a"*32).force_encoding('UTF-8')
|
131
|
+
val = Mochilo.unpack("\xD9#{str.bytesize.chr}#{str}")
|
132
|
+
assert_equal str, val
|
133
|
+
assert_equal Encoding::UTF_8, val.encoding
|
134
|
+
|
135
|
+
str = ("a"*255).force_encoding('UTF-8')
|
136
|
+
val = Mochilo.unpack("\xD9#{str.bytesize.chr}#{str}")
|
137
|
+
assert_equal str, val
|
138
|
+
assert_equal Encoding::UTF_8, val.encoding
|
108
139
|
end
|
109
140
|
|
110
|
-
def
|
111
|
-
str = "
|
112
|
-
|
141
|
+
def test_unpack_str16
|
142
|
+
str = ("a"*256).force_encoding('UTF-8')
|
143
|
+
val = Mochilo.unpack("\xDA\x01\x00#{str}")
|
144
|
+
assert_equal str, val
|
145
|
+
assert_equal Encoding::UTF_8, val.encoding
|
146
|
+
|
147
|
+
str = ("a"*(2**16-1)).force_encoding('UTF-8')
|
148
|
+
val = Mochilo.unpack("\xDA\xFF\xFF#{str}")
|
149
|
+
assert_equal str, val
|
150
|
+
assert_equal Encoding::UTF_8, val.encoding
|
113
151
|
end
|
114
152
|
|
115
|
-
def
|
116
|
-
|
117
|
-
|
118
|
-
|
153
|
+
def test_unpack_str32
|
154
|
+
str = ("a"*(2**16)).force_encoding('UTF-8')
|
155
|
+
val = Mochilo.unpack("\xDB\x00\x01\x00\x00#{str}")
|
156
|
+
assert_equal str, val
|
157
|
+
assert_equal Encoding::UTF_8, val.encoding
|
158
|
+
|
159
|
+
# This will create a 4GB string, so let's just skip that ;)
|
160
|
+
# str = ("a"*(2**32-1)).force_encoding('UTF-8')
|
161
|
+
# val = Mochilo.unpack("\xDB\xFF\xFF\xFF\xFF#{str}")
|
162
|
+
# assert_equal str, val
|
163
|
+
# assert_equal Encoding::UTF_8, val.encoding
|
164
|
+
end
|
119
165
|
|
120
|
-
|
166
|
+
def test_unpack_enc8
|
167
|
+
str = ("a"*32).force_encoding('ISO-8859-1')
|
168
|
+
val = Mochilo.unpack("\xC7#{str.bytesize.chr}\x0C#{str}")
|
169
|
+
assert_equal str, val
|
170
|
+
assert_equal Encoding::ISO_8859_1, val.encoding
|
171
|
+
|
172
|
+
str = ("a"*255).force_encoding('ISO-8859-1')
|
173
|
+
val = Mochilo.unpack("\xC7#{str.bytesize.chr}\x0C#{str}")
|
174
|
+
assert_equal str, val
|
175
|
+
assert_equal Encoding::ISO_8859_1, val.encoding
|
121
176
|
end
|
122
177
|
|
123
|
-
def
|
124
|
-
str = ("a"*
|
125
|
-
|
178
|
+
def test_unpack_enc16
|
179
|
+
str = ("a"*256).force_encoding('ISO-8859-1')
|
180
|
+
val = Mochilo.unpack("\xC8\x01\x00\x0C#{str}")
|
181
|
+
assert_equal str, val
|
182
|
+
assert_equal Encoding::ISO_8859_1, val.encoding
|
183
|
+
|
184
|
+
str = ("a"*(2**16-1)).force_encoding('ISO-8859-1')
|
185
|
+
val = Mochilo.unpack("\xC8\xFF\xFF\x0C#{str}")
|
186
|
+
assert_equal str, val
|
187
|
+
assert_equal Encoding::ISO_8859_1, val.encoding
|
126
188
|
end
|
127
189
|
|
128
|
-
def
|
129
|
-
|
190
|
+
def test_unpack_enc32
|
191
|
+
str = ("a"*(2**16)).force_encoding('ISO-8859-1')
|
192
|
+
val = Mochilo.unpack("\xC9\x00\x01\x00\x00\x0C#{str}")
|
193
|
+
assert_equal str, val
|
194
|
+
assert_equal Encoding::ISO_8859_1, val.encoding
|
195
|
+
|
196
|
+
# This would create a 4GB string, so let's just skip that ;)
|
197
|
+
# str = ("a"*(2**32-1)).force_encoding('ISO-8859-1')
|
198
|
+
# val = Mochilo.unpack("\xC9\x00\x01\x00\x00\x0C#{str}")
|
199
|
+
# assert_equal str, val
|
200
|
+
# assert_equal Encoding::ISO_8859_1, val.encoding
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_unpack_bin8
|
204
|
+
str = ("a"*32).force_encoding('binary')
|
205
|
+
val = Mochilo.unpack("\xC4#{str.bytesize.chr}#{str}")
|
206
|
+
assert_equal str, val
|
207
|
+
assert_equal Encoding::ASCII_8BIT, val.encoding
|
208
|
+
|
209
|
+
str = ("a"*255).force_encoding('binary')
|
210
|
+
val = Mochilo.unpack("\xC4#{str.bytesize.chr}#{str}")
|
211
|
+
assert_equal str, val
|
212
|
+
assert_equal Encoding::ASCII_8BIT, val.encoding
|
213
|
+
end
|
214
|
+
|
215
|
+
def test_unpack_bin16
|
216
|
+
str = ("a"*256).force_encoding('binary')
|
217
|
+
val = Mochilo.unpack("\xC5\x01\x00#{str}")
|
218
|
+
assert_equal str, val
|
219
|
+
assert_equal Encoding::ASCII_8BIT, val.encoding
|
220
|
+
|
221
|
+
str = ("a"*(2**16-1)).force_encoding('binary')
|
222
|
+
val = Mochilo.unpack("\xC5\xFF\xFF#{str}")
|
223
|
+
assert_equal str, val
|
224
|
+
assert_equal Encoding::ASCII_8BIT, val.encoding
|
225
|
+
end
|
226
|
+
|
227
|
+
def test_unpack_bin32
|
228
|
+
str = ("a"*(2**16)).force_encoding('binary')
|
229
|
+
val = Mochilo.unpack("\xC6\x00\x01\x00\x00#{str}")
|
230
|
+
assert_equal str, val
|
231
|
+
assert_equal Encoding::ASCII_8BIT, val.encoding
|
232
|
+
|
233
|
+
# This would create a 4GB string, so let's just skip that ;)
|
234
|
+
# str = ("a"*(2**32-1)).force_encoding('UTF-8')
|
235
|
+
# val = Mochilo.unpack("\xC6\x00\x01\x00\x00#{str}")
|
236
|
+
# assert_equal str, val
|
237
|
+
# assert_equal Encoding::ASCII_8BIT, val.encoding
|
130
238
|
end
|
131
239
|
|
132
240
|
def test_unpack_fixed_array
|
133
241
|
assert_equal [], Mochilo.unpack("\x90")
|
134
|
-
|
242
|
+
|
243
|
+
arr = (1..15).to_a
|
244
|
+
data = "\x9F"
|
245
|
+
arr.each {|i| data << Mochilo.pack(i)}
|
246
|
+
assert_equal arr, Mochilo.unpack(data)
|
135
247
|
end
|
136
248
|
|
137
249
|
def test_unpack_array16
|
138
|
-
|
139
|
-
|
250
|
+
arr = (1..16).to_a
|
251
|
+
data = "\xDC\x00\x10"
|
252
|
+
arr.each {|i| data << Mochilo.pack(i)}
|
253
|
+
assert_equal arr, Mochilo.unpack(data)
|
254
|
+
|
255
|
+
arr = (1..2**16-1).to_a
|
256
|
+
data = "\xDC\xFF\xFF"
|
257
|
+
arr.each {|i| data << Mochilo.pack(i)}
|
258
|
+
assert_equal arr, Mochilo.unpack(data)
|
140
259
|
end
|
141
260
|
|
142
|
-
def
|
143
|
-
|
261
|
+
def test_unpack_array32
|
262
|
+
arr = (1..2**16).to_a
|
263
|
+
data = "\xDD\x00\x01\x00\x00"
|
264
|
+
arr.each {|i| data << Mochilo.pack(i)}
|
265
|
+
assert_equal arr, Mochilo.unpack(data)
|
266
|
+
|
267
|
+
# This would create an array with 4294967295 entries in it, so let's not
|
268
|
+
# arr = (1..2**32-1).to_a
|
269
|
+
# data = "\xDD\xFF\xFF\xFF\xFF"
|
270
|
+
# arr.each {|i| data << Mochilo.pack(i)}
|
271
|
+
# assert_equal arr, Mochilo.unpack(data)
|
144
272
|
end
|
145
273
|
|
146
|
-
def
|
274
|
+
def test_pack_fixed_map
|
147
275
|
assert_equal({}, Mochilo.unpack("\x80"))
|
148
|
-
|
276
|
+
|
277
|
+
arr = (1..15).to_a
|
278
|
+
hash = {}
|
279
|
+
arr.each {|i| hash[i] = i }
|
280
|
+
data = "\x8F"
|
281
|
+
arr.each {|i| data << (Mochilo.pack(i) + Mochilo.pack(i))}
|
282
|
+
assert_equal hash, Mochilo.unpack(data)
|
149
283
|
end
|
150
284
|
|
151
|
-
def
|
152
|
-
|
153
|
-
|
285
|
+
def test_pack_map16
|
286
|
+
arr = (1..16).to_a
|
287
|
+
hash = {}
|
288
|
+
arr.each {|i| hash[i] = i }
|
289
|
+
data = "\xDE\x00\x10"
|
290
|
+
arr.each {|i| data << (Mochilo.pack(i) + Mochilo.pack(i))}
|
291
|
+
assert_equal hash, Mochilo.unpack(data)
|
292
|
+
|
293
|
+
arr = (1..2**16-1).to_a
|
294
|
+
hash = {}
|
295
|
+
arr.each {|i| hash[i] = i }
|
296
|
+
data = "\xDE\xFF\xFF"
|
297
|
+
arr.each {|i| data << (Mochilo.pack(i) + Mochilo.pack(i))}
|
298
|
+
assert_equal hash, Mochilo.unpack(data)
|
154
299
|
end
|
155
300
|
|
156
|
-
def
|
157
|
-
|
301
|
+
def test_pack_map32
|
302
|
+
arr = (1..2**16).to_a
|
303
|
+
hash = {}
|
304
|
+
arr.each {|i| hash[i] = i }
|
305
|
+
data = "\xDF\x00\x01\x00\x00"
|
306
|
+
arr.each {|i| data << (Mochilo.pack(i) + Mochilo.pack(i))}
|
307
|
+
assert_equal hash, Mochilo.unpack(data)
|
308
|
+
|
309
|
+
# This would create a hash with 4294967295 entries in it, so let's not
|
310
|
+
# arr = (1..2**32-1).to_a
|
311
|
+
# hash = {}
|
312
|
+
# arr.each {|i| hash[i] = i }
|
313
|
+
# data = "\xDF\xFF\xFF\xFF\xFF"
|
314
|
+
# arr.each {|i| data << (Mochilo.pack(i) + Mochilo.pack(i))}
|
315
|
+
# assert_equal hash, Mochilo.unpack(data)
|
316
|
+
end
|
317
|
+
|
318
|
+
def test_unpack_custom_types_with_errors
|
319
|
+
# regexp has all the options bits
|
320
|
+
re = Mochilo.unpack("\xC7\x0D\xFF\x01\xFF\xFF\xFF\xFF\x01pa.tern")
|
321
|
+
refute_equal 0, re.options, "unpacked regexp options"
|
322
|
+
|
323
|
+
# time is missing the last char
|
324
|
+
assert_raises Mochilo::UnpackError do
|
325
|
+
Mochilo.unpack("\xC7\x11\xFF\x02\x00\x00\x00\x00\x88\x77\x66\x55\x00\x00\x00\x00\x00\x0E\xDC")
|
326
|
+
end
|
327
|
+
|
328
|
+
# time overflows
|
329
|
+
assert_raises RangeError do
|
330
|
+
# set the top bit of the time.....v ...and of usec................v
|
331
|
+
Mochilo.unpack("\xC7\x15\xFF\x02\x80\x00\x00\x00\x88\x77\x66\x55\x80\x00\x00\x00\x00\x0E\xDC\xBA\xFF\xFF\xFF\xFF")
|
332
|
+
end
|
333
|
+
|
334
|
+
# unknown field
|
335
|
+
assert_raises Mochilo::UnpackError do
|
336
|
+
Mochilo.unpack("\xC7\x07\xFF\x10unknowncustomtype")
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
# Make sure that the custom parsers never read past the end
|
341
|
+
# of their buffers.
|
342
|
+
def test_unpack_custom_types_with_missing_char
|
343
|
+
assert_error_on_truncated_unpack "\xC7\x07\xFF\x00symbol"
|
344
|
+
assert_error_on_truncated_unpack "\xC7\x0D\xFF\x01\x00\x00\x00\x00\x01pa.tern"
|
345
|
+
assert_error_on_truncated_unpack "\xC7\x15\xFF\x02\x00\x00\x00\x00\x88\x77\x66\x55\x00\x00\x00\x00\x00\x0E\xDC\xBA\x00\x00\x00\x00"
|
346
|
+
end
|
347
|
+
|
348
|
+
def assert_error_on_truncated_unpack(packed)
|
349
|
+
refute_nil Mochilo.unpack(packed)
|
350
|
+
assert_raises Mochilo::UnpackError do
|
351
|
+
Mochilo.unpack(packed.chop)
|
352
|
+
end
|
158
353
|
end
|
159
354
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mochilo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1
|
4
|
+
version: '2.1'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vicent Martí
|
@@ -50,7 +50,7 @@ files:
|
|
50
50
|
- ".travis.yml"
|
51
51
|
- Gemfile
|
52
52
|
- Gemfile.lock
|
53
|
-
-
|
53
|
+
- LICENSE
|
54
54
|
- README.md
|
55
55
|
- Rakefile
|
56
56
|
- docs/format-spec.md
|
@@ -78,7 +78,8 @@ files:
|
|
78
78
|
- test/setup.rb
|
79
79
|
- test/unpack_test.rb
|
80
80
|
homepage: http://github.com/brianmario/mochilo
|
81
|
-
licenses:
|
81
|
+
licenses:
|
82
|
+
- MIT
|
82
83
|
metadata: {}
|
83
84
|
post_install_message:
|
84
85
|
rdoc_options:
|
@@ -100,8 +101,4 @@ rubygems_version: 3.3.10
|
|
100
101
|
signing_key:
|
101
102
|
specification_version: 4
|
102
103
|
summary: A ruby library for BananaPack
|
103
|
-
test_files:
|
104
|
-
- test/assets/pulls.json
|
105
|
-
- test/pack_test.rb
|
106
|
-
- test/setup.rb
|
107
|
-
- test/unpack_test.rb
|
104
|
+
test_files: []
|
data/MIT-LICENSE
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
Copyright (c) 2013 Brian Lopez - http://github.com/brianmario
|
2
|
-
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
-
a copy of this software and associated documentation files (the
|
5
|
-
"Software"), to deal in the Software without restriction, including
|
6
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
-
permit persons to whom the Software is furnished to do so, subject to
|
9
|
-
the following conditions:
|
10
|
-
|
11
|
-
The above copyright notice and this permission notice shall be
|
12
|
-
included in all copies or substantial portions of the Software.
|
13
|
-
|
14
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|