virtualbox-com 0.9.9 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +339 -19
- data/examples/simple.rb +2 -0
- data/ext/virtualbox-com/4.1/extconf.rb +4 -0
- data/ext/virtualbox-com/4.1/generated.inc +17345 -0
- data/ext/virtualbox-com/4.1/vbox.c +858 -0
- data/ext/virtualbox-com/4.2/extconf.rb +4 -0
- data/ext/virtualbox-com/4.2/generated.inc +19751 -0
- data/ext/virtualbox-com/4.2/vbox.c +858 -0
- data/ext/virtualbox-com/helpers.h +62 -0
- data/ext/virtualbox-com/loader/extconf.rb +3 -0
- data/ext/virtualbox-com/loader/vbox-loader.c +187 -0
- data/ext/virtualbox-com/types.h +34 -0
- data/ext/virtualbox-com/vbox.c +858 -0
- data/lib/virtualbox/com.rb +4 -26
- data/lib/virtualbox/com/{abstract_enum.rb → abstracts.rb} +22 -18
- data/lib/virtualbox/com/exceptions.rb +29 -3
- data/lib/virtualbox/com/model/4.1-generated.rb +2141 -0
- data/lib/virtualbox/com/model/4.2-generated.rb +141 -432
- data/lib/virtualbox/com/model/4.2.rb +4 -4
- data/lib/virtualbox/com/util.rb +2 -1
- data/lib/virtualbox/com/version.rb +1 -1
- data/lib/virtualbox/com/xpcomc-ffi.rb +5 -19
- data/lib/virtualbox/com/xpcomc-ffi/abstracts.rb +103 -0
- data/lib/virtualbox/com/{iid.rb → xpcomc-ffi/iid.rb} +18 -0
- data/lib/virtualbox/com/xpcomc-ffi/lib.rb +6 -0
- data/lib/virtualbox/com/xpcomc-ffi/model-types.rb +1 -0
- data/lib/virtualbox/com/xpcomc-native.rb +8 -0
- data/scripts/abstracts.rb +84 -0
- data/scripts/sig.rb +201 -0
- data/scripts/spec.rb +56 -0
- data/scripts/to_c.rb +157 -0
- data/scripts/xidl-conv.rb +110 -50
- data/virtualbox-com.gemspec +18 -11
- metadata +49 -47
- data/.gitignore +0 -9
- data/README.md +0 -89
- data/Rakefile +0 -8
- data/lib/virtualbox/com/abstract_interface.rb +0 -144
- data/lib/virtualbox/com/abstract_model.rb +0 -14
data/scripts/spec.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require_relative 'sig'
|
2
|
+
|
3
|
+
module VirtualBox
|
4
|
+
module COM
|
5
|
+
|
6
|
+
class Spec
|
7
|
+
attr_reader :name
|
8
|
+
|
9
|
+
def hide?
|
10
|
+
@opts[:hide]
|
11
|
+
end
|
12
|
+
|
13
|
+
class Function < Spec
|
14
|
+
def initialize(name, type, args, opts)
|
15
|
+
@name, @type, @args, @opts = name, type, args, opts
|
16
|
+
end
|
17
|
+
|
18
|
+
def signatures
|
19
|
+
{ name => to_call }
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_call
|
23
|
+
Sig.new( if @type.nil?
|
24
|
+
then @args
|
25
|
+
else @args + [ [ :out, @type ] ]
|
26
|
+
end)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Property < Spec
|
31
|
+
attr_reader :getter, :setter
|
32
|
+
|
33
|
+
def initialize(name, type, opts)
|
34
|
+
@name, @type, @opts = name, type, opts
|
35
|
+
end
|
36
|
+
|
37
|
+
def signatures
|
38
|
+
r = {}
|
39
|
+
r[getter] = to_read
|
40
|
+
r[setter] = to_write unless self.readonly?
|
41
|
+
r
|
42
|
+
end
|
43
|
+
|
44
|
+
def readonly?
|
45
|
+
@opts[:readonly]
|
46
|
+
end
|
47
|
+
|
48
|
+
def getter ; :"get_#{@name}" ; end
|
49
|
+
def setter ; :"set_#{@name}" ; end
|
50
|
+
def to_read ; Sig.new([[:out, @type]]) ; end
|
51
|
+
def to_write ; Sig.new([ @type ]) ; end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
data/scripts/to_c.rb
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'getoptlong'
|
3
|
+
|
4
|
+
module VirtualBox
|
5
|
+
module COM
|
6
|
+
WSTRING = 'wstring_t'
|
7
|
+
BOOL = 'bool_t'
|
8
|
+
OCTET = 'char'
|
9
|
+
PTR = 'void *'
|
10
|
+
INT8 = 'int8_t'
|
11
|
+
INT16 = 'int16_t'
|
12
|
+
INT32 = 'int32_t'
|
13
|
+
INT64 = 'int64_t'
|
14
|
+
UINT8 = 'uint8_t'
|
15
|
+
UINT16 = 'uint16_t'
|
16
|
+
UINT32 = 'uint32_t'
|
17
|
+
UINT64 = 'uint64_t'
|
18
|
+
|
19
|
+
module Model
|
20
|
+
def self.get(name)
|
21
|
+
self.const_get(name, false)
|
22
|
+
rescue NameError
|
23
|
+
raise ModelNotFoundException, name
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.fetch(name)
|
27
|
+
self.const_get(name, false)
|
28
|
+
rescue NameError
|
29
|
+
nil
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class ModelNotFoundException < Exception
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
require 'virtualbox/com/abstracts'
|
39
|
+
require_relative 'abstracts'
|
40
|
+
require_relative 'sig'
|
41
|
+
require_relative 'spec'
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
opts = GetoptLong.new(
|
46
|
+
[ "--api", GetoptLong::REQUIRED_ARGUMENT ],
|
47
|
+
[ "--file", GetoptLong::REQUIRED_ARGUMENT ],
|
48
|
+
[ "--help", GetoptLong::NO_ARGUMENT ] )
|
49
|
+
|
50
|
+
api = nil
|
51
|
+
file = nil
|
52
|
+
|
53
|
+
begin
|
54
|
+
opts.each do |opt, arg|
|
55
|
+
case opt
|
56
|
+
when "--api" then api = arg
|
57
|
+
when "--file" then file = arg
|
58
|
+
when "--help" then raise
|
59
|
+
end
|
60
|
+
end
|
61
|
+
raise if api.nil?
|
62
|
+
rescue
|
63
|
+
$stderr.print <<EOT
|
64
|
+
usage: xidl-conv.rb: --api version [--file output]
|
65
|
+
--api Model description
|
66
|
+
--file path to generated output
|
67
|
+
--help Show this message.
|
68
|
+
|
69
|
+
EOT
|
70
|
+
exit 0
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
require "virtualbox/com/model/#{api}-generated"
|
75
|
+
OUT = file.nil? ? $stdout : File.open(file, 'w')
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
|
81
|
+
M = VirtualBox::COM::Model
|
82
|
+
|
83
|
+
|
84
|
+
M.constants.each {|name| model = VirtualBox::COM::Model.get(name)
|
85
|
+
next unless model <= VirtualBox::COM::AbstractInterface
|
86
|
+
OUT << "struct #{name} {\n"
|
87
|
+
if (s = model.superclass) < VirtualBox::COM::AbstractInterface
|
88
|
+
OUT << " struct #{s.nickname} #{s.nickname};\n"
|
89
|
+
end
|
90
|
+
model.members.each {|spec|
|
91
|
+
spec.signatures.each {|n, sig|
|
92
|
+
OUT << " uint32_t (*#{n})(#{sig.to_c.join(', ')});\n"
|
93
|
+
}
|
94
|
+
}
|
95
|
+
OUT << "};\n"
|
96
|
+
}
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
M.constants.each {|name| model = VirtualBox::COM::Model.get(name)
|
101
|
+
OUT << "static VALUE c#{name} = Qundef;\n"
|
102
|
+
}
|
103
|
+
|
104
|
+
|
105
|
+
M.constants.each {|name| model = VirtualBox::COM::Model.get(name)
|
106
|
+
next unless model <= VirtualBox::COM::AbstractInterface
|
107
|
+
|
108
|
+
model.functions.each {|spec|
|
109
|
+
spec.to_call.to_c_func("#{name}__#{spec.name}", name, spec.name);
|
110
|
+
}
|
111
|
+
|
112
|
+
model.properties.each {|spec|
|
113
|
+
spec.to_read.to_c_func("#{name}__#{spec.getter}", name, spec.getter);
|
114
|
+
next if spec.readonly?
|
115
|
+
spec.to_write.to_c_func("#{name}__#{spec.setter}", name, spec.setter);
|
116
|
+
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
|
121
|
+
OUT << "static void comclass_init(VALUE under) {\n"
|
122
|
+
M.constants.each {|name| model = VirtualBox::COM::Model.get(name)
|
123
|
+
kAbstract = 'c' + model.superclass.name.split('::')[-1]
|
124
|
+
|
125
|
+
OUT << " {\n"
|
126
|
+
OUT << " iid_t iid = #{model::IID.to_struct};\n"
|
127
|
+
OUT << " VALUE c = c#{name}\n"
|
128
|
+
OUT << " = rb_define_class_under(under, \"#{name}\", #{kAbstract});\n"
|
129
|
+
OUT << " no_instantiation(c);\n"
|
130
|
+
OUT << " rb_const_set(c, _IID, iid__new(&iid));\n"
|
131
|
+
|
132
|
+
if model <= VirtualBox::COM::AbstractEnum
|
133
|
+
OUT << " VALUE h = rb_hash_new();\n"
|
134
|
+
model.map.each {|sym, val|
|
135
|
+
OUT << " rb_funcall(h, _bracketseq, 2, SYM(\"#{sym}\"), ULL2NUM(#{val}));\n"
|
136
|
+
}
|
137
|
+
OUT << " rb_funcall(c, _map, 1, h);\n"
|
138
|
+
elsif model <= VirtualBox::COM::AbstractInterface
|
139
|
+
model.members.each {|spec|
|
140
|
+
next if spec.hide?
|
141
|
+
case spec
|
142
|
+
when VirtualBox::COM::Spec::Function
|
143
|
+
if spec.to_call.size > 15
|
144
|
+
warn "Binding for #{model.nickname}\##{spec.name} need to be handcrafted"
|
145
|
+
next
|
146
|
+
end
|
147
|
+
OUT << " rb_define_method(c, \"#{spec.name}\", #{model.nickname}__#{spec.name}, #{spec.to_call.in.size});\n"
|
148
|
+
when VirtualBox::COM::Spec::Property
|
149
|
+
OUT << " rb_define_method(c, \"#{spec.name}\", #{model.nickname}__#{spec.getter}, 0);\n"
|
150
|
+
|
151
|
+
OUT << " rb_define_method(c, \"#{spec.name}=\", #{model.nickname}__#{spec.setter}, 1);\n" if !spec.readonly?
|
152
|
+
end
|
153
|
+
}
|
154
|
+
end
|
155
|
+
OUT << " }\n"
|
156
|
+
}
|
157
|
+
OUT << "}\n"
|
data/scripts/xidl-conv.rb
CHANGED
@@ -1,47 +1,102 @@
|
|
1
1
|
require 'bundler/setup'
|
2
|
+
require 'getoptlong'
|
2
3
|
require 'nokogiri'
|
3
4
|
require 'virtualbox/com/util'
|
4
5
|
|
5
|
-
XIDL = Nokogiri::XML(File.new("../VirtualBox.xidl"))
|
6
|
-
LIB = XIDL.root.xpath('library')
|
7
6
|
|
7
|
+
# Parse command line
|
8
|
+
opts = GetoptLong.new(
|
9
|
+
[ "--xidl", GetoptLong::REQUIRED_ARGUMENT ],
|
10
|
+
[ "--file", GetoptLong::REQUIRED_ARGUMENT ],
|
11
|
+
[ "--help", GetoptLong::NO_ARGUMENT ] )
|
8
12
|
|
13
|
+
xidl = nil
|
14
|
+
file = nil
|
9
15
|
|
10
|
-
|
16
|
+
begin
|
17
|
+
opts.each do |opt, arg|
|
18
|
+
case opt
|
19
|
+
when "--xidl" then xidl = arg
|
20
|
+
when "--file" then file = arg
|
21
|
+
when "--help" then raise
|
22
|
+
end
|
23
|
+
end
|
24
|
+
raise if xidl.nil?
|
25
|
+
rescue
|
26
|
+
$stderr.print <<EOT
|
27
|
+
usage: xidl-conv.rb: --xidl file [--file output]
|
28
|
+
--xidl VirtualBox XIDL file
|
29
|
+
--file path to generated output
|
30
|
+
--help Show this message.
|
31
|
+
|
32
|
+
EOT
|
33
|
+
exit 0
|
34
|
+
end
|
11
35
|
|
12
|
-
|
36
|
+
|
37
|
+
XIDL = Nokogiri::XML(File.new(xidl))
|
38
|
+
LIB = XIDL.root.xpath('library')
|
39
|
+
OUT = file.nil? ? $stdout : File.open(file, 'w')
|
40
|
+
|
41
|
+
OUT << <<-EOT
|
13
42
|
#
|
14
43
|
# This file has been automatically generated from the VirtualBox.xidl
|
44
|
+
# NOTE: it is not always loaded.
|
15
45
|
#
|
16
46
|
|
17
47
|
EOT
|
18
48
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
io << "\n"
|
24
|
-
io << "module Model\n"
|
25
|
-
io << "\n"
|
49
|
+
OUT << "module VirtualBox\n"
|
50
|
+
OUT << "module COM\n"
|
51
|
+
OUT << "module Model\n"
|
52
|
+
OUT << "\n"
|
26
53
|
|
27
54
|
|
28
|
-
|
55
|
+
OUT << <<-EOT
|
29
56
|
class NSISupports < AbstractInterface
|
30
57
|
iid "00000000-0000-0000-c000-000000000046"
|
31
|
-
function :QueryInterface,
|
32
|
-
function :AddRef, nil, [],
|
33
|
-
function :Release, nil, [],
|
58
|
+
function :QueryInterface, PTR, [ PTR ], :hide => true
|
59
|
+
function :AddRef, nil, [], :hide => true
|
60
|
+
function :Release, nil, [], :hide => true
|
61
|
+
end
|
62
|
+
|
63
|
+
class NSIException < NSISupports
|
64
|
+
iid "f3a8d3b4-c424-4edc-8bf6-8974c983ba78"
|
65
|
+
property :message, WSTRING, :readonly => true
|
66
|
+
property :result, UINT32, :readonly => true
|
67
|
+
property :name, WSTRING, :readonly => true
|
68
|
+
property :filename, WSTRING, :readonly => true
|
69
|
+
property :line_number, UINT32, :readonly => true
|
70
|
+
property :column_number, UINT32, :readonly => true
|
71
|
+
property :location, PTR, :readonly => true
|
72
|
+
property :inner, :NSIException, :readonly => true
|
73
|
+
property :data, :NSISupports, :readonly => true
|
74
|
+
function :to_string, nil, [WSTRING]
|
34
75
|
end
|
35
76
|
|
36
77
|
EOT
|
37
78
|
|
38
79
|
|
39
|
-
|
40
|
-
|
80
|
+
class String
|
81
|
+
def uncamelize
|
82
|
+
VirtualBox::COM::Util.uncamelize(self)
|
83
|
+
end
|
84
|
+
|
85
|
+
def up1case
|
86
|
+
self[0].upcase + self[1..-1]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def origin_of(type)
|
91
|
+
if !LIB.xpath("interface[@name = '#{type}']").empty?
|
92
|
+
:interface
|
93
|
+
elsif !LIB.xpath("enum [@name = '#{type}']").empty?
|
94
|
+
:enum
|
95
|
+
end
|
41
96
|
end
|
42
97
|
|
43
98
|
def cnv_type(name, array=nil, ptr=nil)
|
44
|
-
return '
|
99
|
+
return 'PTR' if ptr
|
45
100
|
t = case name
|
46
101
|
when 'boolean' then 'BOOL'
|
47
102
|
when 'octet' then 'OCTET'
|
@@ -54,7 +109,13 @@ def cnv_type(name, array=nil, ptr=nil)
|
|
54
109
|
when 'uuid' then 'WSTRING'
|
55
110
|
when 'wstring' then 'WSTRING'
|
56
111
|
when '$unknown' then ':NSISupports'
|
57
|
-
|
112
|
+
when '$errorinfo' then ':NSIException'
|
113
|
+
else
|
114
|
+
case origin_of(name)
|
115
|
+
when :interface then ':' + name.gsub(/^I/, '')
|
116
|
+
when :enum then ':' + name
|
117
|
+
else raise "Unknown type #{name}"
|
118
|
+
end
|
58
119
|
end
|
59
120
|
t = '[' + t + ']' if array
|
60
121
|
t
|
@@ -63,42 +124,42 @@ end
|
|
63
124
|
|
64
125
|
# Enumeration
|
65
126
|
for enum in LIB.xpath('enum')
|
66
|
-
|
67
|
-
|
68
|
-
|
127
|
+
OUT << "class #{enum[:name]} < AbstractEnum\n"
|
128
|
+
OUT << " iid \"#{enum[:uuid]}\"\n"
|
129
|
+
OUT << " map({\n"
|
69
130
|
enum.xpath('const').each {|c|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
io << "\n"
|
131
|
+
OUT << " :%-40s => %s,\n" % [ c[:name].uncamelize, c[:value] ] }
|
132
|
+
OUT << " })\n"
|
133
|
+
OUT << "end\n"
|
134
|
+
OUT << "\n"
|
75
135
|
end
|
76
136
|
|
77
137
|
# Interface
|
78
138
|
for interface in LIB.xpath('interface')
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
when /^I/ then io << " extends :#{e[1..-1]}\n"
|
87
|
-
else raise "Unkown extension"
|
88
|
-
end
|
139
|
+
klass = case e=interface[:extends]
|
140
|
+
when 'AbstractInterface'
|
141
|
+
when '$errorinfo' then 'NSIException'
|
142
|
+
when '$unknown' then 'NSISupports'
|
143
|
+
when /^I/ then e[1..-1]
|
144
|
+
else raise "Unknown extension"
|
145
|
+
end
|
89
146
|
|
147
|
+
OUT << "class #{interface[:name][1..-1]} < #{klass}\n"
|
148
|
+
OUT << " iid \"#{interface[:uuid]}\"\n"
|
90
149
|
|
91
150
|
interface.xpath('attribute').each {|a|
|
92
|
-
name = ':' +
|
93
|
-
type = cnv_type(a[:type], a[:safearray])
|
94
|
-
opts =
|
151
|
+
name = ':' + a[:name].uncamelize
|
152
|
+
type = cnv_type(a[:type], a[:safearray], a[:mod] == 'ptr')
|
153
|
+
opts = if a[:readonly]
|
154
|
+
then [ ':readonly => true' ]
|
155
|
+
end
|
95
156
|
args = [ name, type ]
|
96
157
|
args << opts if opts && !opts.empty?
|
97
158
|
|
98
|
-
|
159
|
+
OUT << " property " << args.join(', ') << "\n"
|
99
160
|
}
|
100
161
|
interface.xpath('method').each {|m|
|
101
|
-
name = ':' +
|
162
|
+
name = ':' + m[:name].uncamelize
|
102
163
|
ret = if ret = m.xpath("param[@dir = 'return']")[0]
|
103
164
|
cnv_type(ret[:type], ret[:safearray], ret[:mod] == 'ptr')
|
104
165
|
else 'nil'
|
@@ -109,17 +170,16 @@ for interface in LIB.xpath('interface')
|
|
109
170
|
t
|
110
171
|
}.join(', ') + ']'
|
111
172
|
|
112
|
-
|
173
|
+
OUT << " function " << [name, ret, param].join(', ') << "\n"
|
113
174
|
}
|
114
175
|
|
115
|
-
|
116
|
-
|
117
|
-
io << "\n"
|
176
|
+
OUT << "end\n"
|
177
|
+
OUT << "\n"
|
118
178
|
end
|
119
179
|
|
120
180
|
|
121
|
-
|
122
|
-
|
123
|
-
|
181
|
+
OUT << "end\n"
|
182
|
+
OUT << "end\n"
|
183
|
+
OUT << "end\n"
|
124
184
|
|
125
|
-
|
185
|
+
OUT.flush
|
data/virtualbox-com.gemspec
CHANGED
@@ -5,23 +5,30 @@ require "virtualbox/com/version"
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = "virtualbox-com"
|
7
7
|
s.version = VirtualBox::COM::VERSION
|
8
|
-
s.
|
9
|
-
s.
|
10
|
-
s.email = ["stephane.dalu@gmail.com", "mitchell.hashimoto@gmail.com"]
|
8
|
+
s.authors = [ "Stephane D'Alu" ]
|
9
|
+
s.email = [ "stephane.dalu@gmail.com" ]
|
11
10
|
s.homepage = "http://github.com/sdalu/virtualbox-com"
|
12
|
-
s.summary = "Low level VirtualBox
|
13
|
-
s.description = "Low level VirtualBox
|
11
|
+
s.summary = "Low level VirtualBox binding"
|
12
|
+
s.description = "Low level VirtualBox binding using native code"
|
13
|
+
s.extensions = [ "ext/virtualbox-com/loader/extconf.rb",
|
14
|
+
"ext/virtualbox-com/4.2/extconf.rb",
|
15
|
+
"ext/virtualbox-com/4.1/extconf.rb",
|
16
|
+
]
|
14
17
|
|
15
|
-
|
16
|
-
s.rubyforge_project = "virtualbox-com"
|
17
|
-
|
18
|
-
s.add_dependency "ffi"
|
18
|
+
# s.add_dependency "ffi"
|
19
19
|
s.add_development_dependency "rake"
|
20
20
|
s.add_development_dependency "nokogiri"
|
21
|
+
|
22
|
+
s.has_rdoc = false
|
23
|
+
|
24
|
+
s.license = 'GPL-2'
|
21
25
|
|
22
26
|
|
23
|
-
s.files =
|
24
|
-
|
27
|
+
s.files = %w[ LICENSE Gemfile virtualbox-com.gemspec ] +
|
28
|
+
Dir['scripts/*.rb'] +
|
29
|
+
Dir['examples/*.rb'] +
|
30
|
+
Dir['ext/**/*.{c,h,rb,inc}'] +
|
31
|
+
Dir['lib/**/*.rb']
|
25
32
|
s.require_path = 'lib'
|
26
33
|
end
|
27
34
|
|