ruby-dbus 0.12.0 → 0.13.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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/NEWS.md +344 -0
  3. data/Rakefile +21 -15
  4. data/VERSION +1 -1
  5. data/doc/Reference.md +26 -37
  6. data/examples/doc/_extract_examples +4 -4
  7. data/examples/gdbus/gdbus +40 -39
  8. data/examples/no-introspect/nm-test.rb +1 -3
  9. data/examples/no-introspect/tracker-test.rb +2 -4
  10. data/examples/rhythmbox/playpause.rb +1 -2
  11. data/examples/service/call_service.rb +0 -3
  12. data/examples/service/service_newapi.rb +3 -4
  13. data/examples/simple/call_introspect.rb +0 -3
  14. data/examples/simple/get_id.rb +1 -3
  15. data/examples/simple/properties.rb +3 -4
  16. data/examples/utils/listnames.rb +6 -7
  17. data/examples/utils/notify.rb +3 -5
  18. data/lib/dbus.rb +8 -20
  19. data/lib/dbus/auth.rb +59 -61
  20. data/lib/dbus/bus.rb +86 -97
  21. data/lib/dbus/error.rb +1 -1
  22. data/lib/dbus/export.rb +20 -18
  23. data/lib/dbus/introspect.rb +26 -28
  24. data/lib/dbus/logger.rb +1 -1
  25. data/lib/dbus/marshall.rb +72 -74
  26. data/lib/dbus/matchrule.rb +22 -26
  27. data/lib/dbus/message.rb +24 -33
  28. data/lib/dbus/message_queue.rb +30 -30
  29. data/lib/dbus/proxy_object.rb +34 -30
  30. data/lib/dbus/proxy_object_factory.rb +5 -2
  31. data/lib/dbus/proxy_object_interface.rb +10 -8
  32. data/lib/dbus/type.rb +154 -156
  33. data/lib/dbus/xml.rb +22 -16
  34. data/ruby-dbus.gemspec +15 -3
  35. data/spec/async_spec.rb +2 -4
  36. data/spec/binding_spec.rb +1 -5
  37. data/spec/bus_and_xml_backend_spec.rb +6 -9
  38. data/spec/bus_spec.rb +1 -1
  39. data/spec/byte_array_spec.rb +0 -2
  40. data/spec/err_msg_spec.rb +13 -10
  41. data/spec/introspect_xml_parser_spec.rb +2 -2
  42. data/spec/introspection_spec.rb +1 -1
  43. data/spec/main_loop_spec.rb +4 -5
  44. data/spec/property_spec.rb +0 -3
  45. data/spec/proxy_object_spec.rb +42 -0
  46. data/spec/server_robustness_spec.rb +0 -2
  47. data/spec/service_newapi.rb +51 -41
  48. data/spec/session_bus_spec.rb +6 -7
  49. data/spec/signal_spec.rb +2 -3
  50. data/spec/spec_helper.rb +28 -24
  51. data/spec/thread_safety_spec.rb +1 -2
  52. data/spec/type_spec.rb +2 -2
  53. data/spec/value_spec.rb +7 -10
  54. data/spec/variant_spec.rb +15 -16
  55. metadata +60 -3
  56. data/NEWS +0 -279
@@ -15,13 +15,16 @@ module DBus
15
15
  # Creates a new proxy object factory for the given introspection XML _xml_,
16
16
  # _bus_, destination _dest_, and _path_.
17
17
  def initialize(xml, bus, dest, path, api: ApiOptions::CURRENT)
18
- @xml, @bus, @path, @dest = xml, bus, path, dest
18
+ @xml = xml
19
+ @bus = bus
20
+ @path = path
21
+ @dest = dest
19
22
  @api = api
20
23
  end
21
24
 
22
25
  # Investigates the sub-nodes of the proxy object _po_ based on the
23
26
  # introspection XML data _xml_ and sets them up recursively.
24
- def ProxyObjectFactory.introspect_into(po, xml)
27
+ def self.introspect_into(po, xml)
25
28
  intfs, po.subnodes = IntrospectXMLParser.new(xml).parse
26
29
  intfs.each do |i|
27
30
  poi = ProxyObjectInterface.new(po, i.name)
@@ -25,8 +25,10 @@ module DBus
25
25
  # Creates a new proxy interface for the given proxy _object_
26
26
  # and the given _name_.
27
27
  def initialize(object, name)
28
- @object, @name = object, name
29
- @methods, @signals = Hash.new, Hash.new
28
+ @object = object
29
+ @name = name
30
+ @methods = {}
31
+ @signals = {}
30
32
  end
