ruby-dbus 0.16.0 → 0.18.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/NEWS.md +160 -0
  3. data/README.md +3 -5
  4. data/Rakefile +18 -8
  5. data/VERSION +1 -1
  6. data/doc/Reference.md +106 -7
  7. data/examples/doc/_extract_examples +7 -0
  8. data/examples/gdbus/gdbus +31 -24
  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 +2 -1
  13. data/examples/service/complex-property.rb +21 -0
  14. data/examples/service/service_newapi.rb +1 -1
  15. data/examples/simple/call_introspect.rb +1 -0
  16. data/examples/simple/get_id.rb +2 -1
  17. data/examples/simple/properties.rb +2 -0
  18. data/examples/utils/listnames.rb +1 -0
  19. data/examples/utils/notify.rb +1 -0
  20. data/lib/dbus/api_options.rb +9 -0
  21. data/lib/dbus/auth.rb +20 -15
  22. data/lib/dbus/bus.rb +123 -75
  23. data/lib/dbus/bus_name.rb +12 -8
  24. data/lib/dbus/core_ext/class/attribute.rb +1 -1
  25. data/lib/dbus/data.rb +821 -0
  26. data/lib/dbus/emits_changed_signal.rb +83 -0
  27. data/lib/dbus/error.rb +4 -2
  28. data/lib/dbus/introspect.rb +132 -31
  29. data/lib/dbus/logger.rb +3 -1
  30. data/lib/dbus/marshall.rb +247 -296
  31. data/lib/dbus/matchrule.rb +16 -16
  32. data/lib/dbus/message.rb +44 -37
  33. data/lib/dbus/message_queue.rb +16 -10
  34. data/lib/dbus/object.rb +358 -24
  35. data/lib/dbus/object_path.rb +11 -6
  36. data/lib/dbus/proxy_object.rb +22 -1
  37. data/lib/dbus/proxy_object_factory.rb +13 -7
  38. data/lib/dbus/proxy_object_interface.rb +63 -30
  39. data/lib/dbus/raw_message.rb +91 -0
  40. data/lib/dbus/type.rb +318 -86
  41. data/lib/dbus/xml.rb +32 -17
  42. data/lib/dbus.rb +14 -7
  43. data/ruby-dbus.gemspec +7 -3
  44. data/spec/async_spec.rb +2 -0
  45. data/spec/binding_spec.rb +2 -0
  46. data/spec/bus_and_xml_backend_spec.rb +2 -0
  47. data/spec/bus_driver_spec.rb +2 -0
  48. data/spec/bus_name_spec.rb +3 -1
  49. data/spec/bus_spec.rb +2 -0
  50. data/spec/byte_array_spec.rb +2 -0
  51. data/spec/client_robustness_spec.rb +4 -2
  52. data/spec/data/marshall.yaml +1667 -0
  53. data/spec/data_spec.rb +673 -0
  54. data/spec/emits_changed_signal_spec.rb +58 -0
  55. data/spec/err_msg_spec.rb +2 -0
  56. data/spec/introspect_xml_parser_spec.rb +2 -0
  57. data/spec/introspection_spec.rb +2 -0
  58. data/spec/main_loop_spec.rb +3 -1
  59. data/spec/node_spec.rb +23 -0
  60. data/spec/object_path_spec.rb +3 -0
  61. data/spec/object_spec.rb +138 -0
  62. data/spec/packet_marshaller_spec.rb +41 -0
  63. data/spec/packet_unmarshaller_spec.rb +248 -0
  64. data/spec/property_spec.rb +192 -5
  65. data/spec/proxy_object_spec.rb +2 -0
  66. data/spec/server_robustness_spec.rb +2 -0
  67. data/spec/server_spec.rb +2 -0
  68. data/spec/service_newapi.rb +70 -70
  69. data/spec/session_bus_spec.rb +3 -1
  70. data/spec/session_bus_spec_manual.rb +2 -0
  71. data/spec/signal_spec.rb +5 -3
  72. data/spec/spec_helper.rb +37 -9
  73. data/spec/thread_safety_spec.rb +2 -0
  74. data/spec/tools/dbus-limited-session.conf +4 -0
  75. data/spec/type_spec.rb +214 -6
  76. data/spec/value_spec.rb +16 -1
  77. data/spec/variant_spec.rb +4 -2
  78. data/spec/zzz_quit_spec.rb +16 -0
  79. metadata +34 -8
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
@@ -9,13 +11,33 @@
9
11
  # See the file "COPYING" for the exact licensing terms.
