In Files

  • dl/lib/dl/struct.rb

Parent

Included Modules

DL::CStructEntity

A C struct wrapper

Public Class Methods

malloc(types, func = nil) click to toggle source

Allocates a C struct the types provided. The C function func is called when the instance is garbage collected.

 
               # File dl/lib/dl/struct.rb, line 85
def CStructEntity.malloc(types, func = nil)
  addr = DL.malloc(CStructEntity.size(types))
  CStructEntity.new(addr, types, func)
end
            
new(addr, types, func = nil) click to toggle source

Wraps the C pointer addr as a C struct with the given types. The C function func is called when the instance is garbage collected.

See also DL::CPtr.new

 
               # File dl/lib/dl/struct.rb, line 115
def initialize(addr, types, func = nil)
  set_ctypes(types)
  super(addr, @size, func)
end
            
size(types) click to toggle source

Given types, returns the offset for the packed sizes of those types

DL::CStructEntity.size([DL::TYPE_DOUBLE, DL::TYPE_INT, DL::TYPE_CHAR,
                        DL::TYPE_VOIDP])
=> 24
 
               # File dl/lib/dl/struct.rb, line 95
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
            

Public Instance Methods

[](name) click to toggle source

Fetch struct member name

 
               # File dl/lib/dl/struct.rb, line 148
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| CPtr.new(v)}
    end
  when TYPE_VOIDP
    val = CPtr.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) click to toggle source

Set struct member name, to value val

 
               # File dl/lib/dl/struct.rb, line 182
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) click to toggle source

Set the names of the members in this C struct

 
               # File dl/lib/dl/struct.rb, line 121
def assign_names(members)
  @members = members
end
            
set_ctypes(types) click to toggle source

Given types, calculate the offsets and sizes for the types in the struct.

 
               # File dl/lib/dl/struct.rb, line 127
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
            

Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.

If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.

If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.

If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.

blog comments powered by Disqus