ffi-bitfield 0.0.10 → 0.1.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.
- checksums.yaml +4 -4
 - data/LICENSE.txt +1 -1
 - data/README.md +33 -3
 - data/lib/ffi/bit_field/class_methods.rb +98 -5
 - data/lib/ffi/bit_field/instance_methods.rb +34 -10
 - data/lib/ffi/bit_field/version.rb +1 -3
 - data/lib/ffi/bit_field.rb +0 -2
 - data/lib/ffi/bit_struct.rb +0 -2
 - data/lib/ffi/managed_bit_struct.rb +0 -2
 - metadata +5 -5
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: fe9149d50ec1010a72da77b760d5c9f110688a2fae95fa51fd8df155ea6f85f7
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 6f2e4d91b7386406e89512d8a3a352c5e40a39a554ca128b70fc6c4573984dd6
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 18912f59cc0434df26e14b211b275478c89fe2a96852728a6213ffb134e7d5a83d698d274a3258f17735c38dc7c38ef2b9dde4a62f23d6a0903b1b356be72e1d
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: c5cda72742bdf29f27f24512d7d3263c6700ffcfc19cff4a7d4e8687cd44f60a7f7ad4a03b4939f6a55bd30a606e3e93a63cc41dccbe52b1b24ecb62901ef59e
         
     | 
    
        data/LICENSE.txt
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | 
         @@ -2,6 +2,7 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            [](https://badge.fury.io/rb/ffi-bitfield)
         
     | 
| 
       4 
4 
     | 
    
         
             
            [](https://github.com/kojix2/ffi-bitfield/actions/workflows/ci.yml)
         
     | 
| 
      
 5 
     | 
    
         
            +
            [](https://tokei.kojix2.net/github/kojix2/ffi-bitfield)
         
     | 
| 
       5 
6 
     | 
    
         | 
| 
       6 
7 
     | 
    
         
             
            Bit field for [Ruby-FFI](https://github.com/ffi/ffi)
         
     | 
| 
       7 
8 
     | 
    
         | 
| 
         @@ -15,8 +16,8 @@ gem install ffi-bitfield 
     | 
|
| 
       15 
16 
     | 
    
         | 
| 
       16 
17 
     | 
    
         
             
            Classes
         
     | 
| 
       17 
18 
     | 
    
         | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
      
 19 
     | 
    
         
            +
            - class BitStruct < FFI::Struct
         
     | 
| 
      
 20 
     | 
    
         
            +
            - class ManagedBitStruct < FFI::ManagedStruct
         
     | 
| 
       20 
21 
     | 
    
         | 
| 
       21 
22 
     | 
    
         
             
            Loading
         
     | 
| 
       22 
23 
     | 
    
         | 
| 
         @@ -70,6 +71,35 @@ s[:y] = 1 
     | 
|
| 
       70 
71 
     | 
    
         
             
            p s[:a] # 64
         
     | 
| 
       71 
72 
     | 
    
         
             
            ```
         
     | 
| 
       72 
73 
     | 
    
         | 
| 
      
 74 
     | 
    
         
            +
            ### Typed Bit Fields
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            You can use the `bit_fields_typed` method to define bit fields with type information. This method accepts a hash where keys are field names and values are arrays containing `[width, type]`. For boolean fields (width of 1 with `:bool` type), it automatically generates a `?` helper method:
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 79 
     | 
    
         
            +
            class AccessFlags < FFI::BitStruct
         
     | 
| 
      
 80 
     | 
    
         
            +
              layout \
         
     | 
| 
      
 81 
     | 
    
         
            +
                :flags, :uint8
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
              bit_fields_typed :flags,
         
     | 
| 
      
 84 
     | 
    
         
            +
                revoked: [1, :bool],       # Creates revoked? method
         
     | 
| 
      
 85 
     | 
    
         
            +
                expired: [1, :bool],       # Creates expired? method
         
     | 
| 
      
 86 
     | 
    
         
            +
                some_string: [4, :string],
         
     | 
| 
      
 87 
     | 
    
         
            +
                reserved: [2, :int]
         
     | 
| 
      
 88 
     | 
    
         
            +
            end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
            flags = AccessFlags.new
         
     | 
| 
      
 91 
     | 
    
         
            +
            flags[:revoked] = 1
         
     | 
| 
      
 92 
     | 
    
         
            +
            flags[:expired] = 0
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
            p flags.revoked?  # => true
         
     | 
| 
      
 95 
     | 
    
         
            +
            p flags.expired?  # => false
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
            flags[:expired] = 1
         
     | 
| 
      
 98 
     | 
    
         
            +
            p flags.expired?  # => true
         
     | 
| 
      
 99 
     | 
    
         
            +
            ```
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
            The `?` methods are only generated for fields that are 1 bit wide and have type `:bool`. Other field types can be used for documentation purposes and future functionality.
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
       73 
103 
     | 
    
         
             
            ### Inspecting Bit Fields
         
     | 
| 
       74 
104 
     | 
    
         | 
| 
       75 
105 
     | 
    
         
             
            You can use the `bit_field_members` method to get a hash of bit fields grouped by parent field:
         
     | 
| 
         @@ -128,7 +158,7 @@ bundle install 
     | 
|
| 
       128 
158 
     | 
    
         
             
            bundle exec rake test
         
     | 
| 
       129 
159 
     | 
    
         
             
            ```
         
     | 
| 
       130 
160 
     | 
    
         | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
      
 161 
     | 
    
         
            +
            - [ffi-bitfield - read/write bit fields with Ruby-FFI](https://dev.to/kojix2/ffi-bitfield-g4h)
         
     | 
| 
       132 
162 
     | 
    
         | 
| 
       133 
163 
     | 
    
         
             
            ## Contributing
         
     | 
| 
       134 
164 
     | 
    
         | 
| 
         @@ -1,5 +1,3 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # frozen_string_literal: true
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
1 
     | 
    
         
             
            module FFI
         
     | 
| 
       4 
2 
     | 
    
         
             
              module BitField
         
     | 
| 
       5 
3 
     | 
    
         
             
                # ClassMethods provides methods for defining bit field layouts.
         
     | 
| 
         @@ -147,9 +145,13 @@ module FFI 
     | 
|
| 
       147 
145 
     | 
    
         
             
                      member_names << name.to_sym
         
     | 
| 
       148 
146 
     | 
    
         
             
                      widths << width.to_i
         
     | 
| 
       149 
147 
     | 
    
         
             
                    end
         
     | 
| 
       150 
     | 
    
         
            -
             
     | 
| 
       151 
     | 
    
         
            -
             
     | 
| 
       152 
     | 
    
         
            -
                     
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
                    # Prevent redefining bit fields on the same parent field
         
     | 
| 
      
 150 
     | 
    
         
            +
                    ensure_parent_not_defined(parent_name)
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
                    # Validate total width against parent size
         
     | 
| 
      
 153 
     | 
    
         
            +
                    validate_total_width(parent_name, widths)
         
     | 
| 
      
 154 
     | 
    
         
            +
                    starts = bit_start_offsets(widths)
         
     | 
| 
       153 
155 
     | 
    
         
             
                    member_names.zip(starts, widths).each do |name, start, width|
         
     | 
| 
       154 
156 
     | 
    
         
             
                      @bit_field_hash_table[name] = [parent_name, start, width]
         
     | 
| 
       155 
157 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -157,6 +159,97 @@ module FFI 
     | 
|
| 
       157 
159 
     | 
    
         
             
                    parent_name
         
     | 
| 
       158 
160 
     | 
    
         
             
                  end
         
     | 
| 
       159 
161 
     | 
    
         
             
                  alias bit_field bit_fields
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
                  # Defines typed bit fields within a parent field using hash syntax.
         
     | 
| 
      
 164 
     | 
    
         
            +
                  #
         
     | 
| 
      
 165 
     | 
    
         
            +
                  # @param [Symbol] parent_name The name of the parent field
         
     | 
| 
      
 166 
     | 
    
         
            +
                  # @param [Hash] field_definitions A hash where keys are field names and values are arrays [width, type]
         
     | 
| 
      
 167 
     | 
    
         
            +
                  # @return [Symbol] parent_name The name of the parent field
         
     | 
| 
      
 168 
     | 
    
         
            +
                  #
         
     | 
| 
      
 169 
     | 
    
         
            +
                  # @example Define typed bit fields with automatic boolean helpers
         
     | 
| 
      
 170 
     | 
    
         
            +
                  #   bit_fields_typed :flags,
         
     | 
| 
      
 171 
     | 
    
         
            +
                  #     revoked: [1, :bool],      # Creates revoked? methods
         
     | 
| 
      
 172 
     | 
    
         
            +
                  #     expired: [1, :bool],      # Creates expired? methods
         
     | 
| 
      
 173 
     | 
    
         
            +
                  #     some_string: [4, :string] # Creates some_string method
         
     | 
| 
      
 174 
     | 
    
         
            +
                  #
         
     | 
| 
      
 175 
     | 
    
         
            +
                  # @note For fields with width 1 and type :bool, a "?" helper method is automatically created
         
     | 
| 
      
 176 
     | 
    
         
            +
                  # @note The total bit width should not exceed the size of the parent field.
         
     | 
| 
      
 177 
     | 
    
         
            +
                  def bit_fields_typed(parent_name, field_definitions)
         
     | 
| 
      
 178 
     | 
    
         
            +
                    @bit_field_hash_table = {} unless instance_variable_defined?(:@bit_field_hash_table)
         
     | 
| 
      
 179 
     | 
    
         
            +
                    @bit_field_type_table = {} unless instance_variable_defined?(:@bit_field_type_table)
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
      
 181 
     | 
    
         
            +
                    parent_name = parent_name.to_sym
         
     | 
| 
      
 182 
     | 
    
         
            +
                    member_names = []
         
     | 
| 
      
 183 
     | 
    
         
            +
                    widths = []
         
     | 
| 
      
 184 
     | 
    
         
            +
                    types = []
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
                    field_definitions.each do |name, definition|
         
     | 
| 
      
 187 
     | 
    
         
            +
                      width, type = definition
         
     | 
| 
      
 188 
     | 
    
         
            +
                      member_names << name.to_sym
         
     | 
| 
      
 189 
     | 
    
         
            +
                      widths << width.to_i
         
     | 
| 
      
 190 
     | 
    
         
            +
                      types << type.to_sym
         
     | 
| 
      
 191 
     | 
    
         
            +
                    end
         
     | 
| 
      
 192 
     | 
    
         
            +
             
     | 
| 
      
 193 
     | 
    
         
            +
                    # Prevent redefining bit fields on the same parent field
         
     | 
| 
      
 194 
     | 
    
         
            +
                    ensure_parent_not_defined(parent_name)
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
                    # Validate total width against parent size
         
     | 
| 
      
 197 
     | 
    
         
            +
                    validate_total_width(parent_name, widths)
         
     | 
| 
      
 198 
     | 
    
         
            +
             
     | 
| 
      
 199 
     | 
    
         
            +
                    starts = bit_start_offsets(widths)
         
     | 
| 
      
 200 
     | 
    
         
            +
             
     | 
| 
      
 201 
     | 
    
         
            +
                    member_names.zip(starts, widths, types).each do |name, start, width, type|
         
     | 
| 
      
 202 
     | 
    
         
            +
                      @bit_field_hash_table[name] = [parent_name, start, width]
         
     | 
| 
      
 203 
     | 
    
         
            +
                      @bit_field_type_table[name] = type
         
     | 
| 
      
 204 
     | 
    
         
            +
             
     | 
| 
      
 205 
     | 
    
         
            +
                      # Generate "?" method for boolean fields with width 1
         
     | 
| 
      
 206 
     | 
    
         
            +
                      next unless width == 1 && type == :bool
         
     | 
| 
      
 207 
     | 
    
         
            +
             
     | 
| 
      
 208 
     | 
    
         
            +
                      define_method(:"#{name}?") do
         
     | 
| 
      
 209 
     | 
    
         
            +
                        self[name] == 1
         
     | 
| 
      
 210 
     | 
    
         
            +
                      end
         
     | 
| 
      
 211 
     | 
    
         
            +
                    end
         
     | 
| 
      
 212 
     | 
    
         
            +
             
     | 
| 
      
 213 
     | 
    
         
            +
                    parent_name
         
     | 
| 
      
 214 
     | 
    
         
            +
                  end
         
     | 
| 
      
 215 
     | 
    
         
            +
             
     | 
| 
      
 216 
     | 
    
         
            +
                  private
         
     | 
| 
      
 217 
     | 
    
         
            +
             
     | 
| 
      
 218 
     | 
    
         
            +
                  # Return cumulative start positions for given widths
         
     | 
| 
      
 219 
     | 
    
         
            +
                  # e.g., [3, 4, 1] => [0, 3, 7]
         
     | 
| 
      
 220 
     | 
    
         
            +
                  def bit_start_offsets(widths)
         
     | 
| 
      
 221 
     | 
    
         
            +
                    starts = []
         
     | 
| 
      
 222 
     | 
    
         
            +
                    sum = 0
         
     | 
| 
      
 223 
     | 
    
         
            +
                    widths.each do |w|
         
     | 
| 
      
 224 
     | 
    
         
            +
                      starts << sum
         
     | 
| 
      
 225 
     | 
    
         
            +
                      sum += w
         
     | 
| 
      
 226 
     | 
    
         
            +
                    end
         
     | 
| 
      
 227 
     | 
    
         
            +
                    starts
         
     | 
| 
      
 228 
     | 
    
         
            +
                  end
         
     | 
| 
      
 229 
     | 
    
         
            +
             
     | 
| 
      
 230 
     | 
    
         
            +
                  # Raise if the same parent already has bit fields
         
     | 
| 
      
 231 
     | 
    
         
            +
                  def ensure_parent_not_defined(parent_name)
         
     | 
| 
      
 232 
     | 
    
         
            +
                    return unless @bit_field_hash_table&.any? { |_n, info| info[0] == parent_name }
         
     | 
| 
      
 233 
     | 
    
         
            +
             
     | 
| 
      
 234 
     | 
    
         
            +
                    raise ArgumentError, "bit_fields for :#{parent_name} already defined"
         
     | 
| 
      
 235 
     | 
    
         
            +
                  end
         
     | 
| 
      
 236 
     | 
    
         
            +
             
     | 
| 
      
 237 
     | 
    
         
            +
                  # Return parent field size in bits (nil if unknown)
         
     | 
| 
      
 238 
     | 
    
         
            +
                  def parent_size_bits(parent_name)
         
     | 
| 
      
 239 
     | 
    
         
            +
                    field = layout[parent_name] # nil if not found
         
     | 
| 
      
 240 
     | 
    
         
            +
                    return nil unless field&.respond_to?(:type)
         
     | 
| 
      
 241 
     | 
    
         
            +
             
     | 
| 
      
 242 
     | 
    
         
            +
                    field.type.size * 8
         
     | 
| 
      
 243 
     | 
    
         
            +
                  end
         
     | 
| 
      
 244 
     | 
    
         
            +
             
     | 
| 
      
 245 
     | 
    
         
            +
                  # Raise if total width exceeds parent size
         
     | 
| 
      
 246 
     | 
    
         
            +
                  def validate_total_width(parent_name, widths)
         
     | 
| 
      
 247 
     | 
    
         
            +
                    size = parent_size_bits(parent_name)
         
     | 
| 
      
 248 
     | 
    
         
            +
                    return unless size
         
     | 
| 
      
 249 
     | 
    
         
            +
             
     | 
| 
      
 250 
     | 
    
         
            +
                    total = widths.sum
         
     | 
| 
      
 251 
     | 
    
         
            +
                    raise ArgumentError, "Bit width #{total} exceeds :#{parent_name} size (#{size} bits)" if total > size
         
     | 
| 
      
 252 
     | 
    
         
            +
                  end
         
     | 
| 
       160 
253 
     | 
    
         
             
                end
         
     | 
| 
       161 
254 
     | 
    
         
             
              end
         
     | 
| 
       162 
255 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,5 +1,3 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # frozen_string_literal: true
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
1 
     | 
    
         
             
            module FFI
         
     | 
| 
       4 
2 
     | 
    
         
             
              module BitField
         
     | 
| 
       5 
3 
     | 
    
         
             
                # InstanceMethods provides methods for reading and writing bit field values.
         
     | 
| 
         @@ -42,7 +40,7 @@ module FFI 
     | 
|
| 
       42 
40 
     | 
    
         
             
                    parent_name, start, width = member_value_info(member_name)
         
     | 
| 
       43 
41 
     | 
    
         
             
                    if parent_name
         
     | 
| 
       44 
42 
     | 
    
         
             
                      value = get_member_value(parent_name)
         
     | 
| 
       45 
     | 
    
         
            -
                      (value >> start) & ( 
     | 
| 
      
 43 
     | 
    
         
            +
                      (value >> start) & max_value_for_width(width)
         
     | 
| 
       46 
44 
     | 
    
         
             
                    else
         
     | 
| 
       47 
45 
     | 
    
         
             
                      get_member_value(member_name)
         
     | 
| 
       48 
46 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -63,20 +61,20 @@ module FFI 
     | 
|
| 
       63 
61 
     | 
    
         
             
                  # @example Writing a negative value (bit-flipped)
         
     | 
| 
       64 
62 
     | 
    
         
             
                  #   struct[:field] = -1  # Sets all bits to 1
         
     | 
| 
       65 
63 
     | 
    
         
             
                  def []=(member_name, value)
         
     | 
| 
       66 
     | 
    
         
            -
                    # Ensure value is an Integer
         
     | 
| 
       67 
     | 
    
         
            -
                    raise TypeError, "Value must be an Integer, got #{value.class}" unless value.is_a?(Integer)
         
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
64 
     | 
    
         
             
                    # Get bit field information
         
     | 
| 
       70 
65 
     | 
    
         
             
                    field_info = member_value_info(member_name)
         
     | 
| 
       71 
66 
     | 
    
         | 
| 
       72 
67 
     | 
    
         
             
                    # If not a bit field, delegate to regular field setter
         
     | 
| 
       73 
68 
     | 
    
         
             
                    return set_member_value(member_name, value) unless field_info
         
     | 
| 
       74 
69 
     | 
    
         | 
| 
      
 70 
     | 
    
         
            +
                    # Ensure value is an Integer (only for bit fields)
         
     | 
| 
      
 71 
     | 
    
         
            +
                    raise TypeError, "Value must be an Integer, got #{value.class}" unless value.is_a?(Integer)
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
       75 
73 
     | 
    
         
             
                    # Extract bit field information
         
     | 
| 
       76 
74 
     | 
    
         
             
                    parent_name, start, width = field_info
         
     | 
| 
       77 
75 
     | 
    
         | 
| 
       78 
76 
     | 
    
         
             
                    # Calculate max value for this bit width
         
     | 
| 
       79 
     | 
    
         
            -
                    max_value = ( 
     | 
| 
      
 77 
     | 
    
         
            +
                    max_value = max_value_for_width(width)
         
     | 
| 
       80 
78 
     | 
    
         | 
| 
       81 
79 
     | 
    
         
             
                    # Handle negative values by bit-flipping
         
     | 
| 
       82 
80 
     | 
    
         
             
                    if value.negative?
         
     | 
| 
         @@ -105,20 +103,46 @@ module FFI 
     | 
|
| 
       105 
103 
     | 
    
         | 
| 
       106 
104 
     | 
    
         
             
                    # Update the parent field with the new bit field value
         
     | 
| 
       107 
105 
     | 
    
         
             
                    parent_value = get_member_value(parent_name)
         
     | 
| 
       108 
     | 
    
         
            -
                    mask = ( 
     | 
| 
       109 
     | 
    
         
            -
                    new_value = (parent_value & ~mask) | ((value & ( 
     | 
| 
      
 106 
     | 
    
         
            +
                    mask = create_bitmask(width, start)
         
     | 
| 
      
 107 
     | 
    
         
            +
                    new_value = (parent_value & ~mask) | ((value & max_value_for_width(width)) << start)
         
     | 
| 
       110 
108 
     | 
    
         | 
| 
       111 
109 
     | 
    
         
             
                    set_member_value(parent_name, new_value)
         
     | 
| 
       112 
110 
     | 
    
         
             
                  end
         
     | 
| 
       113 
111 
     | 
    
         | 
| 
       114 
112 
     | 
    
         
             
                  private
         
     | 
| 
       115 
113 
     | 
    
         | 
| 
      
 114 
     | 
    
         
            +
                  # Calculates the maximum value that can be stored in the given bit width.
         
     | 
| 
      
 115 
     | 
    
         
            +
                  # For example: 3 bits can store 0b000 to 0b111, so max is 7
         
     | 
| 
      
 116 
     | 
    
         
            +
                  #
         
     | 
| 
      
 117 
     | 
    
         
            +
                  # @param [Integer] width The number of bits
         
     | 
| 
      
 118 
     | 
    
         
            +
                  # @return [Integer] The maximum value
         
     | 
| 
      
 119 
     | 
    
         
            +
                  # @example
         
     | 
| 
      
 120 
     | 
    
         
            +
                  #   max_value_for_width(3)  # => 7 (0b111)
         
     | 
| 
      
 121 
     | 
    
         
            +
                  #   max_value_for_width(4)  # => 15 (0b1111)
         
     | 
| 
      
 122 
     | 
    
         
            +
                  def max_value_for_width(width)
         
     | 
| 
      
 123 
     | 
    
         
            +
                    (1 << width) - 1
         
     | 
| 
      
 124 
     | 
    
         
            +
                  end
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
                  # Creates a bitmask for extracting or setting bits at a specific position.
         
     | 
| 
      
 127 
     | 
    
         
            +
                  # For example: width=3, start=2 creates 0b11100 (mask for bits 2,3,4)
         
     | 
| 
      
 128 
     | 
    
         
            +
                  #
         
     | 
| 
      
 129 
     | 
    
         
            +
                  # @param [Integer] width The number of bits in the mask
         
     | 
| 
      
 130 
     | 
    
         
            +
                  # @param [Integer] start The starting bit position (0-indexed from right)
         
     | 
| 
      
 131 
     | 
    
         
            +
                  # @return [Integer] The bitmask
         
     | 
| 
      
 132 
     | 
    
         
            +
                  # @example
         
     | 
| 
      
 133 
     | 
    
         
            +
                  #   create_bitmask(3, 2)  # => 28 (0b11100)
         
     | 
| 
      
 134 
     | 
    
         
            +
                  #   create_bitmask(2, 0)  # => 3 (0b11)
         
     | 
| 
      
 135 
     | 
    
         
            +
                  def create_bitmask(width, start)
         
     | 
| 
      
 136 
     | 
    
         
            +
                    max_value_for_width(width) << start
         
     | 
| 
      
 137 
     | 
    
         
            +
                  end
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
       116 
139 
     | 
    
         
             
                  # Gets information about a bit field member.
         
     | 
| 
       117 
140 
     | 
    
         
             
                  #
         
     | 
| 
       118 
141 
     | 
    
         
             
                  # @param [Symbol] member_name The name of the bit field
         
     | 
| 
       119 
142 
     | 
    
         
             
                  # @return [Array, nil] An array containing [parent_name, start_bit, width] or nil if not a bit field
         
     | 
| 
       120 
143 
     | 
    
         
             
                  def member_value_info(member_name)
         
     | 
| 
       121 
     | 
    
         
            -
                    self.class.instance_variable_get(:@bit_field_hash_table) 
     | 
| 
      
 144 
     | 
    
         
            +
                    hash_table = self.class.instance_variable_get(:@bit_field_hash_table)
         
     | 
| 
      
 145 
     | 
    
         
            +
                    hash_table&.[](member_name)
         
     | 
| 
       122 
146 
     | 
    
         
             
                  end
         
     | 
| 
       123 
147 
     | 
    
         
             
                end
         
     | 
| 
       124 
148 
     | 
    
         
             
              end
         
     | 
    
        data/lib/ffi/bit_field.rb
    CHANGED
    
    
    
        data/lib/ffi/bit_struct.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | 
         @@ -1,13 +1,13 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: ffi-bitfield
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0.0 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.1.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - kojix2
         
     | 
| 
       8 
8 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       9 
9 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       10 
     | 
    
         
            -
            date:  
     | 
| 
      
 10 
     | 
    
         
            +
            date: 1980-01-02 00:00:00.000000000 Z
         
     | 
| 
       11 
11 
     | 
    
         
             
            dependencies:
         
     | 
| 
       12 
12 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       13 
13 
     | 
    
         
             
              name: ffi
         
     | 
| 
         @@ -23,7 +23,7 @@ dependencies: 
     | 
|
| 
       23 
23 
     | 
    
         
             
                - - ">="
         
     | 
| 
       24 
24 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       25 
25 
     | 
    
         
             
                    version: '0'
         
     | 
| 
       26 
     | 
    
         
            -
            description: bit  
     | 
| 
      
 26 
     | 
    
         
            +
            description: Provides bit field support for FFI::Struct and FFI::ManagedStruct
         
     | 
| 
       27 
27 
     | 
    
         
             
            email:
         
     | 
| 
       28 
28 
     | 
    
         
             
            - 2xijok@gmail.com
         
     | 
| 
       29 
29 
     | 
    
         
             
            executables: []
         
     | 
| 
         @@ -56,7 +56,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       56 
56 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       57 
57 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       58 
58 
     | 
    
         
             
            requirements: []
         
     | 
| 
       59 
     | 
    
         
            -
            rubygems_version: 3.6. 
     | 
| 
      
 59 
     | 
    
         
            +
            rubygems_version: 3.6.9
         
     | 
| 
       60 
60 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       61 
     | 
    
         
            -
            summary:  
     | 
| 
      
 61 
     | 
    
         
            +
            summary: Bit fields for Ruby-FFI
         
     | 
| 
       62 
62 
     | 
    
         
             
            test_files: []
         
     |