Class: FFI::StructLayoutBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/ffi/struct_layout_builder.rb

Overview

Build a struct layout.

Constant Summary collapse

NUMBER_TYPES =

List of number types

[
  Type::INT8,
  Type::UINT8,
  Type::INT16,
  Type::UINT16,
  Type::INT32,
  Type::UINT32,
  Type::LONG,
  Type::ULONG,
  Type::INT64,
  Type::UINT64,
  Type::FLOAT32,
  Type::FLOAT64,
  Type::LONGDOUBLE,
  Type::BOOL,
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeStructLayoutBuilder

Returns a new instance of StructLayoutBuilder.



39
40
41
42
43
44
45
46
# File 'lib/ffi/struct_layout_builder.rb', line 39

def initialize
  @size = 0
  @alignment = 1
  @min_alignment = 1
  @packed = false
  @union = false
  @fields = Array.new
end

Instance Attribute Details

#alignmentObject

Returns the value of attribute alignment.



37
38
39
# File 'lib/ffi/struct_layout_builder.rb', line 37

def alignment
  @alignment
end

#sizeObject

Returns the value of attribute size.



36
37
38
# File 'lib/ffi/struct_layout_builder.rb', line 36

def size
  @size
end

Instance Method Details

#add(name, type, offset = nil) ⇒ self

Note:

Setting offset to nil or -1 is equivalent to 0.

Add a field to the builder.

Parameters:

  • name (String, Symbol)

    name of the field

  • type (Array, DataConverter, Struct, StructLayout::Field, Symbol, Type)

    type of the field

  • offset (Integer, nil) (defaults to: nil)

Returns:

  • (self)


123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/ffi/struct_layout_builder.rb', line 123

def add(name, type, offset = nil)

  if offset.nil? || offset == -1
    offset = @union ? 0 : align(@size, @packed ? [ @packed, type.alignment ].min : [ @min_alignment, type.alignment ].max)
  end

  #
  # If a FFI::Type type was passed in as the field arg, try and convert to a StructLayout::Field instance
  #
  field = type.is_a?(StructLayout::Field) ? type : field_for_type(name, offset, type)
  @fields << field
  @alignment = [ @alignment, field.alignment ].max unless @packed
  @size = [ @size, field.size + (@union ? 0 : field.offset) ].max

  return self
end

#add_array(name, type, count, offset = nil) ⇒ self

Add an array as a field to the builder.

Parameters:

  • count (Integer)

    array length

  • name (String, Symbol)

    name of the field

  • type (Array, DataConverter, Struct, StructLayout::Field, Symbol, Type)

    type of the field

  • offset (Integer, nil) (defaults to: nil)

Returns:

  • (self)


161
162
163
# File 'lib/ffi/struct_layout_builder.rb', line 161

def add_array(name, type, count, offset = nil)
  add(name, Type::Array.new(type, count), offset)
end

#add_field(name, type, offset = nil) ⇒ self

Same as #add.

Parameters:

  • name (String, Symbol)

    name of the field

  • type (Array, DataConverter, Struct, StructLayout::Field, Symbol, Type)

    type of the field

  • offset (Integer, nil) (defaults to: nil)

Returns:

  • (self)

See Also:



144
145
146
# File 'lib/ffi/struct_layout_builder.rb', line 144

def add_field(name, type, offset = nil)
  add(name, type, offset)
end

#add_struct(name, type, offset = nil) ⇒ self

Add a struct as a field to the builder.

Parameters:

  • name (String, Symbol)

    name of the field

  • type (Array, DataConverter, Struct, StructLayout::Field, Symbol, Type)

    type of the field

  • offset (Integer, nil) (defaults to: nil)

Returns:

  • (self)


151
152
153
# File 'lib/ffi/struct_layout_builder.rb', line 151

def add_struct(name, type, offset = nil)
  add(name, Type::Struct.new(type), offset)
end

#buildStructLayout

Build and return the struct layout.

Returns:



167
168
169
170
171
172
173
174
# File 'lib/ffi/struct_layout_builder.rb', line 167

def build
  # Add tail padding if the struct is not packed
  size = @packed ? @size : align(@size, @alignment)

  layout = StructLayout.new(@fields, size, @alignment)
  layout.__union! if @union
  layout
end

#packed=(packed) ⇒ packed #packed=(packed) ⇒ 0, 1

Set packed attribute

Overloads:

  • #packed=(packed) ⇒ packed

    packed.

    Parameters:

    • packed (Integer)

    Returns:

    • (packed)
  • #packed=(packed) ⇒ 0, 1

    Parameters:

    • packed

    Returns:

    • (0, 1)


89
90
91
92
93
94
95
96
# File 'lib/ffi/struct_layout_builder.rb', line 89

def packed=(packed)
  if packed.is_a?(0.class)
    @alignment = packed
    @packed = packed
  else
    @packed = packed ? 1 : 0
  end
end

#union=(is_union) ⇒ is_union

Set union attribute. Set to true to build a Union instead of a FFI::Struct.

Parameters:

  • is_union (Boolean)

Returns:

  • (is_union)


65
66
67
# File 'lib/ffi/struct_layout_builder.rb', line 65

def union=(is_union)
  @union = is_union
end

#union?Boolean

Building a Union or a FFI::Struct ?

Returns:

  • (Boolean)


73
74
75
# File 'lib/ffi/struct_layout_builder.rb', line 73

def union?
  @union
end