ruby-dbus-openplacos 0.6.0 → 0.6.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.
- data/README +1 -1
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/{dbus.rb → dbus-openplacos.rb} +0 -0
- data/lib/dbus/auth.rb +2 -2
- data/lib/dbus/bus.rb +47 -26
- data/lib/dbus/export.rb +9 -6
- data/lib/dbus/introspect.rb +24 -42
- data/lib/dbus/marshall.rb +20 -19
- data/lib/dbus/matchrule.rb +2 -1
- data/lib/dbus/message.rb +1 -1
- data/ruby-dbus-openplacos.gemspec +1 -0
- data/test/binding_test.rb +1 -1
- data/test/bus_driver_test.rb +1 -1
- data/test/bus_test.rb +18 -0
- data/test/property_test.rb +1 -1
- data/test/server_robustness_test.rb +3 -3
- data/test/server_test.rb +1 -1
- data/test/service_newapi.rb +10 -2
- data/test/session_bus_test_manual.rb +1 -1
- data/test/signal_test.rb +2 -2
- data/test/t2.rb +7 -1
- data/test/t3-ticket27.rb +1 -1
- data/test/t5-report-dbus-interface.rb +1 -1
- data/test/t6-loop.rb +1 -1
- data/test/thread_safety_test.rb +35 -0
- data/test/variant_test.rb +1 -1
- metadata +11 -7
data/README
CHANGED
data/Rakefile
CHANGED
@@ -11,7 +11,7 @@ task :default => "env:test"
|
|
11
11
|
|
12
12
|
def common_test_task(t)
|
13
13
|
t.libs << "lib"
|
14
|
-
t.test_files = FileList['test/*_test.rb', 'test/t*.rb']
|
14
|
+
t.test_files = FileList['test/*_test.rb', 'test/t[0-9]*.rb']
|
15
15
|
t.verbose = true
|
16
16
|
end
|
17
17
|
Rake::TestTask.new {|t| common_test_task t }
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.1
|
File without changes
|
data/lib/dbus/auth.rb
CHANGED
@@ -62,7 +62,7 @@ module DBus
|
|
62
62
|
# name of cookie file, id of cookie in file, servers random challenge
|
63
63
|
context, id, s_challenge = data.split(' ')
|
64
64
|
# Random client challenge
|
65
|
-
c_challenge = Array.new(s_challenge.
|
65
|
+
c_challenge = Array.new(s_challenge.bytesize/2).map{|obj|obj=rand(255).to_s}.join
|
66
66
|
# Search cookie file for id
|
67
67
|
path = File.join(ENV['HOME'], '.dbus-keyrings', context)
|
68
68
|
puts "DEBUG: path: #{path.inspect}" if $debug
|
@@ -161,7 +161,7 @@ module DBus
|
|
161
161
|
while left > 0
|
162
162
|
buf = @socket.read( left > 1 ? 1 : left )
|
163
163
|
break if buf.nil?
|
164
|
-
left -= buf.
|
164
|
+
left -= buf.bytesize
|
165
165
|
data += buf
|
166
166
|
break if data.include? crlf #crlf means line finished, the TCP socket keeps on listening, so we break
|
167
167
|
end
|
data/lib/dbus/bus.rb
CHANGED
@@ -141,6 +141,7 @@ module DBus
|
|
141
141
|
end
|
142
142
|
|
143
143
|
# Return an XML string representation of the node.
|
144
|
+
# It is shallow, not recursing into subnodes
|
144
145
|
def to_xml
|
145
146
|
xml = '<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
146
147
|
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
@@ -188,7 +189,7 @@ module DBus
|
|
188
189
|
attr_reader :unique_name
|
189
190
|
# The socket that is used to connect with the bus.
|
190
191
|
attr_reader :socket
|
191
|
-
attr_accessor :main_message_queue, :main_thread, :queue_used_by_thread, :thread_waiting_for_message, :rescuemethod
|
192
|
+
attr_accessor :main_message_queue, :main_thread, :queue_used_by_thread, :thread_waiting_for_message, :rescuemethod, :read_thread
|
192
193
|
|
193
194
|
# Create a new connection to the bus for a given connect _path_. _path_
|
194
195
|
# format is described in the D-Bus specification:
|
@@ -215,7 +216,7 @@ module DBus
|
|
215
216
|
end
|
216
217
|
|
217
218
|
def start_read_thread
|
218
|
-
@
|
219
|
+
@read_thread = Thread.new{
|
219
220
|
puts "start the reading thread on socket #{@socket}" if $DEBUG
|
220
221
|
loop do #loop to read
|
221
222
|
|
@@ -430,33 +431,52 @@ module DBus
|
|
430
431
|
'
|
431
432
|
# This apostroph is for syntax highlighting editors confused by above xml: "
|
432
433
|
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
send_sync(
|
434
|
+
# Send a _message_.
|
435
|
+
# If _reply_handler_ is not given, wait for the reply
|
436
|
+
# and return the reply, or raise the error.
|
437
|
+
# If _reply_handler_ is given, it will be called when the reply
|
438
|
+
# eventually arrives, with the reply message as the 1st param
|
439
|
+
# and its params following
|
440
|
+
def send_sync_or_async(message, &reply_handler)
|
441
|
+
ret = nil
|
442
|
+
if reply_handler.nil?
|
443
|
+
send_sync(message) do |rmsg|
|
443
444
|
if rmsg.is_a?(Error)
|
444
445
|
raise rmsg
|
445
446
|
else
|
446
|
-
|
447
|
+
ret = rmsg.params
|
447
448
|
end
|
448
449
|
end
|
449
450
|
else
|
450
|
-
|
451
|
-
on_return(m) do |rmsg|
|
451
|
+
on_return(message) do |rmsg|
|
452
452
|
if rmsg.is_a?(Error)
|
453
|
-
|
453
|
+
reply_handler.call(rmsg)
|
454
454
|
else
|
455
|
-
|
455
|
+
reply_handler.call(rmsg, * rmsg.params)
|
456
456
|
end
|
457
457
|
end
|
458
|
+
send(message.marshall)
|
459
|
+
end
|
460
|
+
ret
|
461
|
+
end
|
462
|
+
|
463
|
+
def introspect_data(dest, path, &reply_handler)
|
464
|
+
m = DBus::Message.new(DBus::Message::METHOD_CALL)
|
465
|
+
m.path = path
|
466
|
+
m.interface = "org.freedesktop.DBus.Introspectable"
|
467
|
+
m.destination = dest
|
468
|
+
m.member = "Introspect"
|
469
|
+
m.sender = unique_name
|
470
|
+
if reply_handler.nil?
|
471
|
+
send_sync_or_async(m).first
|
472
|
+
else
|
473
|
+
send_sync_or_async(m) do |*args|
|
474
|
+
# TODO test async introspection, is it used at all?
|
475
|
+
args.shift # forget the message, pass only the text
|
476
|
+
reply_handler.call(*args)
|
477
|
+
nil
|
478
|
+
end
|
458
479
|
end
|
459
|
-
nil
|
460
480
|
end
|
461
481
|
|
462
482
|
# Issues a call to the org.freedesktop.DBus.Introspectable.Introspect method
|
@@ -847,6 +867,7 @@ module DBus
|
|
847
867
|
# Create a new main event loop.
|
848
868
|
def initialize
|
849
869
|
@buses = Hash.new
|
870
|
+
@buses_thread = Array.new
|
850
871
|
@quit_queue = Queue.new
|
851
872
|
@quitting = false
|
852
873
|
$mainclass = self
|
@@ -855,14 +876,14 @@ module DBus
|
|
855
876
|
# the standar quit method didn't quit imediately and wait for a last
|
856
877
|
# message. This methodes allow to quit imediately
|
857
878
|
def quit_imediately
|
879
|
+
@buses.each_value do |b|
|
880
|
+
#b.read_thread.exit
|
881
|
+
end
|
858
882
|
@buses_thread.each do |th|
|
859
883
|
@buses_thread_id.delete(th.object_id)
|
860
|
-
th.exit
|
884
|
+
#th.exit
|
861
885
|
end
|
862
886
|
@quit_queue << "quit"
|
863
|
-
@buses.each_value do |b|
|
864
|
-
b.thread.exit
|
865
|
-
end
|
866
887
|
|
867
888
|
end
|
868
889
|
|
@@ -912,10 +933,10 @@ module DBus
|
|
912
933
|
|
913
934
|
@quit_queue.pop
|
914
935
|
|
915
|
-
while not @buses_thread_id.empty?
|
916
|
-
id = @thread_as_quit.pop
|
917
|
-
@buses_thread_id.delete(id)
|
918
|
-
end
|
936
|
+
#~ while not @buses_thread_id.empty?
|
937
|
+
#~ id = @thread_as_quit.pop
|
938
|
+
#~ @buses_thread_id.delete(id)
|
939
|
+
#~ end
|
919
940
|
|
920
941
|
else
|
921
942
|
@buses.each_value do |b|
|
data/lib/dbus/export.rb
CHANGED
@@ -15,19 +15,20 @@ module DBus
|
|
15
15
|
# = Exportable D-Bus object class
|
16
16
|
#
|
17
17
|
# Objects that are going to be exported by a D-Bus service
|
18
|
-
# should inherit from this class.
|
18
|
+
# should inherit from this class. At the client side, use ProxyObject.
|
19
19
|
class Object
|
20
20
|
# The path of the object.
|
21
21
|
attr_reader :path
|
22
|
-
# The interfaces that the object supports.
|
22
|
+
# The interfaces that the object supports. Hash: String => Interface
|
23
23
|
class_attribute :intfs
|
24
24
|
# The service that the object is exported by.
|
25
25
|
attr_writer :service
|
26
26
|
|
27
|
-
@@cur_intf = nil
|
27
|
+
@@cur_intf = nil # Interface
|
28
28
|
@@intfs_mutex = Mutex.new
|
29
29
|
|
30
30
|
# Create a new object with a given _path_.
|
31
|
+
# Use Service#export to export it.
|
31
32
|
def initialize(path)
|
32
33
|
@path = path
|
33
34
|
@service = nil
|
@@ -39,7 +40,7 @@ module DBus
|
|
39
40
|
self.intfs = (self.intfs || {}).merge({intf.name => intf})
|
40
41
|
end
|
41
42
|
|
42
|
-
# Dispatch a message _msg_
|
43
|
+
# Dispatch a message _msg_ to call exported methods
|
43
44
|
def dispatch(msg)
|
44
45
|
case msg.message_type
|
45
46
|
when Message::METHOD_CALL
|
@@ -73,8 +74,10 @@ module DBus
|
|
73
74
|
# belong to.
|
74
75
|
def self.dbus_interface(s)
|
75
76
|
@@intfs_mutex.synchronize do
|
76
|
-
@@cur_intf =
|
77
|
-
|
77
|
+
unless @@cur_intf = (self.intfs && self.intfs[s])
|
78
|
+
@@cur_intf = Interface.new(s)
|
79
|
+
self.intfs = (self.intfs || {}).merge({s => @@cur_intf})
|
80
|
+
end
|
78
81
|
yield
|
79
82
|
@@cur_intf = nil
|
80
83
|
end
|
data/lib/dbus/introspect.rb
CHANGED
@@ -8,6 +8,7 @@
|
|
8
8
|
# License, version 2.1 as published by the Free Software Foundation.
|
9
9
|
# See the file "COPYING" for the exact licensing terms.
|
10
10
|
|
11
|
+
# TODO check if it is slow, make replaceable
|
11
12
|
require 'rexml/document'
|
12
13
|
|
13
14
|
module DBus
|
@@ -27,15 +28,16 @@ module DBus
|
|
27
28
|
# = D-Bus interface class
|
28
29
|
#
|
29
30
|
# This class is the interface descriptor. In most cases, the Introspect()
|
30
|
-
# method call
|
31
|
+
# method call instantiates and configures this class for us.
|
31
32
|
#
|
32
33
|
# It also is the local definition of interface exported by the program.
|
34
|
+
# At the client side, see ProxyObjectInterface
|
33
35
|
class Interface
|
34
|
-
# The name of the interface.
|
36
|
+
# The name of the interface. String
|
35
37
|
attr_reader :name
|
36
|
-
# The methods that are part of the interface.
|
38
|
+
# The methods that are part of the interface. Hash: Symbol => DBus::Method
|
37
39
|
attr_reader :methods
|
38
|
-
# The signals that are part of the interface.
|
40
|
+
# The signals that are part of the interface. Hash: Symbol => Signal
|
39
41
|
attr_reader :signals
|
40
42
|
|
41
43
|
# Creates a new interface with a given _name_.
|
@@ -47,7 +49,7 @@ module DBus
|
|
47
49
|
|
48
50
|
# Validates a service _name_.
|
49
51
|
def validate_name(name)
|
50
|
-
raise InvalidIntrospectionData if name.
|
52
|
+
raise InvalidIntrospectionData if name.bytesize > 255
|
51
53
|
raise InvalidIntrospectionData if name =~ /^\./ or name =~ /\.$/
|
52
54
|
raise InvalidIntrospectionData if name =~ /\.\./
|
53
55
|
raise InvalidIntrospectionData if not name =~ /\./
|
@@ -100,14 +102,14 @@ module DBus
|
|
100
102
|
# This is a generic class for entities that are part of the interface
|
101
103
|
# such as methods and signals.
|
102
104
|
class InterfaceElement
|
103
|
-
# The name of the interface element.
|
105
|
+
# The name of the interface element. Symbol
|
104
106
|
attr_reader :name
|
105
|
-
# The parameters of the interface element
|
107
|
+
# The parameters of the interface element. Array: FormalParameter
|
106
108
|
attr_reader :params
|
107
109
|
|
108
110
|
# Validates element _name_.
|
109
111
|
def validate_name(name)
|
110
|
-
if (not name =~ MethodSignalRE) or (name.
|
112
|
+
if (not name =~ MethodSignalRE) or (name.bytesize > 255)
|
111
113
|
raise InvalidMethodName, name
|
112
114
|
end
|
113
115
|
end
|
@@ -135,7 +137,7 @@ module DBus
|
|
135
137
|
#
|
136
138
|
# This is a class representing methods that are part of an interface.
|
137
139
|
class Method < InterfaceElement
|
138
|
-
# The list of return values for the method.
|
140
|
+
# The list of return values for the method. Array: FormalParameter
|
139
141
|
attr_reader :rets
|
140
142
|
|
141
143
|
# Creates a new method interface element with the given _name_.
|
@@ -227,10 +229,9 @@ module DBus
|
|
227
229
|
@xml = xml
|
228
230
|
end
|
229
231
|
|
230
|
-
#
|
232
|
+
# return the names of direct subnodes
|
231
233
|
def parse_subnodes
|
232
234
|
subnodes = Array.new
|
233
|
-
t = Time.now
|
234
235
|
d = REXML::Document.new(@xml)
|
235
236
|
d.elements.each("node/node") do |e|
|
236
237
|
subnodes << e.attributes["name"]
|
@@ -238,9 +239,9 @@ module DBus
|
|
238
239
|
subnodes
|
239
240
|
end
|
240
241
|
|
241
|
-
#
|
242
|
+
# return a pair: [list of Interfaces, list of direct subnode names]
|
242
243
|
def parse
|
243
|
-
|
244
|
+
interfaces = Array.new
|
244
245
|
subnodes = Array.new
|
245
246
|
t = Time.now
|
246
247
|
d = REXML::Document.new(@xml)
|
@@ -259,13 +260,13 @@ module DBus
|
|
259
260
|
parse_methsig(se, s)
|
260
261
|
i << s
|
261
262
|
end
|
262
|
-
|
263
|
+
interfaces << i
|
263
264
|
end
|
264
265
|
d = Time.now - t
|
265
266
|
if d > 2
|
266
267
|
puts "Some XML took more that two secs to parse. Optimize me!" if $DEBUG
|
267
268
|
end
|
268
|
-
[
|
269
|
+
[interfaces, subnodes]
|
269
270
|
end
|
270
271
|
|
271
272
|
######################################################################
|
@@ -342,7 +343,7 @@ module DBus
|
|
342
343
|
methdef = "def #{m.name}("
|
343
344
|
methdef += (0..(m.params.size - 1)).to_a.collect { |n|
|
344
345
|
"arg#{n}"
|
345
|
-
}.join(", ")
|
346
|
+
}.push("&reply_handler").join(", ")
|
346
347
|
methdef += %{)
|
347
348
|
msg = Message.new(Message::METHOD_CALL)
|
348
349
|
msg.path = @object.path
|
@@ -365,26 +366,7 @@ module DBus
|
|
365
366
|
idx += 1
|
366
367
|
end
|
367
368
|
methdef += "
|
368
|
-
|
369
|
-
if block_given?
|
370
|
-
@object.bus.on_return(msg) do |rmsg|
|
371
|
-
if rmsg.is_a?(Error)
|
372
|
-
yield(rmsg)
|
373
|
-
else
|
374
|
-
yield(rmsg, *rmsg.params)
|
375
|
-
end
|
376
|
-
end
|
377
|
-
@object.bus.send(msg.marshall)
|
378
|
-
else
|
379
|
-
@object.bus.send_sync(msg) do |rmsg|
|
380
|
-
if rmsg.is_a?(Error)
|
381
|
-
raise rmsg
|
382
|
-
else
|
383
|
-
ret = rmsg.params
|
384
|
-
end
|
385
|
-
end
|
386
|
-
end
|
387
|
-
ret
|
369
|
+
@object.bus.send_sync_or_async(msg, &reply_handler)
|
388
370
|
end
|
389
371
|
"
|
390
372
|
singleton_class.class_eval(methdef)
|
@@ -448,7 +430,7 @@ module DBus
|
|
448
430
|
# over the bus so that the method is executed remotely on the correctponding
|
449
431
|
# object.
|
450
432
|
class ProxyObject
|
451
|
-
# The subnodes of the object in the tree.
|
433
|
+
# The names of direct subnodes of the object in the tree.
|
452
434
|
attr_accessor :subnodes
|
453
435
|
# Flag determining whether the object has been introspected.
|
454
436
|
attr_accessor :introspected
|
@@ -458,7 +440,7 @@ module DBus
|
|
458
440
|
attr_reader :path
|
459
441
|
# The bus the object is reachable via.
|
460
442
|
attr_reader :bus
|
461
|
-
# The default interface of the object.
|
443
|
+
# The default interface of the object, as String.
|
462
444
|
attr_accessor :default_iface
|
463
445
|
|
464
446
|
# Creates a new proxy object living on the given _bus_ at destination _dest_
|
@@ -495,11 +477,12 @@ module DBus
|
|
495
477
|
|
496
478
|
# Returns whether the object has an interface with the given _name_.
|
497
479
|
def has_iface?(name)
|
498
|
-
raise "Cannot call has_iface?
|
480
|
+
raise "Cannot call has_iface? if not introspected" if not @introspected
|
499
481
|
@interfaces.member?(name)
|
500
482
|
end
|
501
483
|
|
502
484
|
# Registers a handler, the code block, for a signal with the given _name_.
|
485
|
+
# It uses _default_iface_ which must have been set.
|
503
486
|
def on_signal(name, &block)
|
504
487
|
if @default_iface and has_iface?(@default_iface)
|
505
488
|
@interfaces[@default_iface].on_signal(@bus, name, &block)
|
@@ -521,10 +504,9 @@ module DBus
|
|
521
504
|
rescue NameError => e
|
522
505
|
# interesting, foo.method("unknown")
|
523
506
|
# raises NameError, not NoMethodError
|
524
|
-
|
525
|
-
raise unless match and match[2] == "DBus::ProxyObjectInterface"
|
507
|
+
raise unless e.to_s =~ /undefined method `#{name}'/
|
526
508
|
# BTW e.exception("...") would preserve the class.
|
527
|
-
raise NoMethodError,"undefined method `#{
|
509
|
+
raise NoMethodError,"undefined method `#{name}' for DBus interface `#{@default_iface}' on object `#{@path}'"
|
528
510
|
end
|
529
511
|
else
|
530
512
|
# TODO distinguish:
|
data/lib/dbus/marshall.rb
CHANGED
@@ -42,9 +42,7 @@ module DBus
|
|
42
42
|
@uint16 = "v"
|
43
43
|
@double = "E"
|
44
44
|
else
|
45
|
-
|
46
|
-
# yes, idea for a good name ? :)
|
47
|
-
raise Exception, "Incorrect endianness"
|
45
|
+
raise InvalidPacketException, "Incorrect endianness #{@endianness}"
|
48
46
|
end
|
49
47
|
@idx = 0
|
50
48
|
end
|
@@ -53,7 +51,7 @@ module DBus
|
|
53
51
|
# Return an array of unmarshalled objects
|
54
52
|
def unmarshall(signature, len = nil)
|
55
53
|
if len != nil
|
56
|
-
if @buffy.
|
54
|
+
if @buffy.bytesize < @idx + len
|
57
55
|
raise IncompleteBufferException
|
58
56
|
end
|
59
57
|
end
|
@@ -73,7 +71,7 @@ module DBus
|
|
73
71
|
when 2, 4, 8
|
74
72
|
bits = a - 1
|
75
73
|
@idx = @idx + bits & ~bits
|
76
|
-
raise IncompleteBufferException if @idx > @buffy.
|
74
|
+
raise IncompleteBufferException if @idx > @buffy.bytesize
|
77
75
|
else
|
78
76
|
raise "Unsupported alignment #{a}"
|
79
77
|
end
|
@@ -86,7 +84,7 @@ module DBus
|
|
86
84
|
|
87
85
|
# Retrieve the next _nbytes_ number of bytes from the buffer.
|
88
86
|
def get(nbytes)
|
89
|
-
raise IncompleteBufferException if @idx + nbytes > @buffy.
|
87
|
+
raise IncompleteBufferException if @idx + nbytes > @buffy.bytesize
|
90
88
|
ret = @buffy.slice(@idx, nbytes)
|
91
89
|
@idx += nbytes
|
92
90
|
ret
|
@@ -96,8 +94,8 @@ module DBus
|
|
96
94
|
def get_nul_terminated
|
97
95
|
raise IncompleteBufferException if not @buffy[@idx..-1] =~ /^([^\0]*)\0/
|
98
96
|
str = $1
|
99
|
-
raise IncompleteBufferException if @idx + str.
|
100
|
-
@idx += str.
|
97
|
+
raise IncompleteBufferException if @idx + str.bytesize + 1 > @buffy.bytesize
|
98
|
+
@idx += str.bytesize + 1
|
101
99
|
str
|
102
100
|
end
|
103
101
|
|
@@ -107,7 +105,7 @@ module DBus
|
|
107
105
|
align(4)
|
108
106
|
str_sz = get(4).unpack(@uint32)[0]
|
109
107
|
ret = @buffy.slice(@idx, str_sz)
|
110
|
-
raise IncompleteBufferException if @idx + str_sz + 1 > @buffy.
|
108
|
+
raise IncompleteBufferException if @idx + str_sz + 1 > @buffy.bytesize
|
111
109
|
@idx += str_sz
|
112
110
|
if @buffy[@idx].ord != 0
|
113
111
|
raise InvalidPacketException, "String is not nul-terminated"
|
@@ -122,7 +120,7 @@ module DBus
|
|
122
120
|
def get_signature
|
123
121
|
str_sz = get(1).unpack('C')[0]
|
124
122
|
ret = @buffy.slice(@idx, str_sz)
|
125
|
-
raise IncompleteBufferException if @idx + str_sz + 1 >= @buffy.
|
123
|
+
raise IncompleteBufferException if @idx + str_sz + 1 >= @buffy.bytesize
|
126
124
|
@idx += str_sz
|
127
125
|
if @buffy[@idx].ord != 0
|
128
126
|
raise InvalidPacketException, "Type is not nul-terminated"
|
@@ -193,7 +191,7 @@ module DBus
|
|
193
191
|
raise InvalidPacketException if array_sz > 67108864
|
194
192
|
|
195
193
|
align(signature.child.alignment)
|
196
|
-
raise IncompleteBufferException if @idx + array_sz > @buffy.
|
194
|
+
raise IncompleteBufferException if @idx + array_sz > @buffy.bytesize
|
197
195
|
|
198
196
|
packet = Array.new
|
199
197
|
start_idx = @idx
|
@@ -223,6 +221,7 @@ module DBus
|
|
223
221
|
packet = get_string
|
224
222
|
when Type::STRING
|
225
223
|
packet = get_string
|
224
|
+
packet.force_encoding('UTF-8') if RUBY_VERSION >= '1.9'
|
226
225
|
when Type::SIGNATURE
|
227
226
|
packet = get_signature
|
228
227
|
when Type::DICT_ENTRY
|
@@ -240,7 +239,7 @@ module DBus
|
|
240
239
|
|
241
240
|
# D-Bus packet marshaller class
|
242
241
|
#
|
243
|
-
# Class that handles the conversion (
|
242
|
+
# Class that handles the conversion (marshalling) of Ruby objects to
|
244
243
|
# (binary) payload data.
|
245
244
|
class PacketMarshaller
|
246
245
|
# The current or result packet.
|
@@ -267,18 +266,18 @@ module DBus
|
|
267
266
|
|
268
267
|
# Align the buffer with NULL (\0) bytes on a byte length of _a_.
|
269
268
|
def align(a)
|
270
|
-
@packet = @packet.ljust(num_align(@offset + @packet.
|
269
|
+
@packet = @packet.ljust(num_align(@offset + @packet.bytesize, a) - @offset, 0.chr)
|
271
270
|
end
|
272
271
|
|
273
272
|
# Append the the string _str_ itself to the packet.
|
274
273
|
def append_string(str)
|
275
274
|
align(4)
|
276
|
-
@packet += [str.
|
275
|
+
@packet += [str.bytesize].pack("L") + [str].pack("Z*")
|
277
276
|
end
|
278
277
|
|
279
278
|
# Append the the signature _signature_ itself to the packet.
|
280
279
|
def append_signature(str)
|
281
|
-
@packet += str.
|
280
|
+
@packet += str.bytesize.chr + str + "\0"
|
282
281
|
end
|
283
282
|
|
284
283
|
# Append the array type _type_ to the packet and allow for appending
|
@@ -286,12 +285,12 @@ module DBus
|
|
286
285
|
def array(type)
|
287
286
|
# Thanks to Peter Rullmann for this line
|
288
287
|
align(4)
|
289
|
-
sizeidx = @packet.
|
288
|
+
sizeidx = @packet.bytesize
|
290
289
|
@packet += "ABCD"
|
291
290
|
align(type.alignment)
|
292
|
-
contentidx = @packet.
|
291
|
+
contentidx = @packet.bytesize
|
293
292
|
yield
|
294
|
-
sz = @packet.
|
293
|
+
sz = @packet.bytesize - contentidx
|
295
294
|
raise InvalidPacketException if sz > 67108864
|
296
295
|
@packet[sizeidx...sizeidx + 4] = [sz].pack("L")
|
297
296
|
end
|
@@ -308,6 +307,8 @@ module DBus
|
|
308
307
|
end
|
309
308
|
|
310
309
|
# Append a value _val_ to the packet based on its _type_.
|
310
|
+
#
|
311
|
+
# Host native endianness is used, declared in Message#marshall
|
311
312
|
def append(type, val)
|
312
313
|
raise TypeException, "Cannot send nil" if val.nil?
|
313
314
|
|
@@ -372,7 +373,7 @@ module DBus
|
|
372
373
|
|
373
374
|
append_signature(vartype.to_s)
|
374
375
|
align(vartype.alignment)
|
375
|
-
sub = PacketMarshaller.new(@offset + @packet.
|
376
|
+
sub = PacketMarshaller.new(@offset + @packet.bytesize)
|
376
377
|
sub.append(vartype, vardata)
|
377
378
|
@packet += sub.packet
|
378
379
|
when Type::ARRAY
|
data/lib/dbus/matchrule.rb
CHANGED
@@ -15,7 +15,7 @@ module DBus
|
|
15
15
|
#
|
16
16
|
# FIXME
|
17
17
|
class MatchRule
|
18
|
-
# The list of possible match filters.
|
18
|
+
# The list of possible match filters. TODO argN, argNpath
|
19
19
|
FILTERS = [:sender, :interface, :member, :path, :destination, :type]
|
20
20
|
# The sender filter.
|
21
21
|
attr_accessor :sender
|
@@ -94,6 +94,7 @@ module DBus
|
|
94
94
|
return false if @interface and @interface != msg.interface
|
95
95
|
return false if @member and @member != msg.member
|
96
96
|
return false if @path and @path != msg.path
|
97
|
+
# FIXME sender and destination are ignored
|
97
98
|
true
|
98
99
|
end
|
99
100
|
end # class MatchRule
|
data/lib/dbus/message.rb
CHANGED
@@ -152,7 +152,7 @@ module DBus
|
|
152
152
|
@params.each do |param|
|
153
153
|
params.append(param[0], param[1])
|
154
154
|
end
|
155
|
-
@body_length = params.packet.
|
155
|
+
@body_length = params.packet.bytesize
|
156
156
|
|
157
157
|
marshaller = PacketMarshaller.new
|
158
158
|
marshaller.append(Type::BYTE, HOST_END)
|
data/test/binding_test.rb
CHANGED
data/test/bus_driver_test.rb
CHANGED
data/test/bus_test.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Test the bus class
|
3
|
+
require "test/unit"
|
4
|
+
require "dbus-openplacos"
|
5
|
+
|
6
|
+
class BusTest < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@bus = DBus::ASessionBus.new
|
9
|
+
@svc = @bus.service("org.ruby.service")
|
10
|
+
@svc.object("/").introspect
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_introspection_not_leaking
|
14
|
+
# peek inside the object to see if a cleanup step worked or not
|
15
|
+
some_hash = @bus.instance_eval { @method_call_replies || Hash.new }
|
16
|
+
assert_equal 0, some_hash.size, "there are leftover method handlers"
|
17
|
+
end
|
18
|
+
end
|
data/test/property_test.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# Test that a server survives various error cases
|
3
3
|
require "test/unit"
|
4
|
-
require "dbus"
|
4
|
+
require "dbus-openplacos"
|
5
5
|
|
6
6
|
class ServerRobustnessTest < Test::Unit::TestCase
|
7
7
|
def setup
|
@@ -57,7 +57,7 @@ class ServerRobustnessTest < Test::Unit::TestCase
|
|
57
57
|
ifc.not_the_answer
|
58
58
|
assert false, "should have raised"
|
59
59
|
rescue DBus::Error => e
|
60
|
-
assert_no_match(/timeout/, e)
|
60
|
+
assert_no_match(/timeout/, e.to_s)
|
61
61
|
end
|
62
62
|
|
63
63
|
def test_no_such_interface_without_introspection
|
@@ -67,6 +67,6 @@ class ServerRobustnessTest < Test::Unit::TestCase
|
|
67
67
|
ifc.the_answer
|
68
68
|
assert false, "should have raised"
|
69
69
|
rescue DBus::Error => e
|
70
|
-
assert_no_match(/timeout/, e)
|
70
|
+
assert_no_match(/timeout/, e.to_s)
|
71
71
|
end
|
72
72
|
end
|
data/test/server_test.rb
CHANGED
data/test/service_newapi.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
2
3
|
|
3
4
|
# find the library without external help
|
4
5
|
$:.unshift File.expand_path("../../lib", __FILE__)
|
5
6
|
|
6
|
-
require 'dbus'
|
7
|
+
require 'dbus-openplacos'
|
7
8
|
|
8
9
|
def d(msg)
|
9
10
|
puts "#{$$} #{msg}" if $DEBUG
|
@@ -56,6 +57,13 @@ class Test < DBus::Object
|
|
56
57
|
dbus_method :Error, "in name:s, in description:s" do |name, description|
|
57
58
|
raise DBus.error(name), description
|
58
59
|
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# closing and reopening the same interface
|
63
|
+
dbus_interface INTERFACE do
|
64
|
+
dbus_method :multibyte_string, "out string:s" do
|
65
|
+
"あいうえお"
|
66
|
+
end
|
59
67
|
|
60
68
|
dbus_signal :SomethingJustHappened, "toto:s, tutu:u"
|
61
69
|
end
|
@@ -186,7 +194,7 @@ bus.add_match(mr) do |msg|
|
|
186
194
|
end
|
187
195
|
end
|
188
196
|
|
189
|
-
puts "listening"
|
197
|
+
puts "listening, with ruby-#{RUBY_VERSION}"
|
190
198
|
main = DBus::Main.new
|
191
199
|
main << bus
|
192
200
|
begin
|
data/test/signal_test.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# Test the signal handlers
|
3
3
|
require "test/unit"
|
4
|
-
require "dbus"
|
4
|
+
require "dbus-openplacos"
|
5
5
|
|
6
6
|
def d(msg)
|
7
7
|
puts "#{$$} #{msg}" if $DEBUG
|
@@ -33,7 +33,7 @@ class SignalHandlerTest < Test::Unit::TestCase
|
|
33
33
|
end
|
34
34
|
|
35
35
|
d "will begin"
|
36
|
-
@obj.LongTaskBegin
|
36
|
+
@obj.LongTaskBegin 0.5
|
37
37
|
|
38
38
|
quitter = Thread.new do
|
39
39
|
d "sleep before quit"
|
data/test/t2.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
2
3
|
require "test/unit"
|
3
|
-
require "dbus"
|
4
|
+
require "dbus-openplacos"
|
4
5
|
|
5
6
|
class ValueTest < Test::Unit::TestCase
|
6
7
|
def setup
|
@@ -63,4 +64,9 @@ class ValueTest < Test::Unit::TestCase
|
|
63
64
|
# "warning: default `to_a' will be obsolete"
|
64
65
|
@obj.the_answer
|
65
66
|
end
|
67
|
+
|
68
|
+
def test_multibyte_string
|
69
|
+
str = @obj.multibyte_string[0]
|
70
|
+
assert_equal "あいうえお", str
|
71
|
+
end
|
66
72
|
end
|
data/test/t3-ticket27.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# Test passing a particular struct array through a variant
|
3
3
|
# https://trac.luon.net/ruby-dbus/ticket/27
|
4
|
-
require "dbus"
|
4
|
+
require "dbus-openplacos"
|
5
5
|
session_bus = DBus::ASessionBus.new
|
6
6
|
svc = session_bus.service("org.ruby.service")
|
7
7
|
obj = svc.object("/org/ruby/MyInstance")
|
data/test/t6-loop.rb
CHANGED
@@ -0,0 +1,35 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Test thread safety
|
3
|
+
require "test/unit"
|
4
|
+
require "dbus-openplacos"
|
5
|
+
|
6
|
+
def d(msg)
|
7
|
+
puts "#{$$} #{msg}" if $DEBUG
|
8
|
+
end
|
9
|
+
|
10
|
+
class ThreadSafetyTest < Test::Unit::TestCase
|
11
|
+
def test_thread_competition
|
12
|
+
print "Thread competition: "
|
13
|
+
jobs = []
|
14
|
+
5.times do
|
15
|
+
jobs << Thread.new do
|
16
|
+
Thread.current.abort_on_exception = true
|
17
|
+
|
18
|
+
# use separate connections to avoid races
|
19
|
+
bus = DBus::ASessionBus.new
|
20
|
+
svc = bus.service("org.ruby.service")
|
21
|
+
obj = svc.object("/org/ruby/MyInstance")
|
22
|
+
obj.introspect
|
23
|
+
obj.default_iface = "org.ruby.SampleInterface"
|
24
|
+
|
25
|
+
10.times do |i|
|
26
|
+
print "#{i} "
|
27
|
+
$stdout.flush
|
28
|
+
assert_equal 42, obj.the_answer[0]
|
29
|
+
sleep 0.1 * rand
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
jobs.each do |thread| thread.join end
|
34
|
+
end
|
35
|
+
end
|
data/test/variant_test.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-dbus-openplacos
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 5
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 6
|
9
|
-
-
|
10
|
-
version: 0.6.
|
9
|
+
- 1
|
10
|
+
version: 0.6.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Openplacos Team
|
@@ -45,7 +45,7 @@ files:
|
|
45
45
|
- examples/simple/properties.rb
|
46
46
|
- examples/utils/listnames.rb
|
47
47
|
- examples/utils/notify.rb
|
48
|
-
- lib/dbus.rb
|
48
|
+
- lib/dbus-openplacos.rb
|
49
49
|
- lib/dbus/auth.rb
|
50
50
|
- lib/dbus/bus.rb
|
51
51
|
- lib/dbus/core_ext/class/attribute.rb
|
@@ -61,6 +61,7 @@ files:
|
|
61
61
|
- ruby-dbus-openplacos.gemspec
|
62
62
|
- test/binding_test.rb
|
63
63
|
- test/bus_driver_test.rb
|
64
|
+
- test/bus_test.rb
|
64
65
|
- test/dbus-launch-simple
|
65
66
|
- test/dbus-limited-session.conf
|
66
67
|
- test/property_test.rb
|
@@ -76,6 +77,7 @@ files:
|
|
76
77
|
- test/t6-loop.rb
|
77
78
|
- test/test_env
|
78
79
|
- test/test_server
|
80
|
+
- test/thread_safety_test.rb
|
79
81
|
- test/variant_test.rb
|
80
82
|
- COPYING
|
81
83
|
- README
|
@@ -94,10 +96,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
94
96
|
requirements:
|
95
97
|
- - ">="
|
96
98
|
- !ruby/object:Gem::Version
|
97
|
-
hash:
|
99
|
+
hash: 57
|
98
100
|
segments:
|
99
|
-
-
|
100
|
-
|
101
|
+
- 1
|
102
|
+
- 8
|
103
|
+
- 7
|
104
|
+
version: 1.8.7
|
101
105
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
106
|
none: false
|
103
107
|
requirements:
|