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 BASE_JSON_JSON_VALUE_CONVERTER_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_JSON_JSON_VALUE_CONVERTER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_vector.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_piece.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// JSONValueConverter converts a JSON value into a C++ struct in a
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// lightweight way.
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Usage:
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For real examples, you may want to refer to _unittest.cc file.
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Assume that you have a struct like this:
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   struct Message {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     int foo;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     std::string bar;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     static void RegisterJSONConverter(
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//         JSONValueConverter<Message>* converter);
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   };
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// And you want to parse a json data into this struct.  First, you
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// need to declare RegisterJSONConverter() method in your struct.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   // static
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   void Message::RegisterJSONConverter(
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       JSONValueConverter<Message>* converter) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     converter->RegisterIntField("foo", &Message::foo);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     converter->RegisterStringField("bar", &Message::bar);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Then, you just instantiate your JSONValueConverter of your type and call
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Convert() method.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   Message message;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   JSONValueConverter<Message> converter;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   converter.Convert(json, &message);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Convert() returns false when it fails.  Here "fail" means that the value is
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// structurally different from expected, such like a string value appears
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for an int field.  Do not report failures for missing fields.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Also note that Convert() will modify the passed |message| even when it
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// fails for performance reason.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For nested field, the internal message also has to implement the registration
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// method.  Then, just use RegisterNestedField() from the containing struct's
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RegisterJSONConverter method.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   struct Nested {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     Message foo;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     static void RegisterJSONConverter(...) {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       ...
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       converter->RegisterNestedField("foo", &Nested::foo);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     }
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   };
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For repeated field, we just assume ScopedVector for its container
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and you can put RegisterRepeatedInt or some other types.  Use
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RegisterRepeatedMessage for nested repeated fields.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sometimes JSON format uses string representations for other types such
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// like enum, timestamp, or URL.  You can use RegisterCustomField method
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and specify a function to convert a StringPiece to your type.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   bool ConvertFunc(const StringPiece& s, YourEnum* result) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     // do something and return true if succeed...
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   struct Message {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     YourEnum ye;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     ...
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     static void RegisterJSONConverter(...) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       ...
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       converter->RegsiterCustomField<YourEnum>(
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//           "your_enum", &Message::ye, &ConvertFunc);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   };
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename StructType>
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class JSONValueConverter;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename StructType>
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FieldConverterBase {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit FieldConverterBase(const std::string& path) : field_path_(path) {}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~FieldConverterBase() {}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool ConvertField(const base::Value& value, StructType* obj)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const = 0;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string& field_path() const { return field_path_; }
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string field_path_;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FieldConverterBase);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename FieldType>
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ValueConverter {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ValueConverter() {}
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Convert(const base::Value& value, FieldType* field) const = 0;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename StructType, typename FieldType>
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FieldConverter : public FieldConverterBase<StructType> {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit FieldConverter(const std::string& path,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          FieldType StructType::* field,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          ValueConverter<FieldType>* converter)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : FieldConverterBase<StructType>(path),
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        field_pointer_(field),
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        value_converter_(converter) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool ConvertField(
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::Value& value, StructType* dst) const OVERRIDE {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return value_converter_->Convert(value, &(dst->*field_pointer_));
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FieldType StructType::* field_pointer_;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ValueConverter<FieldType> > value_converter_;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FieldConverter);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename FieldType>
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BasicValueConverter;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BasicValueConverter<int> : public ValueConverter<int> {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BasicValueConverter() {}
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Convert(const base::Value& value, int* field) const OVERRIDE {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return value.GetAsInteger(field);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BasicValueConverter<std::string> : public ValueConverter<std::string> {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BasicValueConverter() {}
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Convert(
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::Value& value, std::string* field) const OVERRIDE {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return value.GetAsString(field);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BasicValueConverter<string16> : public ValueConverter<string16> {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BasicValueConverter() {}
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Convert(
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::Value& value, string16* field) const OVERRIDE {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return value.GetAsString(field);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BasicValueConverter<double> : public ValueConverter<double> {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BasicValueConverter() {}
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Convert(const base::Value& value, double* field) const OVERRIDE {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return value.GetAsDouble(field);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BasicValueConverter<bool> : public ValueConverter<bool> {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BasicValueConverter() {}
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Convert(const base::Value& value, bool* field) const OVERRIDE {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return value.GetAsBoolean(field);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename FieldType>
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ValueFieldConverter : public ValueConverter<FieldType> {
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef bool(*ConvertFunc)(const base::Value* value, FieldType* field);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ValueFieldConverter(ConvertFunc convert_func)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : convert_func_(convert_func) {}
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Convert(const base::Value& value,
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FieldType* field) const OVERRIDE {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return convert_func_(&value, field);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConvertFunc convert_func_;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ValueFieldConverter);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename FieldType>
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CustomFieldConverter : public ValueConverter<FieldType> {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef bool(*ConvertFunc)(const StringPiece& value, FieldType* field);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CustomFieldConverter(ConvertFunc convert_func)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : convert_func_(convert_func) {}
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Convert(const base::Value& value,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FieldType* field) const OVERRIDE {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string string_value;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return value.GetAsString(&string_value) &&
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        convert_func_(string_value, field);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConvertFunc convert_func_;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CustomFieldConverter);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename NestedType>
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NestedValueConverter : public ValueConverter<NestedType> {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NestedValueConverter() {}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Convert(
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::Value& value, NestedType* field) const OVERRIDE {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return converter_.Convert(value, field);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  JSONValueConverter<NestedType> converter_;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NestedValueConverter);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Element>
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RepeatedValueConverter : public ValueConverter<ScopedVector<Element> > {
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RepeatedValueConverter() {}
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Convert(
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::Value& value, ScopedVector<Element>* field) const OVERRIDE {
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::ListValue* list = NULL;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!value.GetAsList(&list)) {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The field is not a list.
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    field->reserve(list->GetSize());
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < list->GetSize(); ++i) {
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::Value* element = NULL;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!list->Get(i, &element))
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_ptr<Element> e(new Element);
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (basic_converter_.Convert(*element, e.get())) {
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        field->push_back(e.release());
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DVLOG(1) << "failure at " << i << "-th element";
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BasicValueConverter<Element> basic_converter_;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RepeatedValueConverter);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename NestedType>
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RepeatedMessageConverter
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public ValueConverter<ScopedVector<NestedType> > {
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RepeatedMessageConverter() {}
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Convert(const base::Value& value,
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       ScopedVector<NestedType>* field) const OVERRIDE {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::ListValue* list = NULL;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!value.GetAsList(&list))
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    field->reserve(list->GetSize());
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < list->GetSize(); ++i) {
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::Value* element = NULL;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!list->Get(i, &element))
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_ptr<NestedType> nested(new NestedType);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (converter_.Convert(*element, nested.get())) {
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        field->push_back(nested.release());
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DVLOG(1) << "failure at " << i << "-th element";
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  JSONValueConverter<NestedType> converter_;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RepeatedMessageConverter);
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename NestedType>
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RepeatedCustomValueConverter
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public ValueConverter<ScopedVector<NestedType> > {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef bool(*ConvertFunc)(const base::Value* value, NestedType* field);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RepeatedCustomValueConverter(ConvertFunc convert_func)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : convert_func_(convert_func) {}
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Convert(const base::Value& value,
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       ScopedVector<NestedType>* field) const OVERRIDE {
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::ListValue* list = NULL;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!value.GetAsList(&list))
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    field->reserve(list->GetSize());
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < list->GetSize(); ++i) {
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::Value* element = NULL;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!list->Get(i, &element))
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_ptr<NestedType> nested(new NestedType);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if ((*convert_func_)(element, nested.get())) {
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        field->push_back(nested.release());
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DVLOG(1) << "failure at " << i << "-th element";
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConvertFunc convert_func_;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RepeatedCustomValueConverter);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class StructType>
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class JSONValueConverter {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  JSONValueConverter() {
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StructType::RegisterJSONConverter(this);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RegisterIntField(const std::string& field_name,
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        int StructType::* field) {
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fields_.push_back(new internal::FieldConverter<StructType, int>(
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        field_name, field, new internal::BasicValueConverter<int>));
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RegisterStringField(const std::string& field_name,
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           std::string StructType::* field) {
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fields_.push_back(new internal::FieldConverter<StructType, std::string>(
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        field_name, field, new internal::BasicValueConverter<std::string>));
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RegisterStringField(const std::string& field_name,
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           string16 StructType::* field) {
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fields_.push_back(new internal::FieldConverter<StructType, string16>(
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        field_name, field, new internal::BasicValueConverter<string16>));
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RegisterBoolField(const std::string& field_name,
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         bool StructType::* field) {
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fields_.push_back(new internal::FieldConverter<StructType, bool>(
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        field_name, field, new internal::BasicValueConverter<bool>));
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RegisterDoubleField(const std::string& field_name,
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           double StructType::* field) {
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fields_.push_back(new internal::FieldConverter<StructType, double>(
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        field_name, field, new internal::BasicValueConverter<double>));
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <class NestedType>
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RegisterNestedField(
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& field_name, NestedType StructType::* field) {
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fields_.push_back(new internal::FieldConverter<StructType, NestedType>(
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            field_name,
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            field,
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            new internal::NestedValueConverter<NestedType>));
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <typename FieldType>
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RegisterCustomField(
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& field_name,
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FieldType StructType::* field,
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool (*convert_func)(const StringPiece&, FieldType*)) {
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fields_.push_back(new internal::FieldConverter<StructType, FieldType>(
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        field_name,
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        field,
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new internal::CustomFieldConverter<FieldType>(convert_func)));
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <typename FieldType>
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RegisterCustomValueField(
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& field_name,
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FieldType StructType::* field,
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool (*convert_func)(const base::Value*, FieldType*)) {
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fields_.push_back(new internal::FieldConverter<StructType, FieldType>(
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        field_name,
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        field,
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new internal::ValueFieldConverter<FieldType>(convert_func)));
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RegisterRepeatedInt(const std::string& field_name,
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           ScopedVector<int> StructType::* field) {
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fields_.push_back(
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new internal::FieldConverter<StructType, ScopedVector<int> >(
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            field_name, field, new internal::RepeatedValueConverter<int>));
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RegisterRepeatedString(const std::string& field_name,
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              ScopedVector<std::string> StructType::* field) {
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fields_.push_back(
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new internal::FieldConverter<StructType, ScopedVector<std::string> >(
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            field_name,
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            field,
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            new internal::RepeatedValueConverter<std::string>));
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RegisterRepeatedString(const std::string& field_name,
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              ScopedVector<string16> StructType::* field) {
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fields_.push_back(
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new internal::FieldConverter<StructType, ScopedVector<string16> >(
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            field_name,
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            field,
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            new internal::RepeatedValueConverter<string16>));
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RegisterRepeatedDouble(const std::string& field_name,
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              ScopedVector<double> StructType::* field) {
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fields_.push_back(
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new internal::FieldConverter<StructType, ScopedVector<double> >(
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            field_name, field, new internal::RepeatedValueConverter<double>));
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RegisterRepeatedBool(const std::string& field_name,
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            ScopedVector<bool> StructType::* field) {
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fields_.push_back(
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new internal::FieldConverter<StructType, ScopedVector<bool> >(
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            field_name, field, new internal::RepeatedValueConverter<bool>));
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <class NestedType>
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RegisterRepeatedCustomValue(
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& field_name,
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ScopedVector<NestedType> StructType::* field,
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool (*convert_func)(const base::Value*, NestedType*)) {
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fields_.push_back(
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new internal::FieldConverter<StructType, ScopedVector<NestedType> >(
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            field_name,
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            field,
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            new internal::RepeatedCustomValueConverter<NestedType>(
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                convert_func)));
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <class NestedType>
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RegisterRepeatedMessage(const std::string& field_name,
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               ScopedVector<NestedType> StructType::* field) {
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fields_.push_back(
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new internal::FieldConverter<StructType, ScopedVector<NestedType> >(
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            field_name,
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            field,
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            new internal::RepeatedMessageConverter<NestedType>));
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Convert(const base::Value& value, StructType* output) const {
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const DictionaryValue* dictionary_value = NULL;
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!value.GetAsDictionary(&dictionary_value))
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for(size_t i = 0; i < fields_.size(); ++i) {
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const internal::FieldConverterBase<StructType>* field_converter =
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          fields_[i];
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::Value* field = NULL;
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (dictionary_value->Get(field_converter->field_path(), &field)) {
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!field_converter->ConvertField(*field, output)) {
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          DVLOG(1) << "failure at field " << field_converter->field_path();
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return false;
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedVector<internal::FieldConverterBase<StructType> > fields_;
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(JSONValueConverter);
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // BASE_JSON_JSON_VALUE_CONVERTER_H_
528