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.
- checksums.yaml +4 -4
- data/NEWS.md +46 -0
- data/README.md +3 -5
- data/Rakefile +18 -8
- data/VERSION +1 -1
- data/doc/Reference.md +94 -4
- data/examples/doc/_extract_examples +7 -0
- data/examples/gdbus/gdbus +31 -24
- data/examples/no-introspect/nm-test.rb +2 -0
- data/examples/no-introspect/tracker-test.rb +3 -1
- data/examples/rhythmbox/playpause.rb +2 -1
- data/examples/service/call_service.rb +2 -1
- data/examples/service/complex-property.rb +21 -0
- data/examples/service/service_newapi.rb +1 -1
- data/examples/simple/call_introspect.rb +1 -0
- data/examples/simple/get_id.rb +2 -1
- data/examples/simple/properties.rb +2 -0
- data/examples/utils/listnames.rb +1 -0
- data/examples/utils/notify.rb +1 -0
- data/lib/dbus/api_options.rb +9 -0
- data/lib/dbus/auth.rb +20 -15
- data/lib/dbus/bus.rb +126 -74
- data/lib/dbus/bus_name.rb +12 -8
- data/lib/dbus/core_ext/class/attribute.rb +1 -1
- data/lib/dbus/data.rb +725 -0
- data/lib/dbus/error.rb +4 -2
- data/lib/dbus/introspect.rb +91 -30
- data/lib/dbus/logger.rb +3 -1
- data/lib/dbus/marshall.rb +228 -294
- data/lib/dbus/matchrule.rb +16 -16
- data/lib/dbus/message.rb +44 -37
- data/lib/dbus/message_queue.rb +16 -10
- data/lib/dbus/object.rb +296 -24
- data/lib/dbus/object_path.rb +11 -6
- data/lib/dbus/proxy_object.rb +22 -1
- data/lib/dbus/proxy_object_factory.rb +11 -7
- data/lib/dbus/proxy_object_interface.rb +26 -21
- data/lib/dbus/raw_message.rb +91 -0
- data/lib/dbus/type.rb +182 -80
- data/lib/dbus/xml.rb +28 -17
- data/lib/dbus.rb +13 -7
- data/ruby-dbus.gemspec +7 -3
- data/spec/async_spec.rb +2 -0
- data/spec/binding_spec.rb +2 -0
- data/spec/bus_and_xml_backend_spec.rb +2 -0
- data/spec/bus_driver_spec.rb +2 -0
- data/spec/bus_name_spec.rb +3 -1
- data/spec/bus_spec.rb +2 -0
- data/spec/byte_array_spec.rb +2 -0
- data/spec/client_robustness_spec.rb +4 -2
- data/spec/data/marshall.yaml +1639 -0
- data/spec/data_spec.rb +298 -0
- data/spec/err_msg_spec.rb +2 -0
- data/spec/introspect_xml_parser_spec.rb +2 -0
- data/spec/introspection_spec.rb +2 -0
- data/spec/main_loop_spec.rb +3 -1
- data/spec/node_spec.rb +23 -0
- data/spec/object_path_spec.rb +3 -0
- data/spec/packet_marshaller_spec.rb +34 -0
- data/spec/packet_unmarshaller_spec.rb +262 -0
- data/spec/property_spec.rb +88 -5
- data/spec/proxy_object_spec.rb +2 -0
- data/spec/server_robustness_spec.rb +2 -0
- data/spec/server_spec.rb +2 -0
- data/spec/service_newapi.rb +39 -70
- data/spec/session_bus_spec.rb +3 -1
- data/spec/session_bus_spec_manual.rb +2 -0
- data/spec/signal_spec.rb +5 -3
- data/spec/spec_helper.rb +35 -9
- data/spec/thread_safety_spec.rb +2 -0
- data/spec/tools/dbus-limited-session.conf +4 -0
- data/spec/type_spec.rb +69 -6
- data/spec/value_spec.rb +16 -1
- data/spec/variant_spec.rb +4 -2
- metadata +32 -10
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file is part of the ruby-dbus project
|
4
|
+
# Copyright (C) 2022 Martin Vidner
|
5
|
+
#
|
6
|
+
# This library is free software; you can redistribute it and/or
|
7
|
+
# modify it under the terms of the GNU Lesser General Public
|
8
|
+
# License, version 2.1 as published by the Free Software Foundation.
|
9
|
+
# See the file "COPYING" for the exact licensing terms.
|
10
|
+
|
11
|
+
module DBus
|
12
|
+
# A message while it is being parsed: a binary string,
|
13
|
+
# with a position cursor (*pos*), and an *endianness* tag.
|
14
|
+
class RawMessage
|
15
|
+
# @return [String]
|
16
|
+
# attr_reader :bytes
|
17
|
+
|
18
|
+
# @return [Integer] position in the byte buffer
|
19
|
+
attr_reader :pos
|
20
|
+
|
21
|
+
# @return [:little,:big]
|
22
|
+
attr_reader :endianness
|
23
|
+
|
24
|
+
# @param bytes [String]
|
25
|
+
# @param endianness [:little,:big,nil]
|
26
|
+
# if not given, read the 1st byte of *bytes*
|
27
|
+
def initialize(bytes, endianness = nil)
|
28
|
+
@bytes = bytes
|
29
|
+
@pos = 0
|
30
|
+
@endianness = endianness || self.class.endianness(@bytes[0])
|
31
|
+
end
|
32
|
+
|
33
|
+
# Get the endiannes switch as a Symbol,
|
34
|
+
# which will make using it slightly more efficient
|
35
|
+
# @param tag_char [String]
|
36
|
+
# @return [:little,:big]
|
37
|
+
def self.endianness(tag_char)
|
38
|
+
case tag_char
|
39
|
+
when LIL_END
|
40
|
+
:little
|
41
|
+
when BIG_END
|
42
|
+
:big
|
43
|
+
else
|
44
|
+
raise InvalidPacketException, "Incorrect endianness #{tag_char.inspect}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [void]
|
49
|
+
# @raise IncompleteBufferException if there are not enough bytes remaining
|
50
|
+
def want!(size)
|
51
|
+
raise IncompleteBufferException if @pos + size > @bytes.bytesize
|
52
|
+
end
|
53
|
+
|
54
|
+
# @return [String]
|
55
|
+
# @raise IncompleteBufferException if there are not enough bytes remaining
|
56
|
+
# TODO: stress test this with encodings. always binary?
|
57
|
+
def read(size)
|
58
|
+
want!(size)
|
59
|
+
ret = @bytes.slice(@pos, size)
|
60
|
+
@pos += size
|
61
|
+
ret
|
62
|
+
end
|
63
|
+
|
64
|
+
# @return [String]
|
65
|
+
# @api private
|
66
|
+
def remaining_bytes
|
67
|
+
# This returns "" if pos is just past the end of the string,
|
68
|
+
# and nil if it is further.
|
69
|
+
@bytes[@pos..-1]
|
70
|
+
end
|
71
|
+
|
72
|
+
# Align the *pos* index on a multiple of *alignment*
|
73
|
+
# @param alignment [Integer] must be 1, 2, 4 or 8
|
74
|
+
# @return [void]
|
75
|
+
def align(alignment)
|
76
|
+
case alignment
|
77
|
+
when 1
|
78
|
+
nil
|
79
|
+
when 2, 4, 8
|
80
|
+
bits = alignment - 1
|
81
|
+
pad_size = ((@pos + bits) & ~bits) - @pos
|
82
|
+
pad = read(pad_size)
|
83
|
+
unless pad.bytes.all?(&:zero?)
|
84
|
+
raise InvalidPacketException, "Alignment bytes are not NUL"
|
85
|
+
end
|
86
|
+
else
|
87
|
+
raise ArgumentError, "Unsupported alignment #{alignment}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
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
|
@@ -9,13 +11,35 @@
|
|
9
11
|
# See the file "COPYING" for the exact licensing terms.
|
10
12
|
|
11
13
|
module DBus
|
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".
|
28
|
+
#
|
29
|
+
# For documentation purposes only.
|
30
|
+
class Prototype < String; end
|
31
|
+
|
12
32
|
# = D-Bus type module
|
13
33
|
#
|
14
34
|
# This module containts the constants of the types specified in the D-Bus
|
15
35
|
# protocol.
|
16
|
-
|
36
|
+
#
|
37
|
+
# Corresponds to {SingleCompleteType}.
|
38
|
+
#
|
39
|
+
# See also {DBus::Data::Signature}
|
40
|
+
class Type
|
17
41
|
# Mapping from type number to name and alignment.
|
18
|
-
|
42
|
+
TYPE_MAPPING = {
|
19
43
|
0 => ["INVALID", nil],
|
20
44
|
"y" => ["BYTE", 1],
|
21
45
|
"b" => ["BOOLEAN", 4],
|
@@ -36,7 +60,7 @@ module DBus
|
|
36
60
|
"h" => ["UNIX_FD", 4]
|
37
61
|
}.freeze
|
38
62
|
# Defines the set of constants
|
39
|
-
|
63
|
+
TYPE_MAPPING.each_pair do |key, value|
|
40
64
|
Type.const_set(value.first, key)
|
41
65
|
end
|
42
66
|
|
@@ -44,87 +68,117 @@ module DBus
|
|
44
68
|
class SignatureException < Exception
|
45
69
|
end
|
46
70
|
|
47
|
-
#
|
71
|
+
# Formerly this was a Module and there was a DBus::Type::Type class
|
72
|
+
# but the class got too prominent to keep its double double name.
|
73
|
+
# This is for backward compatibility.
|
74
|
+
Type = self # rubocop:disable Naming/ConstantName
|
75
|
+
|
76
|
+
# @return [String] the signature type character, eg "s" or "e".
|
77
|
+
attr_reader :sigtype
|
78
|
+
# @return [Array<Type>] contained member types.
|
79
|
+
attr_reader :members
|
80
|
+
|
81
|
+
# Use {DBus.type} instead, because this allows constructing
|
82
|
+
# incomplete or invalid types, for backward compatibility.
|
48
83
|
#
|
49
|
-
#
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
raise SignatureException, "Unknown
|
84
|
+
# @param abstract [Boolean] allow abstract types "r" and "e"
|
85
|
+
# (Enabled for internal usage by {Parser}.)
|
86
|
+
def initialize(sigtype, abstract: false)
|
87
|
+
if !TYPE_MAPPING.keys.member?(sigtype)
|
88
|
+
case sigtype
|
89
|
+
when ")"
|
90
|
+
raise SignatureException, "STRUCT unexpectedly closed: )"
|
91
|
+
when "}"
|
92
|
+
raise SignatureException, "DICT_ENTRY unexpectedly closed: }"
|
93
|
+
else
|
94
|
+
raise SignatureException, "Unknown type code #{sigtype.inspect}"
|
60
95
|
end
|
61
|
-
@sigtype = sigtype
|
62
|
-
@members = []
|
63
96
|
end
|
64
97
|
|
65
|
-
|
66
|
-
|
67
|
-
TypeMapping[@sigtype].last
|
68
|
-
end
|
69
|
-
|
70
|
-
# Return a string representation of the type according to the
|
71
|
-
# D-Bus specification.
|
72
|
-
def to_s
|
73
|
-
case @sigtype
|
98
|
+
unless abstract
|
99
|
+
case sigtype
|
74
100
|
when STRUCT
|
75
|
-
"
|
76
|
-
when ARRAY
|
77
|
-
"a" + child.to_s
|
101
|
+
raise SignatureException, "Abstract STRUCT, use \"(...)\" instead of \"#{STRUCT}\""
|
78
102
|
when DICT_ENTRY
|
79
|
-
"{"
|
80
|
-
else
|
81
|
-
if !TypeMapping.keys.member?(@sigtype)
|
82
|
-
raise NotImplementedError
|
83
|
-
end
|
84
|
-
@sigtype.chr
|
103
|
+
raise SignatureException, "Abstract DICT_ENTRY, use \"{..}\" instead of \"#{DICT_ENTRY}\""
|
85
104
|
end
|
86
105
|
end
|
87
106
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
107
|
+
@sigtype = sigtype
|
108
|
+
@members = []
|
109
|
+
end
|
110
|
+
|
111
|
+
# Return the required alignment for the type.
|
112
|
+
def alignment
|
113
|
+
TYPE_MAPPING[@sigtype].last
|
114
|
+
end
|
115
|
+
|
116
|
+
# Return a string representation of the type according to the
|
117
|
+
# D-Bus specification.
|
118
|
+
def to_s
|
119
|
+
case @sigtype
|
120
|
+
when STRUCT
|
121
|
+
"(#{@members.collect(&:to_s).join})"
|
122
|
+
when ARRAY
|
123
|
+
"a#{child}"
|
124
|
+
when DICT_ENTRY
|
125
|
+
"{#{@members.collect(&:to_s).join}}"
|
126
|
+
else
|
127
|
+
if !TYPE_MAPPING.keys.member?(@sigtype)
|
128
|
+
raise NotImplementedError
|
103
129
|
end
|
104
|
-
|
130
|
+
|
131
|
+
@sigtype.chr
|
105
132
|
end
|
133
|
+
end
|
106
134
|
|
107
|
-
|
108
|
-
|
109
|
-
|
135
|
+
# Add a new member type _item_.
|
136
|
+
def <<(item)
|
137
|
+
if ![STRUCT, ARRAY, DICT_ENTRY].member?(@sigtype)
|
138
|
+
raise SignatureException
|
110
139
|
end
|
140
|
+
raise SignatureException if @sigtype == ARRAY && !@members.empty?
|
111
141
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
142
|
+
if @sigtype == DICT_ENTRY
|
143
|
+
case @members.size
|
144
|
+
when 2
|
145
|
+
raise SignatureException, "DICT_ENTRY must have 2 subtypes, found 3 or more in #{@signature}"
|
146
|
+
when 0
|
147
|
+
if [STRUCT, ARRAY, DICT_ENTRY, VARIANT].member?(item.sigtype)
|
148
|
+
raise SignatureException, "DICT_ENTRY key must be basic (non-container)"
|
149
|
+
end
|
116
150
|
end
|
117
|
-
s
|
118
151
|
end
|
119
|
-
|
152
|
+
@members << item
|
153
|
+
end
|
154
|
+
|
155
|
+
# Return the first contained member type.
|
156
|
+
def child
|
157
|
+
@members[0]
|
158
|
+
end
|
159
|
+
|
160
|
+
def inspect
|
161
|
+
s = TYPE_MAPPING[@sigtype].first
|
162
|
+
if [STRUCT, ARRAY].member?(@sigtype)
|
163
|
+
s += ": #{@members.inspect}"
|
164
|
+
end
|
165
|
+
s
|
166
|
+
end
|
120
167
|
|
121
168
|
# = D-Bus type parser class
|
122
169
|
#
|
123
170
|
# Helper class to parse a type signature in the protocol.
|
171
|
+
# @api private
|
124
172
|
class Parser
|
125
173
|
# Create a new parser for the given _signature_.
|
174
|
+
# @param signature [Signature]
|
126
175
|
def initialize(signature)
|
127
176
|
@signature = signature
|
177
|
+
if signature.size > 255
|
178
|
+
msg = "Potential signature is longer than 255 characters (#{@signature.size}): #{@signature}"
|
179
|
+
raise SignatureException, msg
|
180
|
+
end
|
181
|
+
|
128
182
|
@idx = 0
|
129
183
|
end
|
130
184
|
|
@@ -135,35 +189,54 @@ module DBus
|
|
135
189
|
c
|
136
190
|
end
|
137
191
|
|
138
|
-
# Parse one character
|
139
|
-
|
192
|
+
# Parse one character _char_ of the signature.
|
193
|
+
# @param for_array [Boolean] are we parsing an immediate child of an ARRAY
|
194
|
+
# @return [Type]
|
195
|
+
def parse_one(char, for_array: false)
|
140
196
|
res = nil
|
141
|
-
case
|
197
|
+
case char
|
142
198
|
when "a"
|
143
199
|
res = Type.new(ARRAY)
|
144
|
-
|
145
|
-
raise SignatureException, "
|
146
|
-
|
200
|
+
char = nextchar
|
201
|
+
raise SignatureException, "Empty ARRAY in #{@signature}" if char.nil?
|
202
|
+
|
203
|
+
child = parse_one(char, for_array: true)
|
147
204
|
res << child
|
148
205
|
when "("
|
149
|
-
res = Type.new(STRUCT)
|
150
|
-
while (
|
151
|
-
res << parse_one(
|
206
|
+
res = Type.new(STRUCT, abstract: true)
|
207
|
+
while (char = nextchar) && char != ")"
|
208
|
+
res << parse_one(char)
|
152
209
|
end
|
153
|
-
raise SignatureException, "
|
210
|
+
raise SignatureException, "STRUCT not closed in #{@signature}" if char.nil?
|
211
|
+
raise SignatureException, "Empty STRUCT in #{@signature}" if res.members.empty?
|
154
212
|
when "{"
|
155
|
-
|
156
|
-
|
157
|
-
|
213
|
+
raise SignatureException, "DICT_ENTRY not an immediate child of an ARRAY" unless for_array
|
214
|
+
|
215
|
+
res = Type.new(DICT_ENTRY, abstract: true)
|
216
|
+
|
217
|
+
# key type, value type
|
218
|
+
2.times do |i|
|
219
|
+
char = nextchar
|
220
|
+
raise SignatureException, "DICT_ENTRY not closed in #{@signature}" if char.nil?
|
221
|
+
|
222
|
+
raise SignatureException, "DICT_ENTRY must have 2 subtypes, found #{i} in #{@signature}" if char == "}"
|
223
|
+
|
224
|
+
res << parse_one(char)
|
158
225
|
end
|
159
|
-
|
226
|
+
|
227
|
+
# closing "}"
|
228
|
+
char = nextchar
|
229
|
+
raise SignatureException, "DICT_ENTRY not closed in #{@signature}" if char.nil?
|
230
|
+
|
231
|
+
raise SignatureException, "DICT_ENTRY must have 2 subtypes, found 3 or more in #{@signature}" if char != "}"
|
160
232
|
else
|
161
|
-
res = Type.new(
|
233
|
+
res = Type.new(char)
|
162
234
|
end
|
163
235
|
res
|
164
236
|
end
|
165
237
|
|
166
238
|
# Parse the entire signature, return a DBus::Type object.
|
239
|
+
# @return [Array<Type>]
|
167
240
|
def parse
|
168
241
|
@idx = 0
|
169
242
|
ret = []
|
@@ -172,20 +245,49 @@ module DBus
|
|
172
245
|
end
|
173
246
|
ret
|
174
247
|
end
|
175
|
-
|
176
|
-
|
248
|
+
|
249
|
+
# Parse one {SingleCompleteType}
|
250
|
+
# @return [Type]
|
251
|
+
def parse1
|
252
|
+
c = nextchar
|
253
|
+
raise SignatureException, "Empty signature, expecting a Single Complete Type" if c.nil?
|
254
|
+
|
255
|
+
t = parse_one(c)
|
256
|
+
raise SignatureException, "Has more than a Single Complete Type: #{@signature}" unless nextchar.nil?
|
257
|
+
|
258
|
+
t
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
177
262
|
|
178
263
|
# shortcuts
|
179
264
|
|
180
|
-
# Parse a String to a DBus::Type
|
265
|
+
# Parse a String to a valid {DBus::Type}.
|
266
|
+
# This is prefered to {Type#initialize} which allows
|
267
|
+
# incomplete or invalid types.
|
268
|
+
# @param string_type [SingleCompleteType]
|
269
|
+
# @return [DBus::Type]
|
270
|
+
# @raise SignatureException
|
181
271
|
def type(string_type)
|
182
|
-
Type::Parser.new(string_type).
|
272
|
+
Type::Parser.new(string_type).parse1
|
183
273
|
end
|
184
274
|
module_function :type
|
185
275
|
|
276
|
+
# Parse a String to zero or more {DBus::Type}s.
|
277
|
+
# @param string_type [Signature]
|
278
|
+
# @return [Array<DBus::Type>]
|
279
|
+
# @raise SignatureException
|
280
|
+
def types(string_type)
|
281
|
+
Type::Parser.new(string_type).parse
|
282
|
+
end
|
283
|
+
module_function :types
|
284
|
+
|
186
285
|
# Make an explicit [Type, value] pair
|
286
|
+
# @param string_type [SingleCompleteType]
|
287
|
+
# @param value [::Object]
|
288
|
+
# @return [Array(DBus::Type::Type,::Object)]
|
187
289
|
def variant(string_type, value)
|
188
290
|
[type(string_type), value]
|
189
291
|
end
|
190
292
|
module_function :variant
|
191
|
-
end
|
293
|
+
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
|
140
|
-
# method/signal
|
141
|
-
|
142
|
-
|
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
|
-
|
156
|
+
case methsig
|
157
|
+
when DBus::Signal
|
147
158
|
# Direction can only be "out", ignore it
|
148
|
-
|
149
|
-
|
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
|
-
|
164
|
+
methsig.add_fparam(name, sig)
|
154
165
|
when "out"
|
155
|
-
|
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
|
163
|
-
end
|
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
|
@@ -12,6 +14,7 @@ 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"
|
15
18
|
require_relative "dbus/error"
|
16
19
|
require_relative "dbus/introspect"
|
17
20
|
require_relative "dbus/logger"
|
@@ -24,31 +27,34 @@ require_relative "dbus/object_path"
|
|
24
27
|
require_relative "dbus/proxy_object"
|
25
28
|
require_relative "dbus/proxy_object_factory"
|
26
29
|
require_relative "dbus/proxy_object_interface"
|
30
|
+
require_relative "dbus/raw_message"
|
27
31
|
require_relative "dbus/type"
|
28
32
|
require_relative "dbus/xml"
|
29
33
|
|
30
34
|
require "socket"
|
31
|
-
require "thread"
|
32
|
-
|
33
35
|
# = D-Bus main module
|
34
36
|
#
|
35
37
|
# Module containing all the D-Bus modules and classes.
|
36
38
|
module DBus
|
37
39
|
# Default socket name for the system bus.
|
38
|
-
|
40
|
+
SYSTEM_BUS_ADDRESS = "unix:path=/var/run/dbus/system_bus_socket"
|
39
41
|
|
40
42
|
# Byte signifying big endianness.
|
41
|
-
BIG_END = "B"
|
43
|
+
BIG_END = "B"
|
42
44
|
# Byte signifying little endianness.
|
43
|
-
LIL_END = "l"
|
45
|
+
LIL_END = "l"
|
44
46
|
|
45
47
|
# Byte signifying the host's endianness.
|
46
|
-
HOST_END = if [0x01020304].pack("L").
|
48
|
+
HOST_END = if [0x01020304].pack("L").unpack1("V") == 0x01020304
|
47
49
|
LIL_END
|
48
50
|
else
|
49
51
|
BIG_END
|
50
52
|
end
|
51
53
|
|
54
|
+
# Comparing symbols is faster than strings
|
55
|
+
# @return [:little,:big]
|
56
|
+
HOST_ENDIANNESS = RawMessage.endianness(HOST_END)
|
57
|
+
|
52
58
|
# General exceptions.
|
53
59
|
|
54
60
|
# Exception raised when there is a problem with a type (may be unknown or
|
@@ -69,4 +75,4 @@ module DBus
|
|
69
75
|
# Exception raised when invalid introspection data is parsed/used.
|
70
76
|
class InvalidIntrospectionData < Exception
|
71
77
|
end
|
72
|
-
end
|
78
|
+
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.
|
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
|
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
|
data/spec/async_spec.rb
CHANGED
data/spec/binding_spec.rb
CHANGED
data/spec/bus_driver_spec.rb
CHANGED
data/spec/bus_name_spec.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
#!/usr/bin/env rspec
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
require_relative "spec_helper"
|
3
5
|
require "dbus"
|
4
6
|
|
@@ -17,7 +19,7 @@ describe DBus::BusName do
|
|
17
19
|
expect(described_class.valid?("Empty.Last.Component.")).to be_falsey
|
18
20
|
expect(described_class.valid?("Invalid.Ch@r@cter")).to be_falsey
|
19
21
|
expect(described_class.valid?("/Invalid-Character")).to be_falsey
|
20
|
-
long_name = "a
|
22
|
+
long_name = "a.#{"long." * 100}name"
|
21
23
|
expect(described_class.valid?(long_name)).to be_falsey
|
22
24
|
expect(described_class.valid?("org.7_zip.Archiver")).to be_falsey
|
23
25
|
end
|