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 15namespace json_schema_compiler { 16 17namespace util { 18 19// Creates a new item at |out| from |from|[|index|]. These are used by template 20// specializations of |Get(Optional)ArrayFromList|. 21bool GetItemFromList(const base::ListValue& from, int index, int* out); 22bool GetItemFromList(const base::ListValue& from, int index, bool* out); 23bool GetItemFromList(const base::ListValue& from, int index, double* out); 24bool GetItemFromList(const base::ListValue& from, int index, std::string* out); 25bool GetItemFromList(const base::ListValue& from, 26 int index, 27 linked_ptr<base::Value>* out); 28bool 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. 33template<class T> 34bool 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|. 49template <class T> 50bool 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|. 65template <class T> 66bool 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. 80template <class T> 81bool 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. 100template <class T> 101bool 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|. 122void AddItemToList(const int from, base::ListValue* out); 123void AddItemToList(const bool from, base::ListValue* out); 124void AddItemToList(const double from, base::ListValue* out); 125void AddItemToList(const std::string& from, base::ListValue* out); 126void AddItemToList(const linked_ptr<base::Value>& from, 127 base::ListValue* out); 128void 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. 132template<class T> 133void 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|. 139template <class T> 140void 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|. 152template <class T> 153void PopulateListFromOptionalArray( 154 const scoped_ptr<std::vector<T> >& from, 155 base::ListValue* out) { 156 if (from.get()) 157 PopulateListFromArray(*from, out); 158 159} 160 161template <class T> 162scoped_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 168template <class T> 169scoped_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 176std::string ValueTypeToString(base::Value::Type type); 177 178} // namespace util 179} // namespace json_schema_compiler 180 181#endif // TOOLS_JSON_SCHEMA_COMPILER_UTIL_H__ 182