Skip to content

Commit

Permalink
Fix issue mvidner#45
Browse files Browse the repository at this point in the history
  • Loading branch information
Damiano Stoffie committed Sep 12, 2013
1 parent 85a2df4 commit 3e8a858
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 4 deletions.
14 changes: 14 additions & 0 deletions Gemfile.ci.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
GEM
remote: http://rubygems.org/
specs:
mini_portile (0.5.1)
nokogiri (1.6.0)
mini_portile (~> 0.5.0)
rake (10.1.0)

PLATFORMS
ruby

DEPENDENCIES
nokogiri
rake
36 changes: 32 additions & 4 deletions lib/dbus/export.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class Object
# intfs: Hash: String => Interface
# @@intfs_hash simulates a class attribute by being a hash Class => intfs
@@intfs_hash = {DBus::Object => nil}
# The methods object exports
@@methods_hash = {DBus::Object => {}}
# The service that the object is exported by.
attr_writer :service

Expand Down Expand Up @@ -56,6 +58,18 @@ def intfs= param
self.class.intfs = param
end

def self.exported_methods
if self.equal? DBus::Object
@@methods_hash[DBus::Object]
else
(@@methods_hash[self] || {}).merge(self.superclass.exported_methods)
end
end

def exported_methods
self.class.exported_methods
end

# State that the object implements the given _intf_.
def implements(intf)
# use a setter
Expand All @@ -68,16 +82,28 @@ def dispatch(msg)
when Message::METHOD_CALL
reply = nil
begin
if not self.intfs[msg.interface]
if msg.interface and (not self.intfs[msg.interface])
raise DBus.error("org.freedesktop.DBus.Error.UnknownMethod"),
"Interface \"#{msg.interface}\" of object \"#{msg.path}\" doesn't exist"
end
meth = self.intfs[msg.interface].methods[msg.member.to_sym]

interface = if msg.interface
msg.interface
else
exported_methods[msg.member.to_sym]
end
unless interface
raise DBus.error("org.freedesktop.DBus.Error.UnknownMethod"),
"Method \"#{msg.member}\" of object \"#{msg.path}\" not found on any interface"
end

self.intfs[interface].methods[msg.member.to_sym]
meth = self.intfs[interface].methods[msg.member.to_sym]
if not meth
raise DBus.error("org.freedesktop.DBus.Error.UnknownMethod"),
"Method \"#{msg.member}\" on interface \"#{msg.interface}\" of object \"#{msg.path}\" doesn't exist"
end
methname = Object.make_method_name(msg.interface, msg.member)
methname = Object.make_method_name(interface, msg.member)
retdata = method(methname).call(*msg.params)
retdata = [*retdata]

Expand Down Expand Up @@ -117,7 +143,9 @@ def initialize(sym)
def self.dbus_method(sym, protoype = "", &block)
raise UndefinedInterface, sym if @@cur_intf.nil?
@@cur_intf.define(Method.new(sym.to_s).from_prototype(protoype))
define_method(Object.make_method_name(@@cur_intf.name, sym.to_s), &block)
define_method(Object.make_method_name(@@cur_intf.name, sym.to_s), &block)
# register the method in a method list
(@@methods_hash[self] ||= {})[sym] = @@cur_intf.name
end

# Emits a signal from the object with the given _interface_, signal
Expand Down
15 changes: 15 additions & 0 deletions test/binding_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,19 @@ def test_generic_dbus_error
assert_equal "org.freedesktop.DBus.Error.Failed", e.name
assert_equal "failed as designed", e.message
end

def test_qdbus
# introspection
`qdbus --address $DBUS_SESSION_BUS_ADDRESS org.ruby.service /org/ruby/MyInstance`
assert_equal $?.exitstatus, 0
# method call
`qdbus --address $DBUS_SESSION_BUS_ADDRESS org.ruby.service /org/ruby/MyInstance org.ruby.AnotherInterface.Reverse "yao" `
assert_equal $?.exitstatus, 0
# method call with no interface
`qdbus --address $DBUS_SESSION_BUS_ADDRESS org.ruby.service /org/ruby/MyInstance Reverse "yao" `
assert_equal $?.exitstatus, 0
# method call over a inherited method
`qdbus --address $DBUS_SESSION_BUS_ADDRESS org.ruby.service /org/ruby/MyDerivedInstance Reverse "yao" `
assert_equal $?.exitstatus, 0
end
end

0 comments on commit 3e8a858

Please sign in to comment.