ruby-dbus 0.17.0 → 0.18.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/NEWS.md +15 -0
  3. data/README.md +1 -1
  4. data/Rakefile +3 -11
  5. data/VERSION +1 -1
  6. data/doc/Reference.md +9 -2
  7. data/examples/doc/_extract_examples +2 -0
  8. data/examples/gdbus/gdbus +11 -5
  9. data/examples/no-introspect/nm-test.rb +2 -0
  10. data/examples/no-introspect/tracker-test.rb +3 -1
  11. data/examples/rhythmbox/playpause.rb +2 -1
  12. data/examples/service/call_service.rb +1 -0
  13. data/examples/service/service_newapi.rb +1 -1
  14. data/examples/simple/call_introspect.rb +1 -0
  15. data/examples/simple/get_id.rb +2 -1
  16. data/examples/simple/properties.rb +2 -0
  17. data/examples/utils/listnames.rb +1 -0
  18. data/examples/utils/notify.rb +1 -0
  19. data/lib/dbus/api_options.rb +9 -0
  20. data/lib/dbus/auth.rb +12 -7
  21. data/lib/dbus/bus.rb +114 -70
  22. data/lib/dbus/bus_name.rb +12 -8
  23. data/lib/dbus/error.rb +4 -2
  24. data/lib/dbus/introspect.rb +29 -18
  25. data/lib/dbus/logger.rb +3 -1
  26. data/lib/dbus/marshall.rb +118 -86
  27. data/lib/dbus/matchrule.rb +16 -16
  28. data/lib/dbus/message.rb +40 -27
  29. data/lib/dbus/message_queue.rb +10 -5
  30. data/lib/dbus/object.rb +34 -13
  31. data/lib/dbus/object_path.rb +9 -5
  32. data/lib/dbus/proxy_object.rb +18 -4
  33. data/lib/dbus/proxy_object_factory.rb +11 -7
  34. data/lib/dbus/proxy_object_interface.rb +26 -22
  35. data/lib/dbus/type.rb +41 -34
  36. data/lib/dbus/xml.rb +28 -17
  37. data/lib/dbus.rb +7 -7
  38. data/ruby-dbus.gemspec +4 -2
  39. data/spec/async_spec.rb +2 -0
  40. data/spec/binding_spec.rb +2 -0
  41. data/spec/bus_and_xml_backend_spec.rb +2 -0
  42. data/spec/bus_driver_spec.rb +2 -0
  43. data/spec/bus_name_spec.rb +3 -1
  44. data/spec/bus_spec.rb +2 -0
  45. data/spec/byte_array_spec.rb +2 -0
  46. data/spec/client_robustness_spec.rb +4 -2
  47. data/spec/err_msg_spec.rb +2 -0
  48. data/spec/introspect_xml_parser_spec.rb +2 -0
  49. data/spec/introspection_spec.rb +2 -0
  50. data/spec/main_loop_spec.rb +2 -0
  51. data/spec/node_spec.rb +23 -0
  52. data/spec/object_path_spec.rb +2 -0
  53. data/spec/property_spec.rb +11 -2
  54. data/spec/proxy_object_spec.rb +2 -0
  55. data/spec/server_robustness_spec.rb +2 -0
  56. data/spec/server_spec.rb +2 -0
  57. data/spec/service_newapi.rb +19 -4
  58. data/spec/session_bus_spec.rb +3 -1
  59. data/spec/session_bus_spec_manual.rb +2 -0
  60. data/spec/signal_spec.rb +2 -0
  61. data/spec/spec_helper.rb +5 -3
  62. data/spec/thread_safety_spec.rb +2 -0
  63. data/spec/type_spec.rb +2 -0
  64. data/spec/value_spec.rb +16 -1
  65. data/spec/variant_spec.rb +4 -2
  66. metadata +8 -7
data/lib/dbus/object.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of the ruby-dbus project
2
4
  # Copyright (C) 2007 Arnaud Cornet and Paul van Tilburg
