ruby-dbus 0.12.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
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
-