ruby-dbus 0.15.0 → 0.18.0.beta1
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 +5 -5
- data/NEWS.md +41 -1
- data/README.md +3 -5
- data/Rakefile +18 -8
- data/VERSION +1 -1
- data/doc/Reference.md +93 -3
- 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/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 +129 -74
- data/lib/dbus/bus_name.rb +31 -0
- data/lib/dbus/core_ext/class/attribute.rb +1 -1
- data/lib/dbus/error.rb +4 -2
- data/lib/dbus/introspect.rb +90 -34
- data/lib/dbus/logger.rb +3 -1
- data/lib/dbus/marshall.rb +119 -87
- data/lib/dbus/matchrule.rb +16 -16
- data/lib/dbus/message.rb +40 -27
- data/lib/dbus/message_queue.rb +26 -18
- data/lib/dbus/object.rb +401 -0
- data/lib/dbus/object_path.rb +28 -0
- data/lib/dbus/proxy_object.rb +23 -2
- data/lib/dbus/proxy_object_factory.rb +11 -7
- data/lib/dbus/proxy_object_interface.rb +26 -21
- data/lib/dbus/type.rb +59 -34
- data/lib/dbus/xml.rb +28 -17
- data/lib/dbus.rb +10 -8
- data/ruby-dbus.gemspec +8 -4
- 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 +27 -0
- data/spec/bus_spec.rb +2 -0
- data/spec/byte_array_spec.rb +2 -0
- data/spec/client_robustness_spec.rb +27 -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 +25 -0
- data/spec/property_spec.rb +64 -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 +23 -9
- data/spec/thread_safety_spec.rb +2 -0
- data/spec/tools/dbus-limited-session.conf +4 -0
- data/spec/type_spec.rb +2 -0
- data/spec/value_spec.rb +16 -1
- data/spec/variant_spec.rb +4 -2
- metadata +32 -12
- data/lib/dbus/export.rb +0 -131
data/lib/dbus/bus.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
|
@@ -9,7 +11,6 @@
|
|
9
11
|
# See the file "COPYING" for the exact licensing terms.
|
10
12
|
|
11
13
|
require "socket"
|
12
|
-
require "thread"
|
13
14
|
require "singleton"
|
14
15
|
|
15
16
|
# = D-Bus main module
|
@@ -17,7 +18,7 @@ require "singleton"
|
|
17
18
|
# Module containing all the D-Bus modules and classes.
|
18
19
|
module DBus
|
19
20
|
# This represents a remote service. It should not be instantiated directly
|
20
|
-
# Use
|
21
|
+
# Use {Connection#service}
|
21
22
|
class Service
|
22
23
|
# The service name.
|
23
24
|
attr_reader :name
|
@@ -28,7 +29,7 @@ module DBus
|
|
28
29
|
|
29
30
|
# Create a new service with a given _name_ on a given _bus_.
|
30
31
|
def initialize(name, bus)
|
31
|
-
@name = name
|
32
|
+
@name = BusName.new(name)
|
32
33
|
@bus = bus
|
33
34
|
@root = Node.new("/")
|
34
35
|
end
|
@@ -48,6 +49,7 @@ module DBus
|
|
48
49
|
end
|
49
50
|
|
50
51
|
# Retrieves an object at the given _path_.
|
52
|
+
# @param path [ObjectPath]
|
51
53
|
# @return [ProxyObject]
|
52
54
|
def [](path)
|
53
55
|
object(path, api: ApiOptions::A1)
|
@@ -55,9 +57,11 @@ module DBus
|
|
55
57
|
|
56
58
|
# Retrieves an object at the given _path_
|
57
59
|
# whose methods always return an array.
|
60
|
+
# @param path [ObjectPath]
|
61
|
+
# @param api [ApiOptions]
|
58
62
|
# @return [ProxyObject]
|
59
63
|
def object(path, api: ApiOptions::A0)
|
60
|
-
node = get_node(path,
|
64
|
+
node = get_node(path, create: true)
|
61
65
|
if node.object.nil? || node.object.api != api
|
62
66
|
node.object = ProxyObject.new(
|
63
67
|
@bus, @name, path,
|
@@ -67,35 +71,43 @@ module DBus
|
|
67
71
|
node.object
|
68
72
|
end
|
69
73
|
|
70
|
-
# Export an object
|
74
|
+
# Export an object
|
75
|
+
# @param obj [DBus::Object]
|
71
76
|
def export(obj)
|
72
77
|
obj.service = self
|
73
|
-
get_node(obj.path, true).object = obj
|
78
|
+
get_node(obj.path, create: true).object = obj
|
74
79
|
end
|
75
80
|
|
76
81
|
# Undo exporting an object _obj_.
|
77
82
|
# Raises ArgumentError if it is not a DBus::Object.
|
78
83
|
# Returns the object, or false if _obj_ was not exported.
|
84
|
+
# @param obj [DBus::Object]
|
79
85
|
def unexport(obj)
|
80
86
|
raise ArgumentError, "DBus::Service#unexport() expects a DBus::Object argument" unless obj.is_a?(DBus::Object)
|
81
87
|
return false unless obj.path
|
88
|
+
|
82
89
|
last_path_separator_idx = obj.path.rindex("/")
|
83
90
|
parent_path = obj.path[1..last_path_separator_idx - 1]
|
84
91
|
node_name = obj.path[last_path_separator_idx + 1..-1]
|
85
92
|
|
86
|
-
parent_node = get_node(parent_path, false)
|
93
|
+
parent_node = get_node(parent_path, create: false)
|
87
94
|
return false unless parent_node
|
95
|
+
|
88
96
|
obj.service = nil
|
89
97
|
parent_node.delete(node_name).object
|
90
98
|
end
|
91
99
|
|
92
|
-
# Get the object node corresponding to the given
|
93
|
-
#
|
94
|
-
|
100
|
+
# Get the object node corresponding to the given *path*.
|
101
|
+
# @param path [ObjectPath]
|
102
|
+
# @param create [Boolean] if true, the the {Node}s in the path are created
|
103
|
+
# if they do not already exist.
|
104
|
+
# @return [Node,nil]
|
105
|
+
def get_node(path, create: false)
|
95
106
|
n = @root
|
96
107
|
path.sub(%r{^/}, "").split("/").each do |elem|
|
97
108
|
if !(n[elem])
|
98
109
|
return nil if !create
|
110
|
+
|
99
111
|
n[elem] = Node.new(elem)
|
100
112
|
end
|
101
113
|
n = n[elem]
|
@@ -120,13 +132,14 @@ module DBus
|
|
120
132
|
subnodes.each do |nodename|
|
121
133
|
subnode = node[nodename] = Node.new(nodename)
|
122
134
|
subpath = if path == "/"
|
123
|
-
"
|
135
|
+
"/#{nodename}"
|
124
136
|
else
|
125
|
-
path
|
137
|
+
"#{path}/#{nodename}"
|
126
138
|
end
|
127
139
|
rec_introspect(subnode, subpath)
|
128
140
|
end
|
129
141
|
return if intfs.empty?
|
142
|
+
|
130
143
|
node.object = ProxyObjectFactory.new(xml, @bus, @name, path).build
|
131
144
|
end
|
132
145
|
end
|
@@ -135,34 +148,38 @@ module DBus
|
|
135
148
|
#
|
136
149
|
# Class representing a node on an object path.
|
137
150
|
class Node < Hash
|
138
|
-
#
|
151
|
+
# @return [DBus::Object,DBus::ProxyObject,nil]
|
152
|
+
# The D-Bus object contained by the node.
|
139
153
|
attr_accessor :object
|
154
|
+
|
140
155
|
# The name of the node.
|
156
|
+
# @return [String] the last component of its object path, or "/"
|
141
157
|
attr_reader :name
|
142
158
|
|
143
159
|
# Create a new node with a given _name_.
|
144
160
|
def initialize(name)
|
161
|
+
super()
|
145
162
|
@name = name
|
146
163
|
@object = nil
|
147
164
|
end
|
148
165
|
|
149
166
|
# Return an XML string representation of the node.
|
150
167
|
# It is shallow, not recursing into subnodes
|
151
|
-
|
168
|
+
# @param node_opath [String]
|
169
|
+
def to_xml(node_opath)
|
152
170
|
xml = '<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
153
171
|
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
154
|
-
<node>
|
155
172
|
'
|
173
|
+
xml += "<node name=\"#{node_opath}\">\n"
|
156
174
|
each_pair do |k, _v|
|
157
|
-
xml += "<node name=\"#{k}\"
|
175
|
+
xml += " <node name=\"#{k}\" />\n"
|
158
176
|
end
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
end
|
177
|
+
@object&.intfs&.each_pair do |_k, v|
|
178
|
+
xml += " <interface name=\"#{v.name}\">\n"
|
179
|
+
v.methods.each_value { |m| xml += m.to_xml }
|
180
|
+
v.signals.each_value { |m| xml += m.to_xml }
|
181
|
+
v.properties.each_value { |m| xml += m.to_xml }
|
182
|
+
xml += " </interface>\n"
|
166
183
|
end
|
167
184
|
xml += "</node>"
|
168
185
|
xml
|
@@ -180,9 +197,12 @@ module DBus
|
|
180
197
|
if !@object.nil?
|
181
198
|
s += format("%x ", @object.object_id)
|
182
199
|
end
|
183
|
-
|
200
|
+
contents_sub_inspect = keys
|
201
|
+
.map { |k| "#{k} => #{self[k].sub_inspect}" }
|
202
|
+
.join(",")
|
203
|
+
"#{s}{#{contents_sub_inspect}}"
|
184
204
|
end
|
185
|
-
end
|
205
|
+
end
|
186
206
|
|
187
207
|
# FIXME: rename Connection to Bus?
|
188
208
|
|
@@ -205,7 +225,15 @@ module DBus
|
|
205
225
|
def initialize(path)
|
206
226
|
@message_queue = MessageQueue.new(path)
|
207
227
|
@unique_name = nil
|
228
|
+
|
229
|
+
# @return [Hash{Integer => Proc}]
|
230
|
+
# key: message serial
|
231
|
+
# value: block to be run when the reply to that message is received
|
208
232
|
@method_call_replies = {}
|
233
|
+
|
234
|
+
# @return [Hash{Integer => Message}]
|
235
|
+
# for debugging only: messages for which a reply was not received yet;
|
236
|
+
# key == value.serial
|
209
237
|
@method_call_msgs = {}
|
210
238
|
@signal_matchrules = {}
|
211
239
|
@proxy = nil
|
@@ -216,7 +244,7 @@ module DBus
|
|
216
244
|
# but do not block on the queue.
|
217
245
|
# Called by a main loop when something is available in the queue
|
218
246
|
def dispatch_message_queue
|
219
|
-
while (msg = @message_queue.pop(:
|
247
|
+
while (msg = @message_queue.pop(blocking: false)) # FIXME: EOFError
|
220
248
|
process(msg)
|
221
249
|
end
|
222
250
|
end
|
@@ -323,7 +351,7 @@ module DBus
|
|
323
351
|
</signal>
|
324
352
|
</interface>
|
325
353
|
</node>
|
326
|
-
'
|
354
|
+
'
|
327
355
|
# This apostroph is for syntax highlighting editors confused by above xml: "
|
328
356
|
|
329
357
|
# @api private
|
@@ -338,6 +366,7 @@ module DBus
|
|
338
366
|
if reply_handler.nil?
|
339
367
|
send_sync(message) do |rmsg|
|
340
368
|
raise rmsg if rmsg.is_a?(Error)
|
369
|
+
|
341
370
|
ret = rmsg.params
|
342
371
|
end
|
343
372
|
else
|
@@ -442,41 +471,52 @@ module DBus
|
|
442
471
|
end
|
443
472
|
|
444
473
|
# @api private
|
445
|
-
# Send a message
|
474
|
+
# Send a message _msg_ on to the bus. This is done synchronously, thus
|
446
475
|
# the call will block until a reply message arrives.
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
476
|
+
# @param msg [Message]
|
477
|
+
# @param retc [Proc] the reply handler
|
478
|
+
# @yieldparam rmsg [MethodReturnMessage] the reply
|
479
|
+
# @yieldreturn [Array<Object>] the reply (out) parameters
|
480
|
+
def send_sync(msg, &retc) # :yields: reply/return message
|
481
|
+
return if msg.nil? # check if somethings wrong
|
482
|
+
|
483
|
+
@message_queue.push(msg)
|
484
|
+
@method_call_msgs[msg.serial] = msg
|
485
|
+
@method_call_replies[msg.serial] = retc
|
452
486
|
|
453
487
|
retm = wait_for_message
|
454
488
|
return if retm.nil? # check if somethings wrong
|
455
489
|
|
456
490
|
process(retm)
|
457
|
-
while @method_call_replies.key?
|
491
|
+
while @method_call_replies.key? msg.serial
|
458
492
|
retm = wait_for_message
|
459
493
|
process(retm)
|
460
494
|
end
|
495
|
+
rescue EOFError
|
496
|
+
new_err = DBus::Error.new("Connection dropped after we sent #{msg.inspect}")
|
497
|
+
raise new_err
|
461
498
|
end
|
462
499
|
|
463
500
|
# @api private
|
464
501
|
# Specify a code block that has to be executed when a reply for
|
465
|
-
# message
|
466
|
-
|
502
|
+
# message _msg_ is received.
|
503
|
+
# @param msg [Message]
|
504
|
+
def on_return(msg, &retc)
|
467
505
|
# Have a better exception here
|
468
|
-
if
|
506
|
+
if msg.message_type != Message::METHOD_CALL
|
469
507
|
raise "on_return should only get method_calls"
|
470
508
|
end
|
471
|
-
|
472
|
-
@
|
509
|
+
|
510
|
+
@method_call_msgs[msg.serial] = msg
|
511
|
+
@method_call_replies[msg.serial] = retc
|
473
512
|
end
|
474
513
|
|
475
514
|
# Asks bus to send us messages matching mr, and execute slot when
|
476
515
|
# received
|
477
|
-
|
516
|
+
# @param match_rule [MatchRule,#to_s]
|
517
|
+
def add_match(match_rule, &slot)
|
478
518
|
# check this is a signal.
|
479
|
-
mrs =
|
519
|
+
mrs = match_rule.to_s
|
480
520
|
DBus.logger.debug "#{@signal_matchrules.size} rules, adding #{mrs.inspect}"
|
481
521
|
# don't ask for the same match if we override it
|
482
522
|
unless @signal_matchrules.key?(mrs)
|
@@ -486,69 +526,77 @@ module DBus
|
|
486
526
|
@signal_matchrules[mrs] = slot
|
487
527
|
end
|
488
528
|
|
489
|
-
|
490
|
-
|
529
|
+
# @param match_rule [MatchRule,#to_s]
|
530
|
+
def remove_match(match_rule)
|
531
|
+
mrs = match_rule.to_s
|
491
532
|
rule_existed = @signal_matchrules.delete(mrs).nil?
|
492
533
|
# don't remove nonexisting matches.
|
493
534
|
return if rule_existed
|
535
|
+
|
494
536
|
# FIXME: if we do try, the Error.MatchRuleNotFound is *not* raised
|
495
537
|
# and instead is reported as "no return code for nil"
|
496
538
|
proxy.RemoveMatch(mrs)
|
497
539
|
end
|
498
540
|
|
499
541
|
# @api private
|
500
|
-
# Process a message
|
501
|
-
|
502
|
-
|
503
|
-
|
542
|
+
# Process a message _msg_ based on its type.
|
543
|
+
# @param msg [Message]
|
544
|
+
def process(msg)
|
545
|
+
return if msg.nil? # check if somethings wrong
|
546
|
+
|
547
|
+
case msg.message_type
|
504
548
|
when Message::ERROR, Message::METHOD_RETURN
|
505
|
-
raise InvalidPacketException if
|
506
|
-
|
549
|
+
raise InvalidPacketException if msg.reply_serial.nil?
|
550
|
+
|
551
|
+
mcs = @method_call_replies[msg.reply_serial]
|
507
552
|
if !mcs
|
508
|
-
DBus.logger.debug "no return code for mcs: #{mcs.inspect}
|
553
|
+
DBus.logger.debug "no return code for mcs: #{mcs.inspect} msg: #{msg.inspect}"
|
509
554
|
else
|
510
|
-
if
|
511
|
-
mcs.call(Error.new(
|
555
|
+
if msg.message_type == Message::ERROR
|
556
|
+
mcs.call(Error.new(msg))
|
512
557
|
else
|
513
|
-
mcs.call(
|
558
|
+
mcs.call(msg)
|
514
559
|
end
|
515
|
-
@method_call_replies.delete(
|
516
|
-
@method_call_msgs.delete(
|
560
|
+
@method_call_replies.delete(msg.reply_serial)
|
561
|
+
@method_call_msgs.delete(msg.reply_serial)
|
517
562
|
end
|
518
563
|
when DBus::Message::METHOD_CALL
|
519
|
-
if
|
564
|
+
if msg.path == "/org/freedesktop/DBus"
|
520
565
|
DBus.logger.debug "Got method call on /org/freedesktop/DBus"
|
521
566
|
end
|
522
|
-
node = @service.get_node(
|
567
|
+
node = @service.get_node(msg.path, create: false)
|
523
568
|
if !node
|
524
|
-
reply = Message.error(
|
525
|
-
"Object #{
|
569
|
+
reply = Message.error(msg, "org.freedesktop.DBus.Error.UnknownObject",
|
570
|
+
"Object #{msg.path} doesn't exist")
|
526
571
|
@message_queue.push(reply)
|
527
572
|
# handle introspectable as an exception:
|
528
|
-
elsif
|
529
|
-
|
530
|
-
reply = Message.new(Message::METHOD_RETURN).reply_to(
|
573
|
+
elsif msg.interface == "org.freedesktop.DBus.Introspectable" &&
|
574
|
+
msg.member == "Introspect"
|
575
|
+
reply = Message.new(Message::METHOD_RETURN).reply_to(msg)
|
531
576
|
reply.sender = @unique_name
|
532
|
-
|
577
|
+
xml = node.to_xml(msg.path)
|
578
|
+
reply.add_param(Type::STRING, xml)
|
533
579
|
@message_queue.push(reply)
|
534
580
|
else
|
535
581
|
obj = node.object
|
536
582
|
return if obj.nil? # FIXME, pushes no reply
|
537
|
-
|
583
|
+
|
584
|
+
obj&.dispatch(msg)
|
538
585
|
end
|
539
586
|
when DBus::Message::SIGNAL
|
540
587
|
# the signal can match multiple different rules
|
541
588
|
# clone to allow new signale handlers to be registered
|
542
589
|
@signal_matchrules.dup.each do |mrs, slot|
|
543
|
-
if DBus::MatchRule.new.from_s(mrs).match(
|
544
|
-
slot.call(
|
590
|
+
if DBus::MatchRule.new.from_s(mrs).match(msg)
|
591
|
+
slot.call(msg)
|
545
592
|
end
|
546
593
|
end
|
547
594
|
else
|
548
|
-
|
595
|
+
# spec(Message Format): Unknown types must be ignored.
|
596
|
+
DBus.logger.debug "Unknown message type: #{msg.message_type}"
|
549
597
|
end
|
550
|
-
rescue Exception =>
|
551
|
-
raise
|
598
|
+
rescue Exception => e
|
599
|
+
raise msg.annotate_exception(e)
|
552
600
|
end
|
553
601
|
|
554
602
|
# Retrieves the Service with the given _name_.
|
@@ -563,6 +611,11 @@ module DBus
|
|
563
611
|
# @api private
|
564
612
|
# Emit a signal event for the given _service_, object _obj_, interface
|
565
613
|
# _intf_ and signal _sig_ with arguments _args_.
|
614
|
+
# @param service [Service]
|
615
|
+
# @param obj [DBus::Object]
|
616
|
+
# @param intf [Interface]
|
617
|
+
# @param sig [Signal]
|
618
|
+
# @param args arguments for the signal
|
566
619
|
def emit(service, obj, intf, sig, *args)
|
567
620
|
m = Message.new(DBus::Message::SIGNAL)
|
568
621
|
m.path = obj.path
|
@@ -593,7 +646,7 @@ module DBus
|
|
593
646
|
end
|
594
647
|
@service = Service.new(@unique_name, self)
|
595
648
|
end
|
596
|
-
end
|
649
|
+
end
|
597
650
|
|
598
651
|
# = D-Bus session bus class
|
599
652
|
#
|
@@ -619,6 +672,7 @@ module DBus
|
|
619
672
|
# traditional dbus uses /var/lib/dbus/machine-id
|
620
673
|
machine_id_path = Dir["{/etc,/var/lib/dbus,/var/db/dbus}/machine-id"].first
|
621
674
|
return nil unless machine_id_path
|
675
|
+
|
622
676
|
machine_id = File.read(machine_id_path).chomp
|
623
677
|
|
624
678
|
display = ENV["DISPLAY"][/:(\d+)\.?/, 1]
|
@@ -650,7 +704,7 @@ module DBus
|
|
650
704
|
class ASystemBus < Connection
|
651
705
|
# Get the default system bus.
|
652
706
|
def initialize
|
653
|
-
super(
|
707
|
+
super(SYSTEM_BUS_ADDRESS)
|
654
708
|
send_hello
|
655
709
|
end
|
656
710
|
end
|
@@ -665,7 +719,7 @@ module DBus
|
|
665
719
|
# (for Unix-socket) unix:path=/tmp/my_funky_bus_socket
|
666
720
|
#
|
667
721
|
# you'll need to take care about authentification then, more info here:
|
668
|
-
#
|
722
|
+
# https://gitlab.com/pangdudu/ruby-dbus/-/blob/master/README.rdoc
|
669
723
|
class RemoteBus < Connection
|
670
724
|
# Get the remote bus.
|
671
725
|
def initialize(socket_name)
|
@@ -725,6 +779,7 @@ module DBus
|
|
725
779
|
while !@quitting && !@buses.empty?
|
726
780
|
ready = IO.select(@buses.keys, [], [], 5) # timeout 5 seconds
|
727
781
|
next unless ready # timeout exceeds so continue unless quitting
|
782
|
+
|
728
783
|
ready.first.each do |socket|
|
729
784
|
b = @buses[socket]
|
730
785
|
begin
|
@@ -739,5 +794,5 @@ module DBus
|
|
739
794
|
end
|
740
795
|
end
|
741
796
|
end
|
742
|
-
end
|
743
|
-
end
|
797
|
+
end
|
798
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file is part of the ruby-dbus project
|
4
|
+
# Copyright (C) 2019 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
|
+
# D-Bus: a name for a connection, like ":1.3" or "org.example.ManagerManager".
|
13
|
+
# Implemented as a {::String} that validates at initialization time.
|
14
|
+
# @see https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus
|
15
|
+
class BusName < String
|
16
|
+
# @raise Error if not a valid bus name
|
17
|
+
def initialize(name)
|
18
|
+
unless self.class.valid?(name)
|
19
|
+
raise DBus::Error, "Invalid bus name #{name.inspect}"
|
20
|
+
end
|
21
|
+
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.valid?(name)
|
26
|
+
name.size <= 255 &&
|
27
|
+
(name =~ /\A:[A-Za-z0-9_-]+(\.[A-Za-z0-9_-]+)+\z/ ||
|
28
|
+
name =~ /\A[A-Za-z_-][A-Za-z0-9_-]*(\.[A-Za-z_-][A-Za-z0-9_-]*)+\z/)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
# copied from activesupport/core_ext from Rails, MIT license
|
3
3
|
# https://github.com/rails/rails/tree/9794e85351243cac6d4e78adaba634b8e4ecad0a/activesupport/lib/active_support/core_ext
|
4
4
|
|
5
|
-
|
5
|
+
require_relative "../module/redefine_method"
|
6
6
|
|
7
7
|
class Class
|
8
8
|
# Declare a class-level attribute whose value is inheritable by subclasses.
|
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
|
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
|
48
|
+
end
|