3
5
  #
@@ -6,11 +8,10 @@
6
8
  # License, version 2.1 as published by the Free Software Foundation.
7
9
  # See the file "COPYING" for the exact licensing terms.
8
10
 
9
- require "thread"
10
11
  require_relative "core_ext/class/attribute"
11
12
 
12
13
  module DBus
13
- PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties".freeze
14
+ PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties"
14
15
 
15
16
  # Exported object type
16
17
  # = Exportable D-Bus object class
@@ -20,6 +21,7 @@ module DBus
20
21
  class Object
21
22
  # The path of the object.
22
23
  attr_reader :path
24
+
23
25
  # The interfaces that the object supports. Hash: String => Interface
24
26
  my_class_attribute :intfs
25
27
  self.intfs = {}
@@ -43,11 +45,13 @@ module DBus
43
45
  when Message::METHOD_CALL
44
46
  reply = nil
45
47
  begin
46
- if !intfs[msg.interface]
48
+ iface = intfs[msg.interface]
49
+ if !iface
47
50
  raise DBus.error("org.freedesktop.DBus.Error.UnknownMethod"),
48
51
  "Interface \"#{msg.interface}\" of object \"#{msg.path}\" doesn't exist"
49
52
  end
50
- meth = intfs[msg.interface].methods[msg.member.to_sym]
53
+ member_sym = msg.member.to_sym
54
+ meth = iface.methods[member_sym]
51
55
  if !meth
52
56
  raise DBus.error("org.freedesktop.DBus.Error.UnknownMethod"),
53
57
  "Method \"#{msg.member}\" on interface \"#{msg.interface}\" of object \"#{msg.path}\" doesn't exist"
@@ -57,11 +61,20 @@ module DBus
57
61
  retdata = [*retdata]
58
62
 
59
63
  reply = Message.method_return(msg)
60
- meth.rets.zip(retdata).each do |rsig, rdata|
61
- reply.add_param(rsig.type, rdata)
64
+ if iface.name == PROPERTY_INTERFACE && member_sym == :Get
65
+ # Use the specific property type instead of the generic variant
66
+ # returned by Get.
67
+ # TODO: GetAll and Set still missing
68
+ property = dbus_lookup_property(msg.params[0], msg.params[1])
69
+ rsigs = [property.type]
70
+ else
71
+ rsigs = meth.rets.map(&:type)
72
+ end
73
+ rsigs.zip(retdata).each do |rsig, rdata|
74
+ reply.add_param(rsig, rdata)
62
75
  end
63
- rescue StandardError => ex
64
- dbus_msg_exc = msg.annotate_exception(ex)
76
+ rescue StandardError => e
77
+ dbus_msg_exc = msg.annotate_exception(e)
65
78
  reply = ErrorMessage.from_exception(dbus_msg_exc).reply_to(msg)
66
79
  end
67
80
  @service.bus.message_queue.push(reply)
@@ -70,17 +83,19 @@ module DBus
70
83
 
71
84
  # Select (and create) the interface that the following defined methods
72
85
  # belong to.
73
- def self.dbus_interface(s)
86
+ # @param name [String] interface name like "org.example.ManagerManager"
87
+ # @see https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-interface
88
+ def self.dbus_interface(name)
74
89
  @@intfs_mutex.synchronize do
75
- @@cur_intf = intfs[s]
90
+ @@cur_intf = intfs[name]
76
91
  if !@@cur_intf
77
- @@cur_intf = Interface.new(s)
92
+ @@cur_intf = Interface.new(name) # validates the name
78
93
  # As this is a mutable class_attr, we cannot use
79
- # self.intfs[s] = @@cur_intf # Hash#[]=
94
+ # self.intfs[name] = @@cur_intf # Hash#[]=
80
95
  # as that would modify parent class attr in place.
81
96
  # Using the setter lets a subclass have the new value