31
33
 
32
34
  # Returns the string representation of the interface (the name).
@@ -77,9 +79,9 @@ module DBus
77
79
 
78
80
  # Defines a signal or method based on the descriptor _m_.
79
81
  def define(m)
80
- if m.kind_of?(Method)
82
+ if m.is_a?(Method)
81
83
  define_method_from_descriptor(m)
82
- elsif m.kind_of?(Signal)
84
+ elsif m.is_a?(Signal)
83
85
  define_signal_from_descriptor(m)
84
86
  end
85
87
  end
@@ -107,12 +109,12 @@ module DBus
107
109
  end
108
110
  end
109
111
 
110
- PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties"
112
+ PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties".freeze
111
113
 
112
114
  # Read a property.
113
115
  # @param propname [String]
114
116
  def [](propname)
115
- ret = self.object[PROPERTY_INTERFACE].Get(self.name, propname)
117
+ ret = object[PROPERTY_INTERFACE].Get(name, propname)
116
118
  # this method always returns the single property
117
119
  if @object.api.proxy_method_returns_array
118
120
  ret[0]
@@ -125,13 +127,13 @@ module DBus
125
127
  # @param propname [String]
126
128
  # @param value [Object]
127
129
  def []=(propname, value)
128
- self.object[PROPERTY_INTERFACE].Set(self.name, propname, value)
130
+ object[PROPERTY_INTERFACE].Set(name, propname, value)
129
131
  end
130
132
 
131
133
  # Read all properties at once, as a hash.
132
134
  # @return [Hash{String}]
133
135
  def all_properties
134
- ret = self.object[PROPERTY_INTERFACE].GetAll(self.name)
136
+ ret = object[PROPERTY_INTERFACE].GetAll(name)
135
137
  # this method always returns the single property
136
138
  if @object.api.proxy_method_returns_array
137
139
  ret[0]
@@ -9,185 +9,183 @@
9
9
  # See the file "COPYING" for the exact licensing terms.
10
10
 
11
11
  module DBus
12
-
13
- # = D-Bus type module
14
- #
15
- # This module containts the constants of the types specified in the D-Bus
16
- # protocol.
17
- module Type
18
- # Mapping from type number to name and alignment.
19
- TypeMapping = {
20
- 0 => ["INVALID", nil],
21
- ?y => ["BYTE", 1],
22
- ?b => ["BOOLEAN", 4],
23
- ?n => ["INT16", 2],
24
- ?q => ["UINT16", 2],
25
- ?i => ["INT32", 4],
26
- ?u => ["UINT32", 4],
27
- ?x => ["INT64", 8],
28
- ?t => ["UINT64", 8],
29
- ?d => ["DOUBLE", 8],
30
- ?r => ["STRUCT", 8],
31
- ?a => ["ARRAY", 4],
32
- ?v => ["VARIANT", 1],
33
- ?o => ["OBJECT_PATH", 4],
34
- ?s => ["STRING", 4],
35
- ?g => ["SIGNATURE", 1],
36
- ?e => ["DICT_ENTRY", 8],
37
- ?h => ["UNIX_FD", 4],
38
- }
39
- # Defines the set of constants
40
- TypeMapping.each_pair do |key, value|
41
- Type.const_set(value.first, key)
42
- end
43
-
44
- # Exception raised when an unknown/incorrect type is encountered.
45
- class SignatureException < Exception
46
- end
47
-
48
- # = D-Bus type conversion class
12
+ # = D-Bus type module
49
13
  #
50
- # Helper class for representing a D-Bus type.
51
- class Type
52
- # Returns the signature type number.
53
- attr_reader :sigtype
54
- # Return contained member types.
55
- attr_reader :members
56
-
57
- # Create a new type instance for type number _sigtype_.
58
- def initialize(sigtype)
59
- if not TypeMapping.keys.member?(sigtype)
60
- raise SignatureException, "Unknown key in signature: #{sigtype.chr}"
61
- end
62
- @sigtype = sigtype
63
- @members = Array.new
14
+ # This module containts the constants of the types specified in the D-Bus
15
+ # protocol.
16
+ module Type
17
+ # Mapping from type number to name and alignment.
18
+ TypeMapping = {
19
+ 0 => ["INVALID", nil],
20
+ "y" => ["BYTE", 1],
21
+ "b" => ["BOOLEAN", 4],
22
+ "n" => ["INT16", 2],
23
+ "q" => ["UINT16", 2],
24
+ "i" => ["INT32", 4],
25
+ "u" => ["UINT32", 4],
26
+ "x" => ["INT64", 8],
27
+ "t" => ["UINT64", 8],
28
+ "d" => ["DOUBLE", 8],
29
+ "r" => ["STRUCT", 8],
30
+ "a" => ["ARRAY", 4],
31
+ "v" => ["VARIANT", 1],
32
+ "o" => ["OBJECT_PATH", 4],
33
+ "s" => ["STRING", 4],
34
+ "g" => ["SIGNATURE", 1],
35
+ "e" => ["DICT_ENTRY", 8],
36
+ "h" => ["UNIX_FD", 4]
37
+ }.freeze
38
+ # Defines the set of constants
39
+ TypeMapping.each_pair do |key, value|
40
+ Type.const_set(value.first, key)
64
41
  end
