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
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
|
@@ -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,44 +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
|
461
495
|
rescue EOFError
|
462
|
-
new_err = DBus::Error.new("Connection dropped after we sent #{
|
496
|
+
new_err = DBus::Error.new("Connection dropped after we sent #{msg.inspect}")
|
463
497
|
raise new_err
|
464
498
|
end
|
465
499
|
|
466
500
|
# @api private
|
467
501
|
# Specify a code block that has to be executed when a reply for
|
468
|
-
# message
|
469
|
-
|
502
|
+
# message _msg_ is received.
|
503
|
+
# @param msg [Message]
|
504
|
+
def on_return(msg, &retc)
|
470
505
|
# Have a better exception here
|
471
|
-
if
|
506
|
+
if msg.message_type != Message::METHOD_CALL
|
472
507
|
raise "on_return should only get method_calls"
|
473
508
|
end
|
474
|
-
|
475
|
-
@
|
509
|
+
|
510
|
+
@method_call_msgs[msg.serial] = msg
|
511
|
+
@method_call_replies[msg.serial] = retc
|
476
512
|
end
|
477
513
|
|
478
514
|
# Asks bus to send us messages matching mr, and execute slot when
|
479
515
|
# received
|
480
|
-
|
516
|
+
# @param match_rule [MatchRule,#to_s]
|
517
|
+
def add_match(match_rule, &slot)
|
481
518
|
# check this is a signal.
|
482
|
-
mrs =
|
519
|
+
mrs = match_rule.to_s
|
483
520
|
DBus.logger.debug "#{@signal_matchrules.size} rules, adding #{mrs.inspect}"
|
484
521
|
# don't ask for the same match if we override it
|
485
522
|
unless @signal_matchrules.key?(mrs)
|
@@ -489,69 +526,77 @@ module DBus
|
|
489
526
|
@signal_matchrules[mrs] = slot
|
490
527
|
end
|
491
528
|
|
492
|
-
|
493
|
-
|
529
|
+
# @param match_rule [MatchRule,#to_s]
|
530
|
+
def remove_match(match_rule)
|
531
|
+
mrs = match_rule.to_s
|
494
532
|
rule_existed = @signal_matchrules.delete(mrs).nil?
|
495
533
|
# don't remove nonexisting matches.
|
496
534
|
return if rule_existed
|
535
|
+
|
497
536
|
# FIXME: if we do try, the Error.MatchRuleNotFound is *not* raised
|
498
537
|
# and instead is reported as "no return code for nil"
|
499
538
|
proxy.RemoveMatch(mrs)
|
500
539
|
end
|
501
540
|
|
502
541
|
# @api private
|
503
|
-
# Process a message
|
504
|
-
|
505
|
-
|
506
|
-
|
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
|
507
548
|
when Message::ERROR, Message::METHOD_RETURN
|
508
|
-
raise InvalidPacketException if
|
509
|
-
|
549
|
+
raise InvalidPacketException if msg.reply_serial.nil?
|
550
|
+
|
551
|
+
mcs = @method_call_replies[msg.reply_serial]
|
510
552
|
if !mcs
|
511
|
-
DBus.logger.debug "no return code for mcs: #{mcs.inspect}
|
553
|
+
DBus.logger.debug "no return code for mcs: #{mcs.inspect} msg: #{msg.inspect}"
|
512
554
|
else
|
513
|
-
if
|
514
|
-
mcs.call(Error.new(
|
555
|
+
if msg.message_type == Message::ERROR
|
556
|
+
mcs.call(Error.new(msg))
|
515
557
|
else
|
516
|
-
mcs.call(
|
558
|
+
mcs.call(msg)
|
517
559
|
end
|
518
|
-
@method_call_replies.delete(
|
519
|
-
@method_call_msgs.delete(
|
560
|
+
@method_call_replies.delete(msg.reply_serial)
|
561
|
+
@method_call_msgs.delete(msg.reply_serial)
|
520
562
|
end
|
521
563
|
when DBus::Message::METHOD_CALL
|
522
|
-
if
|
564
|
+
if msg.path == "/org/freedesktop/DBus"
|
523
565
|
DBus.logger.debug "Got method call on /org/freedesktop/DBus"
|
524
566
|
end
|
525
|
-
node = @service.get_node(
|
567
|
+
node = @service.get_node(msg.path, create: false)
|
526
568
|
if !node
|
527
|
-
reply = Message.error(
|
528
|
-
"Object #{
|
569
|
+
reply = Message.error(msg, "org.freedesktop.DBus.Error.UnknownObject",
|
570
|
+
"Object #{msg.path} doesn't exist")
|
529
571
|
@message_queue.push(reply)
|
530
572
|
# handle introspectable as an exception:
|
531
|
-
elsif
|
532
|
-
|
533
|
-
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)
|
534
576
|
reply.sender = @unique_name
|
535
|
-
|
577
|
+
xml = node.to_xml(msg.path)
|
578
|
+
reply.add_param(Type::STRING, xml)
|
536
579
|
@message_queue.push(reply)
|
537
580
|
else
|
538
581
|
obj = node.object
|
539
582
|
return if obj.nil? # FIXME, pushes no reply
|
540
|
-
|
583
|
+
|
584
|
+
obj&.dispatch(msg)
|
541
585
|
end
|
542
586
|
when DBus::Message::SIGNAL
|
543
587
|
# the signal can match multiple different rules
|
544
588
|
# clone to allow new signale handlers to be registered
|
545
589
|
@signal_matchrules.dup.each do |mrs, slot|
|
546
|
-
if DBus::MatchRule.new.from_s(mrs).match(
|
547
|
-
slot.call(
|
590
|
+
if DBus::MatchRule.new.from_s(mrs).match(msg)
|
591
|
+
slot.call(msg)
|
548
592
|
end
|
549
593
|
end
|
550
594
|
else
|
551
|
-
|
595
|
+
# spec(Message Format): Unknown types must be ignored.
|
596
|
+
DBus.logger.debug "Unknown message type: #{msg.message_type}"
|
552
597
|
end
|
553
|
-
rescue Exception =>
|
554
|
-
raise
|
598
|
+
rescue Exception => e
|
599
|
+
raise msg.annotate_exception(e)
|
555
600
|
end
|
556
601
|
|
557
602
|
# Retrieves the Service with the given _name_.
|
@@ -566,6 +611,11 @@ module DBus
|
|
566
611
|
# @api private
|
567
612
|
# Emit a signal event for the given _service_, object _obj_, interface
|
568
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
|
569
619
|
def emit(service, obj, intf, sig, *args)
|
570
620
|
m = Message.new(DBus::Message::SIGNAL)
|
571
621
|
m.path = obj.path
|
@@ -596,7 +646,7 @@ module DBus
|
|
596
646
|
end
|
597
647
|
@service = Service.new(@unique_name, self)
|
598
648
|
end
|
599
|
-
end
|
649
|
+
end
|
600
650
|
|
601
651
|
# = D-Bus session bus class
|
602
652
|
#
|
@@ -622,6 +672,7 @@ module DBus
|
|
622
672
|
# traditional dbus uses /var/lib/dbus/machine-id
|
623
673
|
machine_id_path = Dir["{/etc,/var/lib/dbus,/var/db/dbus}/machine-id"].first
|
624
674
|
return nil unless machine_id_path
|
675
|
+
|
625
676
|
machine_id = File.read(machine_id_path).chomp
|
626
677
|
|
627
678
|
display = ENV["DISPLAY"][/:(\d+)\.?/, 1]
|
@@ -653,7 +704,7 @@ module DBus
|
|
653
704
|
class ASystemBus < Connection
|
654
705
|
# Get the default system bus.
|
655
706
|
def initialize
|
656
|
-
super(
|
707
|
+
super(SYSTEM_BUS_ADDRESS)
|
657
708
|
send_hello
|
658
709
|
end
|
659
710
|
end
|
@@ -668,7 +719,7 @@ module DBus
|
|
668
719
|
# (for Unix-socket) unix:path=/tmp/my_funky_bus_socket
|
669
720
|
#
|
670
721
|
# you'll need to take care about authentification then, more info here:
|
671
|
-
#
|
722
|
+
# https://gitlab.com/pangdudu/ruby-dbus/-/blob/master/README.rdoc
|
672
723
|
class RemoteBus < Connection
|
673
724
|
# Get the remote bus.
|
674
725
|
def initialize(socket_name)
|
@@ -728,6 +779,7 @@ module DBus
|
|
728
779
|
while !@quitting && !@buses.empty?
|
729
780
|
ready = IO.select(@buses.keys, [], [], 5) # timeout 5 seconds
|
730
781
|
next unless ready # timeout exceeds so continue unless quitting
|
782
|
+
|
731
783
|
ready.first.each do |socket|
|
732
784
|
b = @buses[socket]
|
733
785
|
begin
|
@@ -742,5 +794,5 @@ module DBus
|
|
742
794
|
end
|
743
795
|
end
|
744
796
|
end
|
745
|
-
end
|
746
|
-
end
|
797
|
+
end
|
798
|
+
end
|
data/lib/dbus/bus_name.rb
CHANGED
@@ -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) 2019 Martin Vidner
|
3
5
|
#
|
@@ -7,21 +9,23 @@
|
|
7
9
|
# See the file "COPYING" for the exact licensing terms.
|
8
10
|
|
9
11
|
module DBus
|
10
|
-
#
|
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.
|
11
14
|
# @see https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus
|
12
15
|
class BusName < String
|
13
16
|
# @raise Error if not a valid bus name
|
14
|
-
def initialize(
|
15
|
-
unless self.class.valid?(
|
16
|
-
raise DBus::Error, "Invalid bus name #{
|
17
|
+
def initialize(name)
|
18
|
+
unless self.class.valid?(name)
|
19
|
+
raise DBus::Error, "Invalid bus name #{name.inspect}"
|
17
20
|
end
|
21
|
+
|
18
22
|
super
|
19
23
|
end
|
20
24
|
|
21
|
-
def self.valid?(
|
22
|
-
|
23
|
-
(
|
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/)
|
25
29
|
end
|
26
30
|
end
|
27
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.
|