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.
Files changed (39) hide show
  1. data/LICENSE +339 -19
  2. data/examples/simple.rb +2 -0
  3. data/ext/virtualbox-com/4.1/extconf.rb +4 -0
  4. data/ext/virtualbox-com/4.1/generated.inc +17345 -0
  5. data/ext/virtualbox-com/4.1/vbox.c +858 -0
  6. data/ext/virtualbox-com/4.2/extconf.rb +4 -0
  7. data/ext/virtualbox-com/4.2/generated.inc +19751 -0
  8. data/ext/virtualbox-com/4.2/vbox.c +858 -0
  9. data/ext/virtualbox-com/helpers.h +62 -0
  10. data/ext/virtualbox-com/loader/extconf.rb +3 -0
  11. data/ext/virtualbox-com/loader/vbox-loader.c +187 -0
  12. data/ext/virtualbox-com/types.h +34 -0
  13. data/ext/virtualbox-com/vbox.c +858 -0
  14. data/lib/virtualbox/com.rb +4 -26
  15. data/lib/virtualbox/com/{abstract_enum.rb → abstracts.rb} +22 -18
  16. data/lib/virtualbox/com/exceptions.rb +29 -3
  17. data/lib/virtualbox/com/model/4.1-generated.rb +2141 -0
  18. data/lib/virtualbox/com/model/4.2-generated.rb +141 -432
  19. data/lib/virtualbox/com/model/4.2.rb +4 -4
  20. data/lib/virtualbox/com/util.rb +2 -1
  21. data/lib/virtualbox/com/version.rb +1 -1
  22. data/lib/virtualbox/com/xpcomc-ffi.rb +5 -19
  23. data/lib/virtualbox/com/xpcomc-ffi/abstracts.rb +103 -0
  24. data/lib/virtualbox/com/{iid.rb → xpcomc-ffi/iid.rb} +18 -0
  25. data/lib/virtualbox/com/xpcomc-ffi/lib.rb +6 -0
  26. data/lib/virtualbox/com/xpcomc-ffi/model-types.rb +1 -0
  27. data/lib/virtualbox/com/xpcomc-native.rb +8 -0
  28. data/scripts/abstracts.rb +84 -0
  29. data/scripts/sig.rb +201 -0
  30. data/scripts/spec.rb +56 -0
  31. data/scripts/to_c.rb +157 -0
  32. data/scripts/xidl-conv.rb +110 -50
  33. data/virtualbox-com.gemspec +18 -11
  34. metadata +49 -47
  35. data/.gitignore +0 -9
  36. data/README.md +0 -89
  37. data/Rakefile +0 -8
  38. data/lib/virtualbox/com/abstract_interface.rb +0 -144
  39. 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
- io = $stdout
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
- io << <<-EOT
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
- io << "module VirtualBox\n"
20
- io << "module COM\n"
21
- io << "\n"
22
- io << "MODEL_VERSION = \"4.2\"\n"
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
- io << <<-EOT
55
+ OUT << <<-EOT
29
56
  class NSISupports < AbstractInterface
30
57
  iid "00000000-0000-0000-c000-000000000046"
31
- function :QueryInterface, :pointer, [ :pointer ], :hide => true
32
- function :AddRef, nil, [], :hide => true
33
- function :Release, nil, [], :hide => true
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
- def uncamelize(string)
40
- VirtualBox::COM::Util.uncamelize(string)
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 ':pointer' if ptr
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
- else ':'+ name.gsub(/^I/, '')
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
- io << "class #{enum[:name]} < AbstractEnum\n"
67
- io << " iid \"#{enum[:uuid]}\"\n"
68
- io << " map({\n"
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
- io << " :%-40s => %s,\n" % [ uncamelize(c[:name]), c[:value] ] }
71
- io << " })\n"
72
- io << " setup\n"
73
- io << "end\n"
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
- io << "class #{interface[:name][1..-1]} < AbstractInterface\n"
80
- io << " iid \"#{interface[:uuid]}\"\n"
81
-
82
- case e=interface[:extends]
83
- when nil
84
- when '$errorinfo'
85
- when '$unknown' then io << " extends :NSISupports\n"
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 = ':' + uncamelize(a[:name])
93
- type = cnv_type(a[:type], a[:safearray])
94
- opts = [ ':readonly => true' ] if a[:readonly]
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
- io << " property " << args.join(', ') << "\n"
159
+ OUT << " property " << args.join(', ') << "\n"
99
160
  }
100
161
  interface.xpath('method').each {|m|
101
- name = ':' + uncamelize(m[: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
- io << " function " << [name, ret, param].join(', ') << "\n"
173
+ OUT << " function " << [name, ret, param].join(', ') << "\n"
113
174
  }
114
175
 
115
- io << " setup\n"
116
- io << "end\n"
117
- io << "\n"
176
+ OUT << "end\n"
177
+ OUT << "\n"
118
178
  end
119
179
 
120
180
 
121
- io << "end\n"
122
- io << "end\n"
123
- io << "end\n"
181
+ OUT << "end\n"
182
+ OUT << "end\n"
183
+ OUT << "end\n"
124
184
 
125
- io.flush
185
+ OUT.flush
@@ -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.platform = Gem::Platform::RUBY
9
- s.authors = ["Stephane D'Alu", "Mitchell Hashimoto"]
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 interraction using pure ruby"
13
- s.description = "Low level VirtualBox interraction using pure ruby"
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
- s.required_rubygems_version = ">= 1.3.6"
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 = `git ls-files`.split("\n")
24
- s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
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