10
12
 
11
13
  module DBus
12
- # = D-Bus type module
14
+ # Like a {Signature} but containing only a single complete type.
15
+ #
16
+ # For documentation purposes only.
17
+ class SingleCompleteType < String; end
18
+
19
+ # Zero or more {SingleCompleteType}s; its own type code is "g".
20
+ # For example "ssv" for a method taking two Strings and a Variant/
21
+ #
22
+ # For documentation purposes only.
23
+ class Signature < String; end
24
+
25
+ # Similar to {Signature} but for {DBus::Object.define_method},
26
+ # contains names and direction of the parameters.
27
+ # For example "in query:s, in case_sensitive:b, out results:ao".
13
28
  #
14
- # This module containts the constants of the types specified in the D-Bus
15
- # protocol.
16
- module Type
29
+ # For documentation purposes only.
30
+ class Prototype < String; end
31
+
32
+ # Represents the D-Bus types.
33
+ #
34
+ # Corresponds to {SingleCompleteType}.
35
+ # Instances are immutable/frozen once fully constructed.
36
+ #
37
+ # See also {DBus::Data::Signature} which is "type on the wire".
38
+ class Type
17
39
  # Mapping from type number to name and alignment.
18
- TypeMapping = {
40
+ TYPE_MAPPING = {
19
41
  0 => ["INVALID", nil],
20
42
  "y" => ["BYTE", 1],
21
43
  "b" => ["BOOLEAN", 4],
@@ -36,7 +58,7 @@ module DBus
36
58
  "h" => ["UNIX_FD", 4]
37
59
  }.freeze
38
60
  # Defines the set of constants
39
- TypeMapping.each_pair do |key, value|
61
+ TYPE_MAPPING.each_pair do |key, value|
40
62
  Type.const_set(value.first, key)
41
63
  end
42
64
 
@@ -44,87 +66,140 @@ module DBus
44
66
  class SignatureException < Exception
45
67
  end
46
68
 
47
- # = D-Bus type conversion class
69
+ # Formerly this was a Module and there was a DBus::Type::Type class
70
+ # but the class got too prominent to keep its double double name.
71
+ # This is for backward compatibility.
72
+ Type = self # rubocop:disable Naming/ConstantName
73
+
74
+ # @return [String] the signature type character, eg "s" or "e".
75
+ attr_reader :sigtype
76
+ # @return [Array<Type>] contained member types.
77
+ attr_reader :members
78
+
79
+ # Use {DBus.type} instead, because this allows constructing
80
+ # incomplete or invalid types, for backward compatibility.
48
81
  #
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}"
82
+ # @param abstract [Boolean] allow abstract types "r" and "e"
83
+ # (Enabled for internal usage by {Parser}.)
84
+ def initialize(sigtype, abstract: false)
85
+ if !TYPE_MAPPING.keys.member?(sigtype)
86
+ case sigtype
87
+ when ")"
88
+ raise SignatureException, "STRUCT unexpectedly closed: )"
89
+ when "}"
90
+ raise SignatureException, "DICT_ENTRY unexpectedly closed: }"
91
+ else
92
+ raise SignatureException, "Unknown type code #{sigtype.inspect}"
60
93
  end
61
- @sigtype = sigtype
62
- @members = []
63
- end
64
-
65
- # Return the required alignment for the type.
66
- def alignment
67
- TypeMapping[@sigtype].last
68
94
  end
69
95
 
70
- # Return a string representation of the type according to the
71
- # D-Bus specification.
72
- def to_s
73
- case @sigtype
96
+ unless abstract
97
+ case sigtype
74
98
  when STRUCT
75
- "(" + @members.collect(&:to_s).join + ")"
76
- when ARRAY
77
- "a" + child.to_s
99
+ raise SignatureException, "Abstract STRUCT, use \"(...)\" instead of \"#{STRUCT}\""
78
100
  when DICT_ENTRY
79
- "{" + @members.collect(&:to_s).join + "}"
80
- else
81
- if !TypeMapping.keys.member?(@sigtype)
82
- raise NotImplementedError
83
- end
84
- @sigtype.chr
101
+ raise SignatureException, "Abstract DICT_ENTRY, use \"{..}\" instead of \"#{DICT_ENTRY}\""
85
102
  end
86
103
  end
