15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef TOOLS_JSON_SCHEMA_COMPILER_UTIL_H__ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TOOLS_JSON_SCHEMA_COMPILER_UTIL_H__ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/linked_ptr.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace json_schema_compiler { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace util { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates a new item at |out| from |from|[|index|]. These are used by template 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// specializations of |Get(Optional)ArrayFromList|. 21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool GetItemFromList(const base::ListValue& from, int index, int* out); 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool GetItemFromList(const base::ListValue& from, int index, bool* out); 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool GetItemFromList(const base::ListValue& from, int index, double* out); 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool GetItemFromList(const base::ListValue& from, int index, std::string* out); 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool GetItemFromList(const base::ListValue& from, 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int index, 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) linked_ptr<base::Value>* out); 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool GetItemFromList(const base::ListValue& from, 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int index, 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) linked_ptr<base::DictionaryValue>* out); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This template is used for types generated by tools/json_schema_compiler. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<class T> 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool GetItemFromList(const base::ListValue& from, 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int index, 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch linked_ptr<T>* out) { 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const base::DictionaryValue* dict; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!from.GetDictionary(index, &dict)) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<T> obj(new T()); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!T::Populate(*dict, obj.get())) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out = linked_ptr<T>(obj.release()); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Populates |out| with |list|. Returns false if there is no list at the 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// specified key or if the list has anything other than |T|. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T> 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PopulateArrayFromList( 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::ListValue& list, std::vector<T>* out) { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->clear(); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T value; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < list.GetSize(); ++i) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetItemFromList(list, i, &value)) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->push_back(value); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Populates |out| with |from|.|name|. Returns false if there is no list at 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the specified key or if the list has anything other than |T|. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T> 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PopulateArrayFromDictionary( 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::DictionaryValue& from, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& name, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<T>* out) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::ListValue* list = NULL; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!from.GetListWithoutPathExpansion(name, &list)) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PopulateArrayFromList(*list, out); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates a new vector containing |list| at |out|. Returns 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// true on success or if there is nothing at the specified key. Returns false 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if anything other than a list of |T| is at the specified key. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T> 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PopulateOptionalArrayFromList( 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::ListValue& list, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<std::vector<T> >* out) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->reset(new std::vector<T>()); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T value; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < list.GetSize(); ++i) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetItemFromList(list, i, &value)) { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->reset(); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*out)->push_back(value); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates a new vector containing |from|.|name| at |out|. Returns 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// true on success or if there is nothing at the specified key. Returns false 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if anything other than a list of |T| is at the specified key. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T> 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PopulateOptionalArrayFromDictionary( 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::DictionaryValue& from, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& name, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<std::vector<T> >* out) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::ListValue* list = NULL; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Value* maybe_list = NULL; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since |name| is optional, its absence is acceptable. However, anything 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // other than a ListValue is not. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!from.GetWithoutPathExpansion(name, &maybe_list)) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!maybe_list->IsType(base::Value::TYPE_LIST)) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = static_cast<const base::ListValue*>(maybe_list); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PopulateOptionalArrayFromList(*list, out); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Appends a Value newly created from |from| to |out|. These used by template 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// specializations of |Set(Optional)ArrayToList|. 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddItemToList(const int from, base::ListValue* out); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddItemToList(const bool from, base::ListValue* out); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddItemToList(const double from, base::ListValue* out); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddItemToList(const std::string& from, base::ListValue* out); 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AddItemToList(const linked_ptr<base::Value>& from, 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* out); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddItemToList(const linked_ptr<base::DictionaryValue>& from, 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* out); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This template is used for types generated by tools/json_schema_compiler. 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<class T> 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid AddItemToList(const linked_ptr<T>& from, base::ListValue* out) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->Append(from->ToValue().release()); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Set |out| to the the contents of |from|. Requires GetItemFromList to be 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implemented for |T|. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T> 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PopulateListFromArray( 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<T>& from, 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ListValue* out) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->Clear(); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (typename std::vector<T>::const_iterator it = from.begin(); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != from.end(); ++it) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddItemToList(*it, out); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Set |out| to the the contents of |from| if |from| is non-NULL. Requires 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GetItemFromList to be implemented for |T|. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T> 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PopulateListFromOptionalArray( 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_ptr<std::vector<T> >& from, 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ListValue* out) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (from.get()) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PopulateListFromArray(*from, out); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T> 162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochscoped_ptr<base::Value> CreateValueFromArray(const std::vector<T>& from) { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ListValue* list = new base::ListValue(); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PopulateListFromArray(from, list); 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return scoped_ptr<base::Value>(list); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T> 169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochscoped_ptr<base::Value> CreateValueFromOptionalArray( 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_ptr<std::vector<T> >& from) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (from.get()) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CreateValueFromArray(*from); 173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return scoped_ptr<base::Value>(); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string ValueTypeToString(base::Value::Type type); 177c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace util 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace json_schema_compiler 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // TOOLS_JSON_SCHEMA_COMPILER_UTIL_H__ 182