65
42
 
66
- # Return the required alignment for the type.
67
- def alignment
68
- TypeMapping[@sigtype].last
43
+ # Exception raised when an unknown/incorrect type is encountered.
44
+ class SignatureException < Exception
69
45
  end
70
46
 
71
- # Return a string representation of the type according to the
72
- # D-Bus specification.
73
- def to_s
74
- case @sigtype
75
- when STRUCT
76
- "(" + @members.collect { |t| t.to_s }.join + ")"
77
- when ARRAY
78
- "a" + child.to_s
79
- when DICT_ENTRY
80
- "{" + @members.collect { |t| t.to_s }.join + "}"
81
- else
82
- if not TypeMapping.keys.member?(@sigtype)
83
- raise NotImplementedError
47
+ # = D-Bus type conversion class
48
+ #
49
+ # Helper class for representing a D-Bus type.
50
+ class Type
51
+ # Returns the signature type number.
52
+ attr_reader :sigtype
53
+ # Return contained member types.
54
+ attr_reader :members
55
+
56
+ # Create a new type instance for type number _sigtype_.
57
+ def initialize(sigtype)
58
+ if !TypeMapping.keys.member?(sigtype)
59
+ raise SignatureException, "Unknown key in signature: #{sigtype.chr}"
84
60
  end
85
- @sigtype.chr
61
+ @sigtype = sigtype
62
+ @members = []
86
63
  end
87
- end
88
64
 
89
- # Add a new member type _a_.
90
- def <<(a)
91
- if not [STRUCT, ARRAY, DICT_ENTRY].member?(@sigtype)
92
- raise SignatureException
65
+ # Return the required alignment for the type.
66
+ def alignment
67
+ TypeMapping[@sigtype].last
93
68
  end
94
- raise SignatureException if @sigtype == ARRAY and @members.size > 0
95
- if @sigtype == DICT_ENTRY
96
- if @members.size == 2
97
- raise SignatureException, "Dict entries have exactly two members"
98
- end
99
- if @members.size == 0
100
- if [STRUCT, ARRAY, DICT_ENTRY].member?(a.sigtype)
101
- raise SignatureException, "Dict entry keys must be basic types"
69
+
70
+ # Return a string representation of the type according to the
71
+ # D-Bus specification.
72
+ def to_s
73
+ case @sigtype
74
+ when STRUCT
75
+ "(" + @members.collect(&:to_s).join + ")"
76
+ when ARRAY
77
+ "a" + child.to_s
78
+ when DICT_ENTRY
79
+ "{" + @members.collect(&:to_s).join + "}"
80
+ else
81
+ if !TypeMapping.keys.member?(@sigtype)
82
+ raise NotImplementedError
102
83
  end
84
+ @sigtype.chr
103
85
  end
104
86
  end
105
- @members << a
106
- end
107
87
 
108
- # Return the first contained member type.
109
- def child
110
- @members[0]
111
- end
88
+ # Add a new member type _a_.
89
+ def <<(a)
90
+ if ![STRUCT, ARRAY, DICT_ENTRY].member?(@sigtype)
91
+ raise SignatureException
92
+ end
93
+ raise SignatureException if @sigtype == ARRAY && !@members.empty?
94
+ if @sigtype == DICT_ENTRY
95
+ if @members.size == 2
96
+ raise SignatureException, "Dict entries have exactly two members"
97
+ end
98
+ if @members.empty?
99
+ if [STRUCT, ARRAY, DICT_ENTRY].member?(a.sigtype)
100
+ raise SignatureException, "Dict entry keys must be basic types"
101
+ end
102
+ end
103
+ end
104
+ @members << a
105
+ end
112
106
 
113
- def inspect
114
- s = TypeMapping[@sigtype].first
115
- if [STRUCT, ARRAY].member?(@sigtype)
116
- s += ": " + @members.inspect
107
+ # Return the first contained member type.
108
+ def child
109
+ @members[0]
117
110
  end
