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