class Ronin::Support::Binary::CTypes::StructType
Represents a ‘struct` type.
@api private
@since 1.0.0
Attributes
The alignment, in bytes, for the struct type, so that all members within the struct type are themselves aligned.
@return [Integer]
The members of the struct type.
@return [Hash{Symbol => Member}]
The size of the struct type.
@return [Integer, Float::INFINITY]
Public Class Methods
Source
# File lib/ronin/support/binary/ctypes/struct_type.rb, line 176 def self.build(fields, alignment: nil, padding: true) members = {} max_alignment = 0 pack_string = String.new(encoding: Encoding::ASCII_8BIT) offset = 0 fields.each do |name,type| pad = if padding then Member.padding_for(offset,type) else 0 end members[name] = Member.new(offset + pad,type) max_alignment = type.alignment if type.alignment > max_alignment if pack_string if type.pack_string pack_string << Member.pack_string_for(type,pad) else pack_string = nil end end # omit infinite sizes from the struct size unless type.size == Float::INFINITY offset += type.size + pad end end return new(members, size: offset, alignment: alignment || max_alignment, pack_string: pack_string) end
Builds the struct type from the given fields.
@param [Hash{Symbol => Type}] fields
The field names and types for the struct type.
@param [Integer, nil] alignment
Optional custom alignment the struct type.
@param [Boolean] padding
Controls whether to pad struct members for alignment.
@return [StructType]
The new struct type.
Source
# File lib/ronin/support/binary/ctypes/struct_type.rb, line 153 def initialize(members, size: , alignment: , pack_string: ) @members = members @size = size @alignment = alignment super(pack_string: pack_string) end
Initializes the struct type.
@param [Hash{Symbol => Member}] members
The members for the struct type.
@param [Integer, nil] alignment
Optional custom alignment the struct type.
@param [String, nil] pack_string
The String for `Array#pack` or `String#unpack`.
Public Instance Methods
Source
# File lib/ronin/support/binary/ctypes/struct_type.rb, line 240 def align(new_alignment) self.class.new(@members, size: @size, alignment: new_alignment, pack_string: pack_string) end
Creates a copy of the struct type with a different {#alignment}.
@param [Integer] new_alignment
The new alignment for the new struct type.
@return [ScalarType]
The new struct type.
Source
# File lib/ronin/support/binary/ctypes/struct_type.rb, line 345 def dequeue_value(values) hash = {} @members.each do |name,member| hash[name] = member.type.dequeue_value(values) end return hash end
Dequeues a Hash from the flat list of values.
@param [Array] values
The flat array of values.
@return [Hash]
The dequeued hash.
@api private
Source
# File lib/ronin/support/binary/ctypes/struct_type.rb, line 320 def enqueue_value(values,hash) unknown_keys = hash.keys - @members.keys unless unknown_keys.empty? raise(ArgumentError,"unknown struct members: #{unknown_keys.map(&:inspect).join(', ')}") end @members.each do |name,member| value = hash[name] || member.type.uninitialized_value member.type.enqueue_value(values,value) end end
Enqueues a Hash of values onto the flat list of values.
@param [Array] values
The flat array of values.
@param [Hash] hash
The hash to enqueue.
@api private
Source
# File lib/ronin/support/binary/ctypes/struct_type.rb, line 227 def length @members.length end
The number of members within the struct.
@return [Integer]
Source
# File lib/ronin/support/binary/ctypes/struct_type.rb, line 255 def pack(hash) if @pack_string super(hash) else buffer = String.new("\0" * @size, encoding: Encoding::ASCII_8BIT) hash.each do |name,value| member = @members.fetch(name) do raise(ArgumentError,"unknown struct member (#{name.inspect}), must be: #{@members.keys.map(&:inspect).join(', ')}") end data = member.type.pack(value) if member.size == Float::INFINITY buffer[member.offset..] = data else buffer[member.offset,member.size] = data end end return buffer end end
Packs the hash of values into the struct’s binary layout.
@param [Hash{Symbol => Integer
, Float
, String}] hash
The hash of values to pack.
@return [String]
The packed binary data.
Ronin::Support::Binary::CTypes::AggregateType#pack
Source
# File lib/ronin/support/binary/ctypes/struct_type.rb, line 216 def uninitialized_value @members.transform_values do |member| member.type.uninitialized_value end end
Creates a new Hash of the struct’s uninitialized members.
@return [Hash{Symbol => Object}]
The uninitialized values for the new struct's members.
Source
# File lib/ronin/support/binary/ctypes/struct_type.rb, line 289 def unpack(data) if @pack_string super(data) else hash = {} @members.each do |name,member| slice = if member.size == Float::INFINITY data.byteslice(member.offset..) else data.byteslice(member.offset,member.size) end hash[name] = member.type.unpack(slice) end return hash end end
Unpacks binary data into a Hash of values using the struct’s binary layout.
@param [String] data
The binary data to unpack.
@return [Hash{Symbol => Integer
, Float
, String
, nil}]
The unpacked hash.
Ronin::Support::Binary::CTypes::AggregateType#unpack