82
97
  # while the superclass keeps the old one.
83
- self.intfs = intfs.merge(s => @@cur_intf)
98
+ self.intfs = intfs.merge(name => @@cur_intf)
84
99
  end
85
100
  yield
86
101
  @@cur_intf = nil
@@ -110,6 +125,7 @@ module DBus
110
125
  # @return [void]
111
126
  def self.dbus_attr_accessor(ruby_name, type, dbus_name: nil)
112
127
  attr_accessor(ruby_name)
128
+
113
129
  dbus_accessor(ruby_name, type, dbus_name: dbus_name)
114
130
  end
115
131
 
@@ -129,6 +145,7 @@ module DBus
129
145
  # @return (see .dbus_attr_accessor)
130
146
  def self.dbus_attr_reader(ruby_name, type, dbus_name: nil)
131
147
  attr_reader(ruby_name)
148
+
132
149
  dbus_reader(ruby_name, type, dbus_name: dbus_name)
133
150
  end
134
151
 
@@ -139,6 +156,7 @@ module DBus
139
156
  # @return (see .dbus_attr_accessor)
140
157
  def self.dbus_attr_writer(ruby_name, type, dbus_name: nil)
141
158
  attr_writer(ruby_name)
159
+
142
160
  dbus_writer(ruby_name, type, dbus_name: dbus_name)
143
161
  end
144
162
 
@@ -211,6 +229,7 @@ module DBus
211
229
  # @return [void]
212
230
  def self.dbus_watcher(ruby_name, dbus_name: nil)
213
231
  raise UndefinedInterface, ruby_name if @@cur_intf.nil?
232
+
214
233
  cur_intf = @@cur_intf
215
234
 
216
235
  ruby_name = ruby_name.to_s.sub(/=$/, "").to_sym
@@ -235,6 +254,7 @@ module DBus
235
254
  # @param prototype [Prototype]
236
255
  def self.dbus_method(sym, prototype = "", &block)
237
256
  raise UndefinedInterface, sym if @@cur_intf.nil?
257
+
238
258
  @@cur_intf.define(Method.new(sym.to_s).from_prototype(prototype))
239
259
 
240
260
  ruby_name = Object.make_method_name(@@cur_intf.name, sym.to_s)
@@ -254,6 +274,7 @@ module DBus
254
274
  # Defines a signal for the object with a given name _sym_ and _prototype_.
255
275
  def self.dbus_signal(sym, prototype = "")
256
276
  raise UndefinedInterface, sym if @@cur_intf.nil?
277
+
257
278
  cur_intf = @@cur_intf
258
279
  signal = Signal.new(sym.to_s).from_prototype(prototype)
259
280
  cur_intf.define(Signal.new(sym.to_s).from_prototype(prototype))
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of the ruby-dbus project
2
4
  # Copyright (C) 2019 Martin Vidner
3
5
  #
@@ -8,17 +10,19 @@
8
10
 
9
11
  module DBus
10
12
  # A {::String} that validates at initialization time
13
+ # @see https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-marshaling-object-path
11
14
  class ObjectPath < String
12
15
  # @raise Error if not a valid object path
13
- def initialize(s)
14
- unless self.class.valid?(s)
15
- raise DBus::Error, "Invalid object path #{s.inspect}"
16
+ def initialize(str)
17
+ unless self.class.valid?(str)
18
+ raise DBus::Error, "Invalid object path #{str.inspect}"
16
19
  end
20
+
17
21
  super
18
22
  end
19
23
 
20
- def self.valid?(s)
21
- s == "/" || s =~ %r{\A(/[A-Za-z0-9_]+)+\z}
24
+ def self.valid?(str)
25
+ str == "/" || str =~ %r{\A(/[A-Za-z0-9_]+)+\z}
22
26
  end
23
27
  end
24
28
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of the ruby-dbus project
2
4
  # Copyright (C) 2007 Arnaud Cornet and Paul van Tilburg
