// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef TOOLS_JSON_SCHEMA_COMPILER_UTIL_H__ #define TOOLS_JSON_SCHEMA_COMPILER_UTIL_H__ #include <string> #include <vector> #include "base/memory/linked_ptr.h" #include "base/memory/scoped_ptr.h" #include "base/values.h" namespace json_schema_compiler { namespace util { // Creates a new item at |out| from |from|[|index|]. These are used by template // specializations of |Get(Optional)ArrayFromList|. bool GetItemFromList(const base::ListValue& from, int index, int* out); bool GetItemFromList(const base::ListValue& from, int index, bool* out); bool GetItemFromList(const base::ListValue& from, int index, double* out); bool GetItemFromList(const base::ListValue& from, int index, std::string* out); bool GetItemFromList(const base::ListValue& from, int index, linked_ptr<base::Value>* out); bool GetItemFromList(const base::ListValue& from, int index, linked_ptr<base::DictionaryValue>* out); // This template is used for types generated by tools/json_schema_compiler. template<class T> bool GetItemFromList(const base::ListValue& from, int index, linked_ptr<T>* out) { const base::DictionaryValue* dict; if (!from.GetDictionary(index, &dict)) return false; scoped_ptr<T> obj(new T()); if (!T::Populate(*dict, obj.get())) return false; *out = linked_ptr<T>(obj.release()); return true; } // Populates |out| with |list|. Returns false if there is no list at the // specified key or if the list has anything other than |T|. template <class T> bool PopulateArrayFromList( const base::ListValue& list, std::vector<T>* out) { out->clear(); T value; for (size_t i = 0; i < list.GetSize(); ++i) { if (!GetItemFromList(list, i, &value)) return false; out->push_back(value); } return true; } // Populates |out| with |from|.|name|. Returns false if there is no list at // the specified key or if the list has anything other than |T|. template <class T> bool PopulateArrayFromDictionary( const base::DictionaryValue& from, const std::string& name, std::vector<T>* out) { const base::ListValue* list = NULL; if (!from.GetListWithoutPathExpansion(name, &list)) return false; return PopulateArrayFromList(*list, out); } // Creates a new vector containing |list| at |out|. Returns // true on success or if there is nothing at the specified key. Returns false // if anything other than a list of |T| is at the specified key. template <class T> bool PopulateOptionalArrayFromList( const base::ListValue& list, scoped_ptr<std::vector<T> >* out) { out->reset(new std::vector<T>()); T value; for (size_t i = 0; i < list.GetSize(); ++i) { if (!GetItemFromList(list, i, &value)) { out->reset(); return false; } (*out)->push_back(value); } return true; } // Creates a new vector containing |from|.|name| at |out|. Returns // true on success or if there is nothing at the specified key. Returns false // if anything other than a list of |T| is at the specified key. template <class T> bool PopulateOptionalArrayFromDictionary( const base::DictionaryValue& from, const std::string& name, scoped_ptr<std::vector<T> >* out) { const base::ListValue* list = NULL; { const base::Value* maybe_list = NULL; // Since |name| is optional, its absence is acceptable. However, anything // other than a ListValue is not. if (!from.GetWithoutPathExpansion(name, &maybe_list)) return true; if (!maybe_list->IsType(base::Value::TYPE_LIST)) return false; list = static_cast<const base::ListValue*>(maybe_list); } return PopulateOptionalArrayFromList(*list, out); } // Appends a Value newly created from |from| to |out|. These used by template // specializations of |Set(Optional)ArrayToList|. void AddItemToList(const int from, base::ListValue* out); void AddItemToList(const bool from, base::ListValue* out); void AddItemToList(const double from, base::ListValue* out); void AddItemToList(const std::string& from, base::ListValue* out); void AddItemToList(const linked_ptr<base::Value>& from, base::ListValue* out); void AddItemToList(const linked_ptr<base::DictionaryValue>& from, base::ListValue* out); // This template is used for types generated by tools/json_schema_compiler. template<class T> void AddItemToList(const linked_ptr<T>& from, base::ListValue* out) { out->Append(from->ToValue().release()); } // Set |out| to the the contents of |from|. Requires GetItemFromList to be // implemented for |T|. template <class T> void PopulateListFromArray( const std::vector<T>& from, base::ListValue* out) { out->Clear(); for (typename std::vector<T>::const_iterator it = from.begin(); it != from.end(); ++it) { AddItemToList(*it, out); } } // Set |out| to the the contents of |from| if |from| is non-NULL. Requires // GetItemFromList to be implemented for |T|. template <class T> void PopulateListFromOptionalArray( const scoped_ptr<std::vector<T> >& from, base::ListValue* out) { if (from.get()) PopulateListFromArray(*from, out); } template <class T> scoped_ptr<base::Value> CreateValueFromArray(const std::vector<T>& from) { base::ListValue* list = new base::ListValue(); PopulateListFromArray(from, list); return scoped_ptr<base::Value>(list); } template <class T> scoped_ptr<base::Value> CreateValueFromOptionalArray( const scoped_ptr<std::vector<T> >& from) { if (from.get()) return CreateValueFromArray(*from); return scoped_ptr<base::Value>(); } std::string ValueTypeToString(Value::Type type); } // namespace util } // namespace json_schema_compiler #endif // TOOLS_JSON_SCHEMA_COMPILER_UTIL_H__