118
- s
119
- end
120
- end # class Type
121
111
 
122
- # = D-Bus type parser class
123
- #
124
- # Helper class to parse a type signature in the protocol.
125
- class Parser
126
- # Create a new parser for the given _signature_.
127
- def initialize(signature)
128
- @signature = signature
129
- @idx = 0
130
- end
112
+ def inspect
113
+ s = TypeMapping[@sigtype].first
114
+ if [STRUCT, ARRAY].member?(@sigtype)
115
+ s += ": " + @members.inspect
116
+ end
117
+ s
118
+ end
119
+ end # class Type
120
+
121
+ # = D-Bus type parser class
122
+ #
123
+ # Helper class to parse a type signature in the protocol.
124
+ class Parser
125
+ # Create a new parser for the given _signature_.
126
+ def initialize(signature)
127
+ @signature = signature
128
+ @idx = 0
129
+ end
131
130
 
132
- # Returns the next character from the signature.
133
- def nextchar
134
- c = @signature[@idx]
135
- @idx += 1
136
- c
137
- end
131
+ # Returns the next character from the signature.
132
+ def nextchar
133
+ c = @signature[@idx]
134
+ @idx += 1
135
+ c
136
+ end
138
137
 
139
- # Parse one character _c_ of the signature.
140
- def parse_one(c)
141
- res = nil
142
- case c
143
- when ?a
144
- res = Type.new(ARRAY)
145
- c = nextchar
146
- raise SignatureException, "Parse error in #{@signature}" if c == nil
147
- child = parse_one(c)
148
- res << child
149
- when ?(
150
- res = Type.new(STRUCT)
151
- while (c = nextchar) != nil and c != ?)
152
- res << parse_one(c)
153
- end
154
- raise SignatureException, "Parse error in #{@signature}" if c == nil
155
- when ?{
156
- res = Type.new(DICT_ENTRY)
157
- while (c = nextchar) != nil and c != ?}
158
- res << parse_one(c)
138
+ # Parse one character _c_ of the signature.
139
+ def parse_one(c)
140
+ res = nil
141
+ case c
142
+ when "a"
143
+ res = Type.new(ARRAY)
144
+ c = nextchar
145
+ raise SignatureException, "Parse error in #{@signature}" if c.nil?
146
+ child = parse_one(c)
147
+ res << child
148
+ when "("
149
+ res = Type.new(STRUCT)
150
+ while (c = nextchar) && c != ")"
151
+ res << parse_one(c)
152
+ end
153
+ raise SignatureException, "Parse error in #{@signature}" if c.nil?
154
+ when "{"
155
+ res = Type.new(DICT_ENTRY)
156
+ while (c = nextchar) && c != "}"
157
+ res << parse_one(c)
158
+ end
159
+ raise SignatureException, "Parse error in #{@signature}" if c.nil?
160
+ else
161
+ res = Type.new(c)
159
162
  end
160
- raise SignatureException, "Parse error in #{@signature}" if c == nil
161
- else
162
- res = Type.new(c)
163
+ res
163
164
  end
164
- res
165
- end
166
165
 
167
- # Parse the entire signature, return a DBus::Type object.
168
- def parse
169
- @idx = 0
170
- ret = Array.new
171
- while (c = nextchar)
172
- ret << parse_one(c)
166
+ # Parse the entire signature, return a DBus::Type object.
167
+ def parse
168
+ @idx = 0
169
+ ret = []
170
+ while (c = nextchar)
171
+ ret << parse_one(c)
172
+ end
173
+ ret
173
174
  end
174
- ret
175
- end
176
- end # class Parser
177
- end # module Type
178
-
179
- # shortcuts
175
+ end # class Parser
176
+ end # module Type
180
177
 
181
- # Parse a String to a DBus::Type::Type
182
- def type(string_type)
183
- Type::Parser.new(string_type).parse[0]
184
- end
185
- module_function :type
178
+ # shortcuts
186
179
 
187
- # Make an explicit [Type, value] pair
188
- def variant(string_type, value)
189
- [type(string_type), value]
190
- end
191
- module_function :variant
180
+ # Parse a String to a DBus::Type::Type
181
+ def type(string_type)
182
+ Type::Parser.new(string_type).parse[0]
183
+ end
184
+ module_function :type
192
185
 
186
+ # Make an explicit [Type, value] pair
187
+ def variant(string_type, value)
188
+ [type(string_type), value]
189
+ end
190
+ module_function :variant
193
191
  end # module DBus
