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 5 #ifndef TOOLS_JSON_SCHEMA_COMPILER_UTIL_H__ 6 #define TOOLS_JSON_SCHEMA_COMPILER_UTIL_H__ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/memory/linked_ptr.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "base/values.h" 14 15 namespace json_schema_compiler { 16 17 namespace util { 18 19 // Creates a new item at |out| from |from|[|index|]. These are used by template 20 // specializations of |Get(Optional)ArrayFromList|. 21 bool GetItemFromList(const base::ListValue& from, int index, int* out); 22 bool GetItemFromList(const base::ListValue& from, int index, bool* out); 23 bool GetItemFromList(const base::ListValue& from, int index, double* out); 24 bool GetItemFromList(const base::ListValue& from, int index, std::string* out); 25 bool GetItemFromList(const base::ListValue& from, 26 int index, 27 linked_ptr<base::Value>* out); 28 bool GetItemFromList(const base::ListValue& from, 29 int index, 30 linked_ptr<base::DictionaryValue>* out); 31 32 // This template is used for types generated by tools/json_schema_compiler. 33 template<class T> 34 bool GetItemFromList(const base::ListValue& from, 35 int index, 36 linked_ptr<T>* out) { 37 const base::DictionaryValue* dict; 38 if (!from.GetDictionary(index, &dict)) 39 return false; 40 scoped_ptr<T> obj(new T()); 41 if (!T::Populate(*dict, obj.get())) 42 return false; 43 *out = linked_ptr<T>(obj.release()); 44 return true; 45 } 46 47 // Populates |out| with |list|. Returns false if there is no list at the 48 // specified key or if the list has anything other than |T|. 49 template <class T> 50 bool PopulateArrayFromList( 51 const base::ListValue& list, std::vector<T>* out) { 52 out->clear(); 53 T value; 54 for (size_t i = 0; i < list.GetSize(); ++i) { 55 if (!GetItemFromList(list, i, &value)) 56 return false; 57 out->push_back(value); 58 } 59 60 return true; 61 } 62 63 // Populates |out| with |from|.|name|. Returns false if there is no list at 64 // the specified key or if the list has anything other than |T|. 65 template <class T> 66 bool PopulateArrayFromDictionary( 67 const base::DictionaryValue& from, 68 const std::string& name, 69 std::vector<T>* out) { 70 const base::ListValue* list = NULL; 71 if (!from.GetListWithoutPathExpansion(name, &list)) 72 return false; 73 74 return PopulateArrayFromList(*list, out); 75 } 76 77 // Creates a new vector containing |list| at |out|. Returns 78 // true on success or if there is nothing at the specified key. Returns false 79 // if anything other than a list of |T| is at the specified key. 80 template <class T> 81 bool PopulateOptionalArrayFromList( 82 const base::ListValue& list, 83 scoped_ptr<std::vector<T> >* out) { 84 out->reset(new std::vector<T>()); 85 T value; 86 for (size_t i = 0; i < list.GetSize(); ++i) { 87 if (!GetItemFromList(list, i, &value)) { 88 out->reset(); 89 return false; 90 } 91 (*out)->push_back(value); 92 } 93 94 return true; 95 } 96 97 // Creates a new vector containing |from|.|name| at |out|. Returns 98 // true on success or if there is nothing at the specified key. Returns false 99 // if anything other than a list of |T| is at the specified key. 100 template <class T> 101 bool PopulateOptionalArrayFromDictionary( 102 const base::DictionaryValue& from, 103 const std::string& name, 104 scoped_ptr<std::vector<T> >* out) { 105 const base::ListValue* list = NULL; 106 { 107 const base::Value* maybe_list = NULL; 108 // Since |name| is optional, its absence is acceptable. However, anything 109 // other than a ListValue is not. 110 if (!from.GetWithoutPathExpansion(name, &maybe_list)) 111 return true; 112 if (!maybe_list->IsType(base::Value::TYPE_LIST)) 113 return false; 114 list = static_cast<const base::ListValue*>(maybe_list); 115 } 116 117 return PopulateOptionalArrayFromList(*list, out); 118 } 119 120 // Appends a Value newly created from |from| to |out|. These used by template 121 // specializations of |Set(Optional)ArrayToList|. 122 void AddItemToList(const int from, base::ListValue* out); 123 void AddItemToList(const bool from, base::ListValue* out); 124 void AddItemToList(const double from, base::ListValue* out); 125 void AddItemToList(const std::string& from, base::ListValue* out); 126 void AddItemToList(const linked_ptr<base::Value>& from, 127 base::ListValue* out); 128 void AddItemToList(const linked_ptr<base::DictionaryValue>& from, 129 base::ListValue* out); 130 131 // This template is used for types generated by tools/json_schema_compiler. 132 template<class T> 133 void AddItemToList(const linked_ptr<T>& from, base::ListValue* out) { 134 out->Append(from->ToValue().release()); 135 } 136 137 // Set |out| to the the contents of |from|. Requires GetItemFromList to be 138 // implemented for |T|. 139 template <class T> 140 void PopulateListFromArray( 141 const std::vector<T>& from, 142 base::ListValue* out) { 143 out->Clear(); 144 for (typename std::vector<T>::const_iterator it = from.begin(); 145 it != from.end(); ++it) { 146 AddItemToList(*it, out); 147 } 148 } 149 150 // Set |out| to the the contents of |from| if |from| is non-NULL. Requires 151 // GetItemFromList to be implemented for |T|. 152 template <class T> 153 void PopulateListFromOptionalArray( 154 const scoped_ptr<std::vector<T> >& from, 155 base::ListValue* out) { 156 if (from.get()) 157 PopulateListFromArray(*from, out); 158 159 } 160 161 template <class T> 162 scoped_ptr<base::Value> CreateValueFromArray(const std::vector<T>& from) { 163 base::ListValue* list = new base::ListValue(); 164 PopulateListFromArray(from, list); 165 return scoped_ptr<base::Value>(list); 166 } 167 168 template <class T> 169 scoped_ptr<base::Value> CreateValueFromOptionalArray( 170 const scoped_ptr<std::vector<T> >& from) { 171 if (from.get()) 172 return CreateValueFromArray(*from); 173 return scoped_ptr<base::Value>(); 174 } 175 176 std::string ValueTypeToString(Value::Type type); 177 178 } // namespace util 179 } // namespace json_schema_compiler 180 181 #endif // TOOLS_JSON_SCHEMA_COMPILER_UTIL_H__ 182