87
104
 
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
+ @sigtype = sigtype.freeze
106
+ @members = [] # not frozen yet, Parser#parse_one or Factory will do it
107
+ freeze
108
+ end
109
+
110
+ # A Type is equal to
111
+ # - another Type with the same string representation
112
+ # - a String ({SingleCompleteType}) describing the type
113
+ def ==(other)
114
+ case other
115
+ when ::String
116
+ to_s == other
117
+ else
118
+ eql?(other)
105
119
  end
120
+ end
121
+
122
+ # A Type is eql? to
123
+ # - another Type with the same string representation
124
+ #
125
+ # Hash key equality
126
+ # See https://ruby-doc.org/core-3.0.0/Object.html#method-i-eql-3F
127
+ def eql?(other)
128
+ return false unless other.is_a?(Type)
129
+
130
+ @sigtype == other.sigtype && @members == other.members
131
+ end
132
+
133
+ # Return the required alignment for the type.
134
+ def alignment
135
+ TYPE_MAPPING[@sigtype].last
136
+ end
106
137
 
107
- # Return the first contained member type.
108
- def child
109
- @members[0]
138
+ # Return a string representation of the type according to the
139
+ # D-Bus specification.
140
+ def to_s
141
+ case @sigtype
142
+ when STRUCT
143
+ "(#{@members.collect(&:to_s).join})"
144
+ when ARRAY
145
+ "a#{child}"
146
+ when DICT_ENTRY
147
+ "{#{@members.collect(&:to_s).join}}"
148
+ else
149
+ @sigtype.chr
110
150
  end
151
+ end
152
+
153
+ # Add a new member type _item_.
154
+ # @param item [Type]
155
+ def <<(item)
156
+ raise ArgumentError unless item.is_a?(Type)
111
157
 
112
- def inspect
113
- s = TypeMapping[@sigtype].first
114
- if [STRUCT, ARRAY].member?(@sigtype)
115
- s += ": " + @members.inspect
158
+ if ![STRUCT, ARRAY, DICT_ENTRY].member?(@sigtype)
159
+ raise SignatureException
160
+ end
161
+ raise SignatureException if @sigtype == ARRAY && !@members.empty?
162
+
163
+ if @sigtype == DICT_ENTRY
164
+ case @members.size
165
+ when 2
166
+ raise SignatureException, "DICT_ENTRY must have 2 subtypes, found 3 or more in #{@signature}"
167
+ when 0
168
+ if [STRUCT, ARRAY, DICT_ENTRY, VARIANT].member?(item.sigtype)
169
+ raise SignatureException, "DICT_ENTRY key must be basic (non-container)"
170
+ end
116
171
  end
117
- s
118
172
  end
119
- end # class Type
173
+ @members << item
174
+ end
175
+
176
+ # Return the first contained member type.
177
+ def child
178
+ @members[0]
179
+ end
180
+
181
+ def inspect
182
+ s = TYPE_MAPPING[@sigtype].first
183
+ if [STRUCT, ARRAY, DICT_ENTRY].member?(@sigtype)
184
+ s += ": #{@members.inspect}"
185
+ end
186
+ s
187
+ end
120
188
 
121
189
  # = D-Bus type parser class
122
190
  #
123
191
  # Helper class to parse a type signature in the protocol.
192
+ # @api private
124
193
  class Parser
125
194
  # Create a new parser for the given _signature_.
195
+ # @param signature [Signature]
126
196
  def initialize(signature)
127
197
  @signature = signature
198
+ if signature.size > 255
199
+ msg = "Potential signature is longer than 255 characters (#{@signature.size}): #{@signature}"
200
+ raise SignatureException, msg
201
+ end
202
+
128
203
  @idx = 0
129
204
  end
130
205
 
@@ -135,57 +210,214 @@ module DBus
135
210
  c
136
211
  end
137
212
 
138
- # Parse one character _c_ of the signature.
139
- def parse_one(c)
213
+ # Parse one character _char_ of the signature.
214
+ # @param for_array [Boolean] are we parsing an immediate child of an ARRAY
215
+ # @return [Type]
216
+ def parse_one(char, for_array: false)
140
217
  res = nil
141
- case c
218
+ case char
142
219
  when "a"
143
220
  res = Type.new(ARRAY)
144
- c = nextchar
145
- raise SignatureException, "Parse error in #{@signature}" if c.nil?
146
- child = parse_one(c)
221
+ char = nextchar
222
+ raise SignatureException, "Empty ARRAY in #{@signature}" if char.nil?
223
+
224
+ child = parse_one(char, for_array: true)
147
225
  res << child
148
226
  when "("