3
5
  # Copyright (C) 2009-2014 Martin Vidner
@@ -57,6 +59,7 @@ module DBus
57
59
  introspect unless introspected
58
60
  ifc = @interfaces[intfname]
59
61
  raise DBus::Error, "no such interface `#{intfname}' on object `#{@path}'" unless ifc
62
+
60
63
  ifc
61
64
  end
62
65
 
@@ -93,6 +96,7 @@ module DBus
93
96
  # don't overwrite instance methods!
94
97
  next if dup_meths.include?(name)
95
98
  next if self.class.instance_methods.include?(name)
99
+
96
100
  if univocal_meths.include? name
97
101
  univocal_meths.delete name
98
102
  dup_meths << name
@@ -124,14 +128,17 @@ module DBus
124
128
  def on_signal(name, &block)
125
129
  # TODO: improve
126
130
  raise NoMethodError unless @default_iface && has_iface?(@default_iface)
131
+
127
132
  @interfaces[@default_iface].on_signal(name, &block)
128
133
  end
129
134
 
130
135
  ####################################################
131
136
  private
132
137
 
133
- # rubocop:disable Style/MethodMissing
134
- # but https://github.com/rubocop-hq/ruby-style-guide#no-method-missing
138
+ # rubocop:disable Lint/MissingSuper
139
+ # as this should forward everything
140
+ #
141
+ # https://github.com/rubocop-hq/ruby-style-guide#no-method-missing
135
142
  # and http://blog.marc-andre.ca/2010/11/15/methodmissing-politely/
136
143
  # have a point to be investigated
137
144
 
@@ -152,10 +159,17 @@ module DBus
152
159
  # interesting, foo.method("unknown")
153
160
  # raises NameError, not NoMethodError
154
161
  raise unless e.to_s =~ /undefined method `#{name}'/
162
+
155
163
  # BTW e.exception("...") would preserve the class.
156
164
  raise NoMethodError, "undefined method `#{name}' for DBus interface `#{@default_iface}' on object `#{@path}'"
157
165
  end
158
166
  end
159
- # rubocop:enable Style/MethodMissing
160
- end # class ProxyObject
167
+ # rubocop:enable Lint/MissingSuper
168
+
169
+ def respond_to_missing?(name, _include_private = false)
170
+ @default_iface &&
171
+ has_iface?(@default_iface) &&
172
+ @interfaces[@default_iface].methods.key?(name) or super
173
+ end
174
+ end
161
175
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of the ruby-dbus project
2
4
  # Copyright (C) 2007 Arnaud Cornet and Paul van Tilburg
3
5
  # Copyright (C) 2009-2014 Martin Vidner
@@ -22,17 +24,19 @@ module DBus
22
24
  @api = api
23
25
  end
24
26
 
25
- # Investigates the sub-nodes of the proxy object _po_ based on the
27
+ # Investigates the sub-nodes of the proxy object _pobj_ based on the
26
28
  # introspection XML data _xml_ and sets them up recursively.
27
- def self.introspect_into(po, xml)
28
- intfs, po.subnodes = IntrospectXMLParser.new(xml).parse
29
+ # @param pobj [ProxyObject]
30
+ # @param xml [String]
31
+ def self.introspect_into(pobj, xml)
32
+ intfs, pobj.subnodes = IntrospectXMLParser.new(xml).parse
29
33
  intfs.each do |i|
30
- poi = ProxyObjectInterface.new(po, i.name)
34
+ poi = ProxyObjectInterface.new(pobj, i.name)
31
35
  i.methods.each_value { |m| poi.define(m) }
32
36
  i.signals.each_value { |s| poi.define(s) }
33
- po[i.name] = poi
37
+ pobj[i.name] = poi
34
38
  end
35
- po.introspected = true
39
+ pobj.introspected = true
36
40
  end
37
41
 
38
42
  # Generates, sets up and returns the proxy object.
