property.cc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817
  1. // 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. #include "dbus/property.h"
  5. #include <stddef.h>
  6. #include <memory>
  7. #include "base/bind.h"
  8. #include "base/logging.h"
  9. #include "dbus/message.h"
  10. #include "dbus/object_path.h"
  11. #include "dbus/object_proxy.h"
  12. namespace dbus {
  13. //
  14. // PropertyBase implementation.
  15. //
  16. PropertyBase::PropertyBase() : property_set_(nullptr), is_valid_(false) {}
  17. PropertyBase::~PropertyBase() = default;
  18. void PropertyBase::Init(PropertySet* property_set, const std::string& name) {
  19. DCHECK(!property_set_);
  20. property_set_ = property_set;
  21. is_valid_ = false;
  22. name_ = name;
  23. }
  24. //
  25. // PropertySet implementation.
  26. //
  27. PropertySet::PropertySet(
  28. ObjectProxy* object_proxy,
  29. const std::string& interface,
  30. const PropertyChangedCallback& property_changed_callback)
  31. : object_proxy_(object_proxy),
  32. interface_(interface),
  33. property_changed_callback_(property_changed_callback) {}
  34. PropertySet::~PropertySet() = default;
  35. void PropertySet::RegisterProperty(const std::string& name,
  36. PropertyBase* property) {
  37. property->Init(this, name);
  38. properties_map_[name] = property;
  39. }
  40. void PropertySet::ConnectSignals() {
  41. DCHECK(object_proxy_);
  42. object_proxy_->ConnectToSignal(
  43. kPropertiesInterface, kPropertiesChanged,
  44. base::BindRepeating(&PropertySet::ChangedReceived,
  45. weak_ptr_factory_.GetWeakPtr()),
  46. base::BindOnce(&PropertySet::ChangedConnected,
  47. weak_ptr_factory_.GetWeakPtr()));
  48. }
  49. void PropertySet::ChangedReceived(Signal* signal) {
  50. DCHECK(signal);
  51. MessageReader reader(signal);
  52. std::string interface;
  53. if (!reader.PopString(&interface)) {
  54. LOG(WARNING) << "Property changed signal has wrong parameters: "
  55. << "expected interface name: " << signal->ToString();
  56. return;
  57. }
  58. if (interface != this->interface())
  59. return;
  60. if (!UpdatePropertiesFromReader(&reader)) {
  61. LOG(WARNING) << "Property changed signal has wrong parameters: "
  62. << "expected dictionary: " << signal->ToString();
  63. }
  64. if (!InvalidatePropertiesFromReader(&reader)) {
  65. LOG(WARNING) << "Property changed signal has wrong parameters: "
  66. << "expected array to invalidate: " << signal->ToString();
  67. }
  68. }
  69. void PropertySet::ChangedConnected(const std::string& interface_name,
  70. const std::string& signal_name,
  71. bool success) {
  72. LOG_IF(WARNING, !success) << "Failed to connect to " << signal_name
  73. << "signal.";
  74. }
  75. void PropertySet::Get(PropertyBase* property, GetCallback callback) {
  76. MethodCall method_call(kPropertiesInterface, kPropertiesGet);
  77. MessageWriter writer(&method_call);
  78. writer.AppendString(interface());
  79. writer.AppendString(property->name());
  80. DCHECK(object_proxy_);
  81. object_proxy_->CallMethod(&method_call, ObjectProxy::TIMEOUT_USE_DEFAULT,
  82. base::BindOnce(&PropertySet::OnGet, GetWeakPtr(),
  83. property, std::move(callback)));
  84. }
  85. void PropertySet::OnGet(PropertyBase* property, GetCallback callback,
  86. Response* response) {
  87. if (!response) {
  88. LOG(WARNING) << property->name() << ": Get: failed.";
  89. return;
  90. }
  91. MessageReader reader(response);
  92. if (property->PopValueFromReader(&reader)) {
  93. property->set_valid(true);
  94. NotifyPropertyChanged(property->name());
  95. } else {
  96. if (property->is_valid()) {
  97. property->set_valid(false);
  98. NotifyPropertyChanged(property->name());
  99. }
  100. }
  101. if (!callback.is_null())
  102. std::move(callback).Run(response);
  103. }
  104. bool PropertySet::GetAndBlock(PropertyBase* property) {
  105. MethodCall method_call(kPropertiesInterface, kPropertiesGet);
  106. MessageWriter writer(&method_call);
  107. writer.AppendString(interface());
  108. writer.AppendString(property->name());
  109. DCHECK(object_proxy_);
  110. std::unique_ptr<dbus::Response> response(object_proxy_->CallMethodAndBlock(
  111. &method_call, ObjectProxy::TIMEOUT_USE_DEFAULT));
  112. if (!response.get()) {
  113. LOG(WARNING) << property->name() << ": GetAndBlock: failed.";
  114. return false;
  115. }
  116. MessageReader reader(response.get());
  117. if (property->PopValueFromReader(&reader)) {
  118. property->set_valid(true);
  119. NotifyPropertyChanged(property->name());
  120. } else {
  121. if (property->is_valid()) {
  122. property->set_valid(false);
  123. NotifyPropertyChanged(property->name());
  124. }
  125. }
  126. return true;
  127. }
  128. void PropertySet::GetAll() {
  129. MethodCall method_call(kPropertiesInterface, kPropertiesGetAll);
  130. MessageWriter writer(&method_call);
  131. writer.AppendString(interface());
  132. DCHECK(object_proxy_);
  133. object_proxy_->CallMethod(
  134. &method_call, ObjectProxy::TIMEOUT_USE_DEFAULT,
  135. base::BindOnce(&PropertySet::OnGetAll, weak_ptr_factory_.GetWeakPtr()));
  136. }
  137. void PropertySet::OnGetAll(Response* response) {
  138. if (!response) {
  139. LOG(WARNING) << "GetAll request failed for: " << interface_;
  140. return;
  141. }
  142. MessageReader reader(response);
  143. if (!UpdatePropertiesFromReader(&reader)) {
  144. LOG(WARNING) << "GetAll response has wrong parameters: "
  145. << "expected dictionary: " << response->ToString();
  146. }
  147. }
  148. void PropertySet::Set(PropertyBase* property, SetCallback callback) {
  149. MethodCall method_call(kPropertiesInterface, kPropertiesSet);
  150. MessageWriter writer(&method_call);
  151. writer.AppendString(interface());
  152. writer.AppendString(property->name());
  153. property->AppendSetValueToWriter(&writer);
  154. DCHECK(object_proxy_);
  155. object_proxy_->CallMethod(&method_call, ObjectProxy::TIMEOUT_USE_DEFAULT,
  156. base::BindOnce(&PropertySet::OnSet, GetWeakPtr(),
  157. property, std::move(callback)));
  158. }
  159. bool PropertySet::SetAndBlock(PropertyBase* property) {
  160. MethodCall method_call(kPropertiesInterface, kPropertiesSet);
  161. MessageWriter writer(&method_call);
  162. writer.AppendString(interface());
  163. writer.AppendString(property->name());
  164. property->AppendSetValueToWriter(&writer);
  165. DCHECK(object_proxy_);
  166. std::unique_ptr<dbus::Response> response(object_proxy_->CallMethodAndBlock(
  167. &method_call, ObjectProxy::TIMEOUT_USE_DEFAULT));
  168. if (response.get())
  169. return true;
  170. return false;
  171. }
  172. void PropertySet::OnSet(PropertyBase* property,
  173. SetCallback callback,
  174. Response* response) {
  175. LOG_IF(WARNING, !response) << property->name() << ": Set: failed.";
  176. if (!callback.is_null())
  177. std::move(callback).Run(response);
  178. }
  179. bool PropertySet::UpdatePropertiesFromReader(MessageReader* reader) {
  180. DCHECK(reader);
  181. MessageReader array_reader(nullptr);
  182. if (!reader->PopArray(&array_reader))
  183. return false;
  184. while (array_reader.HasMoreData()) {
  185. MessageReader dict_entry_reader(nullptr);
  186. if (array_reader.PopDictEntry(&dict_entry_reader))
  187. UpdatePropertyFromReader(&dict_entry_reader);
  188. }
  189. return true;
  190. }
  191. bool PropertySet::UpdatePropertyFromReader(MessageReader* reader) {
  192. DCHECK(reader);
  193. std::string name;
  194. if (!reader->PopString(&name))
  195. return false;
  196. PropertiesMap::iterator it = properties_map_.find(name);
  197. if (it == properties_map_.end())
  198. return false;
  199. PropertyBase* property = it->second;
  200. if (property->PopValueFromReader(reader)) {
  201. property->set_valid(true);
  202. NotifyPropertyChanged(name);
  203. return true;
  204. } else {
  205. if (property->is_valid()) {
  206. property->set_valid(false);
  207. NotifyPropertyChanged(property->name());
  208. }
  209. return false;
  210. }
  211. }
  212. bool PropertySet::InvalidatePropertiesFromReader(MessageReader* reader) {
  213. DCHECK(reader);
  214. MessageReader array_reader(nullptr);
  215. if (!reader->PopArray(&array_reader))
  216. return false;
  217. while (array_reader.HasMoreData()) {
  218. std::string name;
  219. if (!array_reader.PopString(&name))
  220. return false;
  221. PropertiesMap::iterator it = properties_map_.find(name);
  222. if (it == properties_map_.end())
  223. continue;
  224. PropertyBase* property = it->second;
  225. if (property->is_valid()) {
  226. property->set_valid(false);
  227. NotifyPropertyChanged(property->name());
  228. }
  229. }
  230. return true;
  231. }
  232. void PropertySet::NotifyPropertyChanged(const std::string& name) {
  233. if (!property_changed_callback_.is_null())
  234. property_changed_callback_.Run(name);
  235. }
  236. //
  237. // Property<Byte> specialization.
  238. //
  239. template <>
  240. Property<uint8_t>::Property()
  241. : value_(0) {}
  242. template <>
  243. bool Property<uint8_t>::PopValueFromReader(MessageReader* reader) {
  244. return reader->PopVariantOfByte(&value_);
  245. }
  246. template <>
  247. void Property<uint8_t>::AppendSetValueToWriter(MessageWriter* writer) {
  248. writer->AppendVariantOfByte(set_value_);
  249. }
  250. //
  251. // Property<bool> specialization.
  252. //
  253. template <>
  254. Property<bool>::Property() : value_(false) {
  255. }
  256. template <>
  257. bool Property<bool>::PopValueFromReader(MessageReader* reader) {
  258. return reader->PopVariantOfBool(&value_);
  259. }
  260. template <>
  261. void Property<bool>::AppendSetValueToWriter(MessageWriter* writer) {
  262. writer->AppendVariantOfBool(set_value_);
  263. }
  264. //
  265. // Property<int16_t> specialization.
  266. //
  267. template <>
  268. Property<int16_t>::Property()
  269. : value_(0) {}
  270. template <>
  271. bool Property<int16_t>::PopValueFromReader(MessageReader* reader) {
  272. return reader->PopVariantOfInt16(&value_);
  273. }
  274. template <>
  275. void Property<int16_t>::AppendSetValueToWriter(MessageWriter* writer) {
  276. writer->AppendVariantOfInt16(set_value_);
  277. }
  278. //
  279. // Property<uint16_t> specialization.
  280. //
  281. template <>
  282. Property<uint16_t>::Property()
  283. : value_(0) {}
  284. template <>
  285. bool Property<uint16_t>::PopValueFromReader(MessageReader* reader) {
  286. return reader->PopVariantOfUint16(&value_);
  287. }
  288. template <>
  289. void Property<uint16_t>::AppendSetValueToWriter(MessageWriter* writer) {
  290. writer->AppendVariantOfUint16(set_value_);
  291. }
  292. //
  293. // Property<int32_t> specialization.
  294. //
  295. template <>
  296. Property<int32_t>::Property()
  297. : value_(0) {}
  298. template <>
  299. bool Property<int32_t>::PopValueFromReader(MessageReader* reader) {
  300. return reader->PopVariantOfInt32(&value_);
  301. }
  302. template <>
  303. void Property<int32_t>::AppendSetValueToWriter(MessageWriter* writer) {
  304. writer->AppendVariantOfInt32(set_value_);
  305. }
  306. //
  307. // Property<uint32_t> specialization.
  308. //
  309. template <>
  310. Property<uint32_t>::Property()
  311. : value_(0) {}
  312. template <>
  313. bool Property<uint32_t>::PopValueFromReader(MessageReader* reader) {
  314. return reader->PopVariantOfUint32(&value_);
  315. }
  316. template <>
  317. void Property<uint32_t>::AppendSetValueToWriter(MessageWriter* writer) {
  318. writer->AppendVariantOfUint32(set_value_);
  319. }
  320. //
  321. // Property<int64_t> specialization.
  322. //
  323. template <>
  324. Property<int64_t>::Property()
  325. : value_(0), set_value_(0) {}
  326. template <>
  327. bool Property<int64_t>::PopValueFromReader(MessageReader* reader) {
  328. return reader->PopVariantOfInt64(&value_);
  329. }
  330. template <>
  331. void Property<int64_t>::AppendSetValueToWriter(MessageWriter* writer) {
  332. writer->AppendVariantOfInt64(set_value_);
  333. }
  334. //
  335. // Property<uint64_t> specialization.
  336. //
  337. template <>
  338. Property<uint64_t>::Property()
  339. : value_(0) {}
  340. template <>
  341. bool Property<uint64_t>::PopValueFromReader(MessageReader* reader) {
  342. return reader->PopVariantOfUint64(&value_);
  343. }
  344. template <>
  345. void Property<uint64_t>::AppendSetValueToWriter(MessageWriter* writer) {
  346. writer->AppendVariantOfUint64(set_value_);
  347. }
  348. //
  349. // Property<double> specialization.
  350. //
  351. template <>
  352. Property<double>::Property() : value_(0.0) {
  353. }
  354. template <>
  355. bool Property<double>::PopValueFromReader(MessageReader* reader) {
  356. return reader->PopVariantOfDouble(&value_);
  357. }
  358. template <>
  359. void Property<double>::AppendSetValueToWriter(MessageWriter* writer) {
  360. writer->AppendVariantOfDouble(set_value_);
  361. }
  362. //
  363. // Property<std::string> specialization.
  364. //
  365. template <>
  366. bool Property<std::string>::PopValueFromReader(MessageReader* reader) {
  367. return reader->PopVariantOfString(&value_);
  368. }
  369. template <>
  370. void Property<std::string>::AppendSetValueToWriter(MessageWriter* writer) {
  371. writer->AppendVariantOfString(set_value_);
  372. }
  373. //
  374. // Property<ObjectPath> specialization.
  375. //
  376. template <>
  377. bool Property<ObjectPath>::PopValueFromReader(MessageReader* reader) {
  378. return reader->PopVariantOfObjectPath(&value_);
  379. }
  380. template <>
  381. void Property<ObjectPath>::AppendSetValueToWriter(MessageWriter* writer) {
  382. writer->AppendVariantOfObjectPath(set_value_);
  383. }
  384. //
  385. // Property<std::vector<std::string>> specialization.
  386. //
  387. template <>
  388. bool Property<std::vector<std::string>>::PopValueFromReader(
  389. MessageReader* reader) {
  390. MessageReader variant_reader(nullptr);
  391. if (!reader->PopVariant(&variant_reader))
  392. return false;
  393. value_.clear();
  394. return variant_reader.PopArrayOfStrings(&value_);
  395. }
  396. template <>
  397. void Property<std::vector<std::string>>::AppendSetValueToWriter(
  398. MessageWriter* writer) {
  399. MessageWriter variant_writer(nullptr);
  400. writer->OpenVariant("as", &variant_writer);
  401. variant_writer.AppendArrayOfStrings(set_value_);
  402. writer->CloseContainer(&variant_writer);
  403. }
  404. //
  405. // Property<std::vector<ObjectPath>> specialization.
  406. //
  407. template <>
  408. bool Property<std::vector<ObjectPath>>::PopValueFromReader(
  409. MessageReader* reader) {
  410. MessageReader variant_reader(nullptr);
  411. if (!reader->PopVariant(&variant_reader))
  412. return false;
  413. value_.clear();
  414. return variant_reader.PopArrayOfObjectPaths(&value_);
  415. }
  416. template <>
  417. void Property<std::vector<ObjectPath>>::AppendSetValueToWriter(
  418. MessageWriter* writer) {
  419. MessageWriter variant_writer(nullptr);
  420. writer->OpenVariant("ao", &variant_writer);
  421. variant_writer.AppendArrayOfObjectPaths(set_value_);
  422. writer->CloseContainer(&variant_writer);
  423. }
  424. //
  425. // Property<std::vector<uint8_t>> specialization.
  426. //
  427. template <>
  428. bool Property<std::vector<uint8_t>>::PopValueFromReader(MessageReader* reader) {
  429. MessageReader variant_reader(nullptr);
  430. if (!reader->PopVariant(&variant_reader))
  431. return false;
  432. value_.clear();
  433. const uint8_t* bytes = nullptr;
  434. size_t length = 0;
  435. if (!variant_reader.PopArrayOfBytes(&bytes, &length))
  436. return false;
  437. value_.assign(bytes, bytes + length);
  438. return true;
  439. }
  440. template <>
  441. void Property<std::vector<uint8_t>>::AppendSetValueToWriter(
  442. MessageWriter* writer) {
  443. MessageWriter variant_writer(nullptr);
  444. writer->OpenVariant("ay", &variant_writer);
  445. variant_writer.AppendArrayOfBytes(set_value_.data(), set_value_.size());
  446. writer->CloseContainer(&variant_writer);
  447. }
  448. //
  449. // Property<std::map<std::string, std::string>> specialization.
  450. //
  451. template <>
  452. bool Property<std::map<std::string, std::string>>::PopValueFromReader(
  453. MessageReader* reader) {
  454. MessageReader variant_reader(nullptr);
  455. MessageReader array_reader(nullptr);
  456. if (!reader->PopVariant(&variant_reader) ||
  457. !variant_reader.PopArray(&array_reader))
  458. return false;
  459. value_.clear();
  460. while (array_reader.HasMoreData()) {
  461. dbus::MessageReader dict_entry_reader(nullptr);
  462. if (!array_reader.PopDictEntry(&dict_entry_reader))
  463. return false;
  464. std::string key;
  465. std::string value;
  466. if (!dict_entry_reader.PopString(&key) ||
  467. !dict_entry_reader.PopString(&value))
  468. return false;
  469. value_[key] = value;
  470. }
  471. return true;
  472. }
  473. template <>
  474. void Property<std::map<std::string, std::string>>::AppendSetValueToWriter(
  475. MessageWriter* writer) {
  476. MessageWriter variant_writer(nullptr);
  477. MessageWriter dict_writer(nullptr);
  478. writer->OpenVariant("a{ss}", &variant_writer);
  479. variant_writer.OpenArray("{ss}", &dict_writer);
  480. for (const auto& pair : set_value_) {
  481. dbus::MessageWriter entry_writer(nullptr);
  482. dict_writer.OpenDictEntry(&entry_writer);
  483. entry_writer.AppendString(pair.first);
  484. entry_writer.AppendString(pair.second);
  485. dict_writer.CloseContainer(&entry_writer);
  486. }
  487. variant_writer.CloseContainer(&dict_writer);
  488. writer->CloseContainer(&variant_writer);
  489. }
  490. //
  491. // Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>
  492. // specialization.
  493. //
  494. template <>
  495. bool Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
  496. PopValueFromReader(MessageReader* reader) {
  497. MessageReader variant_reader(nullptr);
  498. MessageReader array_reader(nullptr);
  499. if (!reader->PopVariant(&variant_reader) ||
  500. !variant_reader.PopArray(&array_reader))
  501. return false;
  502. value_.clear();
  503. while (array_reader.HasMoreData()) {
  504. dbus::MessageReader struct_reader(nullptr);
  505. if (!array_reader.PopStruct(&struct_reader))
  506. return false;
  507. std::pair<std::vector<uint8_t>, uint16_t> entry;
  508. const uint8_t* bytes = nullptr;
  509. size_t length = 0;
  510. if (!struct_reader.PopArrayOfBytes(&bytes, &length))
  511. return false;
  512. entry.first.assign(bytes, bytes + length);
  513. if (!struct_reader.PopUint16(&entry.second))
  514. return false;
  515. value_.push_back(entry);
  516. }
  517. return true;
  518. }
  519. template <>
  520. void Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
  521. AppendSetValueToWriter(MessageWriter* writer) {
  522. MessageWriter variant_writer(nullptr);
  523. MessageWriter array_writer(nullptr);
  524. writer->OpenVariant("a(ayq)", &variant_writer);
  525. variant_writer.OpenArray("(ayq)", &array_writer);
  526. for (const auto& pair : set_value_) {
  527. dbus::MessageWriter struct_writer(nullptr);
  528. array_writer.OpenStruct(&struct_writer);
  529. struct_writer.AppendArrayOfBytes(std::get<0>(pair).data(),
  530. std::get<0>(pair).size());
  531. struct_writer.AppendUint16(std::get<1>(pair));
  532. array_writer.CloseContainer(&struct_writer);
  533. }
  534. variant_writer.CloseContainer(&array_writer);
  535. writer->CloseContainer(&variant_writer);
  536. }
  537. //
  538. // Property<std::map<std::string, std::vector<uint8_t>>>
  539. // specialization.
  540. //
  541. template <>
  542. bool Property<std::map<std::string, std::vector<uint8_t>>>::PopValueFromReader(
  543. MessageReader* reader) {
  544. MessageReader variant_reader(nullptr);
  545. MessageReader dict_reader(nullptr);
  546. if (!reader->PopVariant(&variant_reader) ||
  547. !variant_reader.PopArray(&dict_reader))
  548. return false;
  549. value_.clear();
  550. while (dict_reader.HasMoreData()) {
  551. MessageReader entry_reader(nullptr);
  552. if (!dict_reader.PopDictEntry(&entry_reader))
  553. return false;
  554. std::string key;
  555. if (!entry_reader.PopString(&key))
  556. return false;
  557. const uint8_t* bytes = nullptr;
  558. size_t length = 0;
  559. if (entry_reader.GetDataType() == Message::VARIANT) {
  560. // Make BlueZ happy since it wraps the array of bytes with a variant.
  561. MessageReader value_variant_reader(nullptr);
  562. if (!entry_reader.PopVariant(&value_variant_reader))
  563. return false;
  564. if (!value_variant_reader.PopArrayOfBytes(&bytes, &length))
  565. return false;
  566. } else {
  567. if (!entry_reader.PopArrayOfBytes(&bytes, &length))
  568. return false;
  569. }
  570. value_[key].assign(bytes, bytes + length);
  571. }
  572. return true;
  573. }
  574. template <>
  575. void Property<std::map<std::string, std::vector<uint8_t>>>::
  576. AppendSetValueToWriter(MessageWriter* writer) {
  577. MessageWriter variant_writer(nullptr);
  578. MessageWriter dict_writer(nullptr);
  579. writer->OpenVariant("a{sv}", &variant_writer);
  580. variant_writer.OpenArray("{sv}", &dict_writer);
  581. for (const auto& pair : set_value_) {
  582. MessageWriter entry_writer(nullptr);
  583. dict_writer.OpenDictEntry(&entry_writer);
  584. entry_writer.AppendString(pair.first);
  585. MessageWriter value_varient_writer(nullptr);
  586. entry_writer.OpenVariant("ay", &value_varient_writer);
  587. value_varient_writer.AppendArrayOfBytes(pair.second.data(),
  588. pair.second.size());
  589. entry_writer.CloseContainer(&value_varient_writer);
  590. dict_writer.CloseContainer(&entry_writer);
  591. }
  592. variant_writer.CloseContainer(&dict_writer);
  593. writer->CloseContainer(&variant_writer);
  594. }
  595. //
  596. // Property<std::map<uint16_t, std::vector<uint8_t>>>
  597. // specialization.
  598. //
  599. template <>
  600. bool Property<std::map<uint16_t, std::vector<uint8_t>>>::PopValueFromReader(
  601. MessageReader* reader) {
  602. MessageReader variant_reader(nullptr);
  603. MessageReader dict_reader(nullptr);
  604. if (!reader->PopVariant(&variant_reader) ||
  605. !variant_reader.PopArray(&dict_reader))
  606. return false;
  607. value_.clear();
  608. while (dict_reader.HasMoreData()) {
  609. MessageReader entry_reader(nullptr);
  610. if (!dict_reader.PopDictEntry(&entry_reader))
  611. return false;
  612. uint16_t key;
  613. if (!entry_reader.PopUint16(&key))
  614. return false;
  615. const uint8_t* bytes = nullptr;
  616. size_t length = 0;
  617. if (entry_reader.GetDataType() == Message::VARIANT) {
  618. // Make BlueZ happy since it wraps the array of bytes with a variant.
  619. MessageReader value_variant_reader(nullptr);
  620. if (!entry_reader.PopVariant(&value_variant_reader))
  621. return false;
  622. if (!value_variant_reader.PopArrayOfBytes(&bytes, &length))
  623. return false;
  624. } else {
  625. if (!entry_reader.PopArrayOfBytes(&bytes, &length))
  626. return false;
  627. }
  628. value_[key].assign(bytes, bytes + length);
  629. }
  630. return true;
  631. }
  632. template <>
  633. void Property<std::map<uint16_t, std::vector<uint8_t>>>::AppendSetValueToWriter(
  634. MessageWriter* writer) {
  635. MessageWriter variant_writer(nullptr);
  636. MessageWriter dict_writer(nullptr);
  637. writer->OpenVariant("a{qv}", &variant_writer);
  638. variant_writer.OpenArray("{qv}", &dict_writer);
  639. for (const auto& pair : set_value_) {
  640. MessageWriter entry_writer(nullptr);
  641. dict_writer.OpenDictEntry(&entry_writer);
  642. entry_writer.AppendUint16(pair.first);
  643. MessageWriter value_varient_writer(nullptr);
  644. entry_writer.OpenVariant("ay", &value_varient_writer);
  645. value_varient_writer.AppendArrayOfBytes(pair.second.data(),
  646. pair.second.size());
  647. entry_writer.CloseContainer(&value_varient_writer);
  648. dict_writer.CloseContainer(&entry_writer);
  649. }
  650. variant_writer.CloseContainer(&dict_writer);
  651. writer->CloseContainer(&variant_writer);
  652. }
  653. template class Property<uint8_t>;
  654. template class Property<bool>;
  655. template class Property<int16_t>;
  656. template class Property<uint16_t>;
  657. template class Property<int32_t>;
  658. template class Property<uint32_t>;
  659. template class Property<int64_t>;
  660. template class Property<uint64_t>;
  661. template class Property<double>;
  662. template class Property<std::string>;
  663. template class Property<ObjectPath>;
  664. template class Property<std::vector<std::string>>;
  665. template class Property<std::vector<ObjectPath>>;
  666. template class Property<std::vector<uint8_t>>;
  667. template class Property<std::map<std::string, std::string>>;
  668. template class Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>;
  669. template class Property<std::map<std::string, std::vector<uint8_t>>>;
  670. template class Property<std::map<uint16_t, std::vector<uint8_t>>>;
  671. } // namespace dbus