ruby-dbus 0.16.0 → 0.18.0.beta2

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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/NEWS.md +46 -0
  3. data/README.md +3 -5
  4. data/Rakefile +18 -8
  5. data/VERSION +1 -1
  6. data/doc/Reference.md +94 -4
  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 +126 -74
  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 +725 -0
  26. data/lib/dbus/error.rb +4 -2
  27. data/lib/dbus/introspect.rb +91 -30
  28. data/lib/dbus/logger.rb +3 -1
  29. data/lib/dbus/marshall.rb +228 -294
  30. data/lib/dbus/matchrule.rb +16 -16
  31. data/lib/dbus/message.rb +44 -37
  32. data/lib/dbus/message_queue.rb +16 -10
  33. data/lib/dbus/object.rb +296 -24
  34. data/lib/dbus/object_path.rb +11 -6
  35. data/lib/dbus/proxy_object.rb +22 -1
  36. data/lib/dbus/proxy_object_factory.rb +11 -7
  37. data/lib/dbus/proxy_object_interface.rb +26 -21
  38. data/lib/dbus/raw_message.rb +91 -0
  39. data/lib/dbus/type.rb +182 -80
  40. data/lib/dbus/xml.rb +28 -17
  41. data/lib/dbus.rb +13 -7
  42. data/ruby-dbus.gemspec +7 -3
  43. data/spec/async_spec.rb +2 -0
  44. data/spec/binding_spec.rb +2 -0
  45. data/spec/bus_and_xml_backend_spec.rb +2 -0
  46. data/spec/bus_driver_spec.rb +2 -0
  47. data/spec/bus_name_spec.rb +3 -1
  48. data/spec/bus_spec.rb +2 -0
  49. data/spec/byte_array_spec.rb +2 -0
  50. data/spec/client_robustness_spec.rb +4 -2
  51. data/spec/data/marshall.yaml +1639 -0
  52. data/spec/data_spec.rb +298 -0
  53. data/spec/err_msg_spec.rb +2 -0
  54. data/spec/introspect_xml_parser_spec.rb +2 -0
  55. data/spec/introspection_spec.rb +2 -0
  56. data/spec/main_loop_spec.rb +3 -1
  57. data/spec/node_spec.rb +23 -0
  58. data/spec/object_path_spec.rb +3 -0
  59. data/spec/packet_marshaller_spec.rb +34 -0
  60. data/spec/packet_unmarshaller_spec.rb +262 -0
  61. data/spec/property_spec.rb +88 -5
  62. data/spec/proxy_object_spec.rb +2 -0
  63. data/spec/server_robustness_spec.rb +2 -0
  64. data/spec/server_spec.rb +2 -0
  65. data/spec/service_newapi.rb +39 -70
  66. data/spec/session_bus_spec.rb +3 -1
  67. data/spec/session_bus_spec_manual.rb +2 -0
  68. data/spec/signal_spec.rb +5 -3
  69. data/spec/spec_helper.rb +35 -9
  70. data/spec/thread_safety_spec.rb +2 -0
  71. data/spec/tools/dbus-limited-session.conf +4 -0
  72. data/spec/type_spec.rb +69 -6
  73. data/spec/value_spec.rb +16 -1
  74. data/spec/variant_spec.rb +4 -2
  75. metadata +32 -10
data/lib/dbus/error.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # error.rb
2
4
  #
3
5
  # This file is part of the ruby-dbus project
@@ -32,7 +34,7 @@ module DBus
32
34
  end
33
35
  # TODO: validate error name
34
36
  end
35
- end # class Error
37
+ end
36
38
 
37
39
  # @example raise a generic error
38
40
  # raise DBus.error, "message"
@@ -43,4 +45,4 @@ module DBus
43
45
  DBus::Error.new(nil, name)
44
46
  end
45
47
  module_function :error
46
- end # module DBus
48
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # dbus/introspection.rb - module containing a low-level D-Bus introspection implementation
2
4
  #
3
5
  # This file is part of the ruby-dbus project
@@ -10,9 +12,9 @@
10
12
 
11
13
  module DBus
12
14
  # Regular expressions that should match all method names.
13
- METHOD_SIGNAL_RE = /^[A-Za-z][A-Za-z0-9_]*$/
15
+ METHOD_SIGNAL_RE = /^[A-Za-z][A-Za-z0-9_]*$/.freeze
14
16
  # Regular expressions that should match all interface names.
15
- INTERFACE_ELEMENT_RE = /^[A-Za-z][A-Za-z0-9_]*$/
17
+ INTERFACE_ELEMENT_RE = /^[A-Za-z][A-Za-z0-9_]*$/.freeze
16
18
 