@@ -41,5 +45,5 @@ module DBus
41
45
  ProxyObjectFactory.introspect_into(po, @xml)
42
46
  po
43
47
  end
44
- end # class ProxyObjectFactory
48
+ end
45
49
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file is part of the ruby-dbus project
2
4
  # Copyright (C) 2007 Arnaud Cornet and Paul van Tilburg
3
5
  # Copyright (C) 2009-2014 Martin Vidner
@@ -36,27 +38,28 @@ module DBus
36
38
  @name
37
39
  end
38
40
 
39
- # Defines a method on the interface from the Method descriptor _m_.
40
- def define_method_from_descriptor(m)
41
- m.params.each do |fpar|
41
+ # Defines a method on the interface from the Method descriptor _method_.
42
+ # @param method [Method]
43
+ def define_method_from_descriptor(method)
44
+ method.params.each do |fpar|
42
45
  par = fpar.type
43
46
  # This is the signature validity check
44
47
  Type::Parser.new(par).parse
45
48
  end
46
49
 
47
50
  singleton_class.class_eval do
48
- define_method m.name do |*args, &reply_handler|
49
- if m.params.size != args.size
50
- raise ArgumentError, "wrong number of arguments (#{args.size} for #{m.params.size})"
51
+ define_method method.name do |*args, &reply_handler|
52
+ if method.params.size != args.size
53
+ raise ArgumentError, "wrong number of arguments (#{args.size} for #{method.params.size})"
51
54
  end
52
55
 
53
56
  msg = Message.new(Message::METHOD_CALL)
54
57
  msg.path = @object.path
55
58
  msg.interface = @name
56
59
  msg.destination = @object.destination
57
- msg.member = m.name
60
+ msg.member = method.name
58
61
  msg.sender = @object.bus.unique_name
59
- m.params.each do |fpar|
62
+ method.params.each do |fpar|
60
63
  par = fpar.type
61
64
  msg.add_param(par, args.shift)
62
65
  end
@@ -64,30 +67,31 @@ module DBus
64
67
  if ret.nil? || @object.api.proxy_method_returns_array
65
68
  ret
66
69
  else
67
- m.rets.size == 1 ? ret.first : ret
70
+ method.rets.size == 1 ? ret.first : ret
68
71
  end
69
72
  end
70
73
  end
71
74
 
72
- @methods[m.name] = m
75
+ @methods[method.name] = method
73
76
  end
74
77
 
75
- # Defines a signal from the descriptor _s_.
76
- def define_signal_from_descriptor(s)
77
- @signals[s.name] = s
78
+ # Defines a signal from the descriptor _sig_.
79
+ # @param sig [Signal]
80
+ def define_signal_from_descriptor(sig)
81
+ @signals[sig.name] = sig
78
82
  end
79
83
 
80
- # Defines a signal or method based on the descriptor _m_.
81
- def define(m)
82
- if m.is_a?(Method)
83
- define_method_from_descriptor(m)
84
- elsif m.is_a?(Signal)
85
- define_signal_from_descriptor(m)
84
+ # Defines a signal or method based on the descriptor _ifc_el_.
85
+ def define(ifc_el)
86
+ case ifc_el
87
+ when Method
88
+ define_method_from_descriptor(ifc_el)
89
+ when Signal
90
+ define_signal_from_descriptor(ifc_el)
86
91
  end
87
92
  end
88
93
 
89
94
  # Defines a proxied method on the interface.
90
- # Better name: declare_method
91
95
  def define_method(methodname, prototype)
92
96
  m = Method.new(methodname)
93
97
  m.from_prototype(prototype)
@@ -110,7 +114,7 @@ module DBus
110
114
  end
111
115
  end
112
116
 
113
- PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties".freeze
117
+ PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties"
114
118
 
115
119
  # Read a property.
116
120
  # @param propname [String]
@@ -142,5 +146,5 @@ module DBus
142
146
  ret
143
147
  end
144
148
  end
