123456789_123456789_123456789_123456789_123456789_

Class: Fiddle::CStructEntity

Relationships & Source Files
Extension / Inclusion / Inheritance Descendants
Subclasses:
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, Pointer
Instance Chain:
self, Pointer
Inherits: Fiddle::Pointer
Defined in: ext/fiddle/lib/fiddle/struct.rb

Overview

A C struct wrapper

Class Method Summary

Pointer - Inherited

.[]

Get the underlying pointer for ruby object val and return it as a Pointer object.

.new

Create a new pointer to address with an optional .size and freefunc.

.to_ptr

Alias for Pointer.[].

Instance Attribute Summary

Pointer - Inherited

#free

Get the free function for this pointer.

#free=

Set the free function for this pointer to function in the given Function.

#size

Get the size of this pointer.

#size=

Set the size of this pointer to .size

#null?

Returns true if this is a null pointer.

Instance Method Summary

Pointer - Inherited

#+

Returns a new pointer instance that has been advanced n bytes.

#+@

Returns a new Pointer instance that is a dereferenced pointer for this pointer.

#-

Returns a new pointer instance that has been moved back n bytes.

#-@

Returns a new Pointer instance that is a reference pointer for this pointer.

#<=>

Returns -1 if less than, 0 if equal to, 1 if greater than other.

#==

Returns true if other wraps the same pointer, otherwise returns false.

#[]

Returns integer stored at index.

#[]=

Set the value at index to int.

#eql?

Alias for Pointer#==.

#inspect

Returns a string formatted with an easily readable representation of the internal state of the pointer.

#ptr

Alias for Pointer#+@.

#ref

Alias for Pointer#-@.

#to_i

Returns the integer memory location of this pointer.

#to_int

Alias for Pointer#to_i.

#to_s

Returns the pointer contents as a string.

#to_str

Returns the pointer contents as a string.

#to_value

Cast this pointer to a ruby object.

Constructor Details

.new(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 Pointer.new

[ GitHub ]

  
# File 'ext/fiddle/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)

Allocates a C struct with the types provided.

When the instance is garbage collected, the C function func is called.

[ GitHub ]

  
# File 'ext/fiddle/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)

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
[ GitHub ]

  
# File 'ext/fiddle/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)

Fetch struct member name

[ GitHub ]

  
# File 'ext/fiddle/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)

Set struct member name, to value val

[ GitHub ]

  
# File 'ext/fiddle/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)

Set the names of the members in this C struct

[ GitHub ]

  
# File 'ext/fiddle/lib/fiddle/struct.rb', line 126

def assign_names(members)
  @members = members
end

#set_ctypes(types)

Calculates the offsets and sizes for the given types in the struct.

[ GitHub ]

  
# File 'ext/fiddle/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