diff options
author | ttate <ttate@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-04-05 05:11:11 +0000 |
---|---|---|
committer | ttate <ttate@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-04-05 05:11:11 +0000 |
commit | 8d08d9f5134a07af00f9e2ef8a4938e40503f873 (patch) | |
tree | 2b489fca44bc06bd1a8887f2019ec9a7aee0d72a /ext/dl/lib/dl/struct.rb | |
parent | 289fe2b8ee966544d09e2fc00a7365fa7ecc920d (diff) |
Add dl/struct.rb.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2339 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/dl/lib/dl/struct.rb')
-rw-r--r-- | ext/dl/lib/dl/struct.rb | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/ext/dl/lib/dl/struct.rb b/ext/dl/lib/dl/struct.rb new file mode 100644 index 0000000000..b16aa6e6b0 --- /dev/null +++ b/ext/dl/lib/dl/struct.rb @@ -0,0 +1,107 @@ +# -*- ruby -*- + +require 'dl' +require 'dl/import' + +module DL + module Importable + module Internal + def define_struct(contents) + init_types() + Struct.new(@types, contents) + end + + def define_union(contents) + init_types() + Union.new(@types, contents) + end + + 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}) if @dec[\"#{name}\"]", + " return v", + "end", + ].join("\n") + } + end + end + + class Struct + def initialize(types, contents) + @names = [] + @ty = {} + @len = {} + @enc = {} + @dec = {} + @size = 0 + @tys = "" + @types = types + parse(contents) + end + + def new + ptr = DL::malloc(@size) + ptr.struct!(@tys, *@names) + mem = Memory.new(ptr, @names, @ty, @len, @enc, @dec) + return mem + 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 |