DEFINITIONS
This source file includes following functions.
1 # -*- ruby -*-
2
3 require 'dl'
4 require 'dl/import'
5
6 module DL
7 module Importable
8 module Internal
9 def define_struct(contents)
10 init_types()
11 Struct.new(@types, contents)
12 end
13 alias struct define_struct
14
15 def define_union(contents)
16 init_types()
17 Union.new(@types, contents)
18 end
19 alias union define_union
20
21 class Memory
22 def initialize(ptr, names, ty, len, enc, dec)
23 @ptr = ptr
24 @names = names
25 @ty = ty
26 @len = len
27 @enc = enc
28 @dec = dec
29
30 # define methods
31 @names.each{|name|
32 instance_eval [
33 "def #{name}",
34 " v = @ptr[\"#{name}\"]",
35 " v = @dec[\"#{name}\"].call(v,@len[\"#{name}\"]) if @dec[\"#{name}\"]",
36 " return v",
37 "end",
38 "def #{name}=(v)",
39 " v = @enc[\"#{name}\"].call(v,@len[\"#{name}\"]) if @enc[\"#{name}\"]",
40 " @ptr[\"#{name}\"] = v",
41 " return v",
42 "end",
43 ].join("\n")
44 }
45 end
46
47 def to_ptr
48 return @ptr
49 end
50
51 def size
52 return @ptr.size
53 end
54 end
55
56 class Struct
57 def initialize(types, contents)
58 @names = []
59 @ty = {}
60 @len = {}
61 @enc = {}
62 @dec = {}
63 @size = 0
64 @tys = ""
65 @types = types
66 parse(contents)
67 end
68
69 def size
70 return @size
71 end
72
73 def members
74 return @names
75 end
76
77 # ptr must be a PtrData object.
78 def new(ptr)
79 ptr.struct!(@tys, *@names)
80 mem = Memory.new(ptr, @names, @ty, @len, @enc, @dec)
81 return mem
82 end
83
84 def malloc(size = nil)
85 if( !size )
86 size = @size
87 end
88 ptr = DL::malloc(size)
89 return new(ptr)
90 end
91
92 def parse(contents)
93 contents.each{|elem|
94 name,ty,num,enc,dec = parse_elem(elem)
95 @names.push(name)
96 @ty[name] = ty
97 @len[name] = num
98 @enc[name] = enc
99 @dec[name] = dec
100 if( num )
101 @tys += "#{ty}#{num}"
102 else
103 @tys += ty
104 end
105 }
106 @size = DL.sizeof(@tys)
107 end
108
109 def parse_elem(elem)
110 elem.strip!
111 case elem
112 when /^([\w\d_\*]+)([\*\s]+)([\w\d_]+)$/
113 ty = ($1 + $2).strip
114 name = $3
115 num = nil;
116 when /^([\w\d_\*]+)([\*\s]+)([\w\d_]+)\[(\d+)\]$/
117 ty = ($1 + $2).strip
118 name = $3
119 num = $4.to_i
120 else
121 raise(RuntimeError, "invalid element: #{elem}")
122 end
123 ty,_,_,enc,dec = @types.encode_type(ty)
124 return [name,ty,num,enc,dec]
125 end
126 end # class Struct
127
128 class Union < Struct
129 def new
130 ptr = DL::malloc(@size)
131 ptr.union!(@tys, *@names)
132 mem = Memory.new(ptr, @names, @ty, @len, @enc, @dec)
133 return mem
134 end
135 end
136 end # module Internal
137 end # module Importable
138 end # module DL