source: extensions/gsdl-video/trunk/installed/cmdline/lib/ruby/1.8/dl/struct.rb@ 18425

Last change on this file since 18425 was 18425, checked in by davidb, 15 years ago

Video extension to Greenstone

File size: 2.9 KB
Line 
1# -*- ruby -*-
2
3require 'dl'
4require 'dl/import'
5
6module 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 " if( @len[\"#{name}\"] )",
36 " v = v.collect{|x| @dec[\"#{name}\"] ? @dec[\"#{name}\"].call(x) : x }",
37 " else",
38 " v = @dec[\"#{name}\"].call(v) if @dec[\"#{name}\"]",
39 " end",
40 " return v",
41 "end",
42 "def #{name}=(v)",
43 " if( @len[\"#{name}\"] )",
44 " v = v.collect{|x| @enc[\"#{name}\"] ? @enc[\"#{name}\"].call(x) : x }",
45 " else",
46 " v = @enc[\"#{name}\"].call(v) if @enc[\"#{name}\"]",
47 " end",
48 " @ptr[\"#{name}\"] = v",
49 " return v",
50 "end",
51 ].join("\n")
52 }
53 end
54
55 def to_ptr
56 return @ptr
57 end
58
59 def size
60 return @ptr.size
61 end
62 end
63
64 class Struct
65 def initialize(types, contents)
66 @names = []
67 @ty = {}
68 @len = {}
69 @enc = {}
70 @dec = {}
71 @size = 0
72 @tys = ""
73 @types = types
74 parse(contents)
75 end
76
77 def size
78 return @size
79 end
80
81 def members
82 return @names
83 end
84
85 # ptr must be a PtrData object.
86 def new(ptr)
87 ptr.struct!(@tys, *@names)
88 mem = Memory.new(ptr, @names, @ty, @len, @enc, @dec)
89 return mem
90 end
91
92 def malloc(size = nil)
93 if( !size )
94 size = @size
95 end
96 ptr = DL::malloc(size)
97 return new(ptr)
98 end
99
100 def parse(contents)
101 contents.each{|elem|
102 name,ty,num,enc,dec = parse_elem(elem)
103 @names.push(name)
104 @ty[name] = ty
105 @len[name] = num
106 @enc[name] = enc
107 @dec[name] = dec
108 if( num )
109 @tys += "#{ty}#{num}"
110 else
111 @tys += ty
112 end
113 }
114 @size = DL.sizeof(@tys)
115 end
116
117 def parse_elem(elem)
118 elem.strip!
119 case elem
120 when /^([\w\d_\*]+)([\*\s]+)([\w\d_]+)$/
121 ty = ($1 + $2).strip
122 name = $3
123 num = nil;
124 when /^([\w\d_\*]+)([\*\s]+)([\w\d_]+)\[(\d+)\]$/
125 ty = ($1 + $2).strip
126 name = $3
127 num = $4.to_i
128 else
129 raise(RuntimeError, "invalid element: #{elem}")
130 end
131 ty,enc,dec = @types.encode_struct_type(ty)
132 if( !ty )
133 raise(TypeError, "unsupported type: #{ty}")
134 end
135 return [name,ty,num,enc,dec]
136 end
137 end # class Struct
138
139 class Union < Struct
140 def new
141 ptr = DL::malloc(@size)
142 ptr.union!(@tys, *@names)
143 mem = Memory.new(ptr, @names, @ty, @len, @enc, @dec)
144 return mem
145 end
146 end
147 end # module Internal
148 end # module Importable
149end # module DL
Note: See TracBrowser for help on using the repository browser.