ruby-dbus 0.18.0.beta3 → 0.18.0.beta6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/NEWS.md +38 -0
- data/VERSION +1 -1
- data/lib/dbus/data.rb +201 -158
- data/lib/dbus/marshall.rb +23 -8
- data/lib/dbus/type.rb +144 -15
- data/spec/data/marshall.yaml +28 -0
- data/spec/data_spec.rb +328 -44
- data/spec/packet_marshaller_spec.rb +7 -0
- data/spec/packet_unmarshaller_spec.rb +2 -16
- data/spec/property_spec.rb +48 -2
- data/spec/service_newapi.rb +4 -4
- data/spec/type_spec.rb +145 -0
- metadata +6 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54a45385340217271e3fb445cddf6afcddb9892c4bf75b503e7859390f4d2ed7
|
4
|
+
data.tar.gz: 3c4f71745992c5afece87e34909e67f451717c9398ac6efb6235cc64ad1d1b0c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 864aaaaa867ea04247515d875d836560a558b7a3d780712a41dcd52214d95e47e857d640d66a3573eaf4df778a0320f89ad2c59918c005a2fc80adb8a63074cb
|
7
|
+
data.tar.gz: cabd9d699d8b7aad7c5f77a83aa07389b59c11b34b1219822909a031774b078d0bf001a1bce9bb5912be42caa4adba7608906ebc76dde57ff9f06d13afd7850f
|
data/NEWS.md
CHANGED
@@ -2,6 +2,44 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## Ruby D-Bus 0.18.0.beta6 - 2022-05-25
|
6
|
+
|
7
|
+
API:
|
8
|
+
* Data::Base#value returns plain Ruby types;
|
9
|
+
Data::Container#exact_value contains Data::Base ([#114][]).
|
10
|
+
* Data::Base#initialize and .from_typed allow plain or exact values, validate
|
11
|
+
argument types.
|
12
|
+
* Implement #== (converting) and #eql? (strict) for Data::Base and DBus::Type.
|
13
|
+
|
14
|
+
[#114]: https://github.com/mvidner/ruby-dbus/pull/114
|
15
|
+
|
16
|
+
## Ruby D-Bus 0.18.0.beta5 - 2022-04-27
|
17
|
+
|
18
|
+
API:
|
19
|
+
* DBus::Type instances are frozen.
|
20
|
+
* Data::Container classes (Array, Struct, DictEntry, but not Variant)
|
21
|
+
constructors (#initialize, .from_items, .from_typed) changed to have
|
22
|
+
a *type* argument instead of *member_type* or *member_types*.
|
23
|
+
* Added type factories
|
24
|
+
* Type::Array[type]
|
25
|
+
* Type::Hash[key_type, value_type]
|
26
|
+
* Type::Struct[type1, type2...]
|
27
|
+
|
28
|
+
Bug fixes:
|
29
|
+
* Properties containing Variants would return them doubly wrapped ([#111][]).
|
30
|
+
|
31
|
+
[#111]: https://github.com/mvidner/ruby-dbus/pull/111
|
32
|
+
|
33
|
+
## Ruby D-Bus 0.18.0.beta4 - 2022-04-21
|
34
|
+
|
35
|
+
Bug fixes:
|
36
|
+
* Service-side properties: Fix Properties.Get, Properties.GetAll for
|
37
|
+
properties that contain arrays, on other than outermost level ([#109][]).
|
38
|
+
* Sending variants: fixed make_variant to correctly guess the signature
|
39
|
+
for UInt64 and number-keyed hashes/dictionaries.
|
40
|
+
|
41
|
+
[#109]: https://github.com/mvidner/ruby-dbus/pull/109
|
42
|
+
|
5
43
|
## Ruby D-Bus 0.18.0.beta3 - 2022-04-10
|
6
44
|
|
7
45
|
Bug fixes:
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.18.0.
|
1
|
+
0.18.0.beta6
|
data/lib/dbus/data.rb
CHANGED
@@ -35,7 +35,7 @@ module DBus
|
|
35
35
|
# construct an appropriate {Data::Base} instance.
|
36
36
|
#
|
37
37
|
# @param type [SingleCompleteType,Type]
|
38
|
-
# @param value [::Object]
|
38
|
+
# @param value [::Object,Data::Base] a plain value; exact values also allowed
|
39
39
|
# @return [Data::Base]
|
40
40
|
# @raise TypeError
|
41
41
|
def make_typed(type, value)
|
@@ -43,7 +43,7 @@ module DBus
|
|
43
43
|
data_class = Data::BY_TYPE_CODE[type.sigtype]
|
44
44
|
# not nil because DBus.type validates
|
45
45
|
|
46
|
-
data_class.from_typed(value,
|
46
|
+
data_class.from_typed(value, type: type)
|
47
47
|
end
|
48
48
|
module_function :make_typed
|
49
49
|
|
@@ -58,15 +58,28 @@ module DBus
|
|
58
58
|
# @!method self.fixed?
|
59
59
|
# @return [Boolean]
|
60
60
|
|
61
|
-
# @return
|
61
|
+
# @return [::Object] a valid value, plain-Ruby typed.
|
62
|
+
# @see Data::Container#exact_value
|
62
63
|
attr_reader :value
|
63
64
|
|
65
|
+
# @!method self.type_code
|
66
|
+
# @return [String] a single-character string, for example "a" for arrays
|
67
|
+
|
64
68
|
# @!method type
|
65
69
|
# @abstract
|
66
70
|
# Note that for Variants type=="v",
|
67
71
|
# for the specific see {Variant#member_type}
|
68
72
|
# @return [Type] the exact type of this value
|
69
73
|
|
74
|
+
# @!method self.from_typed(value, type:)
|
75
|
+
# @param value [::Object]
|
76
|
+
# @param type [Type]
|
77
|
+
# @return [Base]
|
78
|
+
# @api private
|
79
|
+
# Use {Data.make_typed} instead.
|
80
|
+
# Construct an instance of the specific subclass, with a type further
|
81
|
+
# specified in the *type* argument.
|
82
|
+
|
70
83
|
# Child classes must validate *value*.
|
71
84
|
def initialize(value)
|
72
85
|
@value = value
|
@@ -82,7 +95,19 @@ module DBus
|
|
82
95
|
|
83
96
|
# Hash key equality
|
84
97
|
# See https://ruby-doc.org/core-3.0.0/Object.html#method-i-eql-3F
|
85
|
-
|
98
|
+
# Stricter than #== (RSpec: eq), 1==1.0 but 1.eql(1.0)->false
|
99
|
+
def eql?(other)
|
100
|
+
return false unless other.class == self.class
|
101
|
+
|
102
|
+
other.value.eql?(@value)
|
103
|
+
# TODO: this should work, now check derived classes, exact_value
|
104
|
+
end
|
105
|
+
|
106
|
+
# @param type [Type]
|
107
|
+
def self.assert_type_matches_class(type)
|
108
|
+
raise ArgumentError, "Expecting #{type_code.inspect} for class #{self}, got #{type.sigtype.inspect}" \
|
109
|
+
unless type.sigtype == type_code
|
110
|
+
end
|
86
111
|
end
|
87
112
|
|
88
113
|
# A value that is not a {Container}.
|
@@ -103,10 +128,10 @@ module DBus
|
|
103
128
|
end
|
104
129
|
|
105
130
|
# @param value [::Object]
|
106
|
-
# @param
|
131
|
+
# @param type [Type]
|
107
132
|
# @return [Basic]
|
108
|
-
def self.from_typed(value,
|
109
|
-
|
133
|
+
def self.from_typed(value, type:)
|
134
|
+
assert_type_matches_class(type)
|
110
135
|
new(value)
|
111
136
|
end
|
112
137
|
end
|
@@ -132,34 +157,6 @@ module DBus
|
|
132
157
|
end
|
133
158
|
end
|
134
159
|
|
135
|
-
# {DBus::Data::String}, {DBus::Data::ObjectPath}, or {DBus::Data::Signature}.
|
136
|
-
class StringLike < Basic
|
137
|
-
def self.fixed?
|
138
|
-
false
|
139
|
-
end
|
140
|
-
|
141
|
-
def initialize(value)
|
142
|
-
if value.is_a?(self.class)
|
143
|
-
value = value.value
|
144
|
-
else
|
145
|
-
self.class.validate_raw!(value)
|
146
|
-
end
|
147
|
-
|
148
|
-
super(value)
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
# Contains one or more other values.
|
153
|
-
class Container < Base
|
154
|
-
def self.basic?
|
155
|
-
false
|
156
|
-
end
|
157
|
-
|
158
|
-
def self.fixed?
|
159
|
-
false
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
160
|
# Format strings for String#unpack, both little- and big-endian.
|
164
161
|
Format = ::Struct.new(:little, :big)
|
165
162
|
|
@@ -398,6 +395,23 @@ module DBus
|
|
398
395
|
end
|
399
396
|
end
|
400
397
|
|
398
|
+
# {DBus::Data::String}, {DBus::Data::ObjectPath}, or {DBus::Data::Signature}.
|
399
|
+
class StringLike < Basic
|
400
|
+
def self.fixed?
|
401
|
+
false
|
402
|
+
end
|
403
|
+
|
404
|
+
def initialize(value)
|
405
|
+
if value.is_a?(self.class)
|
406
|
+
value = value.value
|
407
|
+
else
|
408
|
+
self.class.validate_raw!(value)
|
409
|
+
end
|
410
|
+
|
411
|
+
super(value)
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
401
415
|
# UTF-8 encoded string.
|
402
416
|
class String < StringLike
|
403
417
|
def self.type_code
|
@@ -477,7 +491,7 @@ module DBus
|
|
477
491
|
Byte
|
478
492
|
end
|
479
493
|
|
480
|
-
# @return [Array<Type>]
|
494
|
+
# @return [::Array<Type>]
|
481
495
|
def self.validate_raw!(value)
|
482
496
|
DBus.types(value)
|
483
497
|
rescue Type::SignatureException => e
|
@@ -494,6 +508,44 @@ module DBus
|
|
494
508
|
end
|
495
509
|
end
|
496
510
|
|
511
|
+
# Contains one or more other values.
|
512
|
+
class Container < Base
|
513
|
+
def self.basic?
|
514
|
+
false
|
515
|
+
end
|
516
|
+
|
517
|
+
def self.fixed?
|
518
|
+
false
|
519
|
+
end
|
520
|
+
|
521
|
+
# For containers, the type varies among instances
|
522
|
+
# @see Base#type
|
523
|
+
attr_reader :type
|
524
|
+
|
525
|
+
# @return something that is, or contains, {Data::Base}.
|
526
|
+
# Er, this docs kinda sucks.
|
527
|
+
def exact_value
|
528
|
+
@value
|
529
|
+
end
|
530
|
+
|
531
|
+
def value
|
532
|
+
@value.map(&:value)
|
533
|
+
end
|
534
|
+
|
535
|
+
# Hash key equality
|
536
|
+
# See https://ruby-doc.org/core-3.0.0/Object.html#method-i-eql-3F
|
537
|
+
# Stricter than #== (RSpec: eq), 1==1.0 but 1.eql(1.0)->false
|
538
|
+
def eql?(other)
|
539
|
+
return false unless other.class == self.class
|
540
|
+
|
541
|
+
other.exact_value.eql?(exact_value)
|
542
|
+
end
|
543
|
+
|
544
|
+
# def ==(other)
|
545
|
+
# eql?(other) || super
|
546
|
+
# end
|
547
|
+
end
|
548
|
+
|
497
549
|
# An Array, or a Dictionary (Hash).
|
498
550
|
class Array < Container
|
499
551
|
def self.type_code
|
@@ -504,44 +556,33 @@ module DBus
|
|
504
556
|
4
|
505
557
|
end
|
506
558
|
|
507
|
-
# @return [Type]
|
508
|
-
attr_reader :member_type
|
509
|
-
|
510
|
-
def type
|
511
|
-
return @type if @type
|
512
|
-
|
513
|
-
# TODO: reconstructing the type is cumbersome; have #initialize take *type* instead?
|
514
|
-
# TODO: or rather add Type::Array[t]
|
515
|
-
@type = Type.new("a")
|
516
|
-
@type << member_type
|
517
|
-
@type
|
518
|
-
end
|
519
|
-
|
520
559
|
# TODO: check that Hash keys are basic types
|
521
560
|
# @param mode [:plain,:exact]
|
522
|
-
# @param
|
561
|
+
# @param type [Type]
|
523
562
|
# @param hash [Boolean] are we unmarshalling an ARRAY of DICT_ENTRY
|
524
563
|
# @return [Data::Array]
|
525
|
-
def self.from_items(value, mode:,
|
564
|
+
def self.from_items(value, mode:, type:, hash: false)
|
526
565
|
value = Hash[value] if hash
|
527
566
|
return value if mode == :plain
|
528
567
|
|
529
|
-
new(value,
|
568
|
+
new(value, type: type)
|
530
569
|
end
|
531
570
|
|
532
571
|
# @param value [::Object]
|
533
|
-
# @param
|
572
|
+
# @param type [Type]
|
534
573
|
# @return [Data::Array]
|
535
|
-
def self.from_typed(value,
|
536
|
-
|
537
|
-
|
574
|
+
def self.from_typed(value, type:)
|
575
|
+
new(value, type: type) # initialize(::Array<Data::Base>)
|
576
|
+
end
|
538
577
|
|
539
|
-
|
540
|
-
|
541
|
-
|
578
|
+
def value
|
579
|
+
v = super
|
580
|
+
if type.child.sigtype == Type::DICT_ENTRY
|
581
|
+
# BTW this makes a copy so mutating it is pointless
|
582
|
+
v.to_h
|
583
|
+
else
|
584
|
+
v
|
542
585
|
end
|
543
|
-
|
544
|
-
new(items, member_type: member_type) # initialize(::Array<Data::Base>)
|
545
586
|
end
|
546
587
|
|
547
588
|
# FIXME: should Data::Array be mutable?
|
@@ -550,13 +591,27 @@ module DBus
|
|
550
591
|
# TODO: specify type or guess type?
|
551
592
|
# Data is the exact type, so its constructor should be exact
|
552
593
|
# and guesswork should be clearly labeled
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
594
|
+
|
595
|
+
# @param value [Data::Array,Enumerable]
|
596
|
+
# @param type [SingleCompleteType,Type]
|
597
|
+
def initialize(value, type:)
|
598
|
+
type = Type::Factory.make_type(type)
|
599
|
+
self.class.assert_type_matches_class(type)
|
600
|
+
@type = type
|
601
|
+
|
602
|
+
typed_value = case value
|
603
|
+
when Data::Array
|
604
|
+
raise ArgumentError, "Specified type is #{type} but value type is #{value.type}" \
|
605
|
+
unless value.type == type
|
606
|
+
|
607
|
+
value.exact_value
|
608
|
+
else
|
609
|
+
# TODO: Dict??
|
610
|
+
value.map do |i|
|
611
|
+
Data.make_typed(type.child, i)
|
612
|
+
end
|
613
|
+
end
|
614
|
+
super(typed_value)
|
560
615
|
end
|
561
616
|
end
|
562
617
|
|
@@ -572,51 +627,84 @@ module DBus
|
|
572
627
|
8
|
573
628
|
end
|
574
629
|
|
575
|
-
# @return [::Array<Type>]
|
576
|
-
attr_reader :member_types
|
577
|
-
|
578
|
-
def type
|
579
|
-
return @type if @type
|
580
|
-
|
581
|
-
# TODO: reconstructing the type is cumbersome; have #initialize take *type* instead?
|
582
|
-
# TODO: or rather add Type::Struct[t1, t2, ...]
|
583
|
-
@type = Type.new(self.class.type_code, abstract: true)
|
584
|
-
@member_types.each do |member_type|
|
585
|
-
@type << member_type
|
586
|
-
end
|
587
|
-
@type
|
588
|
-
end
|
589
|
-
|
590
630
|
# @param value [::Array]
|
591
|
-
def self.from_items(value, mode:,
|
631
|
+
def self.from_items(value, mode:, type:)
|
592
632
|
value.freeze
|
593
633
|
return value if mode == :plain
|
594
634
|
|
595
|
-
new(value,
|
635
|
+
new(value, type: type)
|
596
636
|
end
|
597
637
|
|
598
638
|
# @param value [::Object] (#size, #each)
|
599
|
-
# @param
|
639
|
+
# @param type [Type]
|
600
640
|
# @return [Struct]
|
601
|
-
def self.from_typed(value,
|
602
|
-
|
603
|
-
|
641
|
+
def self.from_typed(value, type:)
|
642
|
+
new(value, type: type)
|
643
|
+
end
|
644
|
+
|
645
|
+
# @param value [Data::Struct,Enumerable]
|
646
|
+
# @param type [SingleCompleteType,Type]
|
647
|
+
def initialize(value, type:)
|
648
|
+
type = Type::Factory.make_type(type)
|
649
|
+
self.class.assert_type_matches_class(type)
|
650
|
+
@type = type
|
604
651
|
|
605
|
-
|
606
|
-
|
652
|
+
typed_value = case value
|
653
|
+
when self.class
|
654
|
+
raise ArgumentError, "Specified type is #{type} but value type is #{value.type}" \
|
655
|
+
unless value.type == type
|
656
|
+
|
657
|
+
value.exact_value
|
658
|
+
else
|
659
|
+
member_types = type.members
|
660
|
+
unless value.size == member_types.size
|
661
|
+
raise ArgumentError, "Specified type has #{member_types.size} members " \
|
662
|
+
"but value has #{value.size} members"
|
663
|
+
end
|
664
|
+
|
665
|
+
member_types.zip(value).map do |item_type, item|
|
666
|
+
Data.make_typed(item_type, item)
|
667
|
+
end
|
668
|
+
end
|
669
|
+
super(typed_value)
|
670
|
+
end
|
671
|
+
|
672
|
+
def ==(other)
|
673
|
+
case other
|
674
|
+
when ::Struct
|
675
|
+
@value.size == other.size &&
|
676
|
+
@value.zip(other.to_a).all? { |i, other_i| i == other_i }
|
677
|
+
else
|
678
|
+
super
|
607
679
|
end
|
680
|
+
end
|
681
|
+
end
|
608
682
|
|
609
|
-
|
683
|
+
# Dictionary/Hash entry.
|
684
|
+
# TODO: shouldn't instantiate?
|
685
|
+
class DictEntry < Struct
|
686
|
+
def self.type_code
|
687
|
+
"e"
|
610
688
|
end
|
611
689
|
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
690
|
+
# @param value [::Array]
|
691
|
+
def self.from_items(value, mode:, type:) # rubocop:disable Lint/UnusedMethodArgument
|
692
|
+
value.freeze
|
693
|
+
# DictEntry ignores the :exact mode
|
694
|
+
value
|
695
|
+
end
|
696
|
+
|
697
|
+
# @param value [::Object] (#size, #each)
|
698
|
+
# @param type [Type]
|
699
|
+
# @return [DictEntry]
|
700
|
+
def self.from_typed(value, type:)
|
701
|
+
new(value, type: type)
|
616
702
|
end
|
617
703
|
end
|
618
704
|
|
619
|
-
# A generic type
|
705
|
+
# A generic type.
|
706
|
+
#
|
707
|
+
# Implementation note: @value is a {Data::Base}.
|
620
708
|
class Variant < Container
|
621
709
|
def self.type_code
|
622
710
|
"v"
|
@@ -626,6 +714,10 @@ module DBus
|
|
626
714
|
1
|
627
715
|
end
|
628
716
|
|
717
|
+
def value
|
718
|
+
@value.value
|
719
|
+
end
|
720
|
+
|
629
721
|
# @param member_type [Type]
|
630
722
|
def self.from_items(value, mode:, member_type:)
|
631
723
|
return value if mode == :plain
|
@@ -634,12 +726,12 @@ module DBus
|
|
634
726
|
end
|
635
727
|
|
636
728
|
# @param value [::Object]
|
637
|
-
# @param
|
729
|
+
# @param type [Type]
|
638
730
|
# @return [Variant]
|
639
|
-
def self.from_typed(value,
|
640
|
-
|
731
|
+
def self.from_typed(value, type:)
|
732
|
+
assert_type_matches_class(type)
|
641
733
|
|
642
|
-
# decide on type of value
|
734
|
+
# nil: decide on type of value
|
643
735
|
new(value, member_type: nil)
|
644
736
|
end
|
645
737
|
|
@@ -667,73 +759,24 @@ module DBus
|
|
667
759
|
# @param member_type [Type,nil]
|
668
760
|
def initialize(value, member_type:)
|
669
761
|
# TODO: validate that the given *member_type* matches *value*
|
670
|
-
|
762
|
+
case value
|
763
|
+
when Data::Variant
|
671
764
|
# Copy the contained value instead of boxing it more
|
672
765
|
# TODO: except perhaps for round-tripping in exact mode?
|
673
766
|
@member_type = value.member_type
|
674
|
-
value = value.
|
767
|
+
value = value.exact_value
|
768
|
+
when Data::Base
|
769
|
+
@member_type = member_type || value.type
|
770
|
+
raise ArgumentError, "Variant type #{@member_type} does not match value type #{value.type}" \
|
771
|
+
unless @member_type == value.type
|
675
772
|
else
|
676
773
|
@member_type = member_type || self.class.guess_type(value)
|
774
|
+
value = Data.make_typed(@member_type, value)
|
677
775
|
end
|
678
776
|
super(value)
|
679
777
|
end
|
680
778
|
end
|
681
779
|
|
682
|
-
# Dictionary/Hash entry.
|
683
|
-
# TODO: shouldn't instantiate?
|
684
|
-
class DictEntry < Container
|
685
|
-
def self.type_code
|
686
|
-
"e"
|
687
|
-
end
|
688
|
-
|
689
|
-
def self.alignment
|
690
|
-
8
|
691
|
-
end
|
692
|
-
|
693
|
-
# @return [::Array<Type>]
|
694
|
-
attr_reader :member_types
|
695
|
-
|
696
|
-
def type
|
697
|
-
return @type if @type
|
698
|
-
|
699
|
-
# TODO: reconstructing the type is cumbersome; have #initialize take *type* instead?
|
700
|
-
@type = Type.new(self.class.type_code, abstract: true)
|
701
|
-
@member_types.each do |member_type|
|
702
|
-
@type << member_type
|
703
|
-
end
|
704
|
-
@type
|
705
|
-
end
|
706
|
-
|
707
|
-
# @param value [::Array]
|
708
|
-
def self.from_items(value, mode:, member_types:) # rubocop:disable Lint/UnusedMethodArgument
|
709
|
-
value.freeze
|
710
|
-
# DictEntry ignores the :exact mode
|
711
|
-
value
|
712
|
-
end
|
713
|
-
|
714
|
-
# @param value [::Object] (#size, #each)
|
715
|
-
# @param member_types [::Array<Type>]
|
716
|
-
# @return [DictEntry]
|
717
|
-
def self.from_typed(value, member_types:)
|
718
|
-
# assert member_types.size == 2
|
719
|
-
# TODO: duplicated from Struct. Inherit/delegate?
|
720
|
-
# TODO: validation
|
721
|
-
raise unless value.size == member_types.size
|
722
|
-
|
723
|
-
items = member_types.zip(value).map do |item_type, item|
|
724
|
-
Data.make_typed(item_type, item)
|
725
|
-
end
|
726
|
-
|
727
|
-
new(items, member_types: member_types) # initialize(::Array<Data::Base>)
|
728
|
-
end
|
729
|
-
|
730
|
-
def initialize(value, member_types:)
|
731
|
-
@member_types = member_types
|
732
|
-
@type = nil
|
733
|
-
super(value)
|
734
|
-
end
|
735
|
-
end
|
736
|
-
|
737
780
|
consts = constants.map { |c_sym| const_get(c_sym) }
|
738
781
|
classes = consts.find_all { |c| c.respond_to?(:type_code) }
|
739
782
|
by_type_code = classes.map { |cl| [cl.type_code, cl] }.to_h
|
data/lib/dbus/marshall.rb
CHANGED
@@ -118,7 +118,7 @@ module DBus
|
|
118
118
|
values = signature.members.map do |child_sig|
|
119
119
|
do_parse(child_sig, mode: mode)
|
120
120
|
end
|
121
|
-
packet = data_class.from_items(values, mode: mode,
|
121
|
+
packet = data_class.from_items(values, mode: mode, type: signature)
|
122
122
|
|
123
123
|
when Type::VARIANT
|
124
124
|
data_sig = do_parse(Data::Signature.type, mode: :exact) # -> Data::Signature
|
@@ -147,7 +147,7 @@ module DBus
|
|
147
147
|
items << item
|
148
148
|
end
|
149
149
|
is_hash = signature.child.sigtype == Type::DICT_ENTRY
|
150
|
-
packet = data_class.from_items(items, mode: mode,
|
150
|
+
packet = data_class.from_items(items, mode: mode, type: signature, hash: is_hash)
|
151
151
|
end
|
152
152
|
end
|
153
153
|
packet
|
@@ -250,9 +250,10 @@ module DBus
|
|
250
250
|
when Type::VARIANT
|
251
251
|
append_variant(val)
|
252
252
|
when Type::ARRAY
|
253
|
+
val = val.exact_value if val.is_a?(Data::Array)
|
253
254
|
append_array(type.child, val)
|
254
255
|
when Type::STRUCT, Type::DICT_ENTRY
|
255
|
-
val = val.
|
256
|
+
val = val.exact_value if val.is_a?(Data::Struct) || val.is_a?(Data::DictEntry)
|
256
257
|
unless val.is_a?(Array) || val.is_a?(Struct)
|
257
258
|
type_name = Type::TYPE_MAPPING[type.sigtype].first
|
258
259
|
raise TypeException, "#{type_name} expects an Array or Struct, seen #{val.class}"
|
@@ -281,8 +282,14 @@ module DBus
|
|
281
282
|
|
282
283
|
def append_variant(val)
|
283
284
|
vartype = nil
|
284
|
-
if val.is_a?(DBus::Data::
|
285
|
-
vartype = val.
|
285
|
+
if val.is_a?(DBus::Data::Variant)
|
286
|
+
vartype = val.member_type
|
287
|
+
vardata = val.exact_value
|
288
|
+
elsif val.is_a?(DBus::Data::Container)
|
289
|
+
vartype = val.type
|
290
|
+
vardata = val.exact_value
|
291
|
+
elsif val.is_a?(DBus::Data::Base)
|
292
|
+
vartype = val.type
|
286
293
|
vardata = val.value
|
287
294
|
elsif val.is_a?(Array) && val.size == 2
|
288
295
|
case val[0]
|
@@ -353,15 +360,23 @@ module DBus
|
|
353
360
|
elsif value.is_a? Hash
|
354
361
|
h = {}
|
355
362
|
value.each_key { |k| h[k] = make_variant(value[k]) }
|
356
|
-
|
363
|
+
key_type = if value.empty?
|
364
|
+
"s"
|
365
|
+
else
|
366
|
+
t, = make_variant(value.first.first)
|
367
|
+
t
|
368
|
+
end
|
369
|
+
["a{#{key_type}v}", h]
|
357
370
|
elsif value.respond_to? :to_str
|
358
371
|
["s", value.to_str]
|
359
372
|
elsif value.respond_to? :to_int
|
360
373
|
i = value.to_int
|
361
|
-
if
|
374
|
+
if Data::Int32.range.cover?(i)
|
362
375
|
["i", i]
|
363
|
-
|
376
|
+
elsif Data::Int64.range.cover?(i)
|
364
377
|
["x", i]
|
378
|
+
else
|
379
|
+
["t", i]
|
365
380
|
end
|
366
381
|
end
|
367
382
|
end
|