blob: 234036c35db11ddd645a24c920e0a49afb8257c7 [file] [log] [blame]
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +09001// 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
7#include "base/basictypes.h"
8#include "base/bind.h"
9#include "base/logging.h"
10
11#include "dbus/message.h"
12#include "dbus/object_path.h"
13#include "dbus/object_proxy.h"
14
15namespace dbus {
16
17//
18// PropertyBase implementation.
19//
20
derat3f868a42015-07-17 00:06:44 +090021PropertyBase::PropertyBase() : property_set_(nullptr), is_valid_(false) {}
22
23PropertyBase::~PropertyBase() {}
24
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090025void PropertyBase::Init(PropertySet* property_set, const std::string& name) {
26 DCHECK(!property_set_);
27 property_set_ = property_set;
jpawlowski77e73fc2015-05-11 20:07:04 +090028 is_valid_ = false;
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090029 name_ = name;
30}
31
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090032//
33// PropertySet implementation.
34//
35
keybuk@chromium.orgb45e5292012-08-15 10:03:30 +090036PropertySet::PropertySet(
37 ObjectProxy* object_proxy,
38 const std::string& interface,
39 const PropertyChangedCallback& property_changed_callback)
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090040 : object_proxy_(object_proxy),
41 interface_(interface),
42 property_changed_callback_(property_changed_callback),
43 weak_ptr_factory_(this) {}
44
45PropertySet::~PropertySet() {
46}
47
48void PropertySet::RegisterProperty(const std::string& name,
49 PropertyBase* property) {
50 property->Init(this, name);
51 properties_map_[name] = property;
52}
53
54void PropertySet::ConnectSignals() {
55 DCHECK(object_proxy_);
56 object_proxy_->ConnectToSignal(
57 kPropertiesInterface,
58 kPropertiesChanged,
59 base::Bind(&PropertySet::ChangedReceived,
60 weak_ptr_factory_.GetWeakPtr()),
61 base::Bind(&PropertySet::ChangedConnected,
62 weak_ptr_factory_.GetWeakPtr()));
63}
64
65
66void PropertySet::ChangedReceived(Signal* signal) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090067 DCHECK(signal);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090068 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
jpawlowski77e73fc2015-05-11 20:07:04 +090085 if (!InvalidatePropertiesFromReader(&reader)) {
86 LOG(WARNING) << "Property changed signal has wrong parameters: "
87 << "expected array to invalidate: " << signal->ToString();
88 }
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090089}
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
keybuk@chromium.org56028ac2012-06-29 03:43:30 +090099void 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_);
106 object_proxy_->CallMethod(&method_call,
107 ObjectProxy::TIMEOUT_USE_DEFAULT,
108 base::Bind(&PropertySet::OnGet,
109 GetWeakPtr(),
110 property,
111 callback));
112}
113
114void PropertySet::OnGet(PropertyBase* property, GetCallback callback,
115 Response* response) {
116 if (!response) {
117 LOG(WARNING) << property->name() << ": Get: failed.";
118 return;
119 }
120
121 MessageReader reader(response);
jpawlowski77e73fc2015-05-11 20:07:04 +0900122 if (property->PopValueFromReader(&reader)) {
123 property->set_valid(true);
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900124 NotifyPropertyChanged(property->name());
jpawlowski77e73fc2015-05-11 20:07:04 +0900125 } else {
126 if (property->is_valid()) {
127 property->set_valid(false);
128 NotifyPropertyChanged(property->name());
129 }
130 }
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900131
132 if (!callback.is_null())
133 callback.Run(response);
134}
135
nywang80f27162015-09-29 07:46:36 +0900136bool PropertySet::GetAndBlock(PropertyBase* property) {
137 MethodCall method_call(kPropertiesInterface, kPropertiesGet);
138 MessageWriter writer(&method_call);
139 writer.AppendString(interface());
140 writer.AppendString(property->name());
141
142 DCHECK(object_proxy_);
143 scoped_ptr<dbus::Response> response(
144 object_proxy_->CallMethodAndBlock(&method_call,
145 ObjectProxy::TIMEOUT_USE_DEFAULT));
146
147 if (!response.get()) {
148 LOG(WARNING) << property->name() << ": GetAndBlock: failed.";
149 return false;
150 }
151
152 MessageReader reader(response.get());
153 if (property->PopValueFromReader(&reader)) {
154 property->set_valid(true);
155 NotifyPropertyChanged(property->name());
156 } else {
157 if (property->is_valid()) {
158 property->set_valid(false);
159 NotifyPropertyChanged(property->name());
160 }
161 }
162 return true;
163}
164
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900165void PropertySet::GetAll() {
166 MethodCall method_call(kPropertiesInterface, kPropertiesGetAll);
167 MessageWriter writer(&method_call);
168 writer.AppendString(interface());
169
170 DCHECK(object_proxy_);
171 object_proxy_->CallMethod(&method_call,
172 ObjectProxy::TIMEOUT_USE_DEFAULT,
173 base::Bind(&PropertySet::OnGetAll,
174 weak_ptr_factory_.GetWeakPtr()));
175}
176
177void PropertySet::OnGetAll(Response* response) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900178 if (!response) {
stevenjb@chromium.orgfa639cc2014-07-17 14:03:53 +0900179 LOG(WARNING) << "GetAll request failed for: " << interface_;
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900180 return;
181 }
182
183 MessageReader reader(response);
184 if (!UpdatePropertiesFromReader(&reader)) {
185 LOG(WARNING) << "GetAll response has wrong parameters: "
186 << "expected dictionary: " << response->ToString();
187 }
188}
189
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900190void PropertySet::Set(PropertyBase* property, SetCallback callback) {
191 MethodCall method_call(kPropertiesInterface, kPropertiesSet);
192 MessageWriter writer(&method_call);
193 writer.AppendString(interface());
194 writer.AppendString(property->name());
195 property->AppendSetValueToWriter(&writer);
196
197 DCHECK(object_proxy_);
198 object_proxy_->CallMethod(&method_call,
199 ObjectProxy::TIMEOUT_USE_DEFAULT,
200 base::Bind(&PropertySet::OnSet,
201 GetWeakPtr(),
202 property,
203 callback));
204}
205
nywangf1196812015-09-23 09:06:40 +0900206bool PropertySet::SetAndBlock(PropertyBase* property) {
207 MethodCall method_call(kPropertiesInterface, kPropertiesSet);
208 MessageWriter writer(&method_call);
209 writer.AppendString(interface());
210 writer.AppendString(property->name());
211 property->AppendSetValueToWriter(&writer);
212
213 DCHECK(object_proxy_);
214 scoped_ptr<dbus::Response> response(
215 object_proxy_->CallMethodAndBlock(&method_call,
nywang80f27162015-09-29 07:46:36 +0900216 ObjectProxy::TIMEOUT_USE_DEFAULT));
nywangf1196812015-09-23 09:06:40 +0900217 if (response.get())
218 return true;
219 return false;
220}
221
stevenjb@chromium.orgfa639cc2014-07-17 14:03:53 +0900222void PropertySet::OnSet(PropertyBase* property,
223 SetCallback callback,
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900224 Response* response) {
225 LOG_IF(WARNING, !response) << property->name() << ": Set: failed.";
226 if (!callback.is_null())
227 callback.Run(response);
228}
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900229
230bool PropertySet::UpdatePropertiesFromReader(MessageReader* reader) {
231 DCHECK(reader);
232 MessageReader array_reader(NULL);
233 if (!reader->PopArray(&array_reader))
234 return false;
235
236 while (array_reader.HasMoreData()) {
237 MessageReader dict_entry_reader(NULL);
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900238 if (array_reader.PopDictEntry(&dict_entry_reader))
239 UpdatePropertyFromReader(&dict_entry_reader);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900240 }
241
242 return true;
243}
244
245bool PropertySet::UpdatePropertyFromReader(MessageReader* reader) {
246 DCHECK(reader);
247
248 std::string name;
249 if (!reader->PopString(&name))
250 return false;
251
252 PropertiesMap::iterator it = properties_map_.find(name);
253 if (it == properties_map_.end())
254 return false;
255
256 PropertyBase* property = it->second;
257 if (property->PopValueFromReader(reader)) {
jpawlowski77e73fc2015-05-11 20:07:04 +0900258 property->set_valid(true);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900259 NotifyPropertyChanged(name);
260 return true;
261 } else {
jpawlowski77e73fc2015-05-11 20:07:04 +0900262 if (property->is_valid()) {
263 property->set_valid(false);
264 NotifyPropertyChanged(property->name());
265 }
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900266 return false;
267 }
268}
269
jpawlowski77e73fc2015-05-11 20:07:04 +0900270bool PropertySet::InvalidatePropertiesFromReader(MessageReader* reader) {
271 DCHECK(reader);
272 MessageReader array_reader(NULL);
273 if (!reader->PopArray(&array_reader))
274 return false;
275
276 while (array_reader.HasMoreData()) {
277 std::string name;
278 if (!array_reader.PopString(&name))
279 return false;
280
281 PropertiesMap::iterator it = properties_map_.find(name);
282 if (it == properties_map_.end())
283 continue;
284
285 PropertyBase* property = it->second;
286 if (property->is_valid()) {
287 property->set_valid(false);
288 NotifyPropertyChanged(property->name());
289 }
290 }
291
292 return true;
293}
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900294
295void PropertySet::NotifyPropertyChanged(const std::string& name) {
296 if (!property_changed_callback_.is_null())
297 property_changed_callback_.Run(name);
298}
299
300//
301// Property<Byte> specialization.
302//
303
304template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900305Property<uint8>::Property() : value_(0) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900306}
307
308template <>
309bool Property<uint8>::PopValueFromReader(MessageReader* reader) {
310 return reader->PopVariantOfByte(&value_);
311}
312
313template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900314void Property<uint8>::AppendSetValueToWriter(MessageWriter* writer) {
315 writer->AppendVariantOfByte(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900316}
317
318//
319// Property<bool> specialization.
320//
321
322template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900323Property<bool>::Property() : value_(false) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900324}
325
326template <>
327bool Property<bool>::PopValueFromReader(MessageReader* reader) {
328 return reader->PopVariantOfBool(&value_);
329}
330
331template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900332void Property<bool>::AppendSetValueToWriter(MessageWriter* writer) {
333 writer->AppendVariantOfBool(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900334}
335
336//
337// Property<int16> specialization.
338//
339
340template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900341Property<int16>::Property() : value_(0) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900342}
343
344template <>
345bool Property<int16>::PopValueFromReader(MessageReader* reader) {
346 return reader->PopVariantOfInt16(&value_);
347}
348
349template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900350void Property<int16>::AppendSetValueToWriter(MessageWriter* writer) {
351 writer->AppendVariantOfInt16(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900352}
353
354//
355// Property<uint16> specialization.
356//
357
358template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900359Property<uint16>::Property() : value_(0) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900360}
361
362template <>
363bool Property<uint16>::PopValueFromReader(MessageReader* reader) {
364 return reader->PopVariantOfUint16(&value_);
365}
366
367template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900368void Property<uint16>::AppendSetValueToWriter(MessageWriter* writer) {
369 writer->AppendVariantOfUint16(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900370}
371
372//
373// Property<int32> specialization.
374//
375
376template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900377Property<int32>::Property() : value_(0) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900378}
379
380template <>
381bool Property<int32>::PopValueFromReader(MessageReader* reader) {
382 return reader->PopVariantOfInt32(&value_);
383}
384
385template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900386void Property<int32>::AppendSetValueToWriter(MessageWriter* writer) {
387 writer->AppendVariantOfInt32(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900388}
389
390//
391// Property<uint32> specialization.
392//
393
394template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900395Property<uint32>::Property() : value_(0) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900396}
397
398template <>
399bool Property<uint32>::PopValueFromReader(MessageReader* reader) {
400 return reader->PopVariantOfUint32(&value_);
401}
402
403template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900404void Property<uint32>::AppendSetValueToWriter(MessageWriter* writer) {
405 writer->AppendVariantOfUint32(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900406}
407
408//
409// Property<int64> specialization.
410//
411
412template <>
jhawkins@chromium.org9ef14692012-07-26 07:08:27 +0900413Property<int64>::Property() : value_(0), set_value_(0) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900414}
415
416template <>
417bool Property<int64>::PopValueFromReader(MessageReader* reader) {
418 return reader->PopVariantOfInt64(&value_);
419}
420
421template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900422void Property<int64>::AppendSetValueToWriter(MessageWriter* writer) {
423 writer->AppendVariantOfInt64(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900424}
425
426//
427// Property<uint64> specialization.
428//
429
430template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900431Property<uint64>::Property() : value_(0) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900432}
433
434template <>
435bool Property<uint64>::PopValueFromReader(MessageReader* reader) {
436 return reader->PopVariantOfUint64(&value_);
437}
438
439template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900440void Property<uint64>::AppendSetValueToWriter(MessageWriter* writer) {
441 writer->AppendVariantOfUint64(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900442}
443
444//
445// Property<double> specialization.
446//
447
448template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900449Property<double>::Property() : value_(0.0) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900450}
451
452template <>
453bool Property<double>::PopValueFromReader(MessageReader* reader) {
454 return reader->PopVariantOfDouble(&value_);
455}
456
457template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900458void Property<double>::AppendSetValueToWriter(MessageWriter* writer) {
459 writer->AppendVariantOfDouble(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900460}
461
462//
463// Property<std::string> specialization.
464//
465
466template <>
467bool Property<std::string>::PopValueFromReader(MessageReader* reader) {
468 return reader->PopVariantOfString(&value_);
469}
470
471template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900472void Property<std::string>::AppendSetValueToWriter(MessageWriter* writer) {
473 writer->AppendVariantOfString(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900474}
475
476//
477// Property<ObjectPath> specialization.
478//
479
480template <>
481bool Property<ObjectPath>::PopValueFromReader(MessageReader* reader) {
482 return reader->PopVariantOfObjectPath(&value_);
483}
484
485template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900486void Property<ObjectPath>::AppendSetValueToWriter(MessageWriter* writer) {
487 writer->AppendVariantOfObjectPath(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900488}
489
490//
491// Property<std::vector<std::string> > specialization.
492//
493
494template <>
495bool Property<std::vector<std::string> >::PopValueFromReader(
496 MessageReader* reader) {
497 MessageReader variant_reader(NULL);
498 if (!reader->PopVariant(&variant_reader))
499 return false;
500
keybuk@google.comf056b962012-03-22 08:43:45 +0900501 value_.clear();
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900502 return variant_reader.PopArrayOfStrings(&value_);
503}
504
505template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900506void Property<std::vector<std::string> >::AppendSetValueToWriter(
507 MessageWriter* writer) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900508 MessageWriter variant_writer(NULL);
509 writer->OpenVariant("as", &variant_writer);
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900510 variant_writer.AppendArrayOfStrings(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900511 writer->CloseContainer(&variant_writer);
512}
513
514//
515// Property<std::vector<ObjectPath> > specialization.
516//
517
518template <>
519bool Property<std::vector<ObjectPath> >::PopValueFromReader(
520 MessageReader* reader) {
521 MessageReader variant_reader(NULL);
522 if (!reader->PopVariant(&variant_reader))
523 return false;
524
keybuk@google.comf056b962012-03-22 08:43:45 +0900525 value_.clear();
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900526 return variant_reader.PopArrayOfObjectPaths(&value_);
527}
528
529template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900530void Property<std::vector<ObjectPath> >::AppendSetValueToWriter(
531 MessageWriter* writer) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900532 MessageWriter variant_writer(NULL);
533 writer->OpenVariant("ao", &variant_writer);
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900534 variant_writer.AppendArrayOfObjectPaths(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900535 writer->CloseContainer(&variant_writer);
536}
537
armansito@chromium.org11e12742014-03-15 16:40:49 +0900538//
539// Property<std::vector<uint8> > specialization.
540//
541
542template <>
543bool Property<std::vector<uint8> >::PopValueFromReader(MessageReader* reader) {
544 MessageReader variant_reader(NULL);
545 if (!reader->PopVariant(&variant_reader))
546 return false;
547
548 value_.clear();
549 const uint8* bytes = NULL;
550 size_t length = 0;
551 if (!variant_reader.PopArrayOfBytes(&bytes, &length))
552 return false;
553 value_.assign(bytes, bytes + length);
554 return true;
555}
556
557template <>
558void Property<std::vector<uint8> >::AppendSetValueToWriter(
559 MessageWriter* writer) {
560 MessageWriter variant_writer(NULL);
561 writer->OpenVariant("ay", &variant_writer);
562 variant_writer.AppendArrayOfBytes(set_value_.data(), set_value_.size());
563 writer->CloseContainer(&variant_writer);
564}
565
dtapuska95f71722015-02-10 01:02:55 +0900566//
567// Property<std::map<std::string, std::string>> specialization.
568//
569
570template <>
571bool Property<std::map<std::string, std::string>>::PopValueFromReader(
572 MessageReader* reader) {
573 MessageReader variant_reader(NULL);
574 MessageReader array_reader(NULL);
575 if (!reader->PopVariant(&variant_reader) ||
576 !variant_reader.PopArray(&array_reader))
577 return false;
578 value_.clear();
579 while (array_reader.HasMoreData()) {
580 dbus::MessageReader dict_entry_reader(NULL);
581 if (!array_reader.PopDictEntry(&dict_entry_reader))
582 return false;
583 std::string key;
584 std::string value;
585 if (!dict_entry_reader.PopString(&key) ||
586 !dict_entry_reader.PopString(&value))
587 return false;
588 value_[key] = value;
589 }
590 return true;
591}
592
593template <>
594void Property<std::map<std::string, std::string>>::AppendSetValueToWriter(
595 MessageWriter* writer) {
596 MessageWriter variant_writer(NULL);
597 MessageWriter dict_writer(NULL);
598 writer->OpenVariant("a{ss}", &variant_writer);
599 variant_writer.OpenArray("{ss}", &dict_writer);
600 for (const auto& pair : set_value_) {
601 dbus::MessageWriter entry_writer(NULL);
602 dict_writer.OpenDictEntry(&entry_writer);
603 entry_writer.AppendString(pair.first);
604 entry_writer.AppendString(pair.second);
605 dict_writer.CloseContainer(&entry_writer);
606 }
607 variant_writer.CloseContainer(&dict_writer);
608 writer->CloseContainer(&variant_writer);
609}
610
611//
612// Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>
613// specialization.
614//
615
616template <>
617bool Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
618 PopValueFromReader(MessageReader* reader) {
619 MessageReader variant_reader(NULL);
620 MessageReader array_reader(NULL);
621 if (!reader->PopVariant(&variant_reader) ||
622 !variant_reader.PopArray(&array_reader))
623 return false;
624
625 value_.clear();
626 while (array_reader.HasMoreData()) {
627 dbus::MessageReader struct_reader(NULL);
628 if (!array_reader.PopStruct(&struct_reader))
629 return false;
630
631 std::pair<std::vector<uint8_t>, uint16_t> entry;
632 const uint8* bytes = NULL;
633 size_t length = 0;
634 if (!struct_reader.PopArrayOfBytes(&bytes, &length))
635 return false;
636 entry.first.assign(bytes, bytes + length);
637 if (!struct_reader.PopUint16(&entry.second))
638 return false;
639 value_.push_back(entry);
640 }
641 return true;
642}
643
644template <>
645void Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
646 AppendSetValueToWriter(MessageWriter* writer) {
647 MessageWriter variant_writer(NULL);
648 MessageWriter array_writer(NULL);
649 writer->OpenVariant("a(ayq)", &variant_writer);
650 variant_writer.OpenArray("(ayq)", &array_writer);
651 for (const auto& pair : set_value_) {
652 dbus::MessageWriter struct_writer(nullptr);
653 array_writer.OpenStruct(&struct_writer);
654 struct_writer.AppendArrayOfBytes(std::get<0>(pair).data(),
655 std::get<0>(pair).size());
656 struct_writer.AppendUint16(std::get<1>(pair));
657 array_writer.CloseContainer(&struct_writer);
658 }
659 variant_writer.CloseContainer(&array_writer);
660 writer->CloseContainer(&variant_writer);
661}
662
tzik@chromium.org1dc29432014-07-25 13:04:27 +0900663template class Property<uint8>;
664template class Property<bool>;
665template class Property<int16>;
666template class Property<uint16>;
667template class Property<int32>;
668template class Property<uint32>;
669template class Property<int64>;
670template class Property<uint64>;
671template class Property<double>;
672template class Property<std::string>;
673template class Property<ObjectPath>;
674template class Property<std::vector<std::string> >;
675template class Property<std::vector<ObjectPath> >;
676template class Property<std::vector<uint8> >;
dtapuska95f71722015-02-10 01:02:55 +0900677template class Property<std::map<std::string, std::string>>;
678template class Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>;
tzik@chromium.org1dc29432014-07-25 13:04:27 +0900679
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900680} // namespace dbus