149
- res = Type.new(STRUCT)
150
- while (c = nextchar) && c != ")"
151
- res << parse_one(c)
227
+ res = Type.new(STRUCT, abstract: true)
228
+ while (char = nextchar) && char != ")"
229
+ res << parse_one(char)
152
230
  end
153
- raise SignatureException, "Parse error in #{@signature}" if c.nil?
231
+ raise SignatureException, "STRUCT not closed in #{@signature}" if char.nil?
232
+ raise SignatureException, "Empty STRUCT in #{@signature}" if res.members.empty?
154
233
  when "{"
155
- res = Type.new(DICT_ENTRY)
156
- while (c = nextchar) && c != "}"
157
- res << parse_one(c)
234
+ raise SignatureException, "DICT_ENTRY not an immediate child of an ARRAY" unless for_array
235
+
236
+ res = Type.new(DICT_ENTRY, abstract: true)
237
+
238
+ # key type, value type
239
+ 2.times do |i|
240
+ char = nextchar
241
+ raise SignatureException, "DICT_ENTRY not closed in #{@signature}" if char.nil?
242
+
243
+ raise SignatureException, "DICT_ENTRY must have 2 subtypes, found #{i} in #{@signature}" if char == "}"
244
+
245
+ res << parse_one(char)
158
246
  end
159
- raise SignatureException, "Parse error in #{@signature}" if c.nil?
247
+
248
+ # closing "}"
249
+ char = nextchar
250
+ raise SignatureException, "DICT_ENTRY not closed in #{@signature}" if char.nil?
251
+
252
+ raise SignatureException, "DICT_ENTRY must have 2 subtypes, found 3 or more in #{@signature}" if char != "}"
160
253
  else
161
- res = Type.new(c)
254
+ res = Type.new(char)
162
255
  end
256
+ res.members.freeze
163
257
  res
164
258
  end
165
259
 
166
260
  # Parse the entire signature, return a DBus::Type object.
261
+ # @return [Array<Type>]
167
262
  def parse
168
263
  @idx = 0
169
264
  ret = []
170
265
  while (c = nextchar)
171
266
  ret << parse_one(c)
172
267
  end
173
- ret
268
+ ret.freeze
269
+ end
270
+
271
+ # Parse one {SingleCompleteType}
272
+ # @return [Type]
273
+ def parse1
274
+ c = nextchar
275
+ raise SignatureException, "Empty signature, expecting a Single Complete Type" if c.nil?
276
+
277
+ t = parse_one(c)
278
+ raise SignatureException, "Has more than a Single Complete Type: #{@signature}" unless nextchar.nil?
279
+
280
+ t.freeze
281
+ end
282
+ end
283
+
284
+ class Factory
285
+ # @param type [Type,SingleCompleteType,Class]
286
+ # @see from_plain_class
287
+ # @return [Type] (frozen)
288
+ def self.make_type(type)
289
+ case type
290
+ when Type
291
+ type
292
+ when String
293
+ DBus.type(type)
294
+ when Class
295
+ from_plain_class(type)
296
+ else
297
+ msg = "Expecting DBus::Type, DBus::SingleCompleteType(aka ::String), or Class, got #{type.inspect}"
298
+ raise ArgumentError, msg
299
+ end
174
300
  end
