1 // Copyright 2014 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 #ifndef COMPONENTS_CLOUD_DEVICES_COMMON_DESCRIPTION_DESCRIPTION_ITEMS_INL_H_
6 #define COMPONENTS_CLOUD_DEVICES_COMMON_DESCRIPTION_DESCRIPTION_ITEMS_INL_H_
7
8 #include <vector>
9
10 #include "base/numerics/safe_conversions.h"
11 #include "components/cloud_devices/common/description_items.h"
12
13 // Implementation of templates defined in header file.
14 // This file should be included from CC file with implementation of device
15 // specific capabilities.
16
17 namespace cloud_devices {
18
19 template <class Option, class Traits>
ListCapability()20 ListCapability<Option, Traits>::ListCapability() {
21 Reset();
22 }
23
24 template <class Option, class Traits>
~ListCapability()25 ListCapability<Option, Traits>::~ListCapability() {
26 }
27
28 template <class Option, class Traits>
IsValid()29 bool ListCapability<Option, Traits>::IsValid() const {
30 if (empty())
31 return false; // This type of capabilities can't be empty.
32 for (size_t i = 0; i < options_.size(); ++i) {
33 if (!Traits::IsValid(options_[i]))
34 return false;
35 }
36 return true;
37 }
38
39 template <class Option, class Traits>
LoadFrom(const CloudDeviceDescription & description)40 bool ListCapability<Option, Traits>::LoadFrom(
41 const CloudDeviceDescription& description) {
42 Reset();
43 const base::ListValue* options =
44 description.GetListItem(Traits::GetCapabilityPath());
45 if (!options)
46 return false;
47 for (size_t i = 0; i < options->GetSize(); ++i) {
48 const base::DictionaryValue* option_value = NULL;
49 if (!options->GetDictionary(i, &option_value))
50 return false; // Every entry must be a dictionary.
51 Option option;
52 if (!Traits::Load(*option_value, &option))
53 return false;
54 AddOption(option);
55 }
56 return IsValid();
57 }
58
59 template <class Option, class Traits>
SaveTo(CloudDeviceDescription * description)60 void ListCapability<Option, Traits>::SaveTo(
61 CloudDeviceDescription* description) const {
62 DCHECK(IsValid());
63 base::ListValue* options_list =
64 description->CreateListItem(Traits::GetCapabilityPath());
65 for (size_t i = 0; i < options_.size(); ++i) {
66 base::DictionaryValue* option_value = new base::DictionaryValue;
67 options_list->Append(option_value);
68 Traits::Save(options_[i], option_value);
69 }
70 }
71
72 template <class Option, class Traits>
SelectionCapability()73 SelectionCapability<Option, Traits>::SelectionCapability() {
74 Reset();
75 }
76
77 template <class Option, class Traits>
~SelectionCapability()78 SelectionCapability<Option, Traits>::~SelectionCapability() {
79 }
80
81 template <class Option, class Traits>
IsValid()82 bool SelectionCapability<Option, Traits>::IsValid() const {
83 if (empty())
84 return false; // This type of capabilities can't be empty
85 for (size_t i = 0; i < options_.size(); ++i) {
86 if (!Traits::IsValid(options_[i]))
87 return false;
88 }
89 return default_idx_ >= 0 && default_idx_ < base::checked_cast<int>(size());
90 }
91
92 template <class Option, class Traits>
LoadFrom(const CloudDeviceDescription & description)93 bool SelectionCapability<Option, Traits>::LoadFrom(
94 const CloudDeviceDescription& description) {
95 Reset();
96 const base::DictionaryValue* item =
97 description.GetItem(Traits::GetCapabilityPath());
98 if (!item)
99 return false;
100 const base::ListValue* options = NULL;
101 if (!item->GetList(json::kKeyOption, &options))
102 return false;
103 for (size_t i = 0; i < options->GetSize(); ++i) {
104 const base::DictionaryValue* option_value = NULL;
105 if (!options->GetDictionary(i, &option_value))
106 return false; // Every entry must be a dictionary.
107 Option option;
108 if (!Traits::Load(*option_value, &option))
109 return false;
110 bool is_default = false;
111 option_value->GetBoolean(json::kKeyIsDefault, &is_default);
112 if (is_default && default_idx_ >= 0) {
113 return false; // Multiple defaults.
114 }
115 AddDefaultOption(option, is_default);
116 }
117 return IsValid();
118 }
119
120 template <class Option, class Traits>
SaveTo(CloudDeviceDescription * description)121 void SelectionCapability<Option, Traits>::SaveTo(
122 CloudDeviceDescription* description) const {
123 DCHECK(IsValid());
124 base::ListValue* options_list = new base::ListValue;
125 description->CreateItem(Traits::GetCapabilityPath())
126 ->Set(json::kKeyOption, options_list);
127 for (size_t i = 0; i < options_.size(); ++i) {
128 base::DictionaryValue* option_value = new base::DictionaryValue;
129 options_list->Append(option_value);
130 if (base::checked_cast<int>(i) == default_idx_)
131 option_value->SetBoolean(json::kKeyIsDefault, true);
132 Traits::Save(options_[i], option_value);
133 }
134 }
135
136 template <class Traits>
BooleanCapability()137 BooleanCapability<Traits>::BooleanCapability() {
138 Reset();
139 }
140
141 template <class Traits>
~BooleanCapability()142 BooleanCapability<Traits>::~BooleanCapability() {
143 }
144
145 template <class Traits>
LoadFrom(const CloudDeviceDescription & description)146 bool BooleanCapability<Traits>::LoadFrom(
147 const CloudDeviceDescription& description) {
148 Reset();
149 const base::DictionaryValue* dict =
150 description.GetItem(Traits::GetCapabilityPath());
151 if (!dict)
152 return false;
153 default_value_ = Traits::kDefault;
154 dict->GetBoolean(json::kKeyDefault, &default_value_);
155 return true;
156 }
157
158 template <class Traits>
SaveTo(CloudDeviceDescription * description)159 void BooleanCapability<Traits>::SaveTo(
160 CloudDeviceDescription* description) const {
161 base::DictionaryValue* dict =
162 description->CreateItem(Traits::GetCapabilityPath());
163 if (default_value_ != Traits::kDefault)
164 dict->SetBoolean(json::kKeyDefault, default_value_);
165 }
166
167 template <class Traits>
LoadFrom(const CloudDeviceDescription & description)168 bool EmptyCapability<Traits>::LoadFrom(
169 const CloudDeviceDescription& description) {
170 return description.GetItem(Traits::GetCapabilityPath()) != NULL;
171 }
172
173 template <class Traits>
SaveTo(CloudDeviceDescription * description)174 void EmptyCapability<Traits>::SaveTo(
175 CloudDeviceDescription* description) const {
176 description->CreateItem(Traits::GetCapabilityPath());
177 }
178
179 template <class Option, class Traits>
ValueCapability()180 ValueCapability<Option, Traits>::ValueCapability() {
181 Reset();
182 }
183
184 template <class Option, class Traits>
~ValueCapability()185 ValueCapability<Option, Traits>::~ValueCapability() {
186 }
187
188 template <class Option, class Traits>
IsValid()189 bool ValueCapability<Option, Traits>::IsValid() const {
190 return Traits::IsValid(value());
191 }
192
193 template <class Option, class Traits>
LoadFrom(const CloudDeviceDescription & description)194 bool ValueCapability<Option, Traits>::LoadFrom(
195 const CloudDeviceDescription& description) {
196 Reset();
197 const base::DictionaryValue* option_value =
198 description.GetItem(Traits::GetCapabilityPath());
199 if (!option_value)
200 return false;
201 Option option;
202 if (!Traits::Load(*option_value, &option))
203 return false;
204 set_value(option);
205 return IsValid();
206 }
207
208 template <class Option, class Traits>
SaveTo(CloudDeviceDescription * description)209 void ValueCapability<Option, Traits>::SaveTo(
210 CloudDeviceDescription* description) const {
211 DCHECK(IsValid());
212 Traits::Save(value(), description->CreateItem(Traits::GetCapabilityPath()));
213 }
214
215 template <class Option, class Traits>
TicketItem()216 TicketItem<Option, Traits>::TicketItem() {
217 Reset();
218 }
219
220 template <class Option, class Traits>
~TicketItem()221 TicketItem<Option, Traits>::~TicketItem() {
222 }
223
224 template <class Option, class Traits>
IsValid()225 bool TicketItem<Option, Traits>::IsValid() const {
226 return Traits::IsValid(value());
227 }
228
229 template <class Option, class Traits>
LoadFrom(const CloudDeviceDescription & description)230 bool TicketItem<Option, Traits>::LoadFrom(
231 const CloudDeviceDescription& description) {
232 Reset();
233 const base::DictionaryValue* option_value =
234 description.GetItem(Traits::GetTicketItemPath());
235 if (!option_value)
236 return false;
237 Option option;
238 if (!Traits::Load(*option_value, &option))
239 return false;
240 set_value(option);
241 return IsValid();
242 }
243
244 template <class Option, class Traits>
SaveTo(CloudDeviceDescription * description)245 void TicketItem<Option, Traits>::SaveTo(
246 CloudDeviceDescription* description) const {
247 DCHECK(IsValid());
248 Traits::Save(value(), description->CreateItem(Traits::GetTicketItemPath()));
249 }
250
251 } // namespace cloud_devices
252
253 #endif // COMPONENTS_CLOUD_DEVICES_COMMON_DESCRIPTION_DESCRIPTION_ITEMS_INL_H_
254