Class: FFI::DRY::DSL_StructLayoutBuilder

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

Overview

This is a wrapper around the FFI::StructLayoutBuilder. Its goal is to provides a more declarative syntax for defining structures and include the ability to attach arbitrary dsl_metadata information to structure fields during definition.

The “DSL” (and that’s really very in-quotes) supplies 3 ways to define a field (for now):

field()
array()
struct()

See the individual method descriptions for more info.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pbind) ⇒ DSL_StructLayoutBuilder

Initializes the builder with a reference to the structure using it Instead of duplicating Struct features, we just call back to them.



205
206
207
208
209
210
# File 'lib/ffi/dry.rb', line 205

def initialize(pbind)
  @pbind = pbind
  @builder = ::FFI::StructLayoutBuilder.new
  @metadata = []
  super()
end

Instance Attribute Details

#builderObject (readonly)

Returns the value of attribute builder.



201
202
203
# File 'lib/ffi/dry.rb', line 201

def builder
  @builder
end

#metadataObject (readonly)

Returns the value of attribute metadata.



201
202
203
# File 'lib/ffi/dry.rb', line 201

def 
  @metadata
end

Instance Method Details

#array(name, type, o = {}) ⇒ Object

Calls StructLayoutBuider.add_array() on the builder and stores a metadata hash entry (the opts hash with name and type overridden)

Syntax:

array field_name, [ctype, N], { ... metadata ... }

:offset is a special key in metadata, specifies the offset of the field.



244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/ffi/dry.rb', line 244

def array(name, type, o={})
  unless type.kind_of?(::Array)
    raise(::ArgumentError, "type must be an array") 
  end

  opts = o.merge(:name => name, :type => type)
  offset = opts[:offset]
  mod = enclosing_module
  ret=@builder.add_array(name, find_type(type[0], mod), type[1], offset)
  @metadata << opts
  return ret
end

#buildObject

calls StructLayoutBuider.build() on the bulder and returns its result.



214
215
216
# File 'lib/ffi/dry.rb', line 214

def build
  @builder.build
end

#enclosing_module(*args) ⇒ Object



278
279
280
# File 'lib/ffi/dry.rb', line 278

def enclosing_module(*args)
  @pbind.enclosing_module(*args)
end

#field(name, type, o = {}) ⇒ Object

Calls StructLayoutBuider.add_field() on the builder and stores a metadata hash entry (the opts hash with name and type overridden)

Syntax:

field field_name, ctype, { ... metadata ... }

:offset is a special key in metadata, specifies the offset of the field.



265
266
267
268
269
270
271
272
# File 'lib/ffi/dry.rb', line 265

def field(name, type, o={})
  opts = o.merge(:name => name, :type => type)
  offset = opts[:offset]
  mod = enclosing_module
  ret= @builder.add_field(name, find_type(type, mod), offset)
  @metadata << opts
  return ret
end

#find_type(*args) ⇒ Object



274
275
276
# File 'lib/ffi/dry.rb', line 274

def find_type(*args)
  @pbind.find_type(*args)
end

#struct(name, klass, o = {}) ⇒ Object

Calls StructLayoutBuilder.add_struct() on the builder and stores a metadata hash entry (the opts hash with name and type overridden)

struct field_name,  RubyClass, { ... metadata ... }

:offset is a special key in metadata, specifies the offset of the field.



224
225
226
227
228
229
230
231
232
233
234
# File 'lib/ffi/dry.rb', line 224

def struct(name, klass, o={})
  unless klass.kind_of?(Class) and klass < ::FFI::Struct
    raise(::ArgumentError, "klass must be a struct")
  end

  opts = o.merge(:name => name, :type => klass)
  offset = opts[:offset]
  ret=@builder.add_struct(name, klass, offset)
  @metadata << opts
  return ret
end