bitstring 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/CONTRIBUTORS.txt +5 -0
  2. data/Changelog.txt +20 -0
  3. data/LICENCE.txt +202 -0
  4. data/NOTICE.txt +5 -0
  5. data/README.txt +63 -0
  6. data/doc/classes/BitString.html +2479 -0
  7. data/doc/classes/BitString.src/M000001.html +99 -0
  8. data/doc/classes/BitString.src/M000002.html +18 -0
  9. data/doc/classes/BitString.src/M000003.html +20 -0
  10. data/doc/classes/BitString.src/M000004.html +19 -0
  11. data/doc/classes/BitString.src/M000005.html +24 -0
  12. data/doc/classes/BitString.src/M000006.html +44 -0
  13. data/doc/classes/BitString.src/M000007.html +21 -0
  14. data/doc/classes/BitString.src/M000008.html +18 -0
  15. data/doc/classes/BitString.src/M000009.html +18 -0
  16. data/doc/classes/BitString.src/M000010.html +22 -0
  17. data/doc/classes/BitString.src/M000011.html +29 -0
  18. data/doc/classes/BitString.src/M000012.html +22 -0
  19. data/doc/classes/BitString.src/M000013.html +43 -0
  20. data/doc/classes/BitString.src/M000014.html +19 -0
  21. data/doc/classes/BitString.src/M000015.html +40 -0
  22. data/doc/classes/BitString.src/M000016.html +21 -0
  23. data/doc/classes/BitString.src/M000017.html +18 -0
  24. data/doc/classes/BitString.src/M000018.html +18 -0
  25. data/doc/classes/BitString.src/M000019.html +18 -0
  26. data/doc/classes/BitString.src/M000020.html +20 -0
  27. data/doc/classes/BitString.src/M000021.html +24 -0
  28. data/doc/classes/BitString.src/M000022.html +23 -0
  29. data/doc/classes/BitString.src/M000023.html +42 -0
  30. data/doc/classes/BitString.src/M000024.html +61 -0
  31. data/doc/classes/BitString.src/M000025.html +18 -0
  32. data/doc/classes/BitString.src/M000026.html +18 -0
  33. data/doc/classes/BitString.src/M000027.html +20 -0
  34. data/doc/classes/BitString.src/M000028.html +18 -0
  35. data/doc/classes/BitString.src/M000029.html +18 -0
  36. data/doc/classes/BitString.src/M000030.html +18 -0
  37. data/doc/classes/BitString.src/M000031.html +18 -0
  38. data/doc/classes/BitString.src/M000032.html +18 -0
  39. data/doc/created.rid +1 -0
  40. data/doc/files/lib/bitstring/operators_rb.html +122 -0
  41. data/doc/files/lib/bitstring_rb.html +153 -0
  42. data/doc/fr_class_index.html +27 -0
  43. data/doc/fr_file_index.html +28 -0
  44. data/doc/fr_method_index.html +60 -0
  45. data/doc/index.html +24 -0
  46. data/doc/rdoc-style.css +208 -0
  47. data/lib/bitstring.rb +1318 -0
  48. data/lib/bitstring/operators.rb +481 -0
  49. data/test/Rakefile +21 -0
  50. data/test/test_basic.rb +848 -0
  51. data/test/test_data.rb +24 -0
  52. data/test/test_enum.rb +671 -0
  53. data/test/test_helper.rb +3 -0
  54. data/test/test_operators.rb +454 -0
  55. metadata +121 -0
