ruby-dbus 0.16.0 → 0.18.1
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 +160 -0
- data/README.md +3 -5
- data/Rakefile +18 -8
- data/VERSION +1 -1
- data/doc/Reference.md +106 -7
- 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 +123 -75
- data/lib/dbus/bus_name.rb +12 -8
- data/lib/dbus/core_ext/class/attribute.rb +1 -1
- data/lib/dbus/data.rb +821 -0
- data/lib/dbus/emits_changed_signal.rb +83 -0
- data/lib/dbus/error.rb +4 -2
- data/lib/dbus/introspect.rb +132 -31
- data/lib/dbus/logger.rb +3 -1
- data/lib/dbus/marshall.rb +247 -296
- 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 +358 -24
- data/lib/dbus/object_path.rb +11 -6
- data/lib/dbus/proxy_object.rb +22 -1
- data/lib/dbus/proxy_object_factory.rb +13 -7
- data/lib/dbus/proxy_object_interface.rb +63 -30
- data/lib/dbus/raw_message.rb +91 -0
- data/lib/dbus/type.rb +318 -86
- data/lib/dbus/xml.rb +32 -17
- data/lib/dbus.rb +14 -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 +1667 -0
- data/spec/data_spec.rb +673 -0
- data/spec/emits_changed_signal_spec.rb +58 -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/object_spec.rb +138 -0
- data/spec/packet_marshaller_spec.rb +41 -0
- data/spec/packet_unmarshaller_spec.rb +248 -0
- data/spec/property_spec.rb +192 -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 +70 -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 +37 -9
- data/spec/thread_safety_spec.rb +2 -0
- data/spec/tools/dbus-limited-session.conf +4 -0
- data/spec/type_spec.rb +214 -6
- data/spec/value_spec.rb +16 -1
- data/spec/variant_spec.rb +4 -2
- data/spec/zzz_quit_spec.rb +16 -0
- metadata +34 -8
@@ -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
|
@@ -13,13 +15,16 @@ module DBus
|
|
13
15
|
# A class similar to the normal Interface used as a proxy for remote
|
14
16
|
# object interfaces.
|
15
17
|
class ProxyObjectInterface
|
16
|
-
#
|
17
|
-
|
18
|
-
#
|
19
|
-
|
20
|
-
#
|
18
|
+
# @return [Hash{String => DBus::Method}]
|
19
|
+
attr_reader :methods
|
20
|
+
# @return [Hash{String => Signal}]
|
21
|
+
attr_reader :signals
|
22
|
+
# @return [Hash{Symbol => Property}]
|
23
|
+
attr_reader :properties
|
24
|
+
|
25
|
+
# @return [ProxyObject] The proxy object to which this interface belongs.
|
21
26
|
attr_reader :object
|
22
|
-
# The name of the interface.
|
27
|
+
# @return [String] The name of the interface.
|
23
28
|
attr_reader :name
|
24
29
|
|
25
30
|
# Creates a new proxy interface for the given proxy _object_
|
@@ -29,6 +34,7 @@ module DBus
|
|
29
34
|
@name = name
|
30
35
|
@methods = {}
|
31
36
|
@signals = {}
|
37
|
+
@properties = {}
|
32
38
|
end
|
33
39
|
|
34
40
|
# Returns the string representation of the interface (the name).
|
@@ -36,27 +42,28 @@ module DBus
|
|
36
42
|
@name
|
37
43
|
end
|
38
44
|
|
39
|
-
# Defines a method on the interface from the Method descriptor
|
40
|
-
|
41
|
-
|
45
|
+
# Defines a method on the interface from the Method descriptor _method_.
|
46
|
+
# @param method [Method]
|
47
|
+
def define_method_from_descriptor(method)
|
48
|
+
method.params.each do |fpar|
|
42
49
|
par = fpar.type
|
43
50
|
# This is the signature validity check
|
44
51
|
Type::Parser.new(par).parse
|
45
52
|
end
|
46
53
|
|
47
54
|
singleton_class.class_eval do
|
48
|
-
define_method
|
49
|
-
if
|
50
|
-
raise ArgumentError, "wrong number of arguments (#{args.size} for #{
|
55
|
+
define_method method.name do |*args, &reply_handler|
|
56
|
+
if method.params.size != args.size
|
57
|
+
raise ArgumentError, "wrong number of arguments (#{args.size} for #{method.params.size})"
|
51
58
|
end
|
52
59
|
|
53
60
|
msg = Message.new(Message::METHOD_CALL)
|
54
61
|
msg.path = @object.path
|
55
62
|
msg.interface = @name
|
56
63
|
msg.destination = @object.destination
|
57
|
-
msg.member =
|
64
|
+
msg.member = method.name
|
58
65
|
msg.sender = @object.bus.unique_name
|
59
|
-
|
66
|
+
method.params.each do |fpar|
|
60
67
|
par = fpar.type
|
61
68
|
msg.add_param(par, args.shift)
|
62
69
|
end
|
@@ -64,25 +71,35 @@ module DBus
|
|
64
71
|
if ret.nil? || @object.api.proxy_method_returns_array
|
65
72
|
ret
|
66
73
|
else
|
67
|
-
|
74
|
+
method.rets.size == 1 ? ret.first : ret
|
68
75
|
end
|
69
76
|
end
|
70
77
|
end
|
71
78
|
|
72
|
-
@methods[
|
79
|
+
@methods[method.name] = method
|
73
80
|
end
|
74
81
|
|
75
|
-
# Defines a signal from the descriptor
|
76
|
-
|
77
|
-
|
82
|
+
# Defines a signal from the descriptor _sig_.
|
83
|
+
# @param sig [Signal]
|
84
|
+
def define_signal_from_descriptor(sig)
|
85
|
+
@signals[sig.name] = sig
|
78
86
|
end
|
79
87
|
|
80
|
-
#
|
81
|
-
def
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
88
|
+
# @param prop [Property]
|
89
|
+
def define_property_from_descriptor(prop)
|
90
|
+
@properties[prop.name] = prop
|
91
|
+
end
|
92
|
+
|
93
|
+
# Defines a signal or method based on the descriptor _ifc_el_.
|
94
|
+
# @param ifc_el [DBus::Method,Signal,Property]
|
95
|
+
def define(ifc_el)
|
96
|
+
case ifc_el
|
97
|
+
when Method
|
98
|
+
define_method_from_descriptor(ifc_el)
|
99
|
+
when Signal
|
100
|
+
define_signal_from_descriptor(ifc_el)
|
101
|
+
when Property
|
102
|
+
define_property_from_descriptor(ifc_el)
|
86
103
|
end
|
87
104
|
end
|
88
105
|
|
@@ -109,7 +126,7 @@ module DBus
|
|
109
126
|
end
|
110
127
|
end
|
111
128
|
|
112
|
-
PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties"
|
129
|
+
PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties"
|
113
130
|
|
114
131
|
# Read a property.
|
115
132
|
# @param propname [String]
|
@@ -124,10 +141,26 @@ module DBus
|
|
124
141
|
end
|
125
142
|
|
126
143
|
# Write a property.
|
127
|
-
# @param
|
144
|
+
# @param property_name [String]
|
128
145
|
# @param value [Object]
|
129
|
-
def []=(
|
130
|
-
|
146
|
+
def []=(property_name, value)
|
147
|
+
property = properties[property_name.to_sym]
|
148
|
+
if !property
|
149
|
+
raise DBus.error("org.freedesktop.DBus.Error.UnknownProperty"),
|
150
|
+
"Property '#{name}.#{property_name}' (on object '#{object.path}') not found"
|
151
|
+
end
|
152
|
+
|
153
|
+
case value
|
154
|
+
# accommodate former need to explicitly make a variant with the right type
|
155
|
+
when Data::Variant
|
156
|
+
variant = value
|
157
|
+
else
|
158
|
+
type = property.type
|
159
|
+
typed_value = Data.make_typed(type, value)
|
160
|
+
variant = Data::Variant.new(typed_value, member_type: type)
|
161
|
+
end
|
162
|
+
|
163
|
+
object[PROPERTY_INTERFACE].Set(name, property_name, variant)
|
131
164
|
end
|
132
165
|
|
133
166
|
# Read all properties at once, as a hash.
|
@@ -141,5 +174,5 @@ module DBus
|
|
141
174
|
ret
|
142
175
|
end
|
143
176
|
end
|
144
|
-
end
|
177
|
+
end
|
145
178
|
end
|
@@ -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
|