bitstring 1.0.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.
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