ruby-dbus 0.18.0.beta3 → 0.18.0.beta6
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 +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
|