17
19
  # Exception raised when an invalid class definition is encountered.
18
20
  class InvalidClassDefinition < Exception
@@ -26,19 +28,23 @@ module DBus
26
28
  # It also is the local definition of interface exported by the program.
27
29
  # At the client side, see ProxyObjectInterface
28
30
  class Interface
29
- # The name of the interface. String
31
+ # @return [String] The name of the interface.
30
32
  attr_reader :name
31
- # The methods that are part of the interface. Hash: Symbol => DBus::Method
33
+ # @return [Hash{Symbol => DBus::Method}] The methods that are part of the interface.
32
34
  attr_reader :methods
33
- # The signals that are part of the interface. Hash: Symbol => Signal
35
+ # @return [Hash{Symbol => Signal}] The signals that are part of the interface.
34
36
  attr_reader :signals
35
37
 
38
+ # @return [Hash{Symbol => Property}]
39
+ attr_reader :properties
40
+
36
41
  # Creates a new interface with a given _name_.
37
42
  def initialize(name)
38
43
  validate_name(name)
39
44
  @name = name
40
45
  @methods = {}
41
46
  @signals = {}
47
+ @properties = {}
42
48
  end
43
49
 
44
50
  # Validates a service _name_.
@@ -47,33 +53,45 @@ module DBus
47
53
  raise InvalidIntrospectionData if name =~ /^\./ || name =~ /\.$/
48
54
  raise InvalidIntrospectionData if name =~ /\.\./
49
55
  raise InvalidIntrospectionData if name !~ /\./
56
+
50
57
  name.split(".").each do |element|
51
58
  raise InvalidIntrospectionData if element !~ INTERFACE_ELEMENT_RE
52
59
  end
53
60
  end
54
61
 
55
- # Helper method for defining a method _m_.
56
- def define(m)
57
- if m.is_a?(Method)
58
- @methods[m.name.to_sym] = m
59
- elsif m.is_a?(Signal)
60
- @signals[m.name.to_sym] = m
61
- end
62
+ # Add _ifc_el_ as a known {Method}, {Signal} or {Property}
63
+ # @param ifc_el [InterfaceElement]
64
+ def define(ifc_el)
65
+ name = ifc_el.name.to_sym
66
+ category = case ifc_el
67
+ when Method
68
+ @methods
69
+ when Signal
70
+ @signals
71
+ when Property
72
+ @properties
73
+ end
74
+ category[name] = ifc_el
62
75
  end
76
+ alias declare define
63
77
  alias << define
64
78
 
65
79
  # Defines a method with name _id_ and a given _prototype_ in the
66
80
  # interface.
81
+ # Better name: declare_method
67
82
  def define_method(id, prototype)
68
83
  m = Method.new(id)
69
84
  m.from_prototype(prototype)
70
85
  define(m)
71
86
  end
72
- end # class Interface
87
+ alias declare_method define_method
88
+ end
73
89
 
74
90
  # = A formal parameter has a name and a type
75
91
  class FormalParameter
92
+ # @return [#to_s]
76
93
  attr_reader :name
94
+ # @return [SingleCompleteType]
77
95
  attr_reader :type
78
96
 
79
97
  def initialize(name, type)
@@ -95,14 +113,16 @@ module DBus
95
113
  # This is a generic class for entities that are part of the interface
96
114
  # such as methods and signals.
97
115
  class InterfaceElement
98
- # The name of the interface element. Symbol
116
+ # @return [Symbol] The name of the interface element
99
117
  attr_reader :name
100
- # The parameters of the interface element. Array: FormalParameter
118
+
119
+ # @return [Array<FormalParameter>] The parameters of the interface element
101
120
  attr_reader :params
102
121
 
103
122
  # Validates element _name_.
104
123
  def validate_name(name)
105
124
  return if (name =~ METHOD_SIGNAL_RE) && (name.bytesize <= 255)
125
+
106
126
  raise InvalidMethodName, name
107
127
  end
108
128
 
@@ -123,13 +143,13 @@ module DBus
123
143
  def add_param(name_signature_pair)
124
144
  add_fparam(*name_signature_pair)
125
145
  end
126
- end # class InterfaceElement
146
+ end
127
147
 
128
148
  # = D-Bus interface method class
129
149
  #
130
150
  # This is a class representing methods that are part of an interface.
131
151
  class Method < InterfaceElement
132
- # The list of return values for the method. Array: FormalParameter
152
+ # @return [Array<FormalParameter>] The list of return values for the method
133
153
  attr_reader :rets
134
154
 
135
155
  # Creates a new method interface element with the given _name_.