145
- end # class ProxyObjectInterface
149
+ end
146
150
  end
data/lib/dbus/type.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # dbus/type.rb - module containing low-level D-Bus data type information
2
4
  #
3
5
  # This file is part of the ruby-dbus project
@@ -33,7 +35,7 @@ module DBus
33
35
  # protocol.
34
36
  module Type
35
37
  # Mapping from type number to name and alignment.
36
- TypeMapping = {
38
+ TYPE_MAPPING = {
37
39
  0 => ["INVALID", nil],
38
40
  "y" => ["BYTE", 1],
39
41
  "b" => ["BOOLEAN", 4],
@@ -54,7 +56,7 @@ module DBus
54
56
  "h" => ["UNIX_FD", 4]
55
57
  }.freeze
56
58
  # Defines the set of constants
57
- TypeMapping.each_pair do |key, value|
59
+ TYPE_MAPPING.each_pair do |key, value|
58
60
  Type.const_set(value.first, key)
59
61
  end
60
62
 
@@ -73,16 +75,17 @@ module DBus
73
75
 
74
76
  # Create a new type instance for type number _sigtype_.
75
77
  def initialize(sigtype)
76
- if !TypeMapping.keys.member?(sigtype)
78
+ if !TYPE_MAPPING.keys.member?(sigtype)
77
79
  raise SignatureException, "Unknown key in signature: #{sigtype.chr}"
78
80
  end
81
+
79
82
  @sigtype = sigtype
80
83
  @members = []
81
84
  end
82
85
 
83
86
  # Return the required alignment for the type.
84
87
  def alignment
85
- TypeMapping[@sigtype].last
88
+ TYPE_MAPPING[@sigtype].last
86
89
  end
87
90
 
88
91
  # Return a string representation of the type according to the
@@ -90,36 +93,38 @@ module DBus
90
93
  def to_s
91
94
  case @sigtype
92
95
  when STRUCT
93
- "(" + @members.collect(&:to_s).join + ")"
96
+ "(#{@members.collect(&:to_s).join})"
94
97
  when ARRAY
95
- "a" + child.to_s
98
+ "a#{child}"
96
99
  when DICT_ENTRY
97
- "{" + @members.collect(&:to_s).join + "}"
100
+ "{#{@members.collect(&:to_s).join}}"
98
101
  else
99
- if !TypeMapping.keys.member?(@sigtype)
102
+ if !TYPE_MAPPING.keys.member?(@sigtype)
100
103
  raise NotImplementedError
101
104
  end
105
+
102
106
  @sigtype.chr
103
107
  end
104
108
  end
105
109
 
106
- # Add a new member type _a_.
107
- def <<(a)
110
+ # Add a new member type _item_.
111
+ def <<(item)
108
112
  if ![STRUCT, ARRAY, DICT_ENTRY].member?(@sigtype)
109
113
  raise SignatureException
110
114
  end
111
115
  raise SignatureException if @sigtype == ARRAY && !@members.empty?
116
+
112
117
  if @sigtype == DICT_ENTRY
113
- if @members.size == 2
118
+ case @members.size
119
+ when 2
114
120
  raise SignatureException, "Dict entries have exactly two members"
115
- end
116
- if @members.empty?
117
- if [STRUCT, ARRAY, DICT_ENTRY].member?(a.sigtype)
121
+ when 0
122
+ if [STRUCT, ARRAY, DICT_ENTRY].member?(item.sigtype)
118
123
  raise SignatureException, "Dict entry keys must be basic types"
119
124
  end
120
125
  end
121
126
  end
122
- @members << a
127
+ @members << item
123
128
  end
124
129
 
125
130
  # Return the first contained member type.
@@ -128,19 +133,20 @@ module DBus
128
133
  end
129
134
 
130
135
  def inspect
131
- s = TypeMapping[@sigtype].first
136
+ s = TYPE_MAPPING[@sigtype].first
132
137
  if [STRUCT, ARRAY].member?(@sigtype)
133
- s += ": " + @members.inspect
138
+ s += ": #{@members.inspect}"
134
139
  end
135
140
  s
136
141
  end
137
- end # class Type
142
+ end
138
143
 
139
144
  # = D-Bus type parser class
140
145
  #
141
146
  # Helper class to parse a type signature in the protocol.
142
147
  class Parser
143
148
  # Create a new parser for the given _signature_.
149
+ # @param signature [Signature]
144
150
  def initialize(signature)
145
151
  @signature = signature
146
152
  @idx = 0
@@ -153,30 +159,31 @@ module DBus
153
159
  c
154
160
  end
155
161
 
156
- # Parse one character _c_ of the signature.
157
- def parse_one(c)
162
+ # Parse one character _char_ of the signature.
163
+ def parse_one(char)
158
164
  res = nil
159
- case c
165
+ case char
160
166
  when "a"
161
167
  res = Type.new(ARRAY)
162
- c = nextchar
163
- raise SignatureException, "Parse error in #{@signature}" if c.nil?
164
- child = parse_one(c)
168
+ char = nextchar
169
+ raise SignatureException, "Parse error in #{@signature}" if char.nil?
170
+
171
+ child = parse_one(char)
165
172
  res << child
166
173
  when "("
167
174
  res = Type.new(STRUCT)
168
- while (c = nextchar) && c != ")"
169
- res << parse_one(c)
175
+ while (char = nextchar) && char != ")"
176
+ res << parse_one(char)
170
177
  end
171
- raise SignatureException, "Parse error in #{@signature}" if c.nil?
178
+ raise SignatureException, "Parse error in #{@signature}" if char.nil?
172
179
  when "{"
173
180
  res = Type.new(DICT_ENTRY)
174
- while (c = nextchar) && c != "}"
175
- res << parse_one(c)
181
+ while (char = nextchar) && char != "}"
182
+ res << parse_one(char)
176
183
  end
177
- raise SignatureException, "Parse error in #{@signature}" if c.nil?
184
+ raise SignatureException, "Parse error in #{@signature}" if char.nil?
178
185
  else
179
- res = Type.new(c)
186
+ res = Type.new(char)
180
187
  end
181
188
  res
182
189
  end
@@ -190,8 +197,8 @@ module DBus
190
197
  end
191
198
  ret
192
199
  end
193
- end # class Parser
194
- end # module Type
200
+ end
201
+ end
195
202
 
196
203
  # shortcuts
197
204
 
@@ -206,4 +213,4 @@ module DBus
206
213
  [type(string_type), value]
207
214
  end
208
215
  module_function :variant
209
- end # module DBus
216
+ end
data/lib/dbus/xml.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # dbus/xml.rb - introspection parser, rexml/nokogiri abstraction
2
4
  #
3
5
  # This file is part of the ruby-dbus project
@@ -26,14 +28,23 @@ module DBus
26
28
  attr_accessor :backend
27
29
  end
28
30
  # Creates a new parser for XML data in string _xml_.
31
+ # @param xml [String]
29
32
  def initialize(xml)
30
33
  @xml = xml
31
34
  end
32
35
 
33
36
  class AbstractXML
37
+ # @!method initialize(xml)
38
+ # @abstract
39
+
40
+ # @!method each(xpath)
41
+ # @abstract
42
+ # yields nodes which match xpath of type AbstractXML::Node
43
+
34
44
  def self.have_nokogiri?
35
45
  Object.const_defined?("Nokogiri")
36
46
  end
47
+
37
48
  class Node
38
49
  def initialize(node)
39
50
  @node = node
@@ -46,12 +57,6 @@ module DBus
46
57
  # yields child nodes which match xpath of type AbstractXML::Node
47
58
  def each(xpath); end
48
59
  end
49
- # required methods
50
- # initialize parser with xml string
51
- def initialize(xml); end
52
-
53
- # yields nodes which match xpath of type AbstractXML::Node
54
- def each(xpath); end
55
60
  end
56
61
 
57
62
  class NokogiriParser < AbstractXML
@@ -64,7 +69,9 @@ module DBus
64
69
  @node.search(path).each { |node| block.call NokogiriNode.new(node) }
65
70
  end
66
71
  end
72
+
67
73
  def initialize(xml)
74
+ super()
68
75
  @doc = Nokogiri.XML(xml)
69
76
  end
70
77
 
@@ -83,7 +90,9 @@ module DBus
83
90
  @node.elements.each(path) { |node| block.call REXMLNode.new(node) }
84
91
  end
85
92
  end
93
+
86
94
  def initialize(xml)
95
+ super()
87
96
  @doc = REXML::Document.new(xml)
88
97
  end
89
98
 
@@ -136,28 +145,30 @@ module DBus
136
145
  ######################################################################
137
146
  private
138
147
 
139
- # Parses a method signature XML element _e_ and initialises
140
- # method/signal _m_.
141
- def parse_methsig(e, m)
142
- e.each("arg") do |ae|
148
+ # Parses a method signature XML element *elem* and initialises
149
+ # method/signal *methsig*.
150
+ # @param elem [AbstractXML::Node]
151
+ def parse_methsig(elem, methsig)
152
+ elem.each("arg") do |ae|
143
153
  name = ae["name"]
144
154
  dir = ae["direction"]
145
155
  sig = ae["type"]
146
- if m.is_a?(DBus::Signal)
156
+ case methsig
157
+ when DBus::Signal
147
158
  # Direction can only be "out", ignore it
148
- m.add_fparam(name, sig)
149
- elsif m.is_a?(DBus::Method)
159
+ methsig.add_fparam(name, sig)
160
+ when DBus::Method
150
161
  case dir
151
162
  # This is a method, so dir defaults to "in"
152
163
  when "in", nil
153
- m.add_fparam(name, sig)
164
+ methsig.add_fparam(name, sig)
154
165
  when "out"
155
- m.add_return(name, sig)
166
+ methsig.add_return(name, sig)
156
167
  end
157
168
  else
158
169
  raise NotImplementedError, dir
159
170
  end
160
171
  end
161
172
  end
162
- end # class IntrospectXMLParser
163
- end # module DBus
173
+ end
174
+ end
data/lib/dbus.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # dbus.rb - Module containing the low-level D-Bus implementation
2
4
  #
3
5
  # This file is part of the ruby-dbus project
@@ -28,22 +30,20 @@ require_relative "dbus/type"
28
30
  require_relative "dbus/xml"
29
31
 
30
32
  require "socket"
31
- require "thread"
32
-
33
33
  # = D-Bus main module
34
34
  #
35
35
  # Module containing all the D-Bus modules and classes.
36
36
  module DBus
37
37
  # Default socket name for the system bus.
38
- SystemSocketName = "unix:path=/var/run/dbus/system_bus_socket".freeze
38
+ SYSTEM_BUS_ADDRESS = "unix:path=/var/run/dbus/system_bus_socket"
39
39
 
40
40
  # Byte signifying big endianness.
41
- BIG_END = "B".freeze
41
+ BIG_END = "B"
42
42
  # Byte signifying little endianness.
43
- LIL_END = "l".freeze
43
+ LIL_END = "l"
44
44
 
45
45
  # Byte signifying the host's endianness.
46
- HOST_END = if [0x01020304].pack("L").unpack("V")[0] == 0x01020304
46
+ HOST_END = if [0x01020304].pack("L").unpack1("V") == 0x01020304
47
47
  LIL_END
48
48
  else
49
49
  BIG_END
@@ -69,4 +69,4 @@ module DBus
69
69
  # Exception raised when invalid introspection data is parsed/used.
70
70
  class InvalidIntrospectionData < Exception
71
71
  end
72
- end # module DBus
72
+ end