mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2476 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
138 lines
2.5 KiB
Ruby
138 lines
2.5 KiB
Ruby
# -*- ruby -*-
|
|
|
|
require 'dl'
|
|
require 'dl/import'
|
|
|
|
module DL
|
|
module Importable
|
|
module Internal
|
|
def define_struct(contents)
|
|
init_types()
|
|
Struct.new(@types, contents)
|
|
end
|
|
alias struct define_struct
|
|
|
|
def define_union(contents)
|
|
init_types()
|
|
Union.new(@types, contents)
|
|
end
|
|
alias union define_union
|
|
|
|
class Memory
|
|
def initialize(ptr, names, ty, len, enc, dec)
|
|
@ptr = ptr
|
|
@names = names
|
|
@ty = ty
|
|
@len = len
|
|
@enc = enc
|
|
@dec = dec
|
|
|
|
# define methods
|
|
@names.each{|name|
|
|
instance_eval [
|
|
"def #{name}",
|
|
" v = @ptr[\"#{name}\"]",
|
|
" v = @dec[\"#{name}\"].call(v,@len[\"#{name}\"]) if @dec[\"#{name}\"]",
|
|
" return v",
|
|
"end",
|
|
"def #{name}=(v)",
|
|
" v = @enc[\"#{name}\"].call(v,@len[\"#{name}\"]) if @enc[\"#{name}\"]",
|
|
" @ptr[\"#{name}\"] = v",
|
|
" return v",
|
|
"end",
|
|
].join("\n")
|
|
}
|
|
end
|
|
|
|
def to_ptr
|
|
return @ptr
|
|
end
|
|
|
|
def size
|
|
return @ptr.size
|
|
end
|
|
end
|
|
|
|
class Struct
|
|
def initialize(types, contents)
|
|
@names = []
|
|
@ty = {}
|
|
@len = {}
|
|
@enc = {}
|
|
@dec = {}
|
|
@size = 0
|
|
@tys = ""
|
|
@types = types
|
|
parse(contents)
|
|
end
|
|
|
|
def size
|
|
return @size
|
|
end
|
|
|
|
def members
|
|
return @names
|
|
end
|
|
|
|
# ptr must be a PtrData object.
|
|
def new(ptr)
|
|
ptr.struct!(@tys, *@names)
|
|
mem = Memory.new(ptr, @names, @ty, @len, @enc, @dec)
|
|
return mem
|
|
end
|
|
|
|
def malloc(size = nil)
|
|
if( !size )
|
|
size = @size
|
|
end
|
|
ptr = DL::malloc(size)
|
|
return new(ptr)
|
|
end
|
|
|
|
def parse(contents)
|
|
contents.each{|elem|
|
|
name,ty,num,enc,dec = parse_elem(elem)
|
|
@names.push(name)
|
|
@ty[name] = ty
|
|
@len[name] = num
|
|
@enc[name] = enc
|
|
@dec[name] = dec
|
|
if( num )
|
|
@tys += "#{ty}#{num}"
|
|
else
|
|
@tys += ty
|
|
end
|
|
}
|
|
@size = DL.sizeof(@tys)
|
|
end
|
|
|
|
def parse_elem(elem)
|
|
elem.strip!
|
|
case elem
|
|
when /^([\w\d_\*]+)([\*\s]+)([\w\d_]+)$/
|
|
ty = ($1 + $2).strip
|
|
name = $3
|
|
num = nil;
|
|
when /^([\w\d_\*]+)([\*\s]+)([\w\d_]+)\[(\d+)\]$/
|
|
ty = ($1 + $2).strip
|
|
name = $3
|
|
num = $4.to_i
|
|
else
|
|
raise(RuntimeError, "invalid element: #{elem}")
|
|
end
|
|
ty,_,_,enc,dec = @types.encode_type(ty)
|
|
return [name,ty,num,enc,dec]
|
|
end
|
|
end # class Struct
|
|
|
|
class Union < Struct
|
|
def new
|
|
ptr = DL::malloc(@size)
|
|
ptr.union!(@tys, *@names)
|
|
mem = Memory.new(ptr, @names, @ty, @len, @enc, @dec)
|
|
return mem
|
|
end
|
|
end
|
|
end # module Internal
|
|
end # module Importable
|
|
end # module DL
|