bitpack 0.1

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,405 @@
1
+
2
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'ext')
3
+ require 'bitpack'
4
+
5
+ require 'test/unit'
6
+
7
+ class TC_BitPack < Test::Unit::TestCase
8
+ def test_constructor
9
+ bytes = [0xab, 0xcd, 0xef, 0x12].pack("C*")
10
+
11
+ bp1 = BitPack.new
12
+ assert_equal("", bp1.to_bin)
13
+ assert_equal(0, bp1.size)
14
+
15
+ bp2 = BitPack.from_bytes(bytes)
16
+ assert_equal("10101011110011011110111100010010", bp2.to_bin)
17
+ assert_equal(32, bp2.size)
18
+ end
19
+
20
+ def test_get_on_off
21
+ bp = BitPack.new
22
+
23
+ assert_equal(0, bp.size)
24
+ bp.on(0)
25
+ assert_equal(1, bp.size);
26
+ bp.off(1)
27
+ assert_equal(2, bp.size);
28
+ bp.on(2)
29
+ assert_equal(3, bp.size);
30
+ bp.off(3)
31
+ assert_equal(4, bp.size);
32
+ bp.on(4)
33
+ assert_equal(5, bp.size);
34
+ bp.off(5)
35
+ assert_equal(6, bp.size);
36
+ bp.on(6)
37
+ assert_equal(7, bp.size);
38
+ bp.off(7)
39
+ assert_equal(8, bp.size);
40
+ bp.on(8)
41
+ assert_equal(9, bp.size);
42
+ bp.off(9)
43
+ assert_equal(10, bp.size);
44
+
45
+ assert_equal("1010101010", bp.to_bin);
46
+
47
+ 0.upto(9) do |i|
48
+ expected_bit = (i % 2 == 0) ? 1 : 0;
49
+ assert_equal(expected_bit, bp.get(i))
50
+ end
51
+
52
+ bp.off(0)
53
+ bp.off(2)
54
+ bp.off(4)
55
+ bp.off(6)
56
+ bp.off(8)
57
+
58
+ assert_equal("0000000000", bp.to_bin);
59
+
60
+ # error cases
61
+ assert_raise RangeError, "invalid index (10), max index is 9" do
62
+ bp.get(10)
63
+ end
64
+
65
+ bp = BitPack.new
66
+ assert_raise RangeError, "bitpack is empty" do
67
+ bp.get(10)
68
+ end
69
+ end
70
+
71
+ def test_get_set_bits
72
+ bp = BitPack.new(4)
73
+ assert_equal(0, bp.size);
74
+ assert_equal(4, bp.data_size);
75
+
76
+ bp.set_bits(0xff, 8, 0)
77
+ assert_equal(8, bp.size)
78
+ assert_equal(4, bp.data_size)
79
+ assert_equal("11111111", bp.to_bin)
80
+ assert_equal(0xff, bp.get_bits(8, 0))
81
+
82
+ bp.set_bits(5, 3, 8)
83
+ assert_equal(11, bp.size)
84
+ assert_equal(4, bp.data_size)
85
+ assert_equal("11111111101", bp.to_bin)
86
+ assert_equal(5, bp.get_bits(3, 8))
87
+
88
+ bp.set_bits(21, 5, 11)
89
+ assert_equal(16, bp.size)
90
+ assert_equal(4, bp.data_size)
91
+ assert_equal("1111111110110101", bp.to_bin)
92
+ assert_equal(21, bp.get_bits(5, 11))
93
+
94
+ bp.set_bits(0xffffffff, 32, 16)
95
+ assert_equal(48, bp.size)
96
+ assert_equal(6, bp.data_size)
97
+ assert_equal("111111111011010111111111111111111111111111111111", bp.to_bin)
98
+ assert_equal(0xffffffff, bp.get_bits(32, 16))
99
+
100
+ bp.set_bits(0, 8, 0)
101
+ assert_equal(48, bp.size)
102
+ assert_equal(6, bp.data_size)
103
+ assert_equal("000000001011010111111111111111111111111111111111", bp.to_bin)
104
+ assert_equal(0, bp.get_bits(8, 0))
105
+
106
+ unsigned_long_size = [1].pack("L").size
107
+
108
+ # error cases
109
+ msg = sprintf("range size %d bits is too large (maximum size is %d bits)", unsigned_long_size * 8 + 1, unsigned_long_size * 8)
110
+ assert_raise RangeError, msg do
111
+ bp.set_bits(0, unsigned_long_size * 8 + 1, 0)
112
+ end
113
+
114
+ assert_equal(48, bp.size)
115
+ assert_equal(6, bp.data_size)
116
+ assert_equal("000000001011010111111111111111111111111111111111", bp.to_bin)
117
+
118
+ assert_raise ArgumentError, "value 8 does not fit in 3 bits" do
119
+ bp.set_bits(8, 3, 0)
120
+ end
121
+ assert_equal(48, bp.size)
122
+ assert_equal(6, bp.data_size)
123
+ assert_equal("000000001011010111111111111111111111111111111111", bp.to_bin)
124
+
125
+ assert_raise RangeError, "invalid index (48), max index is 47" do
126
+ bp.get_bits(3, 48)
127
+ end
128
+
129
+ assert_raise RangeError, "attempted to read past end of bitpack (last index is 47)" do
130
+ bp.get_bits(25, 24)
131
+ end
132
+
133
+ bp.set_bits(0xffffffff, 32, 48)
134
+ bp.set_bits(0xffffffff, 32, 80)
135
+ bp.set_bits(0xffffffff, 32, 112)
136
+
137
+ msg = sprintf("range size %d bits is too large (maximum size is %d bits)", unsigned_long_size * 8 + 1,
138
+ unsigned_long_size * 8)
139
+ assert_raise RangeError, msg do
140
+ bp.get_bits(unsigned_long_size * 8 + 1, 0)
141
+ end
142
+ end
143
+
144
+ def test_get_set_bytes
145
+ test_bytes1 = [ 0x01, 0x02, 0x03 ].pack("C*")
146
+ test_bytes2 = [ 0xff, 0xfe, 0xfd ].pack("C*")
147
+ test_bytes3 = [ 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff ].pack("C*")
148
+
149
+ bp = BitPack.new(4)
150
+
151
+ assert_equal(0, bp.size)
152
+ assert_equal(4, bp.data_size)
153
+
154
+ bp.set_bytes(test_bytes1, 0)
155
+ assert_equal(24, bp.size)
156
+ assert_equal(4, bp.data_size)
157
+ assert_equal("000000010000001000000011", bp.to_bin)
158
+
159
+ assert_equal(test_bytes1, bp.get_bytes(3, 0));
160
+
161
+ bp.set_bytes(test_bytes2, 24)
162
+ assert_equal(48, bp.size)
163
+ assert_equal(6, bp.data_size)
164
+ assert_equal("000000010000001000000011111111111111111011111101", bp.to_bin)
165
+ assert_equal(test_bytes2, bp.get_bytes(3, 24))
166
+
167
+ # non-byte aligned set
168
+ bp.set_bytes(test_bytes3, 50)
169
+ assert_equal(98, bp.size)
170
+ assert_equal(13, bp.data_size)
171
+ assert_equal("00000001000000100000001111111111111111101111110100101010101011101111001100110111011110111011111111", bp.to_bin);
172
+ assert_equal(test_bytes3, bp.get_bytes(6, 50))
173
+
174
+ # error cases
175
+ assert_raise RangeError, "invalid index(98), max index is 97" do
176
+ bp.get_bytes(5, 98)
177
+ end
178
+
179
+ assert_raise RangeError, "attempted to read past end of bitpack (last index is 97)" do
180
+ bp.get_bytes(13, 0)
181
+ end
182
+ end
183
+
184
+ def test_append_bits
185
+ bp = BitPack.new(4);
186
+
187
+ assert_equal(0, bp.size)
188
+ assert_equal(4, bp.data_size)
189
+
190
+ bp.append_bits(0xff, 8)
191
+ assert_equal(8, bp.size)
192
+ assert_equal(4, bp.data_size)
193
+ assert_equal("11111111", bp.to_bin);
194
+
195
+ bp.append_bits(5, 3)
196
+ assert_equal(11, bp.size)
197
+ assert_equal(4, bp.data_size)
198
+ assert_equal("11111111101", bp.to_bin)
199
+
200
+ bp.append_bits(21, 5)
201
+ assert_equal(16, bp.size)
202
+ assert_equal(4, bp.data_size)
203
+ assert_equal("1111111110110101", bp.to_bin)
204
+
205
+ bp.append_bits(0xffffffff, 32)
206
+ assert_equal(48, bp.size)
207
+ assert_equal(6, bp.data_size)
208
+ assert_equal("111111111011010111111111111111111111111111111111", bp.to_bin);
209
+ end
210
+
211
+ def test_append_bytes
212
+ test_bytes1 = [ 0x01, 0x02, 0x03 ].pack("C*")
213
+ test_bytes2 = [ 0xff, 0xfe, 0xfd ].pack("C*")
214
+ test_bytes3 = [ 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff ].pack("C*")
215
+
216
+ bp = BitPack.new(4);
217
+
218
+ assert_equal(0, bp.size)
219
+ assert_equal(4, bp.data_size)
220
+
221
+ bp.append_bytes(test_bytes1)
222
+ assert_equal(24, bp.size)
223
+ assert_equal(4, bp.data_size)
224
+ assert_equal("000000010000001000000011", bp.to_bin);
225
+
226
+ bp.append_bytes(test_bytes2)
227
+ assert_equal(48, bp.size)
228
+ assert_equal(6, bp.data_size)
229
+ assert_equal("000000010000001000000011111111111111111011111101", bp.to_bin)
230
+
231
+ # non-byte aligned set
232
+ bp.append_bits(0, 2)
233
+ bp.append_bytes(test_bytes3)
234
+ assert_equal(98, bp.size)
235
+ assert_equal(13, bp.data_size)
236
+ assert_equal("00000001000000100000001111111111111111101111110100101010101011101111001100110111011110111011111111", bp.to_bin);
237
+ end
238
+
239
+ def test_read_bits
240
+ bp = BitPack.new(4);
241
+
242
+ bp.append_bits(0xff, 8);
243
+ bp.append_bits(5, 3);
244
+ bp.append_bits(21, 5);
245
+ bp.append_bits(0xffffffff, 32);
246
+
247
+ assert_equal(0, bp.read_pos)
248
+ assert_equal(0xff, bp.read_bits(8))
249
+ assert_equal(8, bp.read_pos)
250
+ assert_equal(5, bp.read_bits(3))
251
+ assert_equal(11, bp.read_pos)
252
+ assert_equal(21, bp.read_bits(5))
253
+ assert_equal(16, bp.read_pos)
254
+ assert_equal(0xffffffff, bp.read_bits(32))
255
+ assert_equal(48, bp.read_pos)
256
+
257
+ # error cases
258
+ assert_raise RangeError, "attempted to read past end of bitpack (last index is 47)" do
259
+ bp.read_bits(1)
260
+ end
261
+ assert_equal(48, bp.read_pos)
262
+
263
+ bp.reset_read_pos
264
+ assert_equal(0, bp.read_pos)
265
+ assert_equal(0xff, bp.read_bits(8))
266
+ assert_equal(8, bp.read_pos)
267
+ end
268
+
269
+ def test_read_bytes
270
+ test_bytes1 = [ 0x01, 0x02, 0x03 ].pack("C*")
271
+ test_bytes2 = [ 0xff, 0xfe, 0xfd ].pack("C*")
272
+ test_bytes3 = [ 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff ].pack("C*")
273
+
274
+ bp = BitPack.new(4);
275
+ bp.append_bytes(test_bytes1);
276
+ bp.append_bytes(test_bytes2);
277
+ bp.append_bits(2, 2);
278
+ bp.append_bytes(test_bytes3);
279
+
280
+ assert_equal(0, bp.read_pos)
281
+
282
+ assert_equal(test_bytes1, bp.read_bytes(3))
283
+ assert_equal(24, bp.read_pos)
284
+
285
+ assert_equal(test_bytes2, bp.read_bytes(3))
286
+ assert_equal(48, bp.read_pos)
287
+
288
+ assert_equal(2, bp.read_bits(2))
289
+ assert_equal(50, bp.read_pos)
290
+
291
+ assert_equal(test_bytes3, bp.read_bytes(6))
292
+ assert_equal(98, bp.read_pos)
293
+
294
+ # error cases
295
+ assert_raise RangeError, "attempted to read past end of bitpack (last index is 97)" do
296
+ bp.read_bytes(1)
297
+ end
298
+ assert_equal(98, bp.read_pos)
299
+
300
+ bp.reset_read_pos
301
+ assert_equal(0, bp.read_pos)
302
+
303
+ assert_equal(test_bytes1, bp.read_bytes(3))
304
+ assert_equal(24, bp.read_pos)
305
+ end
306
+
307
+ def test_to_bytes
308
+ test_bytes1 = [ 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce ].pack("C*")
309
+ test_bytes2 = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a ].pack("C*")
310
+ exp_bytes = [
311
+ 0x1b, 0x91, 0xa2, 0xb3, 0xc0, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa,
312
+ 0xce, 0x03, 0x04, 0x11, 0x11, 0x11, 0x11, 0x01, 0x02, 0x03, 0x04, 0x05,
313
+ 0x06, 0x07, 0x08, 0x09, 0x0a
314
+ ].pack("C*")
315
+ exp_bytes2 = [ 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0x80 ].pack("C*")
316
+ exp_s = "0001101110010001101000101011001111000000110111101010110110111110111011111111111011101101111110101100111000000011000001000001000100010001000100010001000100000001000000100000001100000100000001010000011000000111000010000000100100001010";
317
+
318
+ bp = BitPack.new
319
+
320
+ bp.append_bits(3, 5)
321
+ bp.append_bits(3, 3)
322
+ bp.append_bits(0x12345678, 29)
323
+ bp.append_bits(0, 3)
324
+ bp.append_bytes(test_bytes1)
325
+ bp.append_bits(12, 10)
326
+ bp.append_bits(4, 6)
327
+ bp.append_bits(0x11111111, 32)
328
+ bp.append_bytes(test_bytes2)
329
+
330
+ assert_equal(exp_bytes, bp.to_bytes)
331
+ assert_equal(exp_bytes.length * 8, bp.size)
332
+ assert_equal(exp_s, bp.to_bin)
333
+
334
+ bp = BitPack.new(100);
335
+
336
+ bp.append_bytes(test_bytes1)
337
+ bp.append_bits(1, 1);
338
+
339
+ assert_equal(exp_bytes2, bp.to_bytes)
340
+ assert_equal(test_bytes1.length * 8 + 1, bp.size)
341
+ end
342
+
343
+ def test_from_bytes
344
+ test_bytes1 = [ 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce ].pack("C*")
345
+ test_bytes2 = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a ].pack("C*")
346
+ init_bytes = [
347
+ 0x1b, 0x91, 0xa2, 0xb3, 0xc0, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa,
348
+ 0xce, 0x03, 0x04, 0x11, 0x11, 0x11, 0x11, 0x01, 0x02, 0x03, 0x04, 0x05,
349
+ 0x06, 0x07, 0x08, 0x09, 0x0a
350
+ ].pack("C*")
351
+ exp_s = "0001101110010001101000101011001111000000110111101010110110111110111011111111111011101101111110101100111000000011000001000001000100010001000100010001000100000001000000100000001100000100000001010000011000000111000010000000100100001010"
352
+
353
+ bp = BitPack.from_bytes(init_bytes)
354
+
355
+ assert_equal(init_bytes.length * 8, bp.size)
356
+ assert_equal(exp_s, bp.to_bin)
357
+
358
+ assert_equal(3, bp.read_bits(5))
359
+ assert_equal(3, bp.read_bits(3))
360
+ assert_equal(0x12345678, bp.read_bits(29))
361
+ assert_equal(0, bp.read_bits(3))
362
+ assert_equal(test_bytes1, bp.read_bytes(test_bytes1.length))
363
+ assert_equal(12, bp.read_bits(10))
364
+ assert_equal(4, bp.read_bits(6))
365
+ assert_equal(0x11111111, bp.read_bits(32))
366
+ assert_equal(test_bytes2, bp.read_bytes(test_bytes2.length))
367
+ end
368
+
369
+ def test_assignment_index
370
+ bp = BitPack.new
371
+
372
+ bp[0] = 1
373
+ bp[1] = 0
374
+ bp[2] = 1
375
+ bp[3] = 0
376
+ bp[4] = 1
377
+ bp[5] = 0
378
+ bp[6] = 1
379
+ bp[7] = 0
380
+
381
+ assert_equal(8, bp.size)
382
+ assert_equal(0b10101010, bp.read_bits(8))
383
+ end
384
+
385
+ def test_assignment_range
386
+ bp = BitPack.new
387
+
388
+ bp[0..7] = 0xab
389
+ bp[8...16] = 0xcd
390
+
391
+ assert_equal(16, bp.size)
392
+ assert_equal([0xab, 0xcd].pack("C*"), bp.to_bytes)
393
+ end
394
+
395
+ def test_assignment_index_length
396
+ bp = BitPack.new
397
+
398
+ bp[0, 8] = 0xab
399
+ bp[8, 8] = 0xcd
400
+
401
+ assert_equal(16, bp.size)
402
+ assert_equal([0xab, 0xcd].pack("C*"), bp.to_bytes)
403
+ end
404
+ end
405
+
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4
3
+ specification_version: 1
4
+ name: bitpack
5
+ version: !ruby/object:Gem::Version
6
+ version: "0.1"
7
+ date: 2007-11-14 00:00:00 -06:00
8
+ summary: Library for packing and unpacking binary strings.
9
+ require_paths:
10
+ - .
11
+ email: corey.burrows@gmail.com
12
+ homepage:
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: bitpack
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Corey Burrows
31
+ files:
32
+ - README
33
+ - CHANGELOG
34
+ - LICENSE
35
+ - Rakefile
36
+ - ext/bitpack.h
37
+ - ext/bitpack.c
38
+ - ext/bitpack_ext.c
39
+ - ext/extconf.rb
40
+ - lib/bitpack.rb
41
+ - test/bitpack_tests.rb
42
+ test_files: []
43
+
44
+ rdoc_options: []
45
+
46
+ extra_rdoc_files:
47
+ - README
48
+ - CHANGELOG
49
+ - LICENSE
50
+ executables: []
51
+
52
+ extensions:
53
+ - ext/extconf.rb
54
+ requirements: []
55
+
56
+ dependencies: []
57
+