@@ -139,15 +159,19 @@ module DBus
139
159
  end
140
160
 
141
161
  # Add a return value _name_ and _signature_.
162
+ # @param name [#to_s]
163
+ # @param signature [SingleCompleteType]
142
164
  def add_return(name, signature)
143
165
  @rets << FormalParameter.new(name, signature)
144
166
  end
145
167
 
146
168
  # Add parameter types by parsing the given _prototype_.
169
+ # @param prototype [Prototype]
147
170
  def from_prototype(prototype)
148
171
  prototype.split(/, */).each do |arg|
149
172
  arg = arg.split(" ")
150
173
  raise InvalidClassDefinition if arg.size != 2
174
+
151
175
  dir, arg = arg
152
176
  if arg =~ /:/
153
177
  arg = arg.split(":")
@@ -167,19 +191,19 @@ module DBus
167
191
 
168
192
  # Return an XML string representation of the method interface elment.
169
193
  def to_xml
170
- xml = %(<method name="#{@name}">\n)
194
+ xml = " <method name=\"#{@name}\">\n"
171
195
  @params.each do |param|
172
- name = param.name ? %(name="#{param.name}" ) : ""
173
- xml += %(<arg #{name}direction="in" type="#{param.type}"/>\n)
196
+ name = param.name ? "name=\"#{param.name}\" " : ""
197
+ xml += " <arg #{name}direction=\"in\" type=\"#{param.type}\"/>\n"
174
198
  end
175
199
  @rets.each do |param|
176
- name = param.name ? %(name="#{param.name}" ) : ""
177
- xml += %(<arg #{name}direction="out" type="#{param.type}"/>\n)
200
+ name = param.name ? "name=\"#{param.name}\" " : ""
201
+ xml += " <arg #{name}direction=\"out\" type=\"#{param.type}\"/>\n"
178
202
  end
179
- xml += %(</method>\n)
203
+ xml += " </method>\n"
180
204
  xml
181
205
  end
182
- end # class Method
206
+ end
183
207
 
184
208
  # = D-Bus interface signal class
185
209
  #
@@ -201,13 +225,50 @@ module DBus
201
225
 
202
226
  # Return an XML string representation of the signal interface elment.
203
227
  def to_xml
204
- xml = %(<signal name="#{@name}">\n)
228
+ xml = " <signal name=\"#{@name}\">\n"
205
229
  @params.each do |param|
206
- name = param.name ? %(name="#{param.name}" ) : ""
207
- xml += %(<arg #{name}type="#{param.type}"/>\n)
230
+ name = param.name ? "name=\"#{param.name}\" " : ""
231
+ xml += " <arg #{name}type=\"#{param.type}\"/>\n"
208
232
  end
209
- xml += %(</signal>\n)
233
+ xml += " </signal>\n"
210
234
  xml
211
235
  end
212
- end # class Signal
213
- end # module DBus
236
+ end
237
+
238
+ # An (exported) property
239
+ # https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties
240
+ class Property
241
+ # @return [String] The name of the property, for example FooBar.
242
+ attr_reader :name
243
+ # @return [SingleCompleteType]
244
+ attr_reader :type
245
+ # @return [Symbol] :read :write or :readwrite
246
+ attr_reader :access
247
+
248
+ # @return [Symbol] What to call at Ruby side.
249
+ # (Always without the trailing `=`)
250
+ attr_reader :ruby_name
251
+
252
+ def initialize(name, type, access, ruby_name:)
253
+ @name = name
254
+ @type = type
255
+ @access = access
256
+ @ruby_name = ruby_name
257
+ end
258
+
259
+ # @return [Boolean]
260
+ def readable?
261
+ access == :read || access == :readwrite
262
+ end
263
+
264
+ # @return [Boolean]
265
+ def writable?
266
+ access == :write || access == :readwrite
267
+ end
268
+
269
+ # Return introspection XML string representation of the property.
270
+ def to_xml
271
+ " <property type=\"#{@type}\" name=\"#{@name}\" access=\"#{@access}\"/>\n"
272
+ end
273
+ end
274
+ end
data/lib/dbus/logger.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # dbus/logger.rb - debug logging
2
4
  #
3
5
  # This file is part of the ruby-dbus project
@@ -16,7 +18,7 @@ module DBus
16
18
  # with DEBUG if $DEBUG is set, otherwise INFO.
17
19
  def logger
18
20
  unless defined? @logger
19
- @logger = Logger.new(STDERR)
21
+ @logger = Logger.new($stderr)
20
22
  @logger.level = $DEBUG ? Logger::DEBUG : Logger::INFO
21
23
  end
22
24
  @logger