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 17namespace cloud_devices { 18 19template <class Option, class Traits> 20ListCapability<Option, Traits>::ListCapability() { 21 Reset(); 22} 23 24template <class Option, class Traits> 25ListCapability<Option, Traits>::~ListCapability() { 26} 27 28template <class Option, class Traits> 29bool 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 39template <class Option, class Traits> 40bool 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 59template <class Option, class Traits> 60void 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 72template <class Option, class Traits> 73SelectionCapability<Option, Traits>::SelectionCapability() { 74 Reset(); 75} 76 77template <class Option, class Traits> 78SelectionCapability<Option, Traits>::~SelectionCapability() { 79} 80 81template <class Option, class Traits> 82bool 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 92template <class Option, class Traits> 93bool 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 120template <class Option, class Traits> 121void 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 136template <class Traits> 137BooleanCapability<Traits>::BooleanCapability() { 138 Reset(); 139} 140 141template <class Traits> 142BooleanCapability<Traits>::~BooleanCapability() { 143} 144 145template <class Traits> 146bool 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 158template <class Traits> 159void 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 167template <class Traits> 168bool EmptyCapability<Traits>::LoadFrom( 169 const CloudDeviceDescription& description) { 170 return description.GetItem(Traits::GetCapabilityPath()) != NULL; 171} 172 173template <class Traits> 174void EmptyCapability<Traits>::SaveTo( 175 CloudDeviceDescription* description) const { 176 description->CreateItem(Traits::GetCapabilityPath()); 177} 178 179template <class Option, class Traits> 180ValueCapability<Option, Traits>::ValueCapability() { 181 Reset(); 182} 183 184template <class Option, class Traits> 185ValueCapability<Option, Traits>::~ValueCapability() { 186} 187 188template <class Option, class Traits> 189bool ValueCapability<Option, Traits>::IsValid() const { 190 return Traits::IsValid(value()); 191} 192 193template <class Option, class Traits> 194bool 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 208template <class Option, class Traits> 209void ValueCapability<Option, Traits>::SaveTo( 210 CloudDeviceDescription* description) const { 211 DCHECK(IsValid()); 212 Traits::Save(value(), description->CreateItem(Traits::GetCapabilityPath())); 213} 214 215template <class Option, class Traits> 216TicketItem<Option, Traits>::TicketItem() { 217 Reset(); 218} 219 220template <class Option, class Traits> 221TicketItem<Option, Traits>::~TicketItem() { 222} 223 224template <class Option, class Traits> 225bool TicketItem<Option, Traits>::IsValid() const { 226 return Traits::IsValid(value()); 227} 228 229template <class Option, class Traits> 230bool 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 244template <class Option, class Traits> 245void 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