Class: Fiddle::CStructEntity
- Defined in:
- lib/fiddle/struct.rb
Overview
A C struct wrapper
Direct Known Subclasses
Constant Summary
Constants included from PackInfo
PackInfo::ALIGN_MAP, PackInfo::PACK_MAP, PackInfo::SIZE_MAP
Class Method Summary collapse
-
.malloc(types, func = nil) ⇒ Object
Allocates a C struct with the
types
provided. -
.size(types) ⇒ Object
Returns the offset for the packed sizes for the given
types
.
Instance Method Summary collapse
-
#[](name) ⇒ Object
Fetch struct member
name
. -
#[]=(name, val) ⇒ Object
Set struct member
name
, to valueval
. -
#assign_names(members) ⇒ Object
Set the names of the
members
in this C struct. -
#initialize(addr, types, func = nil) ⇒ CStructEntity
constructor
Wraps the C pointer
addr
as a C struct with the giventypes
. -
#set_ctypes(types) ⇒ Object
Calculates the offsets and sizes for the given
types
in the struct. -
#to_s ⇒ Object
:nodoc:.
Methods included from ValueUtil
#signed_value, #unsigned_value, #wrap_arg, #wrap_args
Methods included from PackInfo
Methods inherited from Pointer
#+, #+@, #-, #-@, #<=>, #==, [], #eql?, #free, #free=, #inspect, #null?, #ptr, #ref, #size, #size=, #to_i, #to_int, to_ptr, #to_str, #to_value
Constructor Details
#initialize(addr, types, func = nil) ⇒ CStructEntity
Wraps the C pointer addr
as a C struct with the given types
.
When the instance is garbage collected, the C function func
is called.
See also Fiddle::Pointer.new
119 120 121 122 |
# File 'lib/fiddle/struct.rb', line 119 def initialize(addr, types, func = nil) set_ctypes(types) super(addr, @size, func) end |
Class Method Details
.malloc(types, func = nil) ⇒ Object
Allocates a C struct with the types
provided.
When the instance is garbage collected, the C function func
is called.
86 87 88 89 |
# File 'lib/fiddle/struct.rb', line 86 def CStructEntity.malloc(types, func = nil) addr = Fiddle.malloc(CStructEntity.size(types)) CStructEntity.new(addr, types, func) end |
.size(types) ⇒ Object
Returns the offset for the packed sizes for the given types
.
Fiddle::CStructEntity.size(
[ Fiddle::TYPE_DOUBLE,
Fiddle::TYPE_INT,
Fiddle::TYPE_CHAR,
Fiddle::TYPE_VOIDP ]) #=> 24
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/fiddle/struct.rb', line 98 def CStructEntity.size(types) offset = 0 max_align = types.map { |type, count = 1| last_offset = offset align = PackInfo::ALIGN_MAP[type] offset = PackInfo.align(last_offset, align) + (PackInfo::SIZE_MAP[type] * count) align }.max PackInfo.align(offset, max_align) end |
Instance Method Details
#[](name) ⇒ Object
Fetch struct member name
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/fiddle/struct.rb', line 151 def [](name) idx = @members.index(name) if( idx.nil? ) raise(ArgumentError, "no such member: #{name}") end ty = @ctypes[idx] if( ty.is_a?(Array) ) r = super(@offset[idx], SIZE_MAP[ty[0]] * ty[1]) else r = super(@offset[idx], SIZE_MAP[ty.abs]) end packer = Packer.new([ty]) val = packer.unpack([r]) case ty when Array case ty[0] when TYPE_VOIDP val = val.collect{|v| Pointer.new(v)} end when TYPE_VOIDP val = Pointer.new(val[0]) else val = val[0] end if( ty.is_a?(Integer) && (ty < 0) ) return unsigned_value(val, ty) elsif( ty.is_a?(Array) && (ty[0] < 0) ) return val.collect{|v| unsigned_value(v,ty[0])} else return val end end |
#[]=(name, val) ⇒ Object
Set struct member name
, to value val
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/fiddle/struct.rb', line 185 def []=(name, val) idx = @members.index(name) if( idx.nil? ) raise(ArgumentError, "no such member: #{name}") end ty = @ctypes[idx] packer = Packer.new([ty]) val = wrap_arg(val, ty, []) buff = packer.pack([val].flatten()) super(@offset[idx], buff.size, buff) if( ty.is_a?(Integer) && (ty < 0) ) return unsigned_value(val, ty) elsif( ty.is_a?(Array) && (ty[0] < 0) ) return val.collect{|v| unsigned_value(v,ty[0])} else return val end end |
#assign_names(members) ⇒ Object
Set the names of the members
in this C struct
125 126 127 |
# File 'lib/fiddle/struct.rb', line 125 def assign_names(members) @members = members end |
#set_ctypes(types) ⇒ Object
Calculates the offsets and sizes for the given types
in the struct.
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/fiddle/struct.rb', line 130 def set_ctypes(types) @ctypes = types @offset = [] offset = 0 max_align = types.map { |type, count = 1| orig_offset = offset align = ALIGN_MAP[type] offset = PackInfo.align(orig_offset, align) @offset << offset offset += (SIZE_MAP[type] * count) align }.max @size = PackInfo.align(offset, max_align) end |
#to_s ⇒ Object
:nodoc:
204 205 206 |
# File 'lib/fiddle/struct.rb', line 204 def to_s() # :nodoc: super(@size) end |