ruby-dbus 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/NEWS +16 -0
- data/README +1 -1
- data/Rakefile +20 -10
- data/VERSION +1 -1
- data/lib/dbus/auth.rb +11 -5
- data/lib/dbus/bus.rb +57 -27
- data/lib/dbus/export.rb +9 -6
- data/lib/dbus/introspect.rb +24 -42
- data/lib/dbus/marshall.rb +20 -19
- data/lib/dbus/matchrule.rb +2 -1
- data/lib/dbus/message.rb +1 -1
- data/ruby-dbus.gemspec +2 -0
- data/test/binding_test.rb +1 -1
- data/test/bus_driver_test.rb +1 -1
- data/test/bus_test.rb +18 -0
- data/test/property_test.rb +1 -1
- data/test/server_robustness_test.rb +3 -3
- data/test/server_test.rb +1 -1
- data/test/service_newapi.rb +9 -1
- data/test/session_bus_test_manual.rb +1 -1
- data/test/signal_test.rb +1 -1
- data/test/t2.rb +7 -1
- data/test/t3-ticket27.rb +1 -1
- data/test/t5-report-dbus-interface.rb +1 -1
- data/test/t6-loop.rb +1 -1
- data/test/thread_safety_test.rb +35 -0
- data/test/variant_test.rb +1 -1
- metadata +15 -13
- data/doc/tutorial/index.html +0 -365
- data/examples/no-introspect/call-overloaded.rb +0 -22
    
        data/NEWS
    CHANGED
    
    | @@ -5,6 +5,22 @@ Note about bug numbers: | |
| 5 5 | 
             
             Issue#1  - http://github.com/mvidner/ruby-dbus/issues#issue/1
         | 
| 6 6 | 
             
             bnc#1    - https://bugzilla.novell.com/show_bug.cgi?id=1
         | 
| 7 7 |  | 
| 8 | 
            +
            == Ruby D-Bus 0.7.0 - 2011-07-26
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            Features:
         | 
| 11 | 
            +
             * Added ASystemBus and ASessionBus, non-singletons useful in tests
         | 
| 12 | 
            +
               and threads.
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            Bug fixes:
         | 