175
- end # class Parser
176
- end # module Type
301
+
302
+ # Make a {Type} corresponding to some plain classes:
303
+ # - String
304
+ # - Float
305
+ # - DBus::ObjectPath
306
+ # - DBus::Signature, DBus::SingleCompleteType
307
+ # @param klass [Class]
308
+ # @return [Type] (frozen)
309
+ def self.from_plain_class(klass)
310
+ @signature_type ||= DBus.type(SIGNATURE)
311
+ @class_to_type ||= {
312
+ DBus::ObjectPath => DBus.type(OBJECT_PATH),
313
+ DBus::Signature => @signature_type,
314
+ DBus::SingleCompleteType => @signature_type,
315
+ String => DBus.type(STRING),
316
+ Float => DBus.type(DOUBLE)
317
+ }
318
+ t = @class_to_type[klass]
319
+ raise ArgumentError, "Cannot convert plain class #{klass} to a D-Bus type" if t.nil?
320
+
321
+ t
322
+ end
323
+ end
324
+
325
+ # Syntactic helper for constructing an array Type.
326
+ # You may be looking for {Data::Array} instead.
327
+ # @example
328
+ # t = Type::Array[Type::INT16]
329
+ class ArrayFactory < Factory
330
+ # @param member_type [Type,SingleCompleteType]
331
+ # @return [Type] (frozen)
332
+ def self.[](member_type)
333
+ t = Type.new(ARRAY)
334
+ t << make_type(member_type)
335
+ t.members.freeze
336
+ t
337
+ end
338
+ end
339
+
340
+ # @example
341
+ # t = Type::Array[Type::INT16]
342
+ Array = ArrayFactory
343
+
344
+ # Syntactic helper for constructing a hash Type.
345
+ # You may be looking for {Data::Array} and {Data::DictEntry} instead.
346
+ # @example
347
+ # t = Type::Hash[Type::STRING, Type::VARIANT]
348
+ class HashFactory < Factory
349
+ # @param key_type [Type,SingleCompleteType]
350
+ # @param value_type [Type,SingleCompleteType]
351
+ # @return [Type] (frozen)
352
+ def self.[](key_type, value_type)
353
+ t = Type.new(ARRAY)
354
+ de = Type.new(DICT_ENTRY, abstract: true)
355
+ de << make_type(key_type)
356
+ de << make_type(value_type)
357
+ de.members.freeze
358
+ t << de
359
+ t.members.freeze
360
+ t
361
+ end
362
+ end
363
+
364
+ # @example
365
+ # t = Type::Hash[Type::INT16]
366
+ Hash = HashFactory
367
+
368
+ # Syntactic helper for constructing a struct Type.
369
+ # You may be looking for {Data::Struct} instead.
370
+ # @example
371
+ # t = Type::Struct[Type::INT16, Type::STRING]
372
+ class StructFactory < Factory
373
+ # @param member_types [::Array<Type,SingleCompleteType>]
374
+ # @return [Type] (frozen)
375
+ def self.[](*member_types)
376
+ raise ArgumentError if member_types.empty?
377
+
378
+ t = Type.new(STRUCT, abstract: true)
379
+ member_types.each do |mt|
380
+ t << make_type(mt)
381
+ end
382
+ t.members.freeze
383
+ t
384
+ end
385
+ end
386
+
387
+ # @example
388
+ # t = Type::Struct[Type::INT16, Type::STRING]
389
+ Struct = StructFactory
390
+ end
177
391
 
178
392
  # shortcuts
179
393
 
180
- # Parse a String to a DBus::Type::Type
394
+ # Parse a String to a valid {DBus::Type}.
395
+ # This is prefered to {Type#initialize} which allows
396
+ # incomplete or invalid types.
397
+ # @param string_type [SingleCompleteType]
398
+ # @return [DBus::Type] (frozen)
399
+ # @raise SignatureException
181
400
  def type(string_type)
182
- Type::Parser.new(string_type).parse[0]
401
+ Type::Parser.new(string_type).parse1
183
402
  end
184
403
  module_function :type
185
404
 
405
+ # Parse a String to zero or more {DBus::Type}s.
406
+ # @param string_type [Signature]
407
+ # @return [Array<DBus::Type>] (frozen)
408
+ # @raise SignatureException
409
+ def types(string_type)
410
+ Type::Parser.new(string_type).parse
411
+ end
412
+ module_function :types
413
+
186
414
  # Make an explicit [Type, value] pair
415
+ # @param string_type [SingleCompleteType]
416
+ # @param value [::Object]
417
+ # @return [Array(DBus::Type::Type,::Object)]
418
+ # @deprecated Use {Data::Variant#initialize} instead
187
419
  def variant(string_type, value)
188
- [type(string_type), value]
420
+ Data::Variant.new(value, member_type: string_type)
189
421
  end
190
422
  module_function :variant
191
- end # module DBus
423
+ 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
 
@@ -125,6 +134,10 @@ module DBus
125
134
  parse_methsig(se, s)
126
135
  i << s
127
136
  end
137
+ e.each("property") do |pe|
138
+ p = Property.from_xml(pe)
139
+ i << p
140
+ end
128
141
  end
129
142
  d = Time.now - t
130
143
  if d > 2
@@ -136,28 +149,30 @@ module DBus
136
149
  ######################################################################
137
150
  private
138
151
 
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|
152
+ # Parses a method signature XML element *elem* and initialises
153
+ # method/signal *methsig*.
154
+ # @param elem [AbstractXML::Node]
155
+ def parse_methsig(elem, methsig)
156
+ elem.each("arg") do |ae|
143
157
  name = ae["name"]
144
158
  dir = ae["direction"]
