Class: BitMagic::BitField

Inherits:
Object
  • Object
show all
Defined in:
lib/bit_magic/bit_field.rb

Overview

Helper class to encapsulate bit field values and read/write operations Note that indices are based off ruby bit reading, so least-significant bits are to the right and negative numbers are handled as two’s complement.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(value = 0) ⇒ BitField

Initialize the BitField with an optional value. Default is 0



16
17
18
19
20
21
22
# File 'lib/bit_magic/bit_field.rb', line 16

def initialize(value = 0)
  if value.is_a?(Integer)
    @value = value
  else
    raise InputError.new("BitField#new expects an integer value, #{value.inspect} is not an integer")
  end
end

Instance Attribute Details

#valueInteger

the current integer value that contains the bit fields



10
11
12
# File 'lib/bit_magic/bit_field.rb', line 10

def value
  @value
end

Instance Method Details

#read_bits(*args) ⇒ Hash

Read the specified bit indices into a hash with bit index as key

Examples:

Read a list of bits into a hash

bit_field = BitField.new(5)
bit_field.read_bits(0, 1, 2)
#=> {0=>1, 1=>0, 2=>1}
# because 5 is 101 in binary


35
36
37
38
39
# File 'lib/bit_magic/bit_field.rb', line 35

def read_bits(*args)
  {}.tap do |m|
    args.each { |bit| m[bit] = @value[bit] }
  end
end

#read_field(*args) ⇒ Integer Also known as: []

Read the specified bit indices as a group, in the order given

Examples:

Read bits or a list of bits into an integer

bit_field = BitField.new(101) # 1100101 in binary, lsb on the right
bit_field.read_field(0, 1, 2) #=> 5 # or 101
bit_field.read_field(0) #= 1
bit_field.read_field( (2..6).to_a ) #=> 25 # or 11001


52
53
54
55
56
57
58
59
60
# File 'lib/bit_magic/bit_field.rb', line 52

def read_field(*args)
  m = 0
  args.flatten.each_with_index do |bit, i|
    if bit.is_a?(Integer)
      m |= ((@value[bit] || 0) << i)
    end
  end
  m
end

#write_bits(bit_values = {}) ⇒ Integer

Write to the specified bits, changing the internal @value to the new value

Examples:

Write new bit withs with their corresponding values

bit_field = BitField.new
bit_field.write_bits(0 => true) #=> 1
bit_field.write_bits(1 => true, 4 => true) #=> 19 # 10011
bit_field.write_bits(0 => false, 4 => false) #=> 2 # 10


76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/bit_magic/bit_field.rb', line 76

def write_bits(bit_values = {})
  bit_values.each_pair do |index, val|
    
    if !index.is_a?(Integer)
      raise InputError.new("BitField#write can only access bits by their index, #{index.inspect} is not a valid index")
    end
    
    if index < 0
      raise InputError.new("BitField#write can not write to negative indices")
    end
    
    if !(val === true) and !(val === false) and !(val === 1) and !(val === 0)
      raise InputError.new("BitField#write must have a boolean value, #{val.inspect} is not a boolean")
    end
    
    if val === true or val === 1
      @value |= (1 << index)
    else
      @value &= ~(1 << index)
    end
  
  end
  
  @value
end