| 15 | 
            +
             * Fixed handling of multibyte strings (Issue#8, by Takayuki YAMAGUCHI).
         | 
| 16 | 
            +
             * Allow reopening of a dbus_interface declaration (Issue#9, by T. YAMAGUCHI).
         | 
| 17 | 
            +
             * Fixed ruby-1.9.2 compatibility again (Issue#12).
         | 
| 18 | 
            +
             * Fixed authentication on BSD (Issue#11, by Jonathan Walker)
         | 
| 19 | 
            +
             * Fixed exiting a nested event loop for synchronous calls
         | 
| 20 | 
            +
               (reported by Timo Warns).
         | 
| 21 | 
            +
             * Fixed introspection calls leaking reply handlers.
         | 
| 22 | 
            +
             * "rake test" now works, doing what was called "rake env:test"
         | 
| 23 | 
            +
             | 
| 8 24 | 
             
            == Ruby D-Bus 0.6.0 - 2010-12-11
         | 
| 9 25 |  | 
| 10 26 | 
             
            Features:
         | 
    
        data/README
    CHANGED
    
    
    
        data/Rakefile
    CHANGED
    
    | @@ -3,33 +3,32 @@ require 'rake' | |
| 3 3 | 
             
            require 'rake/gempackagetask'
         | 
| 4 4 | 
             
            require 'fileutils'
         | 
| 5 5 | 
             
            include FileUtils
         | 
| 6 | 
            +
            require 'tmpdir'
         | 
| 6 7 | 
             
            require 'rake/rdoctask'
         | 
| 7 8 | 
             
            require 'rake/testtask'
         | 
| 8 9 |  | 
| 9 10 | 
             
            desc 'Default: run tests in the proper environment'
         | 
| 10 | 
            -
            task :default =>  | 
| 11 | 
            +
            task :default => :test
         | 
| 11 12 |  | 
| 12 13 | 
             
            def common_test_task(t)
         | 
| 13 14 | 
             
                t.libs << "lib"
         | 
| 14 | 
            -
                t.test_files = FileList['test/*_test.rb', 'test/t*.rb']
         | 
| 15 | 
            +
                t.test_files = FileList['test/*_test.rb', 'test/t[0-9]*.rb']
         | 
| 15 16 | 
             
                t.verbose = true
         | 
| 16 17 | 
             
            end
         | 
| 17 | 
            -
            Rake::TestTask.new {|t| common_test_task t }
         | 
| 18 | 
            +
            Rake::TestTask.new("bare:test") {|t| common_test_task t }
         | 
| 18 19 |  | 
| 19 20 | 
             
            begin
         | 
| 20 21 | 
             
              require 'rcov/rcovtask'
         | 
| 21 | 
            -
              Rcov::RcovTask.new {|t| common_test_task t }
         | 
| 22 | 
            +
              Rcov::RcovTask.new("bare:rcov") {|t| common_test_task t }
         | 
| 22 23 | 
             
            rescue LoadError
         | 
| 23 24 | 
             
              # no rcov, never mind
         | 
| 24 25 | 
             
            end
         | 
| 25 26 |  | 
| 26 27 | 
             
            %w(test rcov).each do |tname|
         | 
| 27 | 
            -
               | 
| 28 | 
            -
             | 
| 29 | 
            -
                 | 
| 30 | 
            -
                   | 
| 31 | 
            -
                    system "./test_env rake #{tname}"
         | 
| 32 | 
            -
                  end
         | 
| 28 | 
            +
              desc "Run bare:#{tname} in the proper environment"
         | 
| 29 | 
            +
              task tname do |t|
         | 
| 30 | 
            +
                cd "test" do
         | 
| 31 | 
            +
                  system "./test_env rake bare:#{tname}"
         | 
| 33 32 | 
             
                end
         | 
| 34 33 | 
             
              end
         | 
| 35 34 | 
             
            end
         | 
| @@ -40,6 +39,17 @@ Rake::GemPackageTask.new(GEMSPEC) do |pkg| | |
| 40 39 | 
             
              # no other formats needed
         | 
| 41 40 | 
             
            end
         | 
| 42 41 |  | 
| 42 | 
            +
            desc "Build a package from a clone of the local Git repo"
         | 
| 43 | 
            +
            task :package_git do |t|
         | 
| 44 | 
            +
              Dir.mktmpdir do |temp|
         | 
| 45 | 
            +
                sh "git clone . #{temp}"
         | 
| 46 | 
            +
                cd temp do
         | 
| 47 | 
            +
                  sh "rake package"
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
                cp_r "#{temp}/pkg", "."
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
            end
         | 
| 52 | 
            +
             | 
| 43 53 | 
             
            Rake::RDocTask.new do |rd|
         | 
| 44 54 | 
             
              rd.rdoc_dir = 'doc/rdoc'
         | 
| 45 55 | 
             
              rd.rdoc_files.include("README", "lib/**/*.rb")
         | 
    
        data/VERSION
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            0. | 
| 1 | 
            +
            0.7.0
         | 
    
        data/lib/dbus/auth.rb
    CHANGED
    
    | @@ -8,6 +8,8 @@ | |
| 8 8 |  | 
| 9 9 | 
             
            $debug = $DEBUG #it's all over the state machine
         | 
| 10 10 |  | 
| 11 | 
            +
            require 'rbconfig'
         | 
| 12 | 
            +
             | 
| 11 13 | 
             
            module DBus
         | 
| 12 14 | 
             
              # Exception raised when authentication fails somehow.
         | 
| 13 15 | 
             
              class AuthenticationFailed < Exception
         | 
| @@ -62,7 +64,7 @@ module DBus | |
| 62 64 | 
             
                  # name of cookie file, id of cookie in file, servers random challenge  
         | 
| 63 65 | 
             
                  context, id, s_challenge = data.split(' ')
         | 
| 64 66 | 
             
                  # Random client challenge        
         | 
| 65 | 
            -
                  c_challenge = Array.new(s_challenge. | 
| 67 | 
            +
                  c_challenge = Array.new(s_challenge.bytesize/2).map{|obj|obj=rand(255).to_s}.join
         | 
| 66 68 | 
             
                  # Search cookie file for id
         | 
| 67 69 | 
             
                  path = File.join(ENV['HOME'], '.dbus-keyrings', context)
         | 
| 68 70 | 
             
                  puts "DEBUG: path: #{path.inspect}" if $debug
         | 
| @@ -118,7 +120,11 @@ module DBus | |
| 118 120 |  | 
| 119 121 | 
             
                # Start the authentication process.
         | 
| 120 122 | 
             
                def authenticate
         | 
| 121 | 
            -
                   | 
| 123 | 
            +
                  if (RbConfig::CONFIG["target_os"] =~ /bsd/)
         | 
| 124 | 
            +
                    @socket.sendmsg(0.chr, 0, nil, [:SOCKET, :SCM_CREDS, ""])
         | 
| 125 | 
            +
                  else
         | 
| 126 | 
            +
                    @socket.write(0.chr)
         | 
| 127 | 
            +
                  end
         | 
| 122 128 | 
             
                  next_authenticator
         | 
| 123 129 | 
             
                  @state = :Starting
         | 
| 124 130 | 
             
                  while @state != :Authenticated
         | 
| @@ -142,12 +148,12 @@ module DBus | |
| 142 148 | 
             
                # Try authentication using the next authenticator.
         | 
| 143 149 | 
             
                def next_authenticator
         | 
| 144 150 | 
             
                  begin
         | 
| 145 | 
            -
                    raise  | 
| 151 | 
            +
                    raise AuthenticationFailed if @auth_list.size == 0
         | 
| 146 152 | 
             
                    @authenticator = @auth_list.shift.new
         | 
| 147 153 | 
             
                    auth_msg = ["AUTH", @authenticator.name, @authenticator.authenticate]
         | 
| 148 154 | 
             
                    puts "DEBUG: auth_msg: #{auth_msg.inspect}" if $debug
         | 
| 149 155 | 
             
                    send(auth_msg)
         | 
| 150 | 
            -
                  rescue  | 
| 156 | 
            +
                  rescue AuthenticationFailed
         | 
| 151 157 | 
             
                    @socket.close
         | 
| 152 158 | 
             
                    raise
         | 
| 153 159 | 
             
                  end
         | 
| @@ -161,7 +167,7 @@ module DBus | |
| 161 167 | 
             
                  while left > 0
         | 
| 162 168 | 
             
                    buf = @socket.read( left > 1 ? 1 : left )
         | 
| 163 169 | 
             
                    break if buf.nil?
         | 
| 164 | 
            -
                    left -= buf. | 
| 170 | 
            +
                    left -= buf.bytesize
         | 
| 165 171 | 
             
                    data += buf
         | 
| 166 172 | 
             
                    break if data.include? crlf #crlf means line finished, the TCP socket keeps on listening, so we break 
         | 
| 167 173 | 
             
                  end
         | 
    
        data/lib/dbus/bus.rb
    CHANGED
    
    | @@ -140,6 +140,7 @@ module DBus | |
| 140 140 | 
             
                end
         | 
| 141 141 |  | 
| 142 142 | 
             
                # Return an XML string representation of the node.
         | 
| 143 | 
            +
                # It is shallow, not recursing into subnodes
         | 
| 143 144 | 
             
                def to_xml
         | 
| 144 145 | 
             
                  xml = '<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
         | 
| 145 146 | 
             
            "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
         | 
| @@ -383,33 +384,52 @@ module DBus | |
| 383 384 | 
             
            '
         | 
| 384 385 | 
             
            # This apostroph is for syntax highlighting editors confused by above xml: "
         | 
| 385 386 |  | 
| 386 | 
            -
                 | 
| 387 | 
            -
             | 
| 388 | 
            -
             | 
| 389 | 
            -
             | 
| 390 | 
            -
             | 
| 391 | 
            -
             | 
| 392 | 
            -
             | 
| 393 | 
            -
                   | 
| 394 | 
            -
             | 
| 395 | 
            -
                    send_sync( | 
| 387 | 
            +
                # Send a _message_.
         | 
| 388 | 
            +
                # If _reply_handler_ is not given, wait for the reply
         | 
| 389 | 
            +
                # and return the reply, or raise the error.
         | 
| 390 | 
            +
                # If _reply_handler_ is given, it will be called when the reply
         | 
| 391 | 
            +
                # eventually arrives, with the reply message as the 1st param
         | 
| 392 | 
            +
                # and its params following
         | 
| 393 | 
            +
                def send_sync_or_async(message, &reply_handler)
         | 
| 394 | 
            +
                  ret = nil
         | 
| 395 | 
            +
                  if reply_handler.nil?
         | 
| 396 | 
            +
                    send_sync(message) do |rmsg|
         | 
| 396 397 | 
             
                      if rmsg.is_a?(Error)
         | 
| 397 398 | 
             
                        raise rmsg
         | 
| 398 399 | 
             
                      else
         | 
| 399 | 
            -
                         | 
| 400 | 
            +
                        ret = rmsg.params
         | 
| 400 401 | 
             
                      end
         | 
| 401 402 | 
             
                    end
         | 
| 402 403 | 
             
                  else
         | 
| 403 | 
            -
                     | 
| 404 | 
            -
                    on_return(m) do |rmsg|
         | 
| 404 | 
            +
                    on_return(message) do |rmsg|
         | 
| 405 405 | 
             
                      if rmsg.is_a?(Error)
         | 
| 406 | 
            -
                         | 
| 406 | 
            +
                        reply_handler.call(rmsg)
         | 
| 407 407 | 
             
                      else
         | 
| 408 | 
            -
                         | 
| 408 | 
            +
                        reply_handler.call(rmsg, * rmsg.params)
         | 
| 409 409 | 
             
                      end
         | 
| 410 410 | 
             
                    end
         | 
| 411 | 
            +
                    send(message.marshall)
         | 
| 412 | 
            +
                  end
         | 
| 413 | 
            +
                  ret
         | 
| 414 | 
            +
                end
         | 
| 415 | 
            +
             | 
| 416 | 
            +
                def introspect_data(dest, path, &reply_handler)
         | 
| 417 | 
            +
                  m = DBus::Message.new(DBus::Message::METHOD_CALL)
         | 
| 418 | 
            +
                  m.path = path
         | 
| 419 | 
            +
                  m.interface = "org.freedesktop.DBus.Introspectable"
         | 
| 420 | 
            +
                  m.destination = dest
         | 
| 421 | 
            +
                  m.member = "Introspect"
         | 
| 422 | 
            +
                  m.sender = unique_name
         | 
| 423 | 
            +
                  if reply_handler.nil?
         | 
| 424 | 
            +
                    send_sync_or_async(m).first
         | 
| 425 | 
            +
                  else
         | 
| 426 | 
            +
                    send_sync_or_async(m) do |*args|
         | 
| 427 | 
            +
                      # TODO test async introspection, is it used at all?
         | 
| 428 | 
            +
                      args.shift            # forget the message, pass only the text
         | 
| 429 | 
            +
                      reply_handler.call(*args)
         | 
| 430 | 
            +
                      nil
         | 
| 431 | 
            +
                    end
         | 
| 411 432 | 
             
                  end
         | 
| 412 | 
            -
                  nil
         | 
| 413 433 | 
             
                end
         | 
| 414 434 |  | 
| 415 435 | 
             
                # Issues a call to the org.freedesktop.DBus.Introspectable.Introspect method
         | 
| @@ -549,9 +569,7 @@ module DBus | |
| 549 569 | 
             
                  return if retm.nil? #check if somethings wrong
         | 
| 550 570 |  | 
| 551 571 | 
             
                  process(retm)
         | 
| 552 | 
            -
                   | 
| 553 | 
            -
                      DBus::Message::METHOD_RETURN].include?(retm.message_type) and
         | 
| 554 | 
            -
                      retm.reply_serial == m.serial
         | 
| 572 | 
            +
                  while @method_call_replies.has_key? m.serial
         | 
| 555 573 | 
             
                    retm = wait_for_message
         | 
| 556 574 | 
             
                    process(retm)
         | 
| 557 575 | 
             
                  end
         | 
| @@ -695,10 +713,10 @@ module DBus | |
| 695 713 | 
             
              # = D-Bus session bus class
         | 
| 696 714 | 
             
              #
         | 
| 697 715 | 
             
              # The session bus is a session specific bus (mostly for desktop use).
         | 
| 698 | 
            -
              # | 
| 699 | 
            -
               | 
| 700 | 
            -
             | 
| 701 | 
            -
             | 
| 716 | 
            +
              #
         | 
| 717 | 
            +
              # Use SessionBus, the non-singleton ASessionBus is
         | 
| 718 | 
            +
              # for the test suite.
         | 
| 719 | 
            +
              class ASessionBus < Connection
         | 
| 702 720 | 
             
                # Get the the default session bus.
         | 
| 703 721 | 
             
                def initialize
         | 
| 704 722 | 
             
                  super(ENV["DBUS_SESSION_BUS_ADDRESS"] || address_from_file)
         | 
| @@ -719,13 +737,20 @@ module DBus | |
| 719 737 | 
             
                end
         | 
| 720 738 | 
             
              end
         | 
| 721 739 |  | 
| 740 | 
            +
              # See ASessionBus
         | 
| 741 | 
            +
              class SessionBus < ASessionBus
         | 
| 742 | 
            +
                include Singleton
         | 
| 743 | 
            +
              end
         | 
| 744 | 
            +
             | 
| 745 | 
            +
             | 
| 722 746 | 
             
              # = D-Bus system bus class
         | 
| 723 747 | 
             
              #
         | 
| 724 748 | 
             
              # The system bus is a system-wide bus mostly used for global or
         | 
| 725 | 
            -
              # system usages. | 
| 726 | 
            -
               | 
| 727 | 
            -
             | 
| 728 | 
            -
             | 
| 749 | 
            +
              # system usages.
         | 
| 750 | 
            +
              #
         | 
| 751 | 
            +
              # Use SystemBus, the non-singleton ASystemBus is
         | 
| 752 | 
            +
              # for the test suite.
         | 
| 753 | 
            +
              class ASystemBus < Connection
         | 
| 729 754 | 
             
                # Get the default system bus.
         | 
| 730 755 | 
             
                def initialize
         | 
| 731 756 | 
             
                  super(SystemSocketName)
         | 
| @@ -755,6 +780,11 @@ module DBus | |
| 755 780 | 
             
                end
         | 
| 756 781 | 
             
              end
         | 
| 757 782 |  | 
| 783 | 
            +
              # See ASystemBus
         | 
| 784 | 
            +
              class SystemBus < ASystemBus
         | 
| 785 | 
            +
                include Singleton
         | 
| 786 | 
            +
              end
         | 
| 787 | 
            +
             | 
| 758 788 | 
             
              # Shortcut for the SystemBus instance
         | 
| 759 789 | 
             
              def DBus.system_bus
         | 
| 760 790 | 
             
                SystemBus.instance
         | 
    
        data/lib/dbus/export.rb
    CHANGED
    
    | @@ -15,19 +15,20 @@ module DBus | |
| 15 15 | 
             
              # = Exportable D-Bus object class
         | 
| 16 16 | 
             
              #
         | 
| 17 17 | 
             
              # Objects that are going to be exported by a D-Bus service
         | 
| 18 | 
            -
              # should inherit from this class.
         | 
| 18 | 
            +
              # should inherit from this class. At the client side, use ProxyObject.
         | 
| 19 19 | 
             
              class Object
         | 
| 20 20 | 
             
                # The path of the object.
         | 
| 21 21 | 
             
                attr_reader :path
         | 
| 22 | 
            -
                # The interfaces that the object supports.
         | 
| 22 | 
            +
                # The interfaces that the object supports. Hash: String => Interface
         | 
| 23 23 | 
             
                class_attribute :intfs
         | 
| 24 24 | 
             
                # The service that the object is exported by.
         | 
| 25 25 | 
             
                attr_writer :service
         | 
| 26 26 |  | 
| 27 | 
            -
                @@cur_intf = nil
         | 
| 27 | 
            +
                @@cur_intf = nil            # Interface
         | 
| 28 28 | 
             
                @@intfs_mutex = Mutex.new
         | 
| 29 29 |  | 
| 30 30 | 
             
                # Create a new object with a given _path_.
         | 
| 31 | 
            +
                # Use Service#export to export it.
         | 
| 31 32 | 
             
                def initialize(path)
         | 
| 32 33 | 
             
                  @path = path
         | 
| 33 34 | 
             
                  @service = nil
         | 
| @@ -39,7 +40,7 @@ module DBus | |
| 39 40 | 
             
                  self.intfs = (self.intfs || {}).merge({intf.name => intf})
         | 
| 40 41 | 
             
                end
         | 
| 41 42 |  | 
| 42 | 
            -
                # Dispatch a message _msg_ | 
| 43 | 
            +
                # Dispatch a message _msg_ to call exported methods
         | 
| 43 44 | 
             
                def dispatch(msg)
         | 
| 44 45 | 
             
                  case msg.message_type
         | 
| 45 46 | 
             
                  when Message::METHOD_CALL
         | 
| @@ -73,8 +74,10 @@ module DBus | |
| 73 74 | 
             
                # belong to.
         | 
| 74 75 | 
             
                def self.dbus_interface(s)
         | 
| 75 76 | 
             
                  @@intfs_mutex.synchronize do
         | 
| 76 | 
            -
                    @@cur_intf =  | 
| 77 | 
            -
             | 
| 77 | 
            +
                    unless @@cur_intf = (self.intfs && self.intfs[s])
         | 
| 78 | 
            +
                      @@cur_intf = Interface.new(s)
         | 
| 79 | 
            +
                      self.intfs = (self.intfs || {}).merge({s => @@cur_intf})
         | 
| 80 | 
            +
                    end
         | 
| 78 81 | 
             
                    yield
         | 
| 79 82 | 
             
                    @@cur_intf = nil
         | 
| 80 83 | 
             
                  end
         | 
    
        data/lib/dbus/introspect.rb
    CHANGED
    
    | @@ -8,6 +8,7 @@ | |
| 8 8 | 
             
            # License, version 2.1 as published by the Free Software Foundation.
         | 
| 9 9 | 
             
            # See the file "COPYING" for the exact licensing terms.
         | 
| 10 10 |  | 
| 11 | 
            +
            # TODO check if it is slow, make replaceable
         | 
| 11 12 | 
             
            require 'rexml/document'
         | 
| 12 13 |  | 
| 13 14 | 
             
            module DBus
         | 
| @@ -27,15 +28,16 @@ module DBus | |
| 27 28 | 
             
              # = D-Bus interface class
         | 
| 28 29 | 
             
              #
         | 
| 29 30 | 
             
              # This class is the interface descriptor.  In most cases, the Introspect()
         | 
| 30 | 
            -
              # method call  | 
| 31 | 
            +
              # method call instantiates and configures this class for us.
         | 
| 31 32 | 
             
              #
         | 
| 32 33 | 
             
              # It also is the local definition of interface exported by the program.
         | 
| 34 | 
            +
              # At the client side, see ProxyObjectInterface
         | 
| 33 35 | 
             
              class Interface
         | 
| 34 | 
            -
                # The name of the interface.
         | 
| 36 | 
            +
                # The name of the interface. String
         | 
| 35 37 | 
             
                attr_reader :name
         | 
| 36 | 
            -
                # The methods that are part of the interface.
         | 
| 38 | 
            +
                # The methods that are part of the interface. Hash: Symbol => DBus::Method
         | 
| 37 39 | 
             
                attr_reader :methods
         | 
| 38 | 
            -
                # The signals that are part of the interface.
         | 
| 40 | 
            +
                # The signals that are part of the interface. Hash: Symbol => Signal
         | 
| 39 41 | 
             
                attr_reader :signals
         | 
| 40 42 |  | 
| 41 43 | 
             
                # Creates a new interface with a given _name_.
         | 
| @@ -47,7 +49,7 @@ module DBus | |
| 47 49 |  | 
| 48 50 | 
             
                # Validates a service _name_.
         | 
| 49 51 | 
             
                def validate_name(name)
         | 
| 50 | 
            -
                  raise InvalidIntrospectionData if name. | 
| 52 | 
            +
                  raise InvalidIntrospectionData if name.bytesize > 255
         | 
| 51 53 | 
             
                  raise InvalidIntrospectionData if name =~ /^\./ or name =~ /\.$/
         | 
| 52 54 | 
             
                  raise InvalidIntrospectionData if name =~ /\.\./
         | 
| 53 55 | 
             
                  raise InvalidIntrospectionData if not name =~ /\./
         | 
| @@ -100,14 +102,14 @@ module DBus | |
| 100 102 | 
             
              # This is a generic class for entities that are part of the interface
         | 
| 101 103 | 
             
              # such as methods and signals.
         | 
| 102 104 | 
             
              class InterfaceElement
         | 
| 103 | 
            -
                # The name of the interface element.
         | 
| 105 | 
            +
                # The name of the interface element. Symbol
         | 
| 104 106 | 
             
                attr_reader :name
         | 
| 105 | 
            -
                # The parameters of the interface element
         | 
| 107 | 
            +
                # The parameters of the interface element. Array: FormalParameter
         | 
| 106 108 | 
             
                attr_reader :params
         | 
| 107 109 |  | 
| 108 110 | 
             
                # Validates element _name_.
         | 
| 109 111 | 
             
                def validate_name(name)
         | 
| 110 | 
            -
                  if (not name =~ MethodSignalRE) or (name. | 
| 112 | 
            +
                  if (not name =~ MethodSignalRE) or (name.bytesize > 255)
         | 
| 111 113 | 
             
                    raise InvalidMethodName, name
         | 
| 112 114 | 
             
                  end
         | 
| 113 115 | 
             
                end
         | 
| @@ -135,7 +137,7 @@ module DBus | |
| 135 137 | 
             
              #
         | 
| 136 138 | 
             
              # This is a class representing methods that are part of an interface.
         | 
| 137 139 | 
             
              class Method < InterfaceElement
         | 
| 138 | 
            -
                # The list of return values for the method.
         | 
| 140 | 
            +
                # The list of return values for the method. Array: FormalParameter
         | 
| 139 141 | 
             
                attr_reader :rets
         | 
| 140 142 |  | 
| 141 143 | 
             
                # Creates a new method interface element with the given _name_.
         | 
| @@ -227,10 +229,9 @@ module DBus | |
| 227 229 | 
             
                  @xml = xml
         | 
| 228 230 | 
             
                end
         | 
| 229 231 |  | 
| 230 | 
            -
                #  | 
| 232 | 
            +
                # return the names of direct subnodes
         | 
| 231 233 | 
             
                def parse_subnodes
         | 
| 232 234 | 
             
                  subnodes = Array.new
         | 
| 233 | 
            -
                  t = Time.now
         | 
| 234 235 | 
             
                  d = REXML::Document.new(@xml)
         | 
| 235 236 | 
             
                  d.elements.each("node/node") do |e|
         | 
| 236 237 | 
             
                    subnodes << e.attributes["name"]
         | 
| @@ -238,9 +239,9 @@ module DBus | |
| 238 239 | 
             
                  subnodes
         | 
| 239 240 | 
             
                end
         | 
| 240 241 |  | 
| 241 | 
            -
                #  | 
| 242 | 
            +
                # return a pair: [list of Interfaces, list of direct subnode names]
         | 
| 242 243 | 
             
                def parse
         | 
| 243 | 
            -
                   | 
| 244 | 
            +
                  interfaces = Array.new
         | 
| 244 245 | 
             
                  subnodes = Array.new
         | 
| 245 246 | 
             
                  t = Time.now
         | 
| 246 247 | 
             
                  d = REXML::Document.new(@xml)
         | 
| @@ -259,13 +260,13 @@ module DBus | |
| 259 260 | 
             
                      parse_methsig(se, s)
         | 
| 260 261 | 
             
                      i << s
         | 
| 261 262 | 
             
                    end
         | 
| 262 | 
            -
                     | 
| 263 | 
            +
                    interfaces << i
         | 
| 263 264 | 
             
                  end
         | 
| 264 265 | 
             
                  d = Time.now - t
         | 
| 265 266 | 
             
                  if d > 2
         | 
| 266 267 | 
             
                    puts "Some XML took more that two secs to parse. Optimize me!" if $DEBUG
         | 
| 267 268 | 
             
                  end
         | 
| 268 | 
            -
                  [ | 
| 269 | 
            +
                  [interfaces, subnodes]
         | 
| 269 270 | 
             
                end
         | 
| 270 271 |  | 
| 271 272 | 
             
                ######################################################################
         | 
| @@ -342,7 +343,7 @@ module DBus | |
| 342 343 | 
             
                  methdef = "def #{m.name}("
         | 
| 343 344 | 
             
                  methdef += (0..(m.params.size - 1)).to_a.collect { |n|
         | 
| 344 345 | 
             
                    "arg#{n}"
         | 
| 345 | 
            -
                  }.join(", ")
         | 
| 346 | 
            +
                  }.push("&reply_handler").join(", ")
         | 
| 346 347 | 
             
                  methdef += %{)
         | 
| 347 348 | 
             
                          msg = Message.new(Message::METHOD_CALL)
         | 
| 348 349 | 
             
                          msg.path = @object.path
         | 
| @@ -365,26 +366,7 @@ module DBus | |
| 365 366 | 
             
                    idx += 1
         | 
| 366 367 | 
             
                  end
         | 
| 367 368 | 
             
                  methdef += "
         | 
| 368 | 
            -
                     | 
| 369 | 
            -
                    if block_given?
         | 
| 370 | 
            -
                      @object.bus.on_return(msg) do |rmsg|
         | 
| 371 | 
            -
                        if rmsg.is_a?(Error)
         | 
| 372 | 
            -
                          yield(rmsg)
         | 
| 373 | 
            -
                        else
         | 
| 374 | 
            -
                          yield(rmsg, *rmsg.params)
         | 
| 375 | 
            -
                        end
         | 
| 376 | 
            -
                      end
         | 
| 377 | 
            -
                      @object.bus.send(msg.marshall)
         | 
| 378 | 
            -
                    else
         | 
| 379 | 
            -
                      @object.bus.send_sync(msg) do |rmsg|
         | 
| 380 | 
            -
                        if rmsg.is_a?(Error)
         | 
| 381 | 
            -
                          raise rmsg
         | 
| 382 | 
            -
                        else
         | 
| 383 | 
            -
                          ret = rmsg.params
         | 
| 384 | 
            -
                        end
         | 
| 385 | 
            -
                      end
         | 
| 386 | 
            -
                    end
         | 
| 387 | 
            -
                    ret
         | 
| 369 | 
            +
                    @object.bus.send_sync_or_async(msg, &reply_handler)
         | 
| 388 370 | 
             
                  end
         | 
| 389 371 | 
             
                  "
         | 
| 390 372 | 
             
                  singleton_class.class_eval(methdef)
         | 
| @@ -448,7 +430,7 @@ module DBus | |
| 448 430 | 
             
              # over the bus so that the method is executed remotely on the correctponding
         | 
| 449 431 | 
             
              # object.
         | 
| 450 432 | 
             
              class ProxyObject
         | 
| 451 | 
            -
                # The subnodes of the object in the tree.
         | 
| 433 | 
            +
                # The names of direct subnodes of the object in the tree.
         | 
| 452 434 | 
             
                attr_accessor :subnodes
         | 
| 453 435 | 
             
                # Flag determining whether the object has been introspected.
         | 
| 454 436 | 
             
                attr_accessor :introspected
         | 
| @@ -458,7 +440,7 @@ module DBus | |
| 458 440 | 
             
                attr_reader :path
         | 
| 459 441 | 
             
                # The bus the object is reachable via.
         | 
| 460 442 | 
             
                attr_reader :bus
         | 
| 461 | 
            -
                # The default interface of the object.
         | 
| 443 | 
            +
                # The default interface of the object, as String.
         | 
| 462 444 | 
             
                attr_accessor :default_iface
         | 
| 463 445 |  | 
| 464 446 | 
             
                # Creates a new proxy object living on the given _bus_ at destination _dest_
         | 
| @@ -495,11 +477,12 @@ module DBus | |
| 495 477 |  | 
| 496 478 | 
             
                # Returns whether the object has an interface with the given _name_.
         | 
| 497 479 | 
             
                def has_iface?(name)
         | 
| 498 | 
            -
                  raise "Cannot call has_iface?  | 
| 480 | 
            +
                  raise "Cannot call has_iface? if not introspected" if not @introspected
         | 
| 499 481 | 
             
                  @interfaces.member?(name)
         | 
| 500 482 | 
             
                end
         | 
| 501 483 |  | 
| 502 484 | 
             
                # Registers a handler, the code block, for a signal with the given _name_.
         | 
| 485 | 
            +
                # It uses _default_iface_ which must have been set.
         | 
| 503 486 | 
             
                def on_signal(name, &block)
         | 
| 504 487 | 
             
                  if @default_iface and has_iface?(@default_iface)
         | 
| 505 488 | 
             
                    @interfaces[@default_iface].on_signal(@bus, name, &block)
         | 
| @@ -521,10 +504,9 @@ module DBus | |
| 521 504 | 
             
                    rescue NameError => e
         | 
| 522 505 | 
             
                      # interesting, foo.method("unknown")
         | 
| 523 506 | 
             
                      # raises NameError, not NoMethodError
         | 
| 524 | 
            -
                       | 
| 525 | 
            -
                      raise unless match and match[2] == "DBus::ProxyObjectInterface"
         | 
| 507 | 
            +
                      raise unless e.to_s =~ /undefined method `#{name}'/
         | 
| 526 508 | 
             
                      # BTW e.exception("...") would preserve the class.
         | 
| 527 | 
            -
                      raise NoMethodError,"undefined method `#{ | 
| 509 | 
            +
                      raise NoMethodError,"undefined method `#{name}' for DBus interface `#{@default_iface}' on object `#{@path}'"
         | 
| 528 510 | 
             
                    end
         | 
| 529 511 | 
             
                  else
         | 
| 530 512 | 
             
                    # TODO distinguish:
         |