blob: b727503415d057b2bebc7f0bd848af226153c643 [file] [log] [blame]
[email protected]cf910da22012-02-15 04:21:081// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "dbus/property.h"
6
avi22437c692015-12-22 18:12:457#include <stddef.h>
8
puthik0dd82b12016-10-06 05:03:039#include <memory>
10
[email protected]cf910da22012-02-15 04:21:0811#include "base/bind.h"
12#include "base/logging.h"
13
14#include "dbus/message.h"
15#include "dbus/object_path.h"
16#include "dbus/object_proxy.h"
17
18namespace dbus {
19
20//
21// PropertyBase implementation.
22//
23
deratdce1abec2015-07-16 15:06:4424PropertyBase::PropertyBase() : property_set_(nullptr), is_valid_(false) {}
25
Chris Watkins3740aae2017-11-29 07:44:1126PropertyBase::~PropertyBase() = default;
deratdce1abec2015-07-16 15:06:4427
[email protected]cf910da22012-02-15 04:21:0828void PropertyBase::Init(PropertySet* property_set, const std::string& name) {
29 DCHECK(!property_set_);
30 property_set_ = property_set;
jpawlowskied276542015-05-11 11:07:0431 is_valid_ = false;
[email protected]cf910da22012-02-15 04:21:0832 name_ = name;
33}
34
[email protected]cf910da22012-02-15 04:21:0835//
36// PropertySet implementation.
37//
38
[email protected]7375e8b22012-08-15 01:03:3039PropertySet::PropertySet(
40 ObjectProxy* object_proxy,
41 const std::string& interface,
42 const PropertyChangedCallback& property_changed_callback)
[email protected]cf910da22012-02-15 04:21:0843 : object_proxy_(object_proxy),
44 interface_(interface),
Jeremy Roman7c5cfabd2019-08-12 15:45:2745 property_changed_callback_(property_changed_callback) {}
[email protected]cf910da22012-02-15 04:21:0846
Chris Watkins3740aae2017-11-29 07:44:1147PropertySet::~PropertySet() = default;
[email protected]cf910da22012-02-15 04:21:0848
49void PropertySet::RegisterProperty(const std::string& name,
50 PropertyBase* property) {
51 property->Init(this, name);
52 properties_map_[name] = property;
53}
54
55void PropertySet::ConnectSignals() {
56 DCHECK(object_proxy_);
57 object_proxy_->ConnectToSignal(
Reilly Grantd4e66132019-11-22 17:14:5058 kPropertiesInterface, kPropertiesChanged,
59 base::BindRepeating(&PropertySet::ChangedReceived,
60 weak_ptr_factory_.GetWeakPtr()),
61 base::BindOnce(&PropertySet::ChangedConnected,
62 weak_ptr_factory_.GetWeakPtr()));
[email protected]cf910da22012-02-15 04:21:0863}
64
65
66void PropertySet::ChangedReceived(Signal* signal) {
[email protected]cf910da22012-02-15 04:21:0867 DCHECK(signal);
[email protected]cf910da22012-02-15 04:21:0868 MessageReader reader(signal);
69
70 std::string interface;
71 if (!reader.PopString(&interface)) {
72 LOG(WARNING) << "Property changed signal has wrong parameters: "
73 << "expected interface name: " << signal->ToString();
74 return;
75 }
76
77 if (interface != this->interface())
78 return;
79
80 if (!UpdatePropertiesFromReader(&reader)) {
81 LOG(WARNING) << "Property changed signal has wrong parameters: "
82 << "expected dictionary: " << signal->ToString();
83 }
84
jpawlowskied276542015-05-11 11:07:0485 if (!InvalidatePropertiesFromReader(&reader)) {
86 LOG(WARNING) << "Property changed signal has wrong parameters: "
87 << "expected array to invalidate: " << signal->ToString();
88 }
[email protected]cf910da22012-02-15 04:21:0889}
90
91void PropertySet::ChangedConnected(const std::string& interface_name,
92 const std::string& signal_name,
93 bool success) {
94 LOG_IF(WARNING, !success) << "Failed to connect to " << signal_name
95 << "signal.";
96}
97
98
[email protected]091e0b62012-06-28 18:43:3099void PropertySet::Get(PropertyBase* property, GetCallback callback) {
100 MethodCall method_call(kPropertiesInterface, kPropertiesGet);
101 MessageWriter writer(&method_call);
102 writer.AppendString(interface());
103 writer.AppendString(property->name());
104
105 DCHECK(object_proxy_);
danakjc78039d2019-04-18 16:35:17106 object_proxy_->CallMethod(&method_call, ObjectProxy::TIMEOUT_USE_DEFAULT,
107 base::BindOnce(&PropertySet::OnGet, GetWeakPtr(),
108 property, std::move(callback)));
[email protected]091e0b62012-06-28 18:43:30109}
110
111void PropertySet::OnGet(PropertyBase* property, GetCallback callback,
112 Response* response) {
113 if (!response) {
114 LOG(WARNING) << property->name() << ": Get: failed.";
115 return;
116 }
117
118 MessageReader reader(response);
jpawlowskied276542015-05-11 11:07:04119 if (property->PopValueFromReader(&reader)) {
120 property->set_valid(true);
[email protected]091e0b62012-06-28 18:43:30121 NotifyPropertyChanged(property->name());
jpawlowskied276542015-05-11 11:07:04122 } else {
123 if (property->is_valid()) {
124 property->set_valid(false);
125 NotifyPropertyChanged(property->name());
126 }
127 }
[email protected]091e0b62012-06-28 18:43:30128
129 if (!callback.is_null())
danakjc78039d2019-04-18 16:35:17130 std::move(callback).Run(response);
[email protected]091e0b62012-06-28 18:43:30131}
132
nywanga5523d02015-09-28 22:46:36133bool PropertySet::GetAndBlock(PropertyBase* property) {
134 MethodCall method_call(kPropertiesInterface, kPropertiesGet);
135 MessageWriter writer(&method_call);
136 writer.AppendString(interface());
137 writer.AppendString(property->name());
138
139 DCHECK(object_proxy_);
dcheng2a193282016-04-08 22:55:04140 std::unique_ptr<dbus::Response> response(object_proxy_->CallMethodAndBlock(
141 &method_call, ObjectProxy::TIMEOUT_USE_DEFAULT));
nywanga5523d02015-09-28 22:46:36142
143 if (!response.get()) {
144 LOG(WARNING) << property->name() << ": GetAndBlock: failed.";
145 return false;
146 }
147
148 MessageReader reader(response.get());
149 if (property->PopValueFromReader(&reader)) {
150 property->set_valid(true);
151 NotifyPropertyChanged(property->name());
152 } else {
153 if (property->is_valid()) {
154 property->set_valid(false);
155 NotifyPropertyChanged(property->name());
156 }
157 }
158 return true;
159}
160
[email protected]cf910da22012-02-15 04:21:08161void PropertySet::GetAll() {
162 MethodCall method_call(kPropertiesInterface, kPropertiesGetAll);
163 MessageWriter writer(&method_call);
164 writer.AppendString(interface());
165
166 DCHECK(object_proxy_);
Reilly Grantd4e66132019-11-22 17:14:50167 object_proxy_->CallMethod(
168 &method_call, ObjectProxy::TIMEOUT_USE_DEFAULT,
169 base::BindOnce(&PropertySet::OnGetAll, weak_ptr_factory_.GetWeakPtr()));
[email protected]cf910da22012-02-15 04:21:08170}
171
172void PropertySet::OnGetAll(Response* response) {
[email protected]cf910da22012-02-15 04:21:08173 if (!response) {
[email protected]e6898662014-07-17 05:03:53174 LOG(WARNING) << "GetAll request failed for: " << interface_;
[email protected]cf910da22012-02-15 04:21:08175 return;
176 }
177
178 MessageReader reader(response);
179 if (!UpdatePropertiesFromReader(&reader)) {
180 LOG(WARNING) << "GetAll response has wrong parameters: "
181 << "expected dictionary: " << response->ToString();
182 }
183}
184
[email protected]091e0b62012-06-28 18:43:30185void PropertySet::Set(PropertyBase* property, SetCallback callback) {
186 MethodCall method_call(kPropertiesInterface, kPropertiesSet);
187 MessageWriter writer(&method_call);
188 writer.AppendString(interface());
189 writer.AppendString(property->name());
190 property->AppendSetValueToWriter(&writer);
191
192 DCHECK(object_proxy_);
danakjc78039d2019-04-18 16:35:17193 object_proxy_->CallMethod(&method_call, ObjectProxy::TIMEOUT_USE_DEFAULT,
194 base::BindOnce(&PropertySet::OnSet, GetWeakPtr(),
195 property, std::move(callback)));
[email protected]091e0b62012-06-28 18:43:30196}
197
nywang8dbb26e2015-09-23 00:06:40198bool PropertySet::SetAndBlock(PropertyBase* property) {
199 MethodCall method_call(kPropertiesInterface, kPropertiesSet);
200 MessageWriter writer(&method_call);
201 writer.AppendString(interface());
202 writer.AppendString(property->name());
203 property->AppendSetValueToWriter(&writer);
204
205 DCHECK(object_proxy_);
dcheng2a193282016-04-08 22:55:04206 std::unique_ptr<dbus::Response> response(object_proxy_->CallMethodAndBlock(
207 &method_call, ObjectProxy::TIMEOUT_USE_DEFAULT));
nywang8dbb26e2015-09-23 00:06:40208 if (response.get())
209 return true;
210 return false;
211}
212
[email protected]e6898662014-07-17 05:03:53213void PropertySet::OnSet(PropertyBase* property,
214 SetCallback callback,
[email protected]091e0b62012-06-28 18:43:30215 Response* response) {
216 LOG_IF(WARNING, !response) << property->name() << ": Set: failed.";
217 if (!callback.is_null())
danakjc78039d2019-04-18 16:35:17218 std::move(callback).Run(response);
[email protected]091e0b62012-06-28 18:43:30219}
[email protected]cf910da22012-02-15 04:21:08220
221bool PropertySet::UpdatePropertiesFromReader(MessageReader* reader) {
222 DCHECK(reader);
Ben Chan14d500372017-11-09 20:20:16223 MessageReader array_reader(nullptr);
[email protected]cf910da22012-02-15 04:21:08224 if (!reader->PopArray(&array_reader))
225 return false;
226
227 while (array_reader.HasMoreData()) {
Ben Chan14d500372017-11-09 20:20:16228 MessageReader dict_entry_reader(nullptr);
[email protected]8a3eaffa2012-03-22 20:34:05229 if (array_reader.PopDictEntry(&dict_entry_reader))
230 UpdatePropertyFromReader(&dict_entry_reader);
[email protected]cf910da22012-02-15 04:21:08231 }
232
233 return true;
234}
235
236bool PropertySet::UpdatePropertyFromReader(MessageReader* reader) {
237 DCHECK(reader);
238
239 std::string name;
240 if (!reader->PopString(&name))
241 return false;
242
243 PropertiesMap::iterator it = properties_map_.find(name);
244 if (it == properties_map_.end())
245 return false;
246
247 PropertyBase* property = it->second;
248 if (property->PopValueFromReader(reader)) {
jpawlowskied276542015-05-11 11:07:04249 property->set_valid(true);
[email protected]cf910da22012-02-15 04:21:08250 NotifyPropertyChanged(name);
251 return true;
252 } else {
jpawlowskied276542015-05-11 11:07:04253 if (property->is_valid()) {
254 property->set_valid(false);
255 NotifyPropertyChanged(property->name());
256 }
[email protected]cf910da22012-02-15 04:21:08257 return false;
258 }
259}
260
jpawlowskied276542015-05-11 11:07:04261bool PropertySet::InvalidatePropertiesFromReader(MessageReader* reader) {
262 DCHECK(reader);
Ben Chan14d500372017-11-09 20:20:16263 MessageReader array_reader(nullptr);
jpawlowskied276542015-05-11 11:07:04264 if (!reader->PopArray(&array_reader))
265 return false;
266
267 while (array_reader.HasMoreData()) {
268 std::string name;
269 if (!array_reader.PopString(&name))
270 return false;
271
272 PropertiesMap::iterator it = properties_map_.find(name);
273 if (it == properties_map_.end())
274 continue;
275
276 PropertyBase* property = it->second;
277 if (property->is_valid()) {
278 property->set_valid(false);
279 NotifyPropertyChanged(property->name());
280 }
281 }
282
283 return true;
284}
[email protected]cf910da22012-02-15 04:21:08285
286void PropertySet::NotifyPropertyChanged(const std::string& name) {
287 if (!property_changed_callback_.is_null())
288 property_changed_callback_.Run(name);
289}
290
291//
292// Property<Byte> specialization.
293//
294
295template <>
avi22437c692015-12-22 18:12:45296Property<uint8_t>::Property()
297 : value_(0) {}
[email protected]cf910da22012-02-15 04:21:08298
299template <>
avi22437c692015-12-22 18:12:45300bool Property<uint8_t>::PopValueFromReader(MessageReader* reader) {
[email protected]cf910da22012-02-15 04:21:08301 return reader->PopVariantOfByte(&value_);
302}
303
304template <>
avi22437c692015-12-22 18:12:45305void Property<uint8_t>::AppendSetValueToWriter(MessageWriter* writer) {
[email protected]091e0b62012-06-28 18:43:30306 writer->AppendVariantOfByte(set_value_);
[email protected]cf910da22012-02-15 04:21:08307}
308
309//
310// Property<bool> specialization.
311//
312
313template <>
[email protected]091e0b62012-06-28 18:43:30314Property<bool>::Property() : value_(false) {
[email protected]cf910da22012-02-15 04:21:08315}
316
317template <>
318bool Property<bool>::PopValueFromReader(MessageReader* reader) {
319 return reader->PopVariantOfBool(&value_);
320}
321
322template <>
[email protected]091e0b62012-06-28 18:43:30323void Property<bool>::AppendSetValueToWriter(MessageWriter* writer) {
324 writer->AppendVariantOfBool(set_value_);
[email protected]cf910da22012-02-15 04:21:08325}
326
327//
avi22437c692015-12-22 18:12:45328// Property<int16_t> specialization.
[email protected]cf910da22012-02-15 04:21:08329//
330
331template <>
avi22437c692015-12-22 18:12:45332Property<int16_t>::Property()
333 : value_(0) {}
[email protected]cf910da22012-02-15 04:21:08334
335template <>
avi22437c692015-12-22 18:12:45336bool Property<int16_t>::PopValueFromReader(MessageReader* reader) {
[email protected]cf910da22012-02-15 04:21:08337 return reader->PopVariantOfInt16(&value_);
338}
339
340template <>
avi22437c692015-12-22 18:12:45341void Property<int16_t>::AppendSetValueToWriter(MessageWriter* writer) {
[email protected]091e0b62012-06-28 18:43:30342 writer->AppendVariantOfInt16(set_value_);
[email protected]cf910da22012-02-15 04:21:08343}
344
345//
avi22437c692015-12-22 18:12:45346// Property<uint16_t> specialization.
[email protected]cf910da22012-02-15 04:21:08347//
348
349template <>
avi22437c692015-12-22 18:12:45350Property<uint16_t>::Property()
351 : value_(0) {}
[email protected]cf910da22012-02-15 04:21:08352
353template <>
avi22437c692015-12-22 18:12:45354bool Property<uint16_t>::PopValueFromReader(MessageReader* reader) {
[email protected]cf910da22012-02-15 04:21:08355 return reader->PopVariantOfUint16(&value_);
356}
357
358template <>
avi22437c692015-12-22 18:12:45359void Property<uint16_t>::AppendSetValueToWriter(MessageWriter* writer) {
[email protected]091e0b62012-06-28 18:43:30360 writer->AppendVariantOfUint16(set_value_);
[email protected]cf910da22012-02-15 04:21:08361}
362
363//
avi22437c692015-12-22 18:12:45364// Property<int32_t> specialization.
[email protected]cf910da22012-02-15 04:21:08365//
366
367template <>
avi22437c692015-12-22 18:12:45368Property<int32_t>::Property()
369 : value_(0) {}
[email protected]cf910da22012-02-15 04:21:08370
371template <>
avi22437c692015-12-22 18:12:45372bool Property<int32_t>::PopValueFromReader(MessageReader* reader) {
[email protected]cf910da22012-02-15 04:21:08373 return reader->PopVariantOfInt32(&value_);
374}
375
376template <>
avi22437c692015-12-22 18:12:45377void Property<int32_t>::AppendSetValueToWriter(MessageWriter* writer) {
[email protected]091e0b62012-06-28 18:43:30378 writer->AppendVariantOfInt32(set_value_);
[email protected]cf910da22012-02-15 04:21:08379}
380
381//
avi22437c692015-12-22 18:12:45382// Property<uint32_t> specialization.
[email protected]cf910da22012-02-15 04:21:08383//
384
385template <>
avi22437c692015-12-22 18:12:45386Property<uint32_t>::Property()
387 : value_(0) {}
[email protected]cf910da22012-02-15 04:21:08388
389template <>
avi22437c692015-12-22 18:12:45390bool Property<uint32_t>::PopValueFromReader(MessageReader* reader) {
[email protected]cf910da22012-02-15 04:21:08391 return reader->PopVariantOfUint32(&value_);
392}
393
394template <>
avi22437c692015-12-22 18:12:45395void Property<uint32_t>::AppendSetValueToWriter(MessageWriter* writer) {
[email protected]091e0b62012-06-28 18:43:30396 writer->AppendVariantOfUint32(set_value_);
[email protected]cf910da22012-02-15 04:21:08397}
398
399//
avi22437c692015-12-22 18:12:45400// Property<int64_t> specialization.
[email protected]cf910da22012-02-15 04:21:08401//
402
403template <>
avi22437c692015-12-22 18:12:45404Property<int64_t>::Property()
405 : value_(0), set_value_(0) {}
[email protected]cf910da22012-02-15 04:21:08406
407template <>
avi22437c692015-12-22 18:12:45408bool Property<int64_t>::PopValueFromReader(MessageReader* reader) {
[email protected]cf910da22012-02-15 04:21:08409 return reader->PopVariantOfInt64(&value_);
410}
411
412template <>
avi22437c692015-12-22 18:12:45413void Property<int64_t>::AppendSetValueToWriter(MessageWriter* writer) {
[email protected]091e0b62012-06-28 18:43:30414 writer->AppendVariantOfInt64(set_value_);
[email protected]cf910da22012-02-15 04:21:08415}
416
417//
avi22437c692015-12-22 18:12:45418// Property<uint64_t> specialization.
[email protected]cf910da22012-02-15 04:21:08419//
420
421template <>
avi22437c692015-12-22 18:12:45422Property<uint64_t>::Property()
423 : value_(0) {}
[email protected]cf910da22012-02-15 04:21:08424
425template <>
avi22437c692015-12-22 18:12:45426bool Property<uint64_t>::PopValueFromReader(MessageReader* reader) {
[email protected]cf910da22012-02-15 04:21:08427 return reader->PopVariantOfUint64(&value_);
428}
429
430template <>
avi22437c692015-12-22 18:12:45431void Property<uint64_t>::AppendSetValueToWriter(MessageWriter* writer) {
[email protected]091e0b62012-06-28 18:43:30432 writer->AppendVariantOfUint64(set_value_);
[email protected]cf910da22012-02-15 04:21:08433}
434
435//
436// Property<double> specialization.
437//
438
439template <>
[email protected]091e0b62012-06-28 18:43:30440Property<double>::Property() : value_(0.0) {
[email protected]cf910da22012-02-15 04:21:08441}
442
443template <>
444bool Property<double>::PopValueFromReader(MessageReader* reader) {
445 return reader->PopVariantOfDouble(&value_);
446}
447
448template <>
[email protected]091e0b62012-06-28 18:43:30449void Property<double>::AppendSetValueToWriter(MessageWriter* writer) {
450 writer->AppendVariantOfDouble(set_value_);
[email protected]cf910da22012-02-15 04:21:08451}
452
453//
454// Property<std::string> specialization.
455//
456
457template <>
458bool Property<std::string>::PopValueFromReader(MessageReader* reader) {
459 return reader->PopVariantOfString(&value_);
460}
461
462template <>
[email protected]091e0b62012-06-28 18:43:30463void Property<std::string>::AppendSetValueToWriter(MessageWriter* writer) {
464 writer->AppendVariantOfString(set_value_);
[email protected]cf910da22012-02-15 04:21:08465}
466
467//
468// Property<ObjectPath> specialization.
469//
470
471template <>
472bool Property<ObjectPath>::PopValueFromReader(MessageReader* reader) {
473 return reader->PopVariantOfObjectPath(&value_);
474}
475
476template <>
[email protected]091e0b62012-06-28 18:43:30477void Property<ObjectPath>::AppendSetValueToWriter(MessageWriter* writer) {
478 writer->AppendVariantOfObjectPath(set_value_);
[email protected]cf910da22012-02-15 04:21:08479}
480
481//
Ben Chanc7c9c762017-11-08 01:50:21482// Property<std::vector<std::string>> specialization.
[email protected]cf910da22012-02-15 04:21:08483//
484
485template <>
Ben Chanc7c9c762017-11-08 01:50:21486bool Property<std::vector<std::string>>::PopValueFromReader(
[email protected]cf910da22012-02-15 04:21:08487 MessageReader* reader) {
Ben Chan14d500372017-11-09 20:20:16488 MessageReader variant_reader(nullptr);
[email protected]cf910da22012-02-15 04:21:08489 if (!reader->PopVariant(&variant_reader))
490 return false;
491
[email protected]72bbacc2012-03-21 23:43:45492 value_.clear();
[email protected]cf910da22012-02-15 04:21:08493 return variant_reader.PopArrayOfStrings(&value_);
494}
495
496template <>
Ben Chanc7c9c762017-11-08 01:50:21497void Property<std::vector<std::string>>::AppendSetValueToWriter(
[email protected]091e0b62012-06-28 18:43:30498 MessageWriter* writer) {
Ben Chan14d500372017-11-09 20:20:16499 MessageWriter variant_writer(nullptr);
[email protected]cf910da22012-02-15 04:21:08500 writer->OpenVariant("as", &variant_writer);
[email protected]091e0b62012-06-28 18:43:30501 variant_writer.AppendArrayOfStrings(set_value_);
[email protected]cf910da22012-02-15 04:21:08502 writer->CloseContainer(&variant_writer);
503}
504
505//
Ben Chanc7c9c762017-11-08 01:50:21506// Property<std::vector<ObjectPath>> specialization.
[email protected]cf910da22012-02-15 04:21:08507//
508
509template <>
Ben Chanc7c9c762017-11-08 01:50:21510bool Property<std::vector<ObjectPath>>::PopValueFromReader(
[email protected]cf910da22012-02-15 04:21:08511 MessageReader* reader) {
Ben Chan14d500372017-11-09 20:20:16512 MessageReader variant_reader(nullptr);
[email protected]cf910da22012-02-15 04:21:08513 if (!reader->PopVariant(&variant_reader))
514 return false;
515
[email protected]72bbacc2012-03-21 23:43:45516 value_.clear();
[email protected]cf910da22012-02-15 04:21:08517 return variant_reader.PopArrayOfObjectPaths(&value_);
518}
519
520template <>
Ben Chanc7c9c762017-11-08 01:50:21521void Property<std::vector<ObjectPath>>::AppendSetValueToWriter(
[email protected]091e0b62012-06-28 18:43:30522 MessageWriter* writer) {
Ben Chan14d500372017-11-09 20:20:16523 MessageWriter variant_writer(nullptr);
[email protected]cf910da22012-02-15 04:21:08524 writer->OpenVariant("ao", &variant_writer);
[email protected]091e0b62012-06-28 18:43:30525 variant_writer.AppendArrayOfObjectPaths(set_value_);
[email protected]cf910da22012-02-15 04:21:08526 writer->CloseContainer(&variant_writer);
527}
528
[email protected]ebbfffa22014-03-15 07:40:49529//
Ben Chanc7c9c762017-11-08 01:50:21530// Property<std::vector<uint8_t>> specialization.
[email protected]ebbfffa22014-03-15 07:40:49531//
532
533template <>
avi22437c692015-12-22 18:12:45534bool Property<std::vector<uint8_t>>::PopValueFromReader(MessageReader* reader) {
Ben Chan14d500372017-11-09 20:20:16535 MessageReader variant_reader(nullptr);
[email protected]ebbfffa22014-03-15 07:40:49536 if (!reader->PopVariant(&variant_reader))
537 return false;
538
539 value_.clear();
Ben Chan14d500372017-11-09 20:20:16540 const uint8_t* bytes = nullptr;
[email protected]ebbfffa22014-03-15 07:40:49541 size_t length = 0;
542 if (!variant_reader.PopArrayOfBytes(&bytes, &length))
543 return false;
544 value_.assign(bytes, bytes + length);
545 return true;
546}
547
548template <>
avi22437c692015-12-22 18:12:45549void Property<std::vector<uint8_t>>::AppendSetValueToWriter(
[email protected]ebbfffa22014-03-15 07:40:49550 MessageWriter* writer) {
Ben Chan14d500372017-11-09 20:20:16551 MessageWriter variant_writer(nullptr);
[email protected]ebbfffa22014-03-15 07:40:49552 writer->OpenVariant("ay", &variant_writer);
553 variant_writer.AppendArrayOfBytes(set_value_.data(), set_value_.size());
554 writer->CloseContainer(&variant_writer);
555}
556
dtapuska32d25452015-02-09 16:02:55557//
558// Property<std::map<std::string, std::string>> specialization.
559//
560
561template <>
562bool Property<std::map<std::string, std::string>>::PopValueFromReader(
563 MessageReader* reader) {
Ben Chan14d500372017-11-09 20:20:16564 MessageReader variant_reader(nullptr);
565 MessageReader array_reader(nullptr);
dtapuska32d25452015-02-09 16:02:55566 if (!reader->PopVariant(&variant_reader) ||
567 !variant_reader.PopArray(&array_reader))
568 return false;
569 value_.clear();
570 while (array_reader.HasMoreData()) {
Ben Chan14d500372017-11-09 20:20:16571 dbus::MessageReader dict_entry_reader(nullptr);
dtapuska32d25452015-02-09 16:02:55572 if (!array_reader.PopDictEntry(&dict_entry_reader))
573 return false;
574 std::string key;
575 std::string value;
576 if (!dict_entry_reader.PopString(&key) ||
577 !dict_entry_reader.PopString(&value))
578 return false;
579 value_[key] = value;
580 }
581 return true;
582}
583
584template <>
585void Property<std::map<std::string, std::string>>::AppendSetValueToWriter(
586 MessageWriter* writer) {
Ben Chan14d500372017-11-09 20:20:16587 MessageWriter variant_writer(nullptr);
588 MessageWriter dict_writer(nullptr);
dtapuska32d25452015-02-09 16:02:55589 writer->OpenVariant("a{ss}", &variant_writer);
590 variant_writer.OpenArray("{ss}", &dict_writer);
591 for (const auto& pair : set_value_) {
Ben Chan14d500372017-11-09 20:20:16592 dbus::MessageWriter entry_writer(nullptr);
dtapuska32d25452015-02-09 16:02:55593 dict_writer.OpenDictEntry(&entry_writer);
594 entry_writer.AppendString(pair.first);
595 entry_writer.AppendString(pair.second);
596 dict_writer.CloseContainer(&entry_writer);
597 }
598 variant_writer.CloseContainer(&dict_writer);
599 writer->CloseContainer(&variant_writer);
600}
601
602//
603// Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>
604// specialization.
605//
606
607template <>
608bool Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
609 PopValueFromReader(MessageReader* reader) {
Ben Chan14d500372017-11-09 20:20:16610 MessageReader variant_reader(nullptr);
611 MessageReader array_reader(nullptr);
dtapuska32d25452015-02-09 16:02:55612 if (!reader->PopVariant(&variant_reader) ||
613 !variant_reader.PopArray(&array_reader))
614 return false;
615
616 value_.clear();
617 while (array_reader.HasMoreData()) {
Ben Chan14d500372017-11-09 20:20:16618 dbus::MessageReader struct_reader(nullptr);
dtapuska32d25452015-02-09 16:02:55619 if (!array_reader.PopStruct(&struct_reader))
620 return false;
621
622 std::pair<std::vector<uint8_t>, uint16_t> entry;
Ben Chan14d500372017-11-09 20:20:16623 const uint8_t* bytes = nullptr;
dtapuska32d25452015-02-09 16:02:55624 size_t length = 0;
625 if (!struct_reader.PopArrayOfBytes(&bytes, &length))
626 return false;
627 entry.first.assign(bytes, bytes + length);
628 if (!struct_reader.PopUint16(&entry.second))
629 return false;
630 value_.push_back(entry);
631 }
632 return true;
633}
634
635template <>
636void Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
637 AppendSetValueToWriter(MessageWriter* writer) {
Ben Chan14d500372017-11-09 20:20:16638 MessageWriter variant_writer(nullptr);
639 MessageWriter array_writer(nullptr);
dtapuska32d25452015-02-09 16:02:55640 writer->OpenVariant("a(ayq)", &variant_writer);
641 variant_writer.OpenArray("(ayq)", &array_writer);
642 for (const auto& pair : set_value_) {
643 dbus::MessageWriter struct_writer(nullptr);
644 array_writer.OpenStruct(&struct_writer);
645 struct_writer.AppendArrayOfBytes(std::get<0>(pair).data(),
646 std::get<0>(pair).size());
647 struct_writer.AppendUint16(std::get<1>(pair));
648 array_writer.CloseContainer(&struct_writer);
649 }
650 variant_writer.CloseContainer(&array_writer);
651 writer->CloseContainer(&variant_writer);
652}
653
puthik0dd82b12016-10-06 05:03:03654//
Sonny Sasakabd3098c62018-03-13 00:59:50655// Property<std::map<std::string, std::vector<uint8_t>>>
puthik0dd82b12016-10-06 05:03:03656// specialization.
657//
658
659template <>
Sonny Sasakabd3098c62018-03-13 00:59:50660bool Property<std::map<std::string, std::vector<uint8_t>>>::PopValueFromReader(
661 MessageReader* reader) {
puthik0dd82b12016-10-06 05:03:03662 MessageReader variant_reader(nullptr);
663 MessageReader dict_reader(nullptr);
664 if (!reader->PopVariant(&variant_reader) ||
665 !variant_reader.PopArray(&dict_reader))
666 return false;
667
668 value_.clear();
669 while (dict_reader.HasMoreData()) {
670 MessageReader entry_reader(nullptr);
671 if (!dict_reader.PopDictEntry(&entry_reader))
672 return false;
673
674 std::string key;
Sonny Sasaka737ad09f2019-02-22 19:58:21675 if (!entry_reader.PopString(&key))
puthik0dd82b12016-10-06 05:03:03676 return false;
677
678 const uint8_t* bytes = nullptr;
679 size_t length = 0;
Sonny Sasaka737ad09f2019-02-22 19:58:21680
681 if (entry_reader.GetDataType() == Message::VARIANT) {
682 // Make BlueZ happy since it wraps the array of bytes with a variant.
683 MessageReader value_variant_reader(nullptr);
684 if (!entry_reader.PopVariant(&value_variant_reader))
685 return false;
686 if (!value_variant_reader.PopArrayOfBytes(&bytes, &length))
687 return false;
688 } else {
689 if (!entry_reader.PopArrayOfBytes(&bytes, &length))
690 return false;
691 }
puthik0dd82b12016-10-06 05:03:03692
693 value_[key].assign(bytes, bytes + length);
694 }
695 return true;
696}
697
698template <>
Sonny Sasakabd3098c62018-03-13 00:59:50699void Property<std::map<std::string, std::vector<uint8_t>>>::
puthik0dd82b12016-10-06 05:03:03700 AppendSetValueToWriter(MessageWriter* writer) {
701 MessageWriter variant_writer(nullptr);
702 MessageWriter dict_writer(nullptr);
703
704 writer->OpenVariant("a{sv}", &variant_writer);
705 variant_writer.OpenArray("{sv}", &dict_writer);
706
707 for (const auto& pair : set_value_) {
708 MessageWriter entry_writer(nullptr);
709 dict_writer.OpenDictEntry(&entry_writer);
710
711 entry_writer.AppendString(pair.first);
712
713 MessageWriter value_varient_writer(nullptr);
714 entry_writer.OpenVariant("ay", &value_varient_writer);
715 value_varient_writer.AppendArrayOfBytes(pair.second.data(),
716 pair.second.size());
717 entry_writer.CloseContainer(&value_varient_writer);
718
719 dict_writer.CloseContainer(&entry_writer);
720 }
721
722 variant_writer.CloseContainer(&dict_writer);
723 writer->CloseContainer(&variant_writer);
724}
725
puthik23399e452016-11-04 19:38:17726//
Sonny Sasakabd3098c62018-03-13 00:59:50727// Property<std::map<uint16_t, std::vector<uint8_t>>>
puthik23399e452016-11-04 19:38:17728// specialization.
729//
730
731template <>
Sonny Sasakabd3098c62018-03-13 00:59:50732bool Property<std::map<uint16_t, std::vector<uint8_t>>>::PopValueFromReader(
733 MessageReader* reader) {
puthik23399e452016-11-04 19:38:17734 MessageReader variant_reader(nullptr);
735 MessageReader dict_reader(nullptr);
736 if (!reader->PopVariant(&variant_reader) ||
737 !variant_reader.PopArray(&dict_reader))
738 return false;
739
740 value_.clear();
741 while (dict_reader.HasMoreData()) {
742 MessageReader entry_reader(nullptr);
743 if (!dict_reader.PopDictEntry(&entry_reader))
744 return false;
745
746 uint16_t key;
Sonny Sasaka737ad09f2019-02-22 19:58:21747 if (!entry_reader.PopUint16(&key))
puthik23399e452016-11-04 19:38:17748 return false;
749
750 const uint8_t* bytes = nullptr;
751 size_t length = 0;
Sonny Sasaka737ad09f2019-02-22 19:58:21752
753 if (entry_reader.GetDataType() == Message::VARIANT) {
754 // Make BlueZ happy since it wraps the array of bytes with a variant.
755 MessageReader value_variant_reader(nullptr);
756 if (!entry_reader.PopVariant(&value_variant_reader))
757 return false;
758 if (!value_variant_reader.PopArrayOfBytes(&bytes, &length))
759 return false;
760 } else {
761 if (!entry_reader.PopArrayOfBytes(&bytes, &length))
762 return false;
763 }
puthik23399e452016-11-04 19:38:17764
765 value_[key].assign(bytes, bytes + length);
766 }
767 return true;
768}
769
770template <>
Sonny Sasakabd3098c62018-03-13 00:59:50771void Property<std::map<uint16_t, std::vector<uint8_t>>>::AppendSetValueToWriter(
772 MessageWriter* writer) {
puthik23399e452016-11-04 19:38:17773 MessageWriter variant_writer(nullptr);
774 MessageWriter dict_writer(nullptr);
775
776 writer->OpenVariant("a{qv}", &variant_writer);
777 variant_writer.OpenArray("{qv}", &dict_writer);
778
779 for (const auto& pair : set_value_) {
780 MessageWriter entry_writer(nullptr);
781 dict_writer.OpenDictEntry(&entry_writer);
782
783 entry_writer.AppendUint16(pair.first);
784
785 MessageWriter value_varient_writer(nullptr);
786 entry_writer.OpenVariant("ay", &value_varient_writer);
787 value_varient_writer.AppendArrayOfBytes(pair.second.data(),
788 pair.second.size());
789 entry_writer.CloseContainer(&value_varient_writer);
790
791 dict_writer.CloseContainer(&entry_writer);
792 }
793
794 variant_writer.CloseContainer(&dict_writer);
795 writer->CloseContainer(&variant_writer);
796}
797
avi22437c692015-12-22 18:12:45798template class Property<uint8_t>;
[email protected]2934be42014-07-25 04:04:27799template class Property<bool>;
avi22437c692015-12-22 18:12:45800template class Property<int16_t>;
801template class Property<uint16_t>;
802template class Property<int32_t>;
803template class Property<uint32_t>;
804template class Property<int64_t>;
805template class Property<uint64_t>;
[email protected]2934be42014-07-25 04:04:27806template class Property<double>;
807template class Property<std::string>;
808template class Property<ObjectPath>;
Ben Chanc7c9c762017-11-08 01:50:21809template class Property<std::vector<std::string>>;
810template class Property<std::vector<ObjectPath>>;
avi22437c692015-12-22 18:12:45811template class Property<std::vector<uint8_t>>;
dtapuska32d25452015-02-09 16:02:55812template class Property<std::map<std::string, std::string>>;
813template class Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>;
Sonny Sasakabd3098c62018-03-13 00:59:50814template class Property<std::map<std::string, std::vector<uint8_t>>>;
815template class Property<std::map<uint16_t, std::vector<uint8_t>>>;
[email protected]2934be42014-07-25 04:04:27816
[email protected]cf910da22012-02-15 04:21:08817} // namespace dbus