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,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