Home | History | Annotate | Download | only in json_schema_compiler
      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(base::Value::Type type);
    177 
    178 }  // namespace util
    179 }  // namespace json_schema_compiler
    180 
    181 #endif // TOOLS_JSON_SCHEMA_COMPILER_UTIL_H__
    182