145
159
  sig = ae["type"]
146
- if m.is_a?(DBus::Signal)
160
+ case methsig
161
+ when DBus::Signal
147
162
  # Direction can only be "out", ignore it
148
- m.add_fparam(name, sig)
149
- elsif m.is_a?(DBus::Method)
163
+ methsig.add_fparam(name, sig)
164
+ when DBus::Method
150
165
  case dir
151
166
  # This is a method, so dir defaults to "in"
152
167
  when "in", nil
153
- m.add_fparam(name, sig)
168
+ methsig.add_fparam(name, sig)
154
169
  when "out"
155
- m.add_return(name, sig)
170
+ methsig.add_return(name, sig)
156
171
  end
157
172
  else
158
173
  raise NotImplementedError, dir
159
174
  end
160
175
  end
161
176
  end
162
- end # class IntrospectXMLParser
163
- end # module DBus
177
+ end
178
+ 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
@@ -12,6 +14,8 @@ require_relative "dbus/api_options"
12
14
  require_relative "dbus/auth"
13
15
  require_relative "dbus/bus"
14
16
  require_relative "dbus/bus_name"
17
+ require_relative "dbus/data"
18
+ require_relative "dbus/emits_changed_signal"
15
19
  require_relative "dbus/error"
16
20
  require_relative "dbus/introspect"
17
21
  require_relative "dbus/logger"
@@ -24,31 +28,34 @@ require_relative "dbus/object_path"
24
28
  require_relative "dbus/proxy_object"
25
29
  require_relative "dbus/proxy_object_factory"
26
30
  require_relative "dbus/proxy_object_interface"
31
+ require_relative "dbus/raw_message"
27
32
  require_relative "dbus/type"
28
33
  require_relative "dbus/xml"
29
34
 
30
35
  require "socket"
31
- require "thread"
32
-
33
36
  # = D-Bus main module
34
37
  #
35
38
  # Module containing all the D-Bus modules and classes.
36
39
  module DBus
37
40
  # Default socket name for the system bus.
38
- SystemSocketName = "unix:path=/var/run/dbus/system_bus_socket".freeze
41
+ SYSTEM_BUS_ADDRESS = "unix:path=/var/run/dbus/system_bus_socket"
39
42
 
40
43
  # Byte signifying big endianness.
41
- BIG_END = "B".freeze
44
+ BIG_END = "B"
42
45
  # Byte signifying little endianness.
43
- LIL_END = "l".freeze
46
+ LIL_END = "l"
44
47
 
45
48
  # Byte signifying the host's endianness.
46
- HOST_END = if [0x01020304].pack("L").unpack("V")[0] == 0x01020304
49
+ HOST_END = if [0x01020304].pack("L").unpack1("V") == 0x01020304
47
50
  LIL_END
48
51
  else
49
52
  BIG_END
50
53
  end
51
54
 
55
+ # Comparing symbols is faster than strings
56
+ # @return [:little,:big]
57
+ HOST_ENDIANNESS = RawMessage.endianness(HOST_END)
58
+
52
59
  # General exceptions.
53
60
 
54
61
  # Exception raised when there is a problem with a type (may be unknown or
@@ -69,4 +76,4 @@ module DBus
69
76
  # Exception raised when invalid introspection data is parsed/used.
70
77
  class InvalidIntrospectionData < Exception
71
78
  end
72
- end # module DBus
79
+ end
data/ruby-dbus.gemspec CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # -*- ruby -*-
2
4
  require "rubygems"
3
5
 
@@ -18,15 +20,17 @@ GEMSPEC = Gem::Specification.new do |s|
18
20
  ]
19
21
  s.require_path = "lib"
20
22
 
21
- s.required_ruby_version = ">= 2.0.0"
23
+ s.required_ruby_version = ">= 2.4.0"
24
+
25
+ s.add_dependency "rexml"
22
26
 
23
27
  # This is optional
24
28
  # s.add_runtime_dependency "nokogiri"
25
29
 
26
- s.add_development_dependency "coveralls"
27
30
  s.add_development_dependency "packaging_rake_tasks"
28
31
  s.add_development_dependency "rake"
29
32
  s.add_development_dependency "rspec", "~> 3"
30
- s.add_development_dependency "rubocop", "= 0.41.2"
33
+ s.add_development_dependency "rubocop", "= 1.0"
31
34
  s.add_development_dependency "simplecov"
35
+ s.add_development_dependency "simplecov-lcov"
32
36
  end