Class: Rstruct::Structure

Inherits:
ContainerType show all
Defined in:
lib/rstruct/structure.rb

Instance Attribute Summary collapse

Attributes inherited from Type

#name, #params

Instance Method Summary collapse

Methods inherited from ContainerType

#claim_value, #field_names, #field_types, #format, #groupable?, #read, #sizeof

Methods included from Packable

#pack_value, #read

Methods inherited from Type

#claim_value, #container?, #groupable?, #register, #sizeof

Constructor Details

#initialize(name, opts = {}, &block) ⇒ Structure

Returns a new instance of Structure.

Raises:



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/rstruct/structure.rb', line 12

def initialize(name, opts={}, &block)
  lkupreg = (opts[:fields_from]) # allow a seperate reg for member types
  builder = opts[:builder] || StructBuilder
  reg = opts[:register]
  reg=nil if reg==true

  # pass a nil block to super to ensure we're claiming the caller's
  super(name, opts, &(nil))

  @fields = builder.new((lkupreg || reg), &block).__fields
  raise(StructError, "no fields were defined") if @fields.empty?

  # set up our internal struct container class
  # we are taking the field name 'structure' 
  # to reference ourselves
  @mystruct = Struct.new(*self.field_names)
end

Instance Attribute Details

#fieldsObject (readonly)

Returns the value of attribute fields.



10
11
12
# File 'lib/rstruct/structure.rb', line 10

def fields
  @fields
end

Instance Method Details

#instance(values = nil) {|s| ... } ⇒ Object

Yields:

  • (s)


30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/rstruct/structure.rb', line 30

def instance(values=nil)
  values ||= {}
  vals = []
  self.fields.each do |f|
    v = values[f.name]
    vals << (f.typ.respond_to?(:instance) ? f.typ.instance(v) : v)
  end
  s = @mystruct.new(*vals).extend(ContainerMixins)
  s.rstruct_type = self
  yield(s) if block_given?
  return s
end

#offset_of(fld) ⇒ Object

Raises:



43
44
45
46
47
48
49
50
# File 'lib/rstruct/structure.rb', line 43

def offset_of(fld)
  o = 0
  self.fields.each do |f|
    return o if f.name == fld
    o += f.sizeof
  end
  raise(InvalidTypeError, "Invalid type: #{fld}")
end