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
120 121 122 123 |
# File 'lib/fiddle/struct.rb', line 120 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.
87 88 89 90 |
# File 'lib/fiddle/struct.rb', line 87 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
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/fiddle/struct.rb', line 99 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
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 183 |
# File 'lib/fiddle/struct.rb', line 152 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
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/fiddle/struct.rb', line 186 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
126 127 128 |
# File 'lib/fiddle/struct.rb', line 126 def assign_names(members) @members = members end |
#set_ctypes(types) ⇒ Object
Calculates the offsets and sizes for the given types
in the struct.
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/fiddle/struct.rb', line 131 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:
205 206 207 |
# File 'lib/fiddle/struct.rb', line 205 def to_s() # :nodoc: super(@size) end |