Module: FFI::BitField::InstanceMethods
- Included in:
- FFI::BitStruct, ManagedBitStruct
- Defined in:
- lib/ffi/bit_field/instance_methods.rb
Overview
InstanceMethods provides methods for reading and writing bit field values. This module is included in BitStruct and ManagedBitStruct classes.
Instance Method Summary collapse
-
#[](member_name) ⇒ Integer
Reads a value from a bit field or regular field.
-
#[]=(member_name, value) ⇒ Integer
Writes a value to a bit field or regular field.
-
#bit_field_members ⇒ Hash
Returns a hash of bit fields grouped by parent field.
-
#bit_field_offsets ⇒ Hash
Returns a hash of bit fields with their bit offsets, grouped by parent field.
Instance Method Details
#[](member_name) ⇒ Integer
Reads a value from a bit field or regular field.
41 42 43 44 45 46 47 48 49 |
# File 'lib/ffi/bit_field/instance_methods.rb', line 41 def [](member_name) parent_name, start, width = member_value_info(member_name) if parent_name value = get_member_value(parent_name) (value >> start) & ((1 << width) - 1) else get_member_value(member_name) end end |
#[]=(member_name, value) ⇒ Integer
Writes a value to a bit field or regular field.
65 66 67 68 69 70 71 72 73 74 75 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 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/ffi/bit_field/instance_methods.rb', line 65 def []=(member_name, value) # Ensure value is an Integer raise TypeError, "Value must be an Integer, got #{value.class}" unless value.is_a?(Integer) # Get bit field information field_info = member_value_info(member_name) # If not a bit field, delegate to regular field setter return set_member_value(member_name, value) unless field_info # Extract bit field information parent_name, start, width = field_info # Calculate max value for this bit width max_value = (1 << width) - 1 # Handle negative values by bit-flipping if value.negative? # For negative values, we interpret them as bit-flipped positive values # For example, with 4 bits, -1 becomes 1111 (15), -2 becomes 1110 (14), etc. # Check if the negative value is within range # For bit-flipping, valid range is -(2^n) to -1 min_value = -(1 << width) if value < min_value raise ArgumentError, "Value #{value} is too small for bit_length: #{width}, minimum is #{min_value}" end # Convert negative value to bit-flipped positive value # -1 -> 15, -2 -> 14, etc. value = max_value + value + 1 # Sanity check after conversion if value.negative? || value > max_value raise ArgumentError, "Internal error: converted value #{value} is out of range for bit_length: #{width}" end elsif value > max_value # For positive values, check if they fit in the bit width raise ArgumentError, "Value #{value} is too large for bit_length: #{width}, maximum is #{max_value}" end # Update the parent field with the new bit field value parent_value = get_member_value(parent_name) mask = ((1 << width) - 1) << start new_value = (parent_value & ~mask) | ((value & ((1 << width) - 1)) << start) set_member_value(parent_name, new_value) end |
#bit_field_members ⇒ Hash
Returns a hash of bit fields grouped by parent field. Instance method version of the class method with the same name.
16 17 18 |
# File 'lib/ffi/bit_field/instance_methods.rb', line 16 def bit_field_members self.class.bit_field_members end |
#bit_field_offsets ⇒ Hash
Returns a hash of bit fields with their bit offsets, grouped by parent field.
30 31 32 |
# File 'lib/ffi/bit_field/instance_methods.rb', line 30 def bit_field_offsets self.class.bit_field_offsets end |