@@ -9,10 +9,10 @@
9
9
  # License, version 2.1 as published by the Free Software Foundation.
10
10
  # See the file "COPYING" for the exact licensing terms.
11
11
 
12
- # TODO check if it is slow, make replaceable
13
- require 'rexml/document'
12
+ # TODO: check if it is slow, make replaceable
13
+ require "rexml/document"
14
14
  begin
15
- require 'nokogiri'
15
+ require "nokogiri"
16
16
  rescue LoadError
17
17
  end
18
18
 
@@ -32,16 +32,18 @@ module DBus
32
32
 
33
33
  class AbstractXML
34
34
  def self.have_nokogiri?
35
- Object.const_defined?('Nokogiri')
35
+ Object.const_defined?("Nokogiri")
36
36
  end
37
37
  class Node
38
38
  def initialize(node)
39
39
  @node = node
40
40
  end
41
+
41
42
  # required methods
42
43
  # returns node attribute value
43
44
  def [](key)
44
45
  end
46
+
45
47
  # yields child nodes which match xpath of type AbstractXML::Node
46
48
  def each(xpath)
47
49
  end
@@ -50,6 +52,7 @@ module DBus
50
52
  # initialize parser with xml string
51
53
  def initialize(xml)
52
54
  end
55
+
53
56
  # yields nodes which match xpath of type AbstractXML::Node
54
57
  def each(xpath)
55
58
  end
@@ -60,6 +63,7 @@ module DBus
60
63
  def [](key)
61
64
  @node[key]
62
65
  end
66
+
63
67
  def each(path, &block)
64
68
  @node.search(path).each { |node| block.call NokogiriNode.new(node) }
65
69
  end
@@ -67,6 +71,7 @@ module DBus
67
71
  def initialize(xml)
68
72
  @doc = Nokogiri.XML(xml)
69
73
  end
74
+
70
75
  def each(path, &block)
71
76
  @doc.search("//#{path}").each { |node| block.call NokogiriNode.new(node) }
72
77
  end
@@ -77,6 +82,7 @@ module DBus
77
82
  def [](key)
78
83
  @node.attributes[key]
79
84
  end
85
+
80
86
  def each(path, &block)
81
87
  @node.elements.each(path) { |node| block.call REXMLNode.new(node) }
82
88
  end
@@ -84,18 +90,20 @@ module DBus
84
90
  def initialize(xml)
85
91
  @doc = REXML::Document.new(xml)
86
92
  end
93
+
87
94
  def each(path, &block)
88
95
  @doc.elements.each(path) { |node| block.call REXMLNode.new(node) }
89
96
  end
90
97
  end
91
98
 
92
- if AbstractXML.have_nokogiri?
93
- @backend = NokogiriParser
94
- else
95
- @backend = REXMLParser
96
- end
99
+ @backend = if AbstractXML.have_nokogiri?
100
+ NokogiriParser
101
+ else
102
+ REXMLParser
103
+ end
97
104
 
98
- # return a pair: [list of Interfaces, list of direct subnode names]
105
+ # @return [Array(Array<Interface>,Array<String>)]
106
+ # a pair: [list of Interfaces, list of direct subnode names]
99
107
  def parse
100
108
  # Using a Hash instead of a list helps merge split-up interfaces,
101
109
  # a quirk observed in ModemManager (I#41).
@@ -105,7 +113,6 @@ module DBus
105
113
  subnodes = []
106
114
  t = Time.now
107
115
 
108
-
109
116
  d = IntrospectXMLParser.backend.new(@xml)
110
117
  d.each("node/node") do |e|
111
118
  subnodes << e["name"]
@@ -140,17 +147,17 @@ module DBus
140
147
  name = ae["name"]
141
148
  dir = ae["direction"]
142
149
  sig = ae["type"]
143
- if m.is_a?(DBus::Signal)
150
+ if m.is_a?(DBus::Signal)
144
151
  # Direction can only be "out", ignore it
145
152
  m.add_fparam(name, sig)
146
- elsif m.is_a?(DBus::Method)
153
+ elsif m.is_a?(DBus::Method)
147
154
  case dir
148
155
  # This is a method, so dir defaults to "in"
149
156
  when "in", nil
150
157
  m.add_fparam(name, sig)
151
158
  when "out"
152
- m.add_return(name, sig)
153
- end
159
+ m.add_return(name, sig)
160
+ end
154
161
  else
155
162
  raise NotImplementedError, dir
156
163
  end
@@ -158,4 +165,3 @@ module DBus
158
165
  end
159
166
  end # class IntrospectXMLParser
160
167
  end # module DBus
161
-