@@ -0,0 +1,3 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/../lib/bitstring'
@@ -0,0 +1,454 @@
1
+ require 'rubygems'
2
+ require File.dirname(__FILE__) + '/test_helper.rb'
3
+ require File.dirname(__FILE__) + '/test_data.rb'
4
+
5
+ #
6
+ # Test the operators (special characters, like & and |).
7
+ # (Other tests handle basic functionality and the methods inherited from
8
+ # the Enumerable mixin.)
9
+ #
10
+
11
+ module Tests
12
+
13
+ class Test_BitStrings < Test::Unit::TestCase
14
+
15
+ def test_000_EQUAL()
16
+ #
17
+ # Test == comparison of bitstrings.
18
+ #
19
+ TestVals.each do |sVal|
20
+ #
21
+ # Compare two identically-created unbounded bitstrings
22
+ #
23
+ bs1 = BitString.new(sVal)
24
+ bs2 = BitString.new(sVal)
25
+ assert(bs1 == bs2,
26
+ "Test unbounded new('#{sVal}') == new('#{sVal}')")
27
+ unless (sVal.gsub(/0/, '').empty?)
28
+ bs2 = BitString.new(sVal + '0')
29
+ assert(bs1 != bs2,
30
+ "Test unbounded new('#{sVal}') != new('#{sVal}0')")
31
+ end
32
+ #
33
+ # Now against the string value.
34
+ #
35
+ assert(bs1 == sVal,
36
+ "Test unbounded new('#{sVal}') == '#{sVal}'")
37
+ unless (sVal.gsub(/0/, '').empty?)
38
+ assert(bs1 != (sVal + '0'),
39
+ "Test unbounded new('#{sVal}') != '#{sVal}0'")
40
+ end
41
+ #
42
+ # Now against the integer value.
43
+ #
44
+ assert(bs1 == sVal.to_i(2),
45
+ "Test unbounded new('#{sVal}') == #{sVal.to_i(2)}")
46
+ unless (sVal.gsub(/0/, '').empty?)
47
+ assert(bs1 != (sVal.to_i(2) * 2),
48
+ "Test unbounded new('#{sVal}') != #{sVal.to_i(2) * 2}")
49
+ end
50
+ #
51
+ # Now against the array representatione.
52
+ #
53
+ expected = sVal.split(//).collect { |val| val.to_i }
54
+ assert(bs1 == expected,
55
+ "Test unbounded new('#{sVal}') == #{expected.inspect}")
56
+ unless (sVal.gsub(/0/, '').empty?)
57
+ expected.push(0)
58
+ assert(bs1 != expected,
59
+ "Test unbounded new('#{sVal}') != #{expected.inspect}")
60
+ end
61
+ #
62
+ # Repeat for bounded bitstrings.
63
+ #
64
+ sVal_l = sVal.length
65
+ bs1 = BitString.new(sVal, sVal_l)
66
+ bs2 = BitString.new(sVal, sVal_l)
67
+ assert(bs1 == bs2,
68
+ "Test bounded new('#{sVal}') == new('#{sVal}')")
69
+ bs2 = BitString.new(sVal + '0', sVal_l + 1)
70
+ assert(bs1 != bs2,
71
+ "Test bounded new('#{sVal}') != new('#{sVal}0')")
72
+ #
73
+ # Now against the string value.
74
+ #
75
+ assert(bs1 == sVal,
76
+ "Test bounded new('#{sVal}') == '#{sVal}'")
77
+ unless (sVal.gsub(/0/, '').empty?)
78
+ assert(bs1 != (sVal + '0'),
79
+ "Test unbounded new('#{sVal}') != '#{sVal}0'")
80
+ end
81
+ #
82
+ # Now against the integer value.
83
+ #
84
+ assert(bs1 == sVal.to_i(2),
85
+ "Test unbounded new('#{sVal}') == #{sVal.to_i(2)}")
86
+ unless (sVal.gsub(/0/, '').empty?)
87
+ assert(bs1 != (sVal.to_i(2) * 2),
88
+ "Test unbounded new('#{sVal}') != #{sVal.to_i(2) * 2}")
89
+ end
90
+ #
91
+ # Now against the array representatione.
92
+ #
93
+ expected = sVal.split(//).collect { |val| val.to_i }
94
+ assert(bs1 == expected,
95
+ "Test unbounded new('#{sVal}') == #{expected.inspect}")
96
+ unless (sVal.gsub(/0/, '').empty?)
97
+ expected.push(0)
98
+ assert(bs1 != expected,
99
+ "Test unbounded new('#{sVal}') != #{expected.inspect}")
100
+ end
101
+ end
102
+ end # def test_001_AND()
103
+
104
+ def test_001_AND()
105
+ #
106
+ # Test ANDing with Array, String, BitString, and Integer values.
107
+ #
108
+ TestVals.each do |sVal|
109
+ #
110
+ # AND with two unbounded bitstrings
111
+ #
112
+ bs1 = BitString.new(sVal)
113
+ bs2 = BitString.new(sVal)
114
+ #
115
+ # First test our assumption
116
+ #
117
+ assert_equal(bs2.to_i,
118
+ bs1.to_i,
119
+ "Verify bitstring.to_i values of two strings made " +
120
+ "from the same value are equal")
121
+ #
122
+ # Unbounded & unbounded
123
+ #
124
+ assert_equal(bs1.to_i,
125
+ (bs1 & bs2).to_i,
126
+ "Test unbounded '#{sVal}'1 & unbounded '#{sVal}'2 => " +
127
+ "'#{sVal}'")
128
+ assert_equal(bs2.to_i,
129
+ (bs2 & bs1).to_i,
130
+ "Test unbounded '#{sVal}'2 & unbounded '#{sVal}'1 => " +
131
+ "'#{sVal}'")
132
+ #
133
+ # Unbounded & bounded
134
+ #
135
+ bs1 = BitString.new(sVal)
136
+ bs2 = BitString.new(sVal, sVal.length)
137
+ assert_equal(bs1.to_i,
138
+ (bs1 & bs2).to_i,
139
+ "Test unbounded '#{sVal}'1 & bounded '#{sVal}'2 => " +
140
+ "'#{sVal}'")
141
+ assert_equal(bs2.to_i,
142
+ (bs2 & bs1).to_i,
143
+ "Test bounded '#{sVal}'2 & unbounded '#{sVal}'1 => " +
144
+ "'#{sVal}'")
145
+ #
146
+ # Bounded & unbounded
147
+ #
148
+ bs1 = BitString.new(sVal, sVal.length)
149
+ bs2 = BitString.new(sVal)
150
+ assert_equal(bs1.to_i,
151
+ (bs1 & bs2).to_i,
152
+ "Test bounded '#{sVal}'1 & unbounded '#{sVal}'2 => " +
153
+ "'#{sVal}'")
154
+ assert_equal(bs2.to_i,
155
+ (bs2 & bs1).to_i,
156
+ "Test unbounded '#{sVal}'2 & bounded '#{sVal}'1 => " +
157
+ "'#{sVal}'")
158
+ #
159
+ # Bounded & bounded
160
+ #
161
+ bs1 = BitString.new(sVal, sVal.length)
162
+ bs2 = BitString.new(sVal, sVal.length)
163
+ assert_equal(bs1.to_i,
164
+ (bs1 & bs2).to_i,
165
+ "Test bounded '#{sVal}'1 & bounded '#{sVal}'2 => " +
166
+ "'#{sVal}'")
167
+ assert_equal(bs2.to_i,
168
+ (bs2 & bs1).to_i,
169
+ "Test bounded '#{sVal}'2 & bounded '#{sVal}'1 => " +
170
+ "'#{sVal}'")
171
+ end
172
+ end # def test_001_AND()
173
+
174
+ def test_002_LT()
175
+ return unless (BitString.new.respond_to?(:<))
176
+ assert(false, '###FAIL! .< not supported but .respond_to? is true!')
177
+ end # def test_002_LT()
178
+
179
+ def test_003_ShiftLeft()
180
+ return unless (BitString.new.respond_to?(:<<))
181
+ TestVals.each do |sVal|
182
+ #
183
+ # Start with unbounded strings.
184
+ #
185
+ rVal = sVal.to_i(2).to_s(2)
186
+ bs = BitString.new(sVal)
187
+ (sVal.length * 2).times do |i|
188
+ expected = (rVal + '0' * i).to_i(2).to_s(2)
189
+ assert_equal(expected,
190
+ (bs << i).to_s,
191
+ "Test unbounded '#{sVal}' << #{i} == #{expected}")
192
+ end
193
+ #
194
+ # Now the bounded ones.
195
+ #
196
+ l = sVal.length
197
+ bs = BitString.new(sVal, l)
198
+ rVal = bs.to_s
199
+ (sVal.length * 2).times do |i|
200
+ expected = (rVal + '0' * i)[-l,l]
201
+ assert_equal(expected,
202
+ (bs << i).to_s,
203
+ "Test bounded '#{sVal}' << #{i} == #{expected}")
204
+ end
205
+ end
206
+ end # def test_003_ShiftLeft()
207
+
208
+ def test_004_LEQ()
209
+ return unless (BitString.new.respond_to?(:<=))
210
+ assert(false, '###FAIL! .<= not supported but .respond_to? is true!')
211
+ end # def test_004_LEQ()
212
+
213
+ def test_005_GT()
214
+ return unless (BitString.new.respond_to?(:>))
215
+ assert(false, '###FAIL! .> not supported but .respond_to? is true!')
216
+ end # def test_005_GT()
217
+
218
+ def test_006_GEQ()
219
+ return unless (BitString.new.respond_to?(:>=))
220
+ assert(false, '###FAIL! .>= not supported but .respond_to? is true!')
221
+ end # def test_006_GEQ()
222
+
223
+ def test_007_ShiftRight()
224
+ return unless (BitString.new.respond_to?(:>>))
225
+ TestVals.each do |sVal|
226
+ #
227
+ # Start with unbounded strings.
228
+ #
229
+ rVal = sVal.to_i(2).to_s(2)
230
+ bs = BitString.new(sVal)
231
+ (sVal.length * 2).times do |i|
232
+ expected = rVal[0,rVal.length-i]
233
+ expected = '0' if (expected.nil? || expected.empty?)
234
+ assert_equal(expected,
235
+ (bs >> i).to_s,
236
+ "Test unbounded '#{sVal}' >> #{i} == #{expected}")
237
+ end
238
+ #
239
+ # Now the bounded ones.
240
+ #
241
+ l = sVal.length
242
+ bs = BitString.new(sVal, l)
243
+ rVal = bs.to_s
244
+ (sVal.length * 2).times do |i|
245
+ expected = ('0' * [i,l].min) + rVal[0,[rVal.length-i,0].max]
246
+ assert_equal(expected,
247
+ (bs >> i).to_s,
248
+ "Test bounded '#{sVal}' >> #{i} == #{expected}")
249
+ end
250
+ end
251
+ end # def test_007_ShiftRight()
252
+
253
+ def test_008_XOR()
254
+ return unless (BitString.new.respond_to?(:^))
255
+ TestVals.each do |sVal|
256
+ sVal_l = sVal.length
257
+ #
258
+ # Start with unbounded strings.
259
+ #
260
+ xbs = BitString.new(sVal)
261
+ bs1 = xbs.dup
262
+ ybs = BitString.new(rand(2**sVal_l))
263
+ bs2 = ybs.dup
264
+ bs1 = bs1 ^ bs2
265
+ bs2 = bs1 ^ bs2
266
+ bs1 = bs1 ^ bs2
267
+ assert_equal(xbs.to_i,
268
+ bs2.to_i,
269
+ "Test unbounded A from A=A^B;B=A^B;A=A^B\n" +
270
+ "xbs=#{xbs.to_s}\n" +
271
+ "ybs=#{ybs.to_s}\n" +
272
+ "bs1=#{bs1.to_s}\n" +
273
+ "bs2=#{bs2.to_s}")
274
+ assert_equal(ybs.to_i,
275
+ bs1.to_i,
276
+ "Test unbounded B from A=A^B;B=A^B;A=A^B\n" +
277
+ "xbs=#{xbs.to_s}\n" +
278
+ "ybs=#{ybs.to_s}\n" +
279
+ "bs1=#{bs1.to_s}\n" +
280
+ "bs2=#{bs2.to_s}")
281
+ #
282
+ # Now with bounded ones.
283
+ #
284
+ xbs = BitString.new(sVal, sVal_l)
285
+ bs1 = xbs.dup
286
+ ybs = BitString.new(rand(2**sVal_l), sVal_l)
287
+ bs2 = ybs.dup
288
+ bs1 = bs1 ^ bs2
289
+ bs2 = bs1 ^ bs2
290
+ bs1 = bs1 ^ bs2
291
+ assert_equal(xbs.to_i,
292
+ bs2.to_i,
293
+ "Test bounded A from A=A^B;B=A^B;A=A^B\n" +
294
+ "xbs=#{xbs.to_s}\n" +
295
+ "ybs=#{ybs.to_s}\n" +
296
+ "bs1=#{bs1.to_s}\n" +
297
+ "bs2=#{bs2.to_s}")
298
+ assert_equal(ybs.to_i,
299
+ bs1.to_i,
300
+ "Test bounded B from A=A^B;B=A^B;A=A^B\n" +
301
+ "xbs=#{xbs.to_s}\n" +
302
+ "ybs=#{ybs.to_s}\n" +
303
+ "bs1=#{bs1.to_s}\n" +
304
+ "bs2=#{bs2.to_s}")
305
+ #
306
+ # Now with bounded ones of different lengths. Note that
307
+ # XOR returns a bitstring the same length as its parent --
308
+ # which means in the swap sequence below, both will end up
309
+ # with the length of the shorter string.
310
+ #
311
+ xbs = BitString.new(sVal, sVal_l)
312
+ bs1 = xbs.dup
313
+ ybs = BitString.new(rand(2**(sVal_l * 2)), sVal_l * 2)
314
+ bs2 = ybs.dup
315
+ bs1 = bs1 ^ bs2
316
+ bs2 = bs1 ^ bs2
317
+ bs1 = bs1 ^ bs2
318
+ new_l = [sVal_l, ybs.length].min
319
+ assert_equal(xbs.resize(new_l).to_i,
320
+ bs2.resize(new_l).to_i,
321
+ "Test bounded A from A=A^B;B=A^B;A=A^B\n" +
322
+ "xbs=#{xbs.to_s}\n" +
323
+ "ybs=#{ybs.to_s}\n" +
324
+ "bs1=#{bs1.to_s}\n" +
325
+ "bs2=#{bs2.to_s}")
326
+ assert_equal(ybs.resize(new_l).to_i,
327
+ bs1.resize(new_l).to_i,
328
+ "Test bounded B from A=A^B;B=A^B;A=A^B\n" +
329
+ "xbs=#{xbs.to_s}\n" +
330
+ "ybs=#{ybs.to_s}\n" +
331
+ "bs1=#{bs1.to_s}\n" +
332
+ "bs2=#{bs2.to_s}")
333
+ end
334
+ end # def test_008_XOR()
335
+
336
+ def test_009_OR()
337
+ return unless (BitString.new.respond_to?(:|))
338
+ TestVals.each do |sVal|
339
+ sVal_l = sVal.length
340
+ #
341
+ # Start with unbounded strings.
342
+ #
343
+ xbs = BitString.new(sVal)
344
+ ybs = BitString.new(rand(2**sVal_l))
345
+ expected = BitString.new(xbs.to_i | ybs.to_i)
346
+ result = xbs | ybs
347
+ assert_equal(expected,
348
+ result,
349
+ "Test unbounded X from X=A|B\n" +
350
+ "A =#{xbs.to_s}\n" +
351
+ "B =#{ybs.to_s}\n" +
352
+ "exp=#{expected.to_s}\n" +
353
+ "got=#{result.to_s}")
354
+ result = ybs | xbs
355
+ assert_equal(expected,
356
+ result,
357
+ "Test unbounded X from X=B|A\n" +
358
+ "A =#{xbs.to_s}\n" +
359
+ "B =#{ybs.to_s}\n" +
360
+ "exp=#{expected.to_s}\n" +
361
+ "got=#{result.to_s}")
362
+ #
363
+ # Now with bounded ones with the same lengths.
364
+ #
365
+ xbs = BitString.new(sVal, sVal_l)
366
+ ybs = BitString.new(rand(2**sVal_l), sVal_l)
367
+ expected = BitString.new(xbs.to_i | ybs.to_i, sVal_l)
368
+ result = xbs | ybs
369
+ assert_equal(expected,
370
+ result,
371
+ "Test bounded X from X=A|B\n" +
372
+ "A =#{xbs.to_s}\n" +
373
+ "B =#{ybs.to_s}\n" +
374
+ "exp=#{expected.to_s}\n" +
375
+ "got=#{result.to_s}")
376
+ result = ybs | xbs
377
+ assert_equal(expected,
378
+ result,
379
+ "Test bounded X from X=B|A\n" +
380
+ "A =#{xbs.to_s}\n" +
381
+ "B =#{ybs.to_s}\n" +
382
+ "exp=#{expected.to_s}\n" +
383
+ "got=#{result.to_s}")
384
+ #
385
+ # Now with bounded ones of different lengths. Note that
386
+ # OR returns a bitstring the same length as its parent --
387
+ # which means in the swap sequence below, both will end up
388
+ # with the length of the shorter string.
389
+ #
390
+ xbs = BitString.new(sVal, sVal_l)
391
+ ybs = BitString.new(rand(2**(sVal_l * 2)), sVal_l * 2)
392
+ expected = BitString.new((xbs.to_i | ybs.to_i) & xbs.mask, xbs.length)
393
+ result = xbs | ybs
394
+ assert_equal(expected,
395
+ result,
396
+ "Test bounded X from X=A|B (A.length != B.length)\n" +
397
+ "A =#{xbs.to_s}\n" +
398
+ "B =#{ybs.to_s}\n" +
399
+ "exp=#{expected.to_s}\n" +
400
+ "got=#{result.to_s}")
401
+ expected = BitString.new((xbs.to_i | ybs.to_i) & ybs.mask, ybs.length)
402
+ result = ybs | xbs
403
+ assert_equal(expected,
404
+ result,
405
+ "Test bounded X from X=B|A (A.length != B.length)\n" +
406
+ "A =#{xbs.to_s}\n" +
407
+ "B =#{ybs.to_s}\n" +
408
+ "exp=#{expected.to_s}\n" +
409
+ "got=#{result.to_s}")
410
+ end
411
+ end # def test_009_OR()
412
+
413
+ def test_010_NOT()
414
+ return unless (BitString.new.respond_to?(:~))
415
+ TestVals.each do |sVal|
416
+ sVal_l = sVal.length
417
+ #
418
+ # Start with unbounded strings.
419
+ #
420
+ bs = BitString.new(sVal)
421
+ expected = bs.mask
422
+ result = (~ bs) | bs
423
+ assert_equal(expected,
424
+ result,
425
+ "Test unbounded (~ '#{sVal}') | '#{sVal}' " +
426
+ "== '#{expected.to_s}'")
427
+ #
428
+ # Move on to bounded ones, which are a little more problematic.
429
+ # Maybe.
430
+ #
431
+ bs = BitString.new(sVal, sVal_l)
432
+ expected = BitString.new(bs.mask, sVal_l)
433
+ result = (~ bs) | bs
434
+ assert_equal(expected,
435
+ result,
436
+ "Test bounded (~ '#{sVal}') | '#{sVal}' " +
437
+ "== '#{expected.to_s}'")
438
+ result = (~ bs) ^ bs
439
+ assert_equal(expected,
440
+ result,
441
+ "Test bounded (~ '#{sVal}') ^ '#{sVal}' " +
442
+ "== '#{expected.to_s}'")
443
+ expected = BitString.new(0, sVal_l)
444
+ result = (~ bs) & bs
445
+ assert_equal(expected,
446
+ result,
447
+ "Test bounded (~ '#{sVal}') & '#{sVal}' " +
448
+ "== '#{expected.to_s}'")
449
+ end
450
+ end # def test_010_NOT()
451
+
452
+ end # class Test_BitStrings
453
+
454
+ end # module Tests