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,1318 @@
1
+ #
2
+ # = bitstring.rb - Bounded and unbounded bit strings
3
+ #
4
+ # Author:: Ken Coar
5
+ # Copyright:: Copyright © 2010 Ken Coar
6
+ # License:: Apache Licence 2.0
7
+ #
8
+ # == Synopsis
9
+ #
10
+ # require 'rubygems'
11
+ # require 'bitstring'
12
+ # bString = BitString.new([initial-value], [bitcount])
13
+ # bString = BitString.new(bitcount) { |index| block }
14
+ #
15
+ # Bug/feature trackers, code, and mailing lists are available at
16
+ # http://rubyforge.org/projects/bitstring.
17
+ #
18
+ # Class and method documentation is online at
19
+ # http://bitstring.rubyforge.org/rdoc/
20
+ #
21
+ # == Description
22
+ #
23
+ # The <i>BitString</i> package provides a class for handling a series
24
+ # of bits as an array-like structure. Bits are addressable individually
25
+ # or as subranges.
26
+ #
27
+ # BitString objects can be either bounded or unbounded. Bounded bitstrings
28
+ # have a specific number of bits, and operations that would affect bits
29
+ # outside those limits will raise exceptions. Unbounded bitstrings can
30
+ # grow to arbitrary lengths, but some operations (like rotation) cannot
31
+ # be performed on them.
32
+ #--
33
+ # Copyright © 2010 Ken Coar
34
+ #
35
+ # Licensed under the Apache License, Version 2.0 (the "License"); you
36
+ # may not use this file except in compliance with the License. You may
37
+ # obtain a copy of the License at
38
+ #
39
+ # http://www.apache.org/licenses/LICENSE-2.0
40
+ #
41
+ # Unless required by applicable law or agreed to in writing, software
42
+ # distributed under the License is distributed on an "AS IS" BASIS,
43
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
44
+ # implied. See the License for the specific language governing
45
+ # permissions and limitations under the License.
46
+ #++
47
+
48
+ require 'rubygems'
49
+ require 'versionomy'
50
+
51
+ require 'bitstring/operators'
52
+
53
+ #
54
+ # It's sort of like a fake a subclass of Integer solely to
55
+ # differentiate bitstrings.
56
+ #
57
+ class BitString
58
+
59
+ #
60
+ # Versionomy object for the class, recording the current version.
61
+ #
62
+ Version = Versionomy.parse('1.0.0')
63
+
64
+ #
65
+ # Version number as a simple readable string.
66
+ #
67
+ VERSION = Version.to_s
68
+
69
+ #
70
+ # Other constants:
71
+ #
72
+
73
+ #
74
+ # Identifer specifying the least significant (low) end of the bitstring
75
+ # (used by <i>grow</i>, <i>shrink</i>, and <i>mask</i>).
76
+ #
77
+ LOW_END = :low
78
+ #
79
+ # Identifer specifying the most significant (high) end of the bitstring
80
+ # (used by <i>grow</i>, <i>shrink</i>, and <i>mask</i>).
81
+ #
82
+ HIGH_END = :high
83
+
84
+ # :stopdoc:
85
+ #
86
+ # These classes are part of our internal error condition handling
87
+ # mechanism, and aren't intended to be used externally.
88
+ #
89
+ class InternalError < Exception
90
+ #
91
+ # Used internally only -- except for internal consistency errors.
92
+ #
93
+ end # class InternalError
94
+
95
+ class BadDigit < InternalError
96
+ #
97
+ # Turned into an ArgumentError.
98
+ #
99
+ end # class BadDigit
100
+
101
+ class BitsRInts < InternalError
102
+ #
103
+ # Turned into an ArgumentError.
104
+ #
105
+ end # class BitsRInts
106
+
107
+ class BogoIndex < InternalError
108
+ #
109
+ # Turned into an IndexError.
110
+ #
111
+ end # class BogoIndex
112
+
113
+ class NeedGPS < InternalError
114
+ #
115
+ # Turned into an ArgumentError.
116
+ #
117
+ end # class NeedGPS
118
+
119
+ class NoDeficitBits < InternalError
120
+ #
121
+ # Turned into an IndexError.
122
+ #
123
+ end # class NoDeficitBits
124
+
125
+ class OuttasightIndex < InternalError
126
+ #
127
+ # Turned into an IndexError.
128
+ #
129
+ end # class OuttasightIndex
130
+
131
+ class UnboundedNonsense < InternalError
132
+ #
133
+ # Turned into a RuntimeError.
134
+ #
135
+ end # class UnboundedNonsense
136
+
137
+ class UnInterable < InternalError
138
+ #
139
+ # Turned into a RuntimeError.
140
+ #
141
+ end # class UnInterable
142
+
143
+ class WrongNargs < InternalError
144
+ #
145
+ # Turned into an ArgumentError.
146
+ #
147
+ end # class WrongNargs
148
+
149
+ # :startdoc:
150
+ #
151
+ # We want a bunch of Enumerable's methods..
152
+ #
153
+ include Enumerable
154
+
155
+ #
156
+ # ..but not all of them. Some just don't make sense for bitstrings.
157
+ # (.zip makes sense, but I'm going to defer it until I have a test for it.)
158
+ #
159
+ undef :grep, :sort, :sort_by, :zip
160
+
161
+ #
162
+ # <i>Boolean</i>. Whether or not the bitstring is bounded and limited
163
+ # to a specific length. Read-only; set at object creation.
164
+ #
165
+ attr_reader :bounded
166
+
167
+ #
168
+ # <i>Integer</i>. Length of the bitstring. Only meaningful for bounded
169
+ # strings. Read-only; set at object creation.
170
+ #
171
+ #attr_reader :length
172
+
173
+ #
174
+ # === Description
175
+ #
176
+ # Create a new <i>BitString</i> object. By default, it will be unbounded and
177
+ # all bits clear.
178
+ #
179
+ # :call-seq:
180
+ # new<i>([val], [bitcount])</i> => <i>BitString</i>
181
+ # new<i>(length) {|index| block }</i> => <i>BitString</i>
182
+ #
183
+ # === Arguments
184
+ # [<i>val</i>] <i>Array</i>, <i>Integer</i>, <i>String</i>, or <i>BitString</i>. Initial value for the bitstring. If a <i>String</i>, the value must contain only '0' and '1' characters; if an <i>Array</i>, all elements must be 0 or 1. Default 0.
185
+ # [<i>bitcount</i>] <i>Integer</i>. Optional length (number of bits) for a bounded bitstring.
186
+ #
187
+ # === Examples
188
+ # bs = BitString.new(4095)
189
+ # bs.to_s
190
+ # => "111111111111"
191
+ # bs.bounded?
192
+ # => false
193
+ #
194
+ # bs = BitString.new('110000010111', 12)
195
+ # bs.bounded?
196
+ # => true
197
+ # bs.to_i
198
+ # => 3095
199
+ #
200
+ # bs = BitString.new(12) { |pos| pos % 2 }
201
+ # bs.to_s
202
+ # => "101010101010"
203
+ #
204
+ # === Exceptions
205
+ # [<tt>RangeError</tt>] <i>val</i> is a string, but contains non-binary digits.
206
+ #
207
+ def initialize(*args_p, &block)
208
+ #
209
+ # Two constructor scenarios:
210
+ #
211
+ # 1. With a block and an optional length (defaults to 1)
212
+ # 2. No block, and with value and length both optional.
213
+ #
214
+ # We don't do any type-checking on the arguments until later.
215
+ #
216
+ unless (block.nil?)
217
+ #
218
+ # We got a block; set up the constraints. Bitstrings constructed
219
+ # this way are bounded.
220
+ #
221
+ unless (args_p.length < 2)
222
+ raise ArgumentError.new('only bitstring length ' +
223
+ 'may be specified with a block')
224
+ end
225
+ @bounded = true
226
+ @length = args_p.length > 0 ? args_p[0] : 1
227
+ else
228
+ #
229
+ # Get value and possibly length from the argument list.
230
+ #
231
+ unless (args_p.length < 3)
232
+ raise ArgumentError.new('wrong number of arguments ' +
233
+ '(must be 2 or fewer)')
234
+ end
235
+ val = args_p[0] || 0
236
+ @length = args_p[1] if (@bounded = ! args_p[1].nil?)
237
+ end
238
+ #
239
+ # Now do some validation on the arguments.
240
+ #
241
+ if (@bounded)
242
+ unless ((@length = @length.to_i) > 0)
243
+ raise ArgumentError.new('bitstring length must be greater than 0')
244
+ end
245
+ end
246
+ if (block.nil?)
247
+ #
248
+ # We weren't passed a block, so get the info directly from the argument
249
+ # list.
250
+ #
251
+ @value = _arg2int(val)
252
+ else
253
+ #
254
+ # We were passed a block, so invoke it for each bit position to
255
+ # determine that bit's value from the LSB of the result.
256
+ #
257
+ @value = 0
258
+ @length.times { |i| self[i] = block.call(i).to_i & 1 }
259
+ end
260
+ end # def initialize
261
+
262
+ #
263
+ # === Description
264
+ #
265
+ # Convert a value from some representation into an integer. Possibly
266
+ # acceptable inputs are:
267
+ #
268
+ # o An <i>Array</i> containing only 0 and 1 values.
269
+ # o An existing <i>BitString</i> object
270
+ # o An <i>Integer</i> or descendent binary value
271
+ # o A <i>String</i> containing only '0' and '1' characters
272
+ #
273
+ # Any other inputs will raise an exception.
274
+ #
275
+ # :call-seq:
276
+ # _arg2int<i>(value)</i> => <i>Integer</i>
277
+ #
278
+ # === Arguments
279
+ # [<i>value</i>] <i>Array</i>, <i>BitString</i>, <i>Integer</i>, <i>String</i>. The value to be converted to an integer.
280
+ # [<i>msg</i>] <i>String</i>. Message to use if we don't have a canned one.
281
+ #
282
+ # === Examples
283
+ # _arg2int(23)
284
+ # => 23
285
+ # _arg2int('110000010111')
286
+ # => 3095
287
+ # _arg2int([1,1,0,0,0,0,0,1,0,1,1,1])
288
+ # => 3095
289
+ # _arg2int('alpha')
290
+ # => exception: "ArgumentError: value ('alpha':String) contains invalid digits"
291
+ #
292
+ # === Exceptions
293
+ # [<tt>ArgumentError</tt>] Can't reduce the argument to a binary integer.
294
+ #
295
+ def _arg2int(val_p) # :nodoc:
296
+ if (val_p.class.eql?(BitString))
297
+ #
298
+ # If we were passed a bitstring, convert it.
299
+ #
300
+ val = val_p.to_i
301
+ elsif (val_p.class.eql?(String))
302
+ #
303
+ # If we were given a String for the value, it must consist of valid
304
+ # binary digits.
305
+ #
306
+ _raise(BadDigit, nil, val_p) unless (val_p.gsub(/[01]/, '').empty?)
307
+ val = val_p.to_i(2)
308
+ elsif (val_p.class.eql?(Array))
309
+ #
310
+ # If we were given an array, make sure that all the values are
311
+ # integers and either 1 or 0.
312
+ #
313
+ _raise(BadDigit, nil, val_p) unless ((val_p - [0, 1]).empty?)
314
+ val = val_p.collect { |bit| bit.to_s(2) }.join('').to_i(2)
315
+ elsif (val_p.kind_of?(Integer))
316
+ val = val_p
317
+ else
318
+ #
319
+ # Let's try to convert it to an integer from whatever class we
320
+ # were passed.
321
+ #
322
+ unless (val_p.respond_to?(:to_i))
323
+ raise ArgumentError.new('unable to determine bitstring value from ' +
324
+ "\"#{val_p.to_s}\":#{val_p.class.name}")
325
+ end
326
+ end
327
+ val
328
+ end # def _arg2int
329
+
330
+ #
331
+ # === Description
332
+ #
333
+ # Raise a standard exception.
334
+ #
335
+ # :call-seq:
336
+ # _raise<i>(exc, [msg])</i> => Exception raised
337
+ #
338
+ # === Arguments
339
+ # [<i>exc</i>] <i>Exception</i>. One of our 'known' repeated exceptions.
340
+ # [<i>msg</i>] <i>String</i>. Message to use if we don't have a canned one.
341
+ #
342
+ # === Examples
343
+ # _raise(BadDigit, nil, bogusvalue)
344
+ # _raise(OuttasightIndex, 'you are kidding, right?')
345
+ #
346
+ # === Exceptions
347
+ # [<tt>InternalError</tt>] Called with something other than an exception.
348
+ # [<i>other</I>] As indicated.
349
+ #
350
+ def _raise(*args) # :nodoc:
351
+ exc = args.shift
352
+ unless (exc.ancestors.include?(Exception))
353
+ raise InternalError.new('asked to raise non-exception')
354
+ end
355
+ begin
356
+ raise InternalError
357
+ rescue InternalError => e
358
+ if (args[0].kind_of?(String) && args[0].match(/%/))
359
+ msg = sprintf(*args)
360
+ args = []
361
+ elsif (args[0].kind_of?(String))
362
+ msg = args.shift
363
+ else
364
+ msg = nil
365
+ end
366
+
367
+ mName = e.backtrace[1].match(/in \`(\S*)'/).captures[0]
368
+ case exc.name.sub(/^.*::/, '')
369
+ when 'BadDigit'
370
+ if (msg.nil?)
371
+ val = args[1].respond_to?(:to_s) ? args[1].to_s : args[1].inspect
372
+ msg = "value ('#{val}':#{args[1].class.name}) contains invalid digits"
373
+ end
374
+ raise ArgumentError.new(msg)
375
+ when 'BitsRInts'
376
+ raise ArgumentError.new(msg || 'bitcount must be an integer')
377
+ when 'BogoIndex'
378
+ if (msg.nil?)
379
+ val = args[0]
380
+ msg = "illegal index value #{val.inspect}"
381
+ end
382
+ raise IndexError.new(msg)
383
+ when 'NeedGPS'
384
+ raise ArgumentError.new(msg ||
385
+ 'invalid direction for operation')
386
+ when 'NoDeficitBits'
387
+ raise IndexError.new(msg || 'bitcount must be positive')
388
+ when 'NotImplementedError'
389
+ raise NotImplementedError.new(msg ||
390
+ "method '#{mName}' not yet implemented")
391
+ when 'OuttasightIndex'
392
+ if (msg.kind_of?(Integer))
393
+ msg = "index out of range: '#{msg.to_s}'"
394
+ end
395
+ raise IndexError.new(msg ||
396
+ 'index out of range')
397
+ when 'UnboundedNonsense'
398
+ raise RuntimeError.new(msg ||
399
+ 'operation only meaningful for ' +
400
+ 'bounded bitstrings')
401
+ when 'UnInterable'
402
+ if (msg.nil?)
403
+ val = args[0].respond_to?(to_s) ? args[0].to_s : args[0].inspect
404
+ msg = "unable to reduce '#{val}':#{args[0].class.name} " +
405
+ "to a binary value"
406
+ end
407
+ raise ArgumentError.new(msg)
408
+ when 'WrongNargs'
409
+ if (msg.nil?)
410
+ val = args[0].respond_to?(:to_i) ? args[0].to_i : args[0].inspect
411
+ req = args[1].respond_to?(:to_i) ? args[1].to_i : args[1].inspect
412
+ msg = "wrong number of arguments (#{val} for #{req})"
413
+ end
414
+ raise ArgumentError.new(msg)
415
+ else
416
+ raise exc.new(msg)
417
+ end
418
+ end
419
+ end # def _raise
420
+
421
+ #
422
+ # === Description
423
+ #
424
+ # Return a binary string representation of the value, zero filled
425
+ # or left-truncated to the specified length.
426
+ #
427
+ # :call-seq:
428
+ # _zfill<i>(value, length)</i> => <i>String</i>
429
+ #
430
+ # === Arguments
431
+ # [<i>val</i>] <i>Integer</i> or <i>String</i>. Value to be represented as a string of binary digits.
432
+ # [<i>length</i>] <i>Integer</i>. Length of output string to return.
433
+ #
434
+ # === Examples
435
+ # _zfill(0, 12)
436
+ # => "000000000000"
437
+ #
438
+ # _zfill(3095, 4)
439
+ # => "0111"
440
+ #
441
+ # _zfill(3095, 15)
442
+ # => "000110000010111"
443
+ #
444
+ # === Exceptions
445
+ # <i>None</i>.
446
+ #
447
+ def _zfill(val_p, length_p) # :nodoc:
448
+ sVal = val_p.kind_of?(String) ? val_p : val_p.to_s(2)
449
+ return sVal if (length_p.to_i <= 0)
450
+ if (length_p > sVal.length)
451
+ ('0' * (length_p - sVal.length)) + sVal
452
+ elsif (length_p < sVal.length)
453
+ sVal[-length_p, length_p]
454
+ else
455
+ sVal
456
+ end
457
+ end # def _zfill
458
+
459
+ #
460
+ # === Description
461
+ #
462
+ # Return a Boolean indicating whether the bitstring has a fixed length
463
+ # (is bounded) or not.
464
+ #
465
+ # :call-seq:
466
+ # bitstring.bounded?()
467
+ #
468
+ # === Arguments
469
+ # <i>None</i>.
470
+ #
471
+ # === Examples
472
+ # bs = BitString.new(3095)
473
+ # bs.bounded?
474
+ # => false
475
+ #
476
+ # bs = BitString.new(3095, 12)
477
+ # bs.bounded?
478
+ # => true
479
+ #
480
+ # === Exceptions
481
+ # <i>None</i>.
482
+ #
483
+ def bounded?()
484
+ @bounded
485
+ end # def bounded?()
486
+
487
+ #
488
+ # === Description
489
+ #
490
+ # Return a duplicate of the current bitstring -- with all bits cleared.
491
+ #
492
+ # :call-seq:
493
+ # bitstring.clear<i>()</i> => <i>BitString</i>
494
+ #
495
+ # === Arguments
496
+ # <i>None</i>.
497
+ #
498
+ # === Examples
499
+ # bs = BitString.new(3095)
500
+ # nbs = bs.clear
501
+ # bs.to_s
502
+ # => "110000010111"
503
+ # nbs.to_s
504
+ # => "0"
505
+ #
506
+ # === Exceptions
507
+ # <i>None</i>.
508
+ #
509
+ def clear()
510
+ bs = dup
511
+ bs.from_i(0)
512
+ bs
513
+ end # def clear()
514
+
515
+ #
516
+ # === Description
517
+ #
518
+ # Clear all the bits in the bitstring.
519
+ #
520
+ # :call-seq:
521
+ # bitstring.clear!<i>()</i> => <i>BitString</i>
522
+ #
523
+ # === Arguments
524
+ # <i>None</i>.
525
+ #
526
+ # === Examples
527
+ # bs = BitString.new(3095, 12)
528
+ # bs.to_s
529
+ # => "110000010111"
530
+ # bs.clear!
531
+ # bs.to_s
532
+ # => "000000000000"
533
+ #
534
+ # === Exceptions
535
+ # <i>None</i>.
536
+ #
537
+ def clear!()
538
+ @value = 0
539
+ self
540
+ end # def clear!()
541
+
542
+ #
543
+ # === Description
544
+ #
545
+ # Execute a block for each bit in the bitstring.
546
+ #
547
+ # :call-seq:
548
+ # bitstring.<i>each</i> { |<i>bitval</i>| <i>block</i> } => <i>BitString</i>
549
+ #
550
+ # === Arguments
551
+ # [<i>block</i>] <i>Proc</i>. Block to be called for each bit in the string. The block is passed the bit value.
552
+ #
553
+ # === Examples
554
+ # bs = BitString.new('100101')
555
+ # bs.each { |bitval| puts bitval }
556
+ # 1
557
+ # 0
558
+ # 1
559
+ # 0
560
+ # 0
561
+ # 1
562
+ #
563
+ # === Exceptions
564
+ # <i>None</i>.
565
+ #
566
+ def each(&block)
567
+ self.length.times { |bit| block.call(self[bit]) }
568
+ self
569
+ end # def each
570
+
571
+ #
572
+ # === Description
573
+ #
574
+ # Treat the bitstring as an Integer and store its entire value at
575
+ # once.
576
+ #
577
+ # :call-seq:
578
+ # bitstring.from_i<i>(newval)</i> => <i>BitString</i>
579
+ #
580
+ # === Arguments
581
+ # [<i>newval</i>] <i>Integer</i>. Value from which bits will be copied to the bitstring.
582
+ #
583
+ # === Examples
584
+ # bs = BitString.new(0, 12)
585
+ # bs.to_s
586
+ # => "000000000000"
587
+ # bs.from_i(3095)
588
+ # bs.to_s
589
+ # => "110000010111"
590
+ #
591
+ # === Exceptions
592
+ # <i>None</i>.
593
+ #
594
+ def from_i(newval)
595
+ unless (newval.respond_to?(:to_i))
596
+ what = newval.respond_to?(:to_s) ? newval.to_s : newval.inspect
597
+ _raise(UnInterable, newval)
598
+ end
599
+ newval = newval.to_i
600
+ newval &= 2**@length - 1 if (bounded?)
601
+ @value = newval
602
+ self
603
+ end # def from_i()
604
+
605
+ #
606
+ # === Description
607
+ #
608
+ # Return a new bitstring based on the current one, grown (made longer)
609
+ # in one direction (toward the least significant bits) or the other.
610
+ # Growing an unbounded string toward the high end is a no-op.
611
+ #
612
+ # Bits added are set to <i>defval</i> (default 0).
613
+ #
614
+ # :call-seq:
615
+ # bitstring.grow<i>(bits, [defval], [direction])</i> => <i>BitString</i>
616
+ #
617
+ # === Arguments
618
+ # [<i>bits</i>] <i>Integer</i>. Number of bits to add.
619
+ # [<i>defval</i>] <i>Integer</i>. Value to which added bits should be set.
620
+ # [<i>direction</i>] <i>Constant</i>. Either <tt>BitString::HIGH_END</tt> (the default) or <tt>BitString::LOW_END</t>. Indicates whether bits are added at the least or most significant end. Growing with <tt>BitString::LOW_END</tt> results in the bitstring being shifted left.
621
+ #
622
+ # === Examples
623
+ # bs = BitString(5, 3)
624
+ # bs.to_s
625
+ # => "101"
626
+ # nbs = bs.grow(3)
627
+ # nbs.to_s
628
+ # => "000101"
629
+ # nbs = bs.grow(3, 1)
630
+ # nbs.to_s
631
+ # => "111101"
632
+ # nbs = bs.grow(3, 0, BitString::LOW_END)
633
+ # nbs.to_s
634
+ # => "101000"
635
+ #
636
+ # === Exceptions
637
+ # [<tt>ArgumentError</tt>] <i>bits</i> isn't an integer, <i>defval</i> can't be reduced to a binary value, or <i>direction</i> isn't one of the defined values.
638
+ # [<tt>IndexError</tt>] <i>bits</i> is negative or meaningless.
639
+ # [<tt>RuntimeError</tt>] Can't grow an unbounded string at the high end.
640
+ #
641
+ def grow(bits=1, defval=0, direction=HIGH_END)
642
+ unless (bits.kind_of?(Integer))
643
+ _raise(BitsRInts)
644
+ end
645
+ unless (defval.respond_to?(:to_i))
646
+ what = defval.respond_to?(:to_s) ? defval.to_s : defval.inspect
647
+ _raise(UnInterable, defval)
648
+ end
649
+ unless ([HIGH_END, LOW_END].include?(direction))
650
+ _raise(NeedGPS)
651
+ end
652
+ unless (bits >= 0)
653
+ _raise(NoDeficitBits)
654
+ end
655
+ unless ((direction == LOW_END) || bounded?)
656
+ _raise(UnboundedNonsense)
657
+ end
658
+ return dup if (bits == 0)
659
+
660
+ value = @value
661
+ vMask = 2**bits - 1
662
+ if (direction == HIGH_END)
663
+ vMask *= 2**@length if (bounded?)
664
+ elsif (direction == LOW_END)
665
+ value *= (2**bits)
666
+ end
667
+ value |= vMask if (defval == 1)
668
+ bounded? ? self.class.new(value, @length + bits) : self.class.new(value)
669
+ end # def grow
670
+
671
+ #
672
+ # === Description
673
+ #
674
+ # As #grow, except that the current bitstring is changed rather
675
+ # than a new one returned.
676
+ #
677
+ # Bits added are set to <i>defval</i> (default 0).
678
+ #
679
+ # :call-seq:
680
+ # bitstring.grow!<i>(bits, [defval], [direction])</i> => <i>BitString</i>
681
+ #
682
+ # === Arguments
683
+ # [<i>bits</i>] <i>Integer</i> Number of bits to add.
684
+ # [<i>defval</i>] <i>Integer</i> Value to which added bits should be set.
685
+ # [<i>direction</i>] <i>Constant</i>. Either <tt>BitString::HIGH_END</tt> (the default) or <tt>BitString::LOW_END</tt>. Indicates whether bits are added at the least or most significant end. Growing with <tt>BitString::LOW_END</tt> results in the bitstring being shifted left.
686
+ #
687
+ # === Examples
688
+ # bs = BitString.new(5, 3)
689
+ # bs.to_s
690
+ # => "101"
691
+ # bs.grow!(3)
692
+ # bs.to_s
693
+ # => "000101"
694
+ # bs.grow!(3, 1, BitString::LOW_END)
695
+ # bs.to_s
696
+ # => "000101111"
697
+ #
698
+ # === Exceptions
699
+ # [<tt>ArgumentError</tt>] <i>bits</i> isn't an integer, <i>defval</i> can't be reduced to a binary value, or <i>direction</i> isn't one of the defined values.
700
+ # [<tt>IndexError</tt>] <i>bits</i> is negative or meaningless.
701
+ # [<tt>RuntimeError</tt>] Can't grow an unbounded string at the high end.
702
+ #
703
+ def grow!(bits=1, defval=0, direction=HIGH_END)
704
+ bs = grow(bits, defval, direction)
705
+ @length = bs.length if (bs.bounded?)
706
+ @value = bs.to_i
707
+ self
708
+ end # def grow!
709
+
710
+ #
711
+ # === Description
712
+ #
713
+ # Return the length of the bitstring. If it's bounded, the fixed size
714
+ # is returned, otherwise the number of significant binary digits.
715
+ #
716
+ # :call-seq:
717
+ # bitstring.length()
718
+ #
719
+ # === Arguments
720
+ # <i>None</i>.
721
+ #
722
+ # === Examples
723
+ # bs = BitString.new('101', 3)
724
+ # bs.length
725
+ # => 3
726
+ #
727
+ # bs = BitString.new('00101', 5)
728
+ # bs.length
729
+ # => 5
730
+ #
731
+ # bs = BitString.new('00101')
732
+ # bs.length
733
+ # => 3
734
+ #
735
+ # === Exceptions
736
+ # <i>None</i>.
737
+ #
738
+ def length()
739
+ bounded? ? @length : @value.to_s(2).length
740
+ end # def length()
741
+
742
+ #
743
+ # === Description
744
+ #
745
+ # Return the value of the least significant (low) bit.
746
+ #
747
+ # :call-seq:
748
+ # bitstring.lsb()
749
+ #
750
+ # === Arguments
751
+ # <i>None</i>.
752
+ #
753
+ # === Examples
754
+ # bs = BitString.new('101')
755
+ # bs.lsb
756
+ # => 1
757
+ #
758
+ # bs = BitString.new('010')
759
+ # bs.lsb
760
+ # => 0
761
+ #
762
+ # === Exceptions
763
+ # <i>None</i>.
764
+ #
765
+ def lsb()
766
+ self[0]
767
+ end # def lsb()
768
+
769
+ #
770
+ # === Description
771
+ #
772
+ # Return an integer with bits set to mask the specified portion of the
773
+ # bitstring.
774
+ #
775
+ # If you want to create a mask wider than the bitstring, use the class
776
+ # method <i>BitString.mask()</i> instead.
777
+ #
778
+ # :call-seq:
779
+ # bitstring.mask<i>([bitcount], [direction])</i> => <i>Integer</i>
780
+ #
781
+ # === Arguments
782
+ # [<i>bitcount</i>] <i>Integer</i>. Number of bits to set in the mask.
783
+ # [<i>direction</i>] <i>Constant</i>. <tt>BitString::HIGH_END</tt> (the default) or <tt>BitString::LOW_END</tt>. Specifies the end of the bitstring from which the mask starts.
784
+ #
785
+ # === Examples
786
+ # bs = BitString.new(0, 12)
787
+ # bs.mask.to_s(2)
788
+ # => "111111111111"
789
+ # bs.mask(5).to_s(2)
790
+ # => "111110000000"
791
+ # bs.mask(5, BitString::LOW_END).to_s(2)
792
+ # => "11111"
793
+ # BitString.new(bs.mask(5, BitString::LOW_END), 12).to_s
794
+ # => "000000011111"
795
+ #
796
+ # === Exceptions
797
+ # [<tt>IndexError</tt>] Raised if <i>bitcount</i> is negative or grater than the bitstring length.
798
+ #
799
+ def mask(bits=self.length, direction=HIGH_END)
800
+ _raise(OuttasightIndex, bits) if (bits > self.length)
801
+ _raise(NoDeficitBits) if (bits < 0)
802
+ vMask = 2**bits - 1
803
+ vMask *= 2**(self.length - bits) if (direction == HIGH_END)
804
+ vMask
805
+ end # def mask()
806
+
807
+ #
808
+ # === Description
809
+ #
810
+ # Class method to return an integer value with the specified number
811
+ # of bits (starting at position 0) all set to 1.
812
+ #
813
+ # :call-seq:
814
+ # BitString.mask<i>(bitcount)</i> => <i>Integer</i>
815
+ #
816
+ # === Arguments
817
+ # [<i>bitcount</i>] <i>Integer</i>. Number of bits to set in the mask.
818
+ #
819
+ # === Examples
820
+ # BitString.mask(5).to_s(2)
821
+ # => "11111"
822
+ #
823
+ # === Exceptions
824
+ # <i>None</i>.
825
+ #
826
+ def self.mask(bits=1)
827
+ new._raise(NoDeficitBits) if (bits < 0)
828
+ vMask = 2**bits - 1
829
+ end # def self.mask
830
+
831
+ #
832
+ # === Description
833
+ #
834
+ # Return the value of the most significant (high) bit.
835
+ # Only meaningful for bounded bitstrings.
836
+ #
837
+ # :call-seq:
838
+ # bitstring.msb()
839
+ #
840
+ # === Arguments
841
+ # <i>None</i>.
842
+ #
843
+ # === Examples
844
+ # bs = BitString.new('0101')
845
+ # bs.msb
846
+ # => 1 # Leading zeroes stripped in unbouded bitstrings
847
+ #
848
+ # bs = BitString.new('0101', 4)
849
+ # bs.msb
850
+ # => 0
851
+ #
852
+ # === Exceptions
853
+ # [<tt>RuntimeError</tt>] There is no 'MSB' for an unbounded bitstring.
854
+ #
855
+ def msb()
856
+ unless (bounded?)
857
+ _raise(UnboundedNonsense,
858
+ 'most significant bit only applies to bounded bitstrings')
859
+ end
860
+ self[@length - 1]
861
+ end # def msb()
862
+
863
+ #
864
+ # === Description
865
+ #
866
+ # Return the number of bits in the bitstring that are either set (1)
867
+ # or clear (0). Leading zeroes on unbounded bitstrings are ignored.
868
+ #
869
+ # :call-seq:
870
+ # bitstring.population<i>(testval)</i> => <i>Integer</i>
871
+ #
872
+ # === Arguments
873
+ # [<i>testval</i>] <i>Array</i>, <i>BitString</i>, <i>Integer</i>, or <i>String</i> whose low bit is used for the test.
874
+ #
875
+ # === Examples
876
+ # bs = BitString.new('0001111001010')
877
+ # bs.population(0)
878
+ # => 4
879
+ # bs.population(1)
880
+ # => 6
881
+ #
882
+ # bs = BitString.new('0001111001010', 13)
883
+ # bs.population(0)
884
+ # => 7
885
+ # bs.population(1)
886
+ # => 6
887
+ #
888
+ # === Exceptions
889
+ # [<tt>ArgumentError</tt>] The argument cannot be reduced to a binary digit.
890
+ #
891
+ def population(val)
892
+ val = _arg2int(val) & 1
893
+ self.select { |bval| bval == val }.length
894
+ end # def population
895
+
896
+ #
897
+ # === Description
898
+ #
899
+ # Return a copy of the bitstring resized to the specified number of bits,
900
+ # resulting in truncation or growth. Bits are added to, or removed from,
901
+ # the high (more significant) end. Resizing an unbounded bitstring
902
+ # makes it bounded.
903
+ #
904
+ # :call-seq:
905
+ # bitstring.resize<i>(bits)</i> => <i>BitString</i>
906
+ #
907
+ # === Arguments
908
+ # [<i>bits</i>] Width of the resulting bitstring.
909
+ #
910
+ # === Examples
911
+ # bs = BitString.new('101')
912
+ # bs.bounded?
913
+ # => false
914
+ # nbs = bs.resize(5)
915
+ # nbs.bounded?
916
+ # => true
917
+ # nbs.length
918
+ # => 5
919
+ # nbs.to_s
920
+ # => "00101"
921
+ # nbs = bs.resize(7)
922
+ # nbs.to_s
923
+ # => "0000101"
924
+ #
925
+ # === Exceptions
926
+ # [<tt>IndexError</tt>] <i>bits</i> is negative or meaningless.
927
+ #
928
+ def resize(bits)
929
+ unless (bits.kind_of?(Integer))
930
+ _raise(BitsRInts)
931
+ end
932
+ unless (bits > 0)
933
+ _raise(NoDeficitBits)
934
+ end
935
+ value = @value
936
+ length = self.length
937
+ bs = self.class.new(value, length)
938
+ diffbits = bits - length
939
+ diffbits < 0 ? bs.shrink!(-diffbits) : bs.grow!(diffbits)
940
+ end # def resize
941
+
942
+ #
943
+ # === Description
944
+ #
945
+ # As #resize except it's the current bitstring that gets resized.
946
+ #
947
+ # :call-seq:
948
+ # bitstring.resize!<i>(bits)</i> => <i>BitString</i>
949
+ #
950
+ # === Arguments
951
+ # [<i>bits</i>] Width of the resulting bitstring.
952
+ #
953
+ # === Examples
954
+ # bs = BitString.new('101')
955
+ # bs.bounded?
956
+ # => false
957
+ # bs.resize!(5)
958
+ # bs.bounded?
959
+ # => true
960
+ # bs.length
961
+ # => 5
962
+ # bs.to_s
963
+ # => "00101"
964
+ # bs.resize!(7)
965
+ # bs.to_s
966
+ # => "0000101"
967
+ #
968
+ # === Exceptions
969
+ # [<tt>IndexError</tt>] <i>bits</i> is negative or meaningless.
970
+ #
971
+ def resize!(bits)
972
+ bs = resize(bits)
973
+ @bounded = true
974
+ @length = bs.length
975
+ @value = bs.to_i
976
+ self
977
+ end # def resize!
978
+
979
+ #
980
+ # === Description
981
+ #
982
+ # Rotate the bitstring, taking bits from one end and shifting them
983
+ # in at the other. Only makes sense with bounded strings.
984
+ #
985
+ # A negative value rotates left; a positive one rotates to the right.
986
+ #
987
+ # :call-seq:
988
+ # bistring.rotate<i>(bits)</i> => <i>BitString</i>
989
+ #
990
+ # === Arguments
991
+ # [<i>bits</i>] <i>Integer</i>. Number of positions to rotate left (negative) or right (positive). Bits rotated off one end are rotated in on the other.
992
+ #
993
+ # === Examples
994
+ # bs = BitString.new('000000011111', 12)
995
+ # bs.rotate(3).to_s
996
+ # => "000011111000"
997
+ # bs.rotate(-4).to_s
998
+ # => "100000001111"
999
+ #
1000
+ # === Exceptions
1001
+ # [<tt>RuntimeError</tt>] Can't rotate an unbounded bitstring.
1002
+ #
1003
+ def rotate(bits_p)
1004
+ unless (bounded?)
1005
+ _raise(UnboundedNonsense,
1006
+ 'rotation only applies to bounded bitstrings')
1007
+ end
1008
+
1009
+ value = @value
1010
+ length = @length
1011
+ bits = bits_p.to_i.abs % length
1012
+ vMask = (mult = 2**bits) - 1
1013
+ ldiff = length - bits
1014
+ if (bits_p > 0)
1015
+ #
1016
+ # Rotate right (toward the LSB)
1017
+ #
1018
+ residue = value & vMask
1019
+ value /= mult
1020
+ value |= residue * 2**ldiff
1021
+ elsif (bits_p < 0)
1022
+ #
1023
+ # Rotate left (toward the MSB)
1024
+ #
1025
+ vMask *= 2**ldiff
1026
+ residue = value & vMask
1027
+ value = ((value & ~vMask) * mult) | (residue / 2**ldiff)
1028
+ end
1029
+ self.class.new(value, @length)
1030
+ end # def rotate
1031
+
1032
+ #
1033
+ # === Description
1034
+ #
1035
+ # Same as #rotate except that the result is stored back into the
1036
+ # current object.
1037
+ #
1038
+ # :call-seq:
1039
+ # bitstring.rotate!<i>(bits)</i> => <i>BitString</i>
1040
+ #
1041
+ # === Arguments
1042
+ # [<i>bits</i>] <i>Integer</i>. Number of positions to rotate left (negative) or right (positive). Bits rotated off one end are rotated in on the other.
1043
+ #
1044
+ # === Examples
1045
+ # bs = BitString.new('000000011111', 12)
1046
+ # bs.rotate!(3)
1047
+ # bs.to_s
1048
+ # => "000011111000"
1049
+ # bs.rotate!(-4)
1050
+ # bs.to_s
1051
+ # => "100000001111"
1052
+ #
1053
+ # === Exceptions
1054
+ # <i>None</i>.
1055
+ #
1056
+ def rotate!(bits_p)
1057
+ @value = rotate(bits_p).to_i
1058
+ self
1059
+ end # def rotate!
1060
+
1061
+ #
1062
+ # === Description
1063
+ #
1064
+ # Iterate through all the bits, invoking the specified block with the
1065
+ # value of each in turn. If the block returns a true value, the
1066
+ # bit value is added to the result array.
1067
+ #
1068
+ # :call-seq:
1069
+ # bitstring.select { <i>|bit| block</i> } => <i>Array</i>
1070
+ #
1071
+ # === Arguments
1072
+ # [<i>bit</i>] <i>Integer</i>. The value (0 or 1) of the current bit.
1073
+ # [<i>block</i>] <i>Proc</i>. The block of code to execute.
1074
+ #
1075
+ # === Examples
1076
+ # bs = BitString.new('11001110001')
1077
+ # bs.select { |bit| bit == 1}
1078
+ # => [1, 1, 1, 1, 1, 1]
1079
+ #
1080
+ # bs = BitString.new('0011001110001')
1081
+ # bs.select { |bit| bit == 0}
1082
+ # => [0, 0, 0, 0, 0] # because unbounded leadings zeroes are dropped
1083
+ #
1084
+ # bs = BitString.new('0011001110001', 13)
1085
+ # bs.select { |bit| bit == 0}
1086
+ # => [0, 0, 0, 0, 0, 0, 0]
1087
+ #
1088
+ # === Exceptions
1089
+ # <i>None</i>.
1090
+ #
1091
+ def select(&block)
1092
+ result = []
1093
+ self.each do |val|
1094
+ result.push(val) if (block.call(val))
1095
+ end
1096
+ result
1097
+ end # def select
1098
+
1099
+ #
1100
+ # === Description
1101
+ #
1102
+ # Shrink the bitstring (make it shorter) by truncating bits from
1103
+ # one end or the other. Shrinking to fewer than 1 bits raises
1104
+ # an exception.
1105
+ #
1106
+ # :call-seq:
1107
+ # bitstring.shrink<i>(bits, [direction])</i>
1108
+ #
1109
+ # === Arguments
1110
+ # [<i>bits</i>] <i>Integer</i>. Number of bits to truncate.
1111
+ # [<i>direction</i>] <i>Constant</i>. Either <tt>BitString::HIGH_END</tt> (the default) or <tt>BitString::LOW_END</tt>.
1112
+ #
1113
+ # === Examples
1114
+ # bs = BitString.new(3095) # 110000010111
1115
+ # nbs = bs.shrink(5)
1116
+ # nbs.to_s
1117
+ # => "10111" # Unbounded leading zeroes aren't significant
1118
+ # nbs = nbs.shrink(2, BitString::LOW_END)
1119
+ # nbs.to_s
1120
+ # => "101"
1121
+ #
1122
+ # bs = BitString.new(3095, 12) # 110000010111
1123
+ # nbs = bs.shrink(5)
1124
+ # nbs.to_s
1125
+ # => "0010111"
1126
+ #
1127
+ # === Exceptions
1128
+ # [<tt>ArgumentError</tt>] <i>bitcount</i> isn't an integer or <i>direction</i> isn't one of the defined values.
1129
+ # [<tt>IndexError</tt>] <i>bits</i> is negative or meaningless.
1130
+ #
1131
+ def shrink(bits=1, direction=HIGH_END)
1132
+ unless (bits.kind_of?(Integer))
1133
+ _raise(BitsRInts)
1134
+ end
1135
+ unless (bits >= 0)
1136
+ _raise(NoDeficitBits)
1137
+ end
1138
+ unless ([HIGH_END, LOW_END].include?(direction))
1139
+ _raise(NeedGPS)
1140
+ end
1141
+ return dup if (bits == 0)
1142
+
1143
+ if (bounded? && (bits >= @length))
1144
+ _raise(RuntimeError, 'shrink count greater than bitstring size')
1145
+ end
1146
+ value = @value
1147
+ length = bounded? ? @length - bits : nil
1148
+ if (direction == LOW_END)
1149
+ value /= 2**bits
1150
+ else
1151
+ _raise(UnboundedNonsense) unless (bounded?)
1152
+ value &= 2**length - 1
1153
+ end
1154
+ bounded? ? self.class.new(value, length) : self.class.new(value)
1155
+ end # def shrink
1156
+
1157
+ #
1158
+ # === Description
1159
+ #
1160
+ # As #shrink except that the current bitstring is modified rather than
1161
+ # a copy being made and altered.
1162
+ #
1163
+ # :call-seq:
1164
+ # bitstring.shrink!<i>(bits, [direction])</i>
1165
+ #
1166
+ # === Arguments
1167
+ # [<i>bits</i>] <i>Integer</i>. Number of bits to truncate.
1168
+ # [<i>direction</i>] <i>Constant</i>. <tt>BitString::HIGH_END</tt> (the default) or <tt>BitString::LOW_END</tt>.
1169
+ #
1170
+ # === Examples
1171
+ # bs = BitString.new(3095) # 110000010111
1172
+ # bs.shrink!(5)
1173
+ # bs.to_s
1174
+ # => "10111" # Unbounded leading zeroes aren't significant
1175
+ # bs.shrink!(2, BitString::LOW_END)
1176
+ # bs.to_s
1177
+ # => "101"
1178
+ #
1179
+ # bs = BitString.new(3095, 12) # 110000010111
1180
+ # bs.shrink!(5)
1181
+ # bs.to_s
1182
+ # => "0010111"
1183
+ #
1184
+ # === Exceptions
1185
+ # [<tt>ArgumentError</tt>] <i>bitcount</i> isn't an integer or <i>direction</i> isn't one of the defined values.
1186
+ # [<tt>IndexError</tt>] <i>bits</i> is negative or meaningless.
1187
+ #
1188
+ def shrink!(bits=1, direction=HIGH_END)
1189
+ bs = shrink(bits, direction)
1190
+ @length = bs.length if (bs.bounded?)
1191
+ @value = bs.to_i
1192
+ self
1193
+ end # def shrink!
1194
+
1195
+ #
1196
+ # === Description
1197
+ #
1198
+ # Extract a subset from the bitstring. See the description of
1199
+ # the <tt>[]</tt> method.
1200
+ #
1201
+ # :call-seq:
1202
+ # bitstring.slice<i>(index)</i> => <i>Integer</i>
1203
+ # bitstring.slice<i>(start, length)</i> => <i>BitString</i>
1204
+ # bitstring.slice<i>(range)</i> => <i>BitString</i>
1205
+ #
1206
+ # === Arguments
1207
+ # [<i>index</i>] <i>Integer</i>. Single bit position.
1208
+ # [<i>start</i>] <i>Integer</i>. Start position of subset.
1209
+ # [<i>length</i>] <i>Integer</i>. Length of subset.
1210
+ # [<i>range</i>] <i>Range</i>. Subset specified as a range.
1211
+ #
1212
+ # === Exceptions
1213
+ # [<tt>ArgumentError</tt>] If length specified with a range.
1214
+ # [<tt>IndexError</tt>] If bounded bitstring and substring is illegal.
1215
+ #
1216
+ def slice(*args)
1217
+ self[*args]
1218
+ end # def slice
1219
+
1220
+ #
1221
+ # === Description
1222
+ #
1223
+ # Select the specified bits from the bitstring, and remake it using
1224
+ # only those bits. If bounded, the size will be adjusted to match
1225
+ # the number of bits selected. This is an alternative way to change
1226
+ # the size and value of an existing bitstring (see the grow!(), shrink!(),
1227
+ # and resize!() methods.)
1228
+ #
1229
+ # :call-seq:
1230
+ # bitstring.slice!<i>(index)</i> => <i>Integer</i>
1231
+ # bitstring.slice!<i>(start, length)</i> => <i>BitString</i>
1232
+ # bitstring.slice!<i>(range)</i> => <i>BitString</i>
1233
+ #
1234
+ # === Arguments
1235
+ # [<i>index</i>] <i>Integer</i>. Single bit position.
1236
+ # [<i>start</i>] <i>Integer</i>. Start position of subset.
1237
+ # [<i>length</i>] <i>Integer</i>. Length of subset.
1238
+ # [<i>range</i>] <i>Range</i>. Subset specified as a range.
1239
+ #
1240
+ # === Examples
1241
+ # bs = BitString.new(3095, 12)
1242
+ # bs.to_s
1243
+ # => "110000010111"
1244
+ # bs.slice!(4..10)
1245
+ # bs.to_s
1246
+ # => "1000001"
1247
+ #
1248
+ # === Exceptions
1249
+ # [<tt>ArgumentError</tt>] If length specified with a range.
1250
+ # [<tt>IndexError</tt>] If bounded bitstring and substring is illegal.
1251
+ #
1252
+ def slice!(*args)
1253
+ bs = self[*args]
1254
+ @value = bs.to_i
1255
+ @bounded = bs.bounded?
1256
+ @length = bs.length if (bs.bounded?)
1257
+ self
1258
+ end # def slice!
1259
+
1260
+ #
1261
+ # === Description
1262
+ #
1263
+ # Return the full value of the bitstring represented as an integer.
1264
+ #
1265
+ # :call-seq:
1266
+ # bitstring.to_i<i>()</i> => <i>Integer</i>
1267
+ #
1268
+ # === Arguments
1269
+ # <i>None</i>.
1270
+ #
1271
+ # === Examples
1272
+ # bs = BitString.new('110000010111')
1273
+ # bs.to_i
1274
+ # => 3095
1275
+ #
1276
+ # === Exceptions
1277
+ # <i>None</i>.
1278
+ #
1279
+ def to_i()
1280
+ @value.to_i
1281
+ end # def to_i()
1282
+
1283
+ #
1284
+ # === Description
1285
+ #
1286
+ # Return the bitlist as a <i>String</i> object consisting of '0' and '1'
1287
+ # characters. If the bitstring is bounded, the <i>String</i> will
1288
+ # be zero-filled on the left (high end).
1289
+ #
1290
+ # :call-seq:
1291
+ # bitstring.to_s<i>()</i> => <i>String</i>
1292
+ #
1293
+ # === Arguments
1294
+ # <i>None</i>.
1295
+ #
1296
+ # === Examples
1297
+ # bs = BitString.new(3095)
1298
+ # bs.to_s
1299
+ # => "110000010111"
1300
+ #
1301
+ # bs = BitString.new(3095, 14)
1302
+ # bs.to_s
1303
+ # => "00110000010111"
1304
+ #
1305
+ # === Exceptions
1306
+ # <i>None</i>.
1307
+ #
1308
+ def to_s()
1309
+ _zfill(@value, @length)
1310
+ end # def to_s()
1311
+
1312
+ #
1313
+ # List visibility alterations here, since the directive effects persist
1314
+ # past the next definition.
1315
+ #
1316
+ protected(:_arg2int, :_raise, :_zfill)
1317
+
1318
+ end # class BitString