Class: Fiddle::CStruct

Inherits:
Object show all
Includes:
Enumerable
Defined in:
ext/fiddle/lib/fiddle/struct.rb

Overview

A base class for objects representing a C structure

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Enumerable

#to_set

Class Method Details

.entity_classObject

accessor to Fiddle::CStructEntity



12
13
14
# File 'ext/fiddle/lib/fiddle/struct.rb', line 12

def CStruct.entity_class
  CStructEntity
end

.offsetof(name, members, types) ⇒ Object

:nodoc:



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'ext/fiddle/lib/fiddle/struct.rb', line 16

def self.offsetof(name, members, types) # :nodoc:
  offset = 0
  worklist = name.split('.')
  this_type = self
  while search_name = worklist.shift
    index = 0
    member_index = members.index(search_name)

    unless member_index
      # Possibly a sub-structure
      member_index = members.index { |member_name, _|
        member_name == search_name
      }
      return unless member_index
    end

    types.each { |type, count = 1|
      orig_offset = offset
      if type.respond_to?(:entity_class)
        align = type.alignment
        type_size = type.size
      else
        align = PackInfo::ALIGN_MAP[type]
        type_size = PackInfo::SIZE_MAP[type]
      end

      # Unions shouldn't advance the offset
      if this_type.entity_class == CUnionEntity
        type_size = 0
      end

      offset = PackInfo.align(orig_offset, align)

      if worklist.empty?
        return offset if index == member_index
      else
        if index == member_index
          subtype = types[member_index]
          members = subtype.members
          types = subtype.types
          this_type = subtype
          break
        end
      end

      offset += (type_size * count)
      index += 1
    }
  end
  nil
end

Instance Method Details

#eachObject



68
69
70
71
72
73
74
# File 'ext/fiddle/lib/fiddle/struct.rb', line 68

def each
  return enum_for(__function__) unless block_given?

  self.class.members.each do |name,|
    yield(self[name])
  end
end

#each_pairObject



76
77
78
79
80
81
82
# File 'ext/fiddle/lib/fiddle/struct.rb', line 76

def each_pair
  return enum_for(__function__) unless block_given?

  self.class.members.each do |name,|
    yield(name, self[name])
  end
end

#replace(another) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'ext/fiddle/lib/fiddle/struct.rb', line 92

def replace(another)
  if another.nil?
    self.class.members.each do |name,|
      self[name] = nil
    end
  elsif another.respond_to?(:each_pair)
    another.each_pair do |name, value|
      self[name] = value
    end
  else
    another.each do |name, value|
      self[name] = value
    end
  end
  self
end

#to_hObject



84
85
86
87
88
89
90
# File 'ext/fiddle/lib/fiddle/struct.rb', line 84

def to_h
  hash = {}
  each_pair do |name, value|
    hash[name] = unstruct(value)
  end
  hash
end