blob: faca4a0a1d76dd1d902c9da4353a2580d7bc524d [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
avi0ad0ce02015-12-23 03:12:45 +09007#include <stddef.h>
8
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +09009#include "base/bind.h"
10#include "base/logging.h"
11
12#include "dbus/message.h"
13#include "dbus/object_path.h"
14#include "dbus/object_proxy.h"
15
16namespace dbus {
17
18//
19// PropertyBase implementation.
20//
21
derat3f868a42015-07-17 00:06:44 +090022PropertyBase::PropertyBase() : property_set_(nullptr), is_valid_(false) {}
23
24PropertyBase::~PropertyBase() {}
25
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090026void PropertyBase::Init(PropertySet* property_set, const std::string& name) {
27 DCHECK(!property_set_);
28 property_set_ = property_set;
jpawlowski77e73fc2015-05-11 20:07:04 +090029 is_valid_ = false;
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090030 name_ = name;
31}
32
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090033//
34// PropertySet implementation.
35//
36
keybuk@chromium.orgb45e5292012-08-15 10:03:30 +090037PropertySet::PropertySet(
38 ObjectProxy* object_proxy,
39 const std::string& interface,
40 const PropertyChangedCallback& property_changed_callback)
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090041 : object_proxy_(object_proxy),
42 interface_(interface),
43 property_changed_callback_(property_changed_callback),
44 weak_ptr_factory_(this) {}
45
46PropertySet::~PropertySet() {
47}
48
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(
58 kPropertiesInterface,
59 kPropertiesChanged,
60 base::Bind(&PropertySet::ChangedReceived,
61 weak_ptr_factory_.GetWeakPtr()),
62 base::Bind(&PropertySet::ChangedConnected,
63 weak_ptr_factory_.GetWeakPtr()));
64}
65
66
67void PropertySet::ChangedReceived(Signal* signal) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090068 DCHECK(signal);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090069 MessageReader reader(signal);
70
71 std::string interface;
72 if (!reader.PopString(&interface)) {
73 LOG(WARNING) << "Property changed signal has wrong parameters: "
74 << "expected interface name: " << signal->ToString();
75 return;
76 }
77
78 if (interface != this->interface())
79 return;
80
81 if (!UpdatePropertiesFromReader(&reader)) {
82 LOG(WARNING) << "Property changed signal has wrong parameters: "
83 << "expected dictionary: " << signal->ToString();
84 }
85
jpawlowski77e73fc2015-05-11 20:07:04 +090086 if (!InvalidatePropertiesFromReader(&reader)) {
87 LOG(WARNING) << "Property changed signal has wrong parameters: "
88 << "expected array to invalidate: " << signal->ToString();
89 }
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +090090}
91
92void PropertySet::ChangedConnected(const std::string& interface_name,
93 const std::string& signal_name,
94 bool success) {
95 LOG_IF(WARNING, !success) << "Failed to connect to " << signal_name
96 << "signal.";
97}
98
99
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900100void PropertySet::Get(PropertyBase* property, GetCallback callback) {
101 MethodCall method_call(kPropertiesInterface, kPropertiesGet);
102 MessageWriter writer(&method_call);
103 writer.AppendString(interface());
104 writer.AppendString(property->name());
105
106 DCHECK(object_proxy_);
107 object_proxy_->CallMethod(&method_call,
108 ObjectProxy::TIMEOUT_USE_DEFAULT,
109 base::Bind(&PropertySet::OnGet,
110 GetWeakPtr(),
111 property,
112 callback));
113}
114
115void PropertySet::OnGet(PropertyBase* property, GetCallback callback,
116 Response* response) {
117 if (!response) {
118 LOG(WARNING) << property->name() << ": Get: failed.";
119 return;
120 }
121
122 MessageReader reader(response);
jpawlowski77e73fc2015-05-11 20:07:04 +0900123 if (property->PopValueFromReader(&reader)) {
124 property->set_valid(true);
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900125 NotifyPropertyChanged(property->name());
jpawlowski77e73fc2015-05-11 20:07:04 +0900126 } else {
127 if (property->is_valid()) {
128 property->set_valid(false);
129 NotifyPropertyChanged(property->name());
130 }
131 }
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900132
133 if (!callback.is_null())
134 callback.Run(response);
135}
136
nywang80f27162015-09-29 07:46:36 +0900137bool PropertySet::GetAndBlock(PropertyBase* property) {
138 MethodCall method_call(kPropertiesInterface, kPropertiesGet);
139 MessageWriter writer(&method_call);
140 writer.AppendString(interface());
141 writer.AppendString(property->name());
142
143 DCHECK(object_proxy_);
dcheng30c5a172016-04-09 07:55:04 +0900144 std::unique_ptr<dbus::Response> response(object_proxy_->CallMethodAndBlock(
145 &method_call, ObjectProxy::TIMEOUT_USE_DEFAULT));
nywang80f27162015-09-29 07:46:36 +0900146
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_);
dcheng30c5a172016-04-09 07:55:04 +0900214 std::unique_ptr<dbus::Response> response(object_proxy_->CallMethodAndBlock(
215 &method_call, ObjectProxy::TIMEOUT_USE_DEFAULT));
nywangf1196812015-09-23 09:06:40 +0900216 if (response.get())
217 return true;
218 return false;
219}
220
stevenjb@chromium.orgfa639cc2014-07-17 14:03:53 +0900221void PropertySet::OnSet(PropertyBase* property,
222 SetCallback callback,
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900223 Response* response) {
224 LOG_IF(WARNING, !response) << property->name() << ": Set: failed.";
225 if (!callback.is_null())
226 callback.Run(response);
227}
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900228
229bool PropertySet::UpdatePropertiesFromReader(MessageReader* reader) {
230 DCHECK(reader);
231 MessageReader array_reader(NULL);
232 if (!reader->PopArray(&array_reader))
233 return false;
234
235 while (array_reader.HasMoreData()) {
236 MessageReader dict_entry_reader(NULL);
keybuk@chromium.org683dd8c2012-03-23 05:34:05 +0900237 if (array_reader.PopDictEntry(&dict_entry_reader))
238 UpdatePropertyFromReader(&dict_entry_reader);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900239 }
240
241 return true;
242}
243
244bool PropertySet::UpdatePropertyFromReader(MessageReader* reader) {
245 DCHECK(reader);
246
247 std::string name;
248 if (!reader->PopString(&name))
249 return false;
250
251 PropertiesMap::iterator it = properties_map_.find(name);
252 if (it == properties_map_.end())
253 return false;
254
255 PropertyBase* property = it->second;
256 if (property->PopValueFromReader(reader)) {
jpawlowski77e73fc2015-05-11 20:07:04 +0900257 property->set_valid(true);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900258 NotifyPropertyChanged(name);
259 return true;
260 } else {
jpawlowski77e73fc2015-05-11 20:07:04 +0900261 if (property->is_valid()) {
262 property->set_valid(false);
263 NotifyPropertyChanged(property->name());
264 }
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900265 return false;
266 }
267}
268
jpawlowski77e73fc2015-05-11 20:07:04 +0900269bool PropertySet::InvalidatePropertiesFromReader(MessageReader* reader) {
270 DCHECK(reader);
271 MessageReader array_reader(NULL);
272 if (!reader->PopArray(&array_reader))
273 return false;
274
275 while (array_reader.HasMoreData()) {
276 std::string name;
277 if (!array_reader.PopString(&name))
278 return false;
279
280 PropertiesMap::iterator it = properties_map_.find(name);
281 if (it == properties_map_.end())
282 continue;
283
284 PropertyBase* property = it->second;
285 if (property->is_valid()) {
286 property->set_valid(false);
287 NotifyPropertyChanged(property->name());
288 }
289 }
290
291 return true;
292}
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900293
294void PropertySet::NotifyPropertyChanged(const std::string& name) {
295 if (!property_changed_callback_.is_null())
296 property_changed_callback_.Run(name);
297}
298
299//
300// Property<Byte> specialization.
301//
302
303template <>
avi0ad0ce02015-12-23 03:12:45 +0900304Property<uint8_t>::Property()
305 : value_(0) {}
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900306
307template <>
avi0ad0ce02015-12-23 03:12:45 +0900308bool Property<uint8_t>::PopValueFromReader(MessageReader* reader) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900309 return reader->PopVariantOfByte(&value_);
310}
311
312template <>
avi0ad0ce02015-12-23 03:12:45 +0900313void Property<uint8_t>::AppendSetValueToWriter(MessageWriter* writer) {
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900314 writer->AppendVariantOfByte(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900315}
316
317//
318// Property<bool> specialization.
319//
320
321template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900322Property<bool>::Property() : value_(false) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900323}
324
325template <>
326bool Property<bool>::PopValueFromReader(MessageReader* reader) {
327 return reader->PopVariantOfBool(&value_);
328}
329
330template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900331void Property<bool>::AppendSetValueToWriter(MessageWriter* writer) {
332 writer->AppendVariantOfBool(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900333}
334
335//
avi0ad0ce02015-12-23 03:12:45 +0900336// Property<int16_t> specialization.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900337//
338
339template <>
avi0ad0ce02015-12-23 03:12:45 +0900340Property<int16_t>::Property()
341 : value_(0) {}
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900342
343template <>
avi0ad0ce02015-12-23 03:12:45 +0900344bool Property<int16_t>::PopValueFromReader(MessageReader* reader) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900345 return reader->PopVariantOfInt16(&value_);
346}
347
348template <>
avi0ad0ce02015-12-23 03:12:45 +0900349void Property<int16_t>::AppendSetValueToWriter(MessageWriter* writer) {
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900350 writer->AppendVariantOfInt16(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900351}
352
353//
avi0ad0ce02015-12-23 03:12:45 +0900354// Property<uint16_t> specialization.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900355//
356
357template <>
avi0ad0ce02015-12-23 03:12:45 +0900358Property<uint16_t>::Property()
359 : value_(0) {}
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900360
361template <>
avi0ad0ce02015-12-23 03:12:45 +0900362bool Property<uint16_t>::PopValueFromReader(MessageReader* reader) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900363 return reader->PopVariantOfUint16(&value_);
364}
365
366template <>
avi0ad0ce02015-12-23 03:12:45 +0900367void Property<uint16_t>::AppendSetValueToWriter(MessageWriter* writer) {
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900368 writer->AppendVariantOfUint16(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900369}
370
371//
avi0ad0ce02015-12-23 03:12:45 +0900372// Property<int32_t> specialization.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900373//
374
375template <>
avi0ad0ce02015-12-23 03:12:45 +0900376Property<int32_t>::Property()
377 : value_(0) {}
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900378
379template <>
avi0ad0ce02015-12-23 03:12:45 +0900380bool Property<int32_t>::PopValueFromReader(MessageReader* reader) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900381 return reader->PopVariantOfInt32(&value_);
382}
383
384template <>
avi0ad0ce02015-12-23 03:12:45 +0900385void Property<int32_t>::AppendSetValueToWriter(MessageWriter* writer) {
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900386 writer->AppendVariantOfInt32(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900387}
388
389//
avi0ad0ce02015-12-23 03:12:45 +0900390// Property<uint32_t> specialization.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900391//
392
393template <>
avi0ad0ce02015-12-23 03:12:45 +0900394Property<uint32_t>::Property()
395 : value_(0) {}
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900396
397template <>
avi0ad0ce02015-12-23 03:12:45 +0900398bool Property<uint32_t>::PopValueFromReader(MessageReader* reader) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900399 return reader->PopVariantOfUint32(&value_);
400}
401
402template <>
avi0ad0ce02015-12-23 03:12:45 +0900403void Property<uint32_t>::AppendSetValueToWriter(MessageWriter* writer) {
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900404 writer->AppendVariantOfUint32(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900405}
406
407//
avi0ad0ce02015-12-23 03:12:45 +0900408// Property<int64_t> specialization.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900409//
410
411template <>
avi0ad0ce02015-12-23 03:12:45 +0900412Property<int64_t>::Property()
413 : value_(0), set_value_(0) {}
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900414
415template <>
avi0ad0ce02015-12-23 03:12:45 +0900416bool Property<int64_t>::PopValueFromReader(MessageReader* reader) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900417 return reader->PopVariantOfInt64(&value_);
418}
419
420template <>
avi0ad0ce02015-12-23 03:12:45 +0900421void Property<int64_t>::AppendSetValueToWriter(MessageWriter* writer) {
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900422 writer->AppendVariantOfInt64(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900423}
424
425//
avi0ad0ce02015-12-23 03:12:45 +0900426// Property<uint64_t> specialization.
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900427//
428
429template <>
avi0ad0ce02015-12-23 03:12:45 +0900430Property<uint64_t>::Property()
431 : value_(0) {}
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900432
433template <>
avi0ad0ce02015-12-23 03:12:45 +0900434bool Property<uint64_t>::PopValueFromReader(MessageReader* reader) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900435 return reader->PopVariantOfUint64(&value_);
436}
437
438template <>
avi0ad0ce02015-12-23 03:12:45 +0900439void Property<uint64_t>::AppendSetValueToWriter(MessageWriter* writer) {
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900440 writer->AppendVariantOfUint64(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900441}
442
443//
444// Property<double> specialization.
445//
446
447template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900448Property<double>::Property() : value_(0.0) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900449}
450
451template <>
452bool Property<double>::PopValueFromReader(MessageReader* reader) {
453 return reader->PopVariantOfDouble(&value_);
454}
455
456template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900457void Property<double>::AppendSetValueToWriter(MessageWriter* writer) {
458 writer->AppendVariantOfDouble(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900459}
460
461//
462// Property<std::string> specialization.
463//
464
465template <>
466bool Property<std::string>::PopValueFromReader(MessageReader* reader) {
467 return reader->PopVariantOfString(&value_);
468}
469
470template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900471void Property<std::string>::AppendSetValueToWriter(MessageWriter* writer) {
472 writer->AppendVariantOfString(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900473}
474
475//
476// Property<ObjectPath> specialization.
477//
478
479template <>
480bool Property<ObjectPath>::PopValueFromReader(MessageReader* reader) {
481 return reader->PopVariantOfObjectPath(&value_);
482}
483
484template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900485void Property<ObjectPath>::AppendSetValueToWriter(MessageWriter* writer) {
486 writer->AppendVariantOfObjectPath(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900487}
488
489//
490// Property<std::vector<std::string> > specialization.
491//
492
493template <>
494bool Property<std::vector<std::string> >::PopValueFromReader(
495 MessageReader* reader) {
496 MessageReader variant_reader(NULL);
497 if (!reader->PopVariant(&variant_reader))
498 return false;
499
keybuk@google.comf056b962012-03-22 08:43:45 +0900500 value_.clear();
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900501 return variant_reader.PopArrayOfStrings(&value_);
502}
503
504template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900505void Property<std::vector<std::string> >::AppendSetValueToWriter(
506 MessageWriter* writer) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900507 MessageWriter variant_writer(NULL);
508 writer->OpenVariant("as", &variant_writer);
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900509 variant_writer.AppendArrayOfStrings(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900510 writer->CloseContainer(&variant_writer);
511}
512
513//
514// Property<std::vector<ObjectPath> > specialization.
515//
516
517template <>
518bool Property<std::vector<ObjectPath> >::PopValueFromReader(
519 MessageReader* reader) {
520 MessageReader variant_reader(NULL);
521 if (!reader->PopVariant(&variant_reader))
522 return false;
523
keybuk@google.comf056b962012-03-22 08:43:45 +0900524 value_.clear();
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900525 return variant_reader.PopArrayOfObjectPaths(&value_);
526}
527
528template <>
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900529void Property<std::vector<ObjectPath> >::AppendSetValueToWriter(
530 MessageWriter* writer) {
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900531 MessageWriter variant_writer(NULL);
532 writer->OpenVariant("ao", &variant_writer);
keybuk@chromium.org56028ac2012-06-29 03:43:30 +0900533 variant_writer.AppendArrayOfObjectPaths(set_value_);
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900534 writer->CloseContainer(&variant_writer);
535}
536
armansito@chromium.org11e12742014-03-15 16:40:49 +0900537//
avi0ad0ce02015-12-23 03:12:45 +0900538// Property<std::vector<uint8_t> > specialization.
armansito@chromium.org11e12742014-03-15 16:40:49 +0900539//
540
541template <>
avi0ad0ce02015-12-23 03:12:45 +0900542bool Property<std::vector<uint8_t>>::PopValueFromReader(MessageReader* reader) {
armansito@chromium.org11e12742014-03-15 16:40:49 +0900543 MessageReader variant_reader(NULL);
544 if (!reader->PopVariant(&variant_reader))
545 return false;
546
547 value_.clear();
avi0ad0ce02015-12-23 03:12:45 +0900548 const uint8_t* bytes = NULL;
armansito@chromium.org11e12742014-03-15 16:40:49 +0900549 size_t length = 0;
550 if (!variant_reader.PopArrayOfBytes(&bytes, &length))
551 return false;
552 value_.assign(bytes, bytes + length);
553 return true;
554}
555
556template <>
avi0ad0ce02015-12-23 03:12:45 +0900557void Property<std::vector<uint8_t>>::AppendSetValueToWriter(
armansito@chromium.org11e12742014-03-15 16:40:49 +0900558 MessageWriter* writer) {
559 MessageWriter variant_writer(NULL);
560 writer->OpenVariant("ay", &variant_writer);
561 variant_writer.AppendArrayOfBytes(set_value_.data(), set_value_.size());
562 writer->CloseContainer(&variant_writer);
563}
564
dtapuska95f71722015-02-10 01:02:55 +0900565//
566// Property<std::map<std::string, std::string>> specialization.
567//
568
569template <>
570bool Property<std::map<std::string, std::string>>::PopValueFromReader(
571 MessageReader* reader) {
572 MessageReader variant_reader(NULL);
573 MessageReader array_reader(NULL);
574 if (!reader->PopVariant(&variant_reader) ||
575 !variant_reader.PopArray(&array_reader))
576 return false;
577 value_.clear();
578 while (array_reader.HasMoreData()) {
579 dbus::MessageReader dict_entry_reader(NULL);
580 if (!array_reader.PopDictEntry(&dict_entry_reader))
581 return false;
582 std::string key;
583 std::string value;
584 if (!dict_entry_reader.PopString(&key) ||
585 !dict_entry_reader.PopString(&value))
586 return false;
587 value_[key] = value;
588 }
589 return true;
590}
591
592template <>
593void Property<std::map<std::string, std::string>>::AppendSetValueToWriter(
594 MessageWriter* writer) {
595 MessageWriter variant_writer(NULL);
596 MessageWriter dict_writer(NULL);
597 writer->OpenVariant("a{ss}", &variant_writer);
598 variant_writer.OpenArray("{ss}", &dict_writer);
599 for (const auto& pair : set_value_) {
600 dbus::MessageWriter entry_writer(NULL);
601 dict_writer.OpenDictEntry(&entry_writer);
602 entry_writer.AppendString(pair.first);
603 entry_writer.AppendString(pair.second);
604 dict_writer.CloseContainer(&entry_writer);
605 }
606 variant_writer.CloseContainer(&dict_writer);
607 writer->CloseContainer(&variant_writer);
608}
609
610//
611// Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>
612// specialization.
613//
614
615template <>
616bool Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
617 PopValueFromReader(MessageReader* reader) {
618 MessageReader variant_reader(NULL);
619 MessageReader array_reader(NULL);
620 if (!reader->PopVariant(&variant_reader) ||
621 !variant_reader.PopArray(&array_reader))
622 return false;
623
624 value_.clear();
625 while (array_reader.HasMoreData()) {
626 dbus::MessageReader struct_reader(NULL);
627 if (!array_reader.PopStruct(&struct_reader))
628 return false;
629
630 std::pair<std::vector<uint8_t>, uint16_t> entry;
avi0ad0ce02015-12-23 03:12:45 +0900631 const uint8_t* bytes = NULL;
dtapuska95f71722015-02-10 01:02:55 +0900632 size_t length = 0;
633 if (!struct_reader.PopArrayOfBytes(&bytes, &length))
634 return false;
635 entry.first.assign(bytes, bytes + length);
636 if (!struct_reader.PopUint16(&entry.second))
637 return false;
638 value_.push_back(entry);
639 }
640 return true;
641}
642
643template <>
644void Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
645 AppendSetValueToWriter(MessageWriter* writer) {
646 MessageWriter variant_writer(NULL);
647 MessageWriter array_writer(NULL);
648 writer->OpenVariant("a(ayq)", &variant_writer);
649 variant_writer.OpenArray("(ayq)", &array_writer);
650 for (const auto& pair : set_value_) {
651 dbus::MessageWriter struct_writer(nullptr);
652 array_writer.OpenStruct(&struct_writer);
653 struct_writer.AppendArrayOfBytes(std::get<0>(pair).data(),
654 std::get<0>(pair).size());
655 struct_writer.AppendUint16(std::get<1>(pair));
656 array_writer.CloseContainer(&struct_writer);
657 }
658 variant_writer.CloseContainer(&array_writer);
659 writer->CloseContainer(&variant_writer);
660}
661
avi0ad0ce02015-12-23 03:12:45 +0900662template class Property<uint8_t>;
tzik@chromium.org1dc29432014-07-25 13:04:27 +0900663template class Property<bool>;
avi0ad0ce02015-12-23 03:12:45 +0900664template class Property<int16_t>;
665template class Property<uint16_t>;
666template class Property<int32_t>;
667template class Property<uint32_t>;
668template class Property<int64_t>;
669template class Property<uint64_t>;
tzik@chromium.org1dc29432014-07-25 13:04:27 +0900670template class Property<double>;
671template class Property<std::string>;
672template class Property<ObjectPath>;
673template class Property<std::vector<std::string> >;
674template class Property<std::vector<ObjectPath> >;
avi0ad0ce02015-12-23 03:12:45 +0900675template class Property<std::vector<uint8_t>>;
dtapuska95f71722015-02-10 01:02:55 +0900676template class Property<std::map<std::string, std::string>>;
677template class Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>;
tzik@chromium.org1dc29432014-07-25 13:04:27 +0900678
keybuk@chromium.org7e0c4932012-02-15 13:21:08 +0900679} // namespace dbus