Module: FFI::BitField::Property
- Included in:
- FFI::BitStruct, ManagedBitStruct
- Defined in:
- lib/ffi/bit_field/property.rb
Overview
Property 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.
Instance Method Details
#[](member_name) ⇒ Integer
Reads a value from a bit field or regular field.
15 16 17 18 19 20 21 22 23 |
# File 'lib/ffi/bit_field/property.rb', line 15 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.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/ffi/bit_field/property.rb', line 39 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 |