10d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// Copyright (c) 2012 The Chromium Authors. All rights reserved.
20d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// Use of this source code is governed by a BSD-style license that can be
30d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// found in the LICENSE file.
40d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
50d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#ifndef BASE_JSON_JSON_VALUE_CONVERTER_H_
60d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#define BASE_JSON_JSON_VALUE_CONVERTER_H_
70d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
80d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include <stddef.h>
90d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1094ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez#include <memory>
110d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include <string>
120d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include <vector>
130d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
140d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "base/base_export.h"
150d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "base/logging.h"
160d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "base/macros.h"
170d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "base/memory/scoped_vector.h"
180d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "base/stl_util.h"
190d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "base/strings/string16.h"
200d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "base/strings/string_piece.h"
210d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "base/values.h"
220d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
230d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// JSONValueConverter converts a JSON value into a C++ struct in a
240d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// lightweight way.
250d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//
260d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// Usage:
270d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// For real examples, you may want to refer to _unittest.cc file.
280d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//
290d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// Assume that you have a struct like this:
300d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//   struct Message {
310d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//     int foo;
320d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//     std::string bar;
330d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//     static void RegisterJSONConverter(
340d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//         JSONValueConverter<Message>* converter);
350d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//   };
360d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//
370d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// And you want to parse a json data into this struct.  First, you
380d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// need to declare RegisterJSONConverter() method in your struct.
390d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//   // static
400d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//   void Message::RegisterJSONConverter(
410d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//       JSONValueConverter<Message>* converter) {
420d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//     converter->RegisterIntField("foo", &Message::foo);
430d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//     converter->RegisterStringField("bar", &Message::bar);
440d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//   }
450d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//
460d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// Then, you just instantiate your JSONValueConverter of your type and call
470d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// Convert() method.
480d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//   Message message;
490d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//   JSONValueConverter<Message> converter;
500d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//   converter.Convert(json, &message);
510d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//
520d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// Convert() returns false when it fails.  Here "fail" means that the value is
530d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// structurally different from expected, such like a string value appears
540d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// for an int field.  Do not report failures for missing fields.
550d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// Also note that Convert() will modify the passed |message| even when it
560d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// fails for performance reason.
570d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//
580d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// For nested field, the internal message also has to implement the registration
590d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// method.  Then, just use RegisterNestedField() from the containing struct's
600d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// RegisterJSONConverter method.
610d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//   struct Nested {
620d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//     Message foo;
630d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//     static void RegisterJSONConverter(...) {
640d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//       ...
650d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//       converter->RegisterNestedField("foo", &Nested::foo);
660d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//     }
670d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//   };
680d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//
690d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// For repeated field, we just assume ScopedVector for its container
700d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// and you can put RegisterRepeatedInt or some other types.  Use
710d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// RegisterRepeatedMessage for nested repeated fields.
720d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//
730d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// Sometimes JSON format uses string representations for other types such
740d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// like enum, timestamp, or URL.  You can use RegisterCustomField method
750d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// and specify a function to convert a StringPiece to your type.
760d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//   bool ConvertFunc(const StringPiece& s, YourEnum* result) {
770d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//     // do something and return true if succeed...
780d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//   }
790d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//   struct Message {
800d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//     YourEnum ye;
810d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//     ...
820d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//     static void RegisterJSONConverter(...) {
830d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//       ...
840d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//       converter->RegsiterCustomField<YourEnum>(
850d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//           "your_enum", &Message::ye, &ConvertFunc);
860d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//     }
870d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko//   };
880d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
890d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkonamespace base {
900d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
910d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkotemplate <typename StructType>
920d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoclass JSONValueConverter;
930d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
940d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkonamespace internal {
950d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
960d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkotemplate<typename StructType>
970d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoclass FieldConverterBase {
980d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko public:
990d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  explicit FieldConverterBase(const std::string& path) : field_path_(path) {}
1000d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  virtual ~FieldConverterBase() {}
1010d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  virtual bool ConvertField(const base::Value& value, StructType* obj)
1020d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const = 0;
1030d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  const std::string& field_path() const { return field_path_; }
1040d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1050d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko private:
1060d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  std::string field_path_;
1070d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(FieldConverterBase);
1080d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko};
1090d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1100d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkotemplate <typename FieldType>
1110d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoclass ValueConverter {
1120d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko public:
1130d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  virtual ~ValueConverter() {}
1140d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  virtual bool Convert(const base::Value& value, FieldType* field) const = 0;
1150d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko};
1160d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1170d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkotemplate <typename StructType, typename FieldType>
1180d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoclass FieldConverter : public FieldConverterBase<StructType> {
1190d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko public:
1200d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  explicit FieldConverter(const std::string& path,
1210d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                          FieldType StructType::* field,
1220d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                          ValueConverter<FieldType>* converter)
1230d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      : FieldConverterBase<StructType>(path),
1240d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        field_pointer_(field),
1250d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        value_converter_(converter) {
1260d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
1270d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1280d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  bool ConvertField(const base::Value& value, StructType* dst) const override {
1290d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    return value_converter_->Convert(value, &(dst->*field_pointer_));
1300d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
1310d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1320d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko private:
1330d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  FieldType StructType::* field_pointer_;
13494ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  std::unique_ptr<ValueConverter<FieldType>> value_converter_;
1350d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(FieldConverter);
1360d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko};
1370d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1380d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkotemplate <typename FieldType>
1390d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoclass BasicValueConverter;
1400d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1410d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkotemplate <>
1420d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoclass BASE_EXPORT BasicValueConverter<int> : public ValueConverter<int> {
1430d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko public:
1440d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  BasicValueConverter() {}
1450d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1460d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  bool Convert(const base::Value& value, int* field) const override;
1470d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1480d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko private:
1490d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
1500d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko};
1510d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1520d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkotemplate <>
1530d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoclass BASE_EXPORT BasicValueConverter<std::string>
1540d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    : public ValueConverter<std::string> {
1550d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko public:
1560d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  BasicValueConverter() {}
1570d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1580d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  bool Convert(const base::Value& value, std::string* field) const override;
1590d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1600d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko private:
1610d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
1620d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko};
1630d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1640d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkotemplate <>
1650d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoclass BASE_EXPORT BasicValueConverter<string16>
1660d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    : public ValueConverter<string16> {
1670d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko public:
1680d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  BasicValueConverter() {}
1690d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1700d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  bool Convert(const base::Value& value, string16* field) const override;
1710d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1720d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko private:
1730d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
1740d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko};
1750d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1760d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkotemplate <>
1770d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoclass BASE_EXPORT BasicValueConverter<double> : public ValueConverter<double> {
1780d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko public:
1790d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  BasicValueConverter() {}
1800d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1810d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  bool Convert(const base::Value& value, double* field) const override;
1820d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1830d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko private:
1840d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
1850d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko};
1860d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1870d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkotemplate <>
1880d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoclass BASE_EXPORT BasicValueConverter<bool> : public ValueConverter<bool> {
1890d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko public:
1900d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  BasicValueConverter() {}
1910d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1920d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  bool Convert(const base::Value& value, bool* field) const override;
1930d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1940d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko private:
1950d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
1960d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko};
1970d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
1980d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkotemplate <typename FieldType>
1990d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoclass ValueFieldConverter : public ValueConverter<FieldType> {
2000d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko public:
2010d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  typedef bool(*ConvertFunc)(const base::Value* value, FieldType* field);
2020d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2030d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  ValueFieldConverter(ConvertFunc convert_func)
2040d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      : convert_func_(convert_func) {}
2050d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2060d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  bool Convert(const base::Value& value, FieldType* field) const override {
2070d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    return convert_func_(&value, field);
2080d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
2090d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2100d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko private:
2110d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  ConvertFunc convert_func_;
2120d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2130d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(ValueFieldConverter);
2140d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko};
2150d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2160d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkotemplate <typename FieldType>
2170d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoclass CustomFieldConverter : public ValueConverter<FieldType> {
2180d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko public:
2190d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  typedef bool(*ConvertFunc)(const StringPiece& value, FieldType* field);
2200d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2210d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  CustomFieldConverter(ConvertFunc convert_func)
2220d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      : convert_func_(convert_func) {}
2230d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2240d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  bool Convert(const base::Value& value, FieldType* field) const override {
2250d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    std::string string_value;
2260d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    return value.GetAsString(&string_value) &&
2270d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        convert_func_(string_value, field);
2280d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
2290d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2300d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko private:
2310d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  ConvertFunc convert_func_;
2320d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2330d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(CustomFieldConverter);
2340d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko};
2350d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2360d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkotemplate <typename NestedType>
2370d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoclass NestedValueConverter : public ValueConverter<NestedType> {
2380d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko public:
2390d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  NestedValueConverter() {}
2400d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2410d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  bool Convert(const base::Value& value, NestedType* field) const override {
2420d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    return converter_.Convert(value, field);
2430d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
2440d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2450d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko private:
2460d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  JSONValueConverter<NestedType> converter_;
2470d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(NestedValueConverter);
2480d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko};
2490d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2500d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkotemplate <typename Element>
2510d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoclass RepeatedValueConverter : public ValueConverter<ScopedVector<Element> > {
2520d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko public:
2530d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  RepeatedValueConverter() {}
2540d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2550d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  bool Convert(const base::Value& value,
2560d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko               ScopedVector<Element>* field) const override {
2570d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    const base::ListValue* list = NULL;
2580d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    if (!value.GetAsList(&list)) {
2590d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      // The field is not a list.
2600d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      return false;
2610d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    }
2620d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2630d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    field->reserve(list->GetSize());
2640d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    for (size_t i = 0; i < list->GetSize(); ++i) {
2650d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const base::Value* element = NULL;
2660d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      if (!list->Get(i, &element))
2670d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        continue;
2680d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
26994ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez      std::unique_ptr<Element> e(new Element);
2700d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      if (basic_converter_.Convert(*element, e.get())) {
2710d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        field->push_back(e.release());
2720d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      } else {
2730d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        DVLOG(1) << "failure at " << i << "-th element";
2740d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        return false;
2750d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      }
2760d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    }
2770d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    return true;
2780d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
2790d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2800d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko private:
2810d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  BasicValueConverter<Element> basic_converter_;
2820d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(RepeatedValueConverter);
2830d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko};
2840d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2850d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkotemplate <typename NestedType>
2860d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoclass RepeatedMessageConverter
2870d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    : public ValueConverter<ScopedVector<NestedType> > {
2880d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko public:
2890d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  RepeatedMessageConverter() {}
2900d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2910d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  bool Convert(const base::Value& value,
2920d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko               ScopedVector<NestedType>* field) const override {
2930d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    const base::ListValue* list = NULL;
2940d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    if (!value.GetAsList(&list))
2950d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      return false;
2960d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
2970d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    field->reserve(list->GetSize());
2980d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    for (size_t i = 0; i < list->GetSize(); ++i) {
2990d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const base::Value* element = NULL;
3000d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      if (!list->Get(i, &element))
3010d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        continue;
3020d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
30394ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez      std::unique_ptr<NestedType> nested(new NestedType);
3040d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      if (converter_.Convert(*element, nested.get())) {
3050d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        field->push_back(nested.release());
3060d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      } else {
3070d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        DVLOG(1) << "failure at " << i << "-th element";
3080d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        return false;
3090d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      }
3100d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    }
3110d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    return true;
3120d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
3130d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3140d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko private:
3150d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  JSONValueConverter<NestedType> converter_;
3160d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(RepeatedMessageConverter);
3170d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko};
3180d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3190d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkotemplate <typename NestedType>
3200d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoclass RepeatedCustomValueConverter
3210d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    : public ValueConverter<ScopedVector<NestedType> > {
3220d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko public:
3230d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  typedef bool(*ConvertFunc)(const base::Value* value, NestedType* field);
3240d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3250d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  RepeatedCustomValueConverter(ConvertFunc convert_func)
3260d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      : convert_func_(convert_func) {}
3270d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3280d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  bool Convert(const base::Value& value,
3290d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko               ScopedVector<NestedType>* field) const override {
3300d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    const base::ListValue* list = NULL;
3310d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    if (!value.GetAsList(&list))
3320d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      return false;
3330d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3340d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    field->reserve(list->GetSize());
3350d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    for (size_t i = 0; i < list->GetSize(); ++i) {
3360d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const base::Value* element = NULL;
3370d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      if (!list->Get(i, &element))
3380d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        continue;
3390d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
34094ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez      std::unique_ptr<NestedType> nested(new NestedType);
3410d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      if ((*convert_func_)(element, nested.get())) {
3420d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        field->push_back(nested.release());
3430d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      } else {
3440d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        DVLOG(1) << "failure at " << i << "-th element";
3450d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        return false;
3460d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      }
3470d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    }
3480d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    return true;
3490d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
3500d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3510d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko private:
3520d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  ConvertFunc convert_func_;
3530d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(RepeatedCustomValueConverter);
3540d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko};
3550d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3560d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3570d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko}  // namespace internal
3580d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3590d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkotemplate <class StructType>
3600d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoclass JSONValueConverter {
3610d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko public:
3620d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  JSONValueConverter() {
3630d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    StructType::RegisterJSONConverter(this);
3640d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
3650d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3660d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void RegisterIntField(const std::string& field_name,
3670d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                        int StructType::* field) {
3680d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    fields_.push_back(new internal::FieldConverter<StructType, int>(
3690d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        field_name, field, new internal::BasicValueConverter<int>));
3700d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
3710d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3720d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void RegisterStringField(const std::string& field_name,
3730d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                           std::string StructType::* field) {
3740d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    fields_.push_back(new internal::FieldConverter<StructType, std::string>(
3750d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        field_name, field, new internal::BasicValueConverter<std::string>));
3760d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
3770d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3780d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void RegisterStringField(const std::string& field_name,
3790d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                           string16 StructType::* field) {
3800d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    fields_.push_back(new internal::FieldConverter<StructType, string16>(
3810d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        field_name, field, new internal::BasicValueConverter<string16>));
3820d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
3830d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3840d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void RegisterBoolField(const std::string& field_name,
3850d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                         bool StructType::* field) {
3860d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    fields_.push_back(new internal::FieldConverter<StructType, bool>(
3870d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        field_name, field, new internal::BasicValueConverter<bool>));
3880d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
3890d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3900d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void RegisterDoubleField(const std::string& field_name,
3910d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                           double StructType::* field) {
3920d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    fields_.push_back(new internal::FieldConverter<StructType, double>(
3930d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        field_name, field, new internal::BasicValueConverter<double>));
3940d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
3950d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3960d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  template <class NestedType>
3970d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void RegisterNestedField(
3980d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const std::string& field_name, NestedType StructType::* field) {
3990d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    fields_.push_back(new internal::FieldConverter<StructType, NestedType>(
4000d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko            field_name,
4010d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko            field,
4020d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko            new internal::NestedValueConverter<NestedType>));
4030d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
4040d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4050d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  template <typename FieldType>
4060d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void RegisterCustomField(
4070d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const std::string& field_name,
4080d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      FieldType StructType::* field,
4090d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      bool (*convert_func)(const StringPiece&, FieldType*)) {
4100d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    fields_.push_back(new internal::FieldConverter<StructType, FieldType>(
4110d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        field_name,
4120d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        field,
4130d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        new internal::CustomFieldConverter<FieldType>(convert_func)));
4140d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
4150d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4160d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  template <typename FieldType>
4170d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void RegisterCustomValueField(
4180d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const std::string& field_name,
4190d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      FieldType StructType::* field,
4200d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      bool (*convert_func)(const base::Value*, FieldType*)) {
4210d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    fields_.push_back(new internal::FieldConverter<StructType, FieldType>(
4220d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        field_name,
4230d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        field,
4240d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        new internal::ValueFieldConverter<FieldType>(convert_func)));
4250d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
4260d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4270d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void RegisterRepeatedInt(const std::string& field_name,
4280d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                           ScopedVector<int> StructType::* field) {
4290d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    fields_.push_back(
4300d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        new internal::FieldConverter<StructType, ScopedVector<int> >(
4310d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko            field_name, field, new internal::RepeatedValueConverter<int>));
4320d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
4330d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4340d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void RegisterRepeatedString(const std::string& field_name,
4350d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                              ScopedVector<std::string> StructType::* field) {
4360d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    fields_.push_back(
4370d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        new internal::FieldConverter<StructType, ScopedVector<std::string> >(
4380d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko            field_name,
4390d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko            field,
4400d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko            new internal::RepeatedValueConverter<std::string>));
4410d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
4420d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4430d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void RegisterRepeatedString(const std::string& field_name,
4440d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                              ScopedVector<string16> StructType::* field) {
4450d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    fields_.push_back(
4460d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        new internal::FieldConverter<StructType, ScopedVector<string16> >(
4470d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko            field_name,
4480d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko            field,
4490d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko            new internal::RepeatedValueConverter<string16>));
4500d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
4510d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4520d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void RegisterRepeatedDouble(const std::string& field_name,
4530d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                              ScopedVector<double> StructType::* field) {
4540d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    fields_.push_back(
4550d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        new internal::FieldConverter<StructType, ScopedVector<double> >(
4560d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko            field_name, field, new internal::RepeatedValueConverter<double>));
4570d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
4580d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4590d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void RegisterRepeatedBool(const std::string& field_name,
4600d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                            ScopedVector<bool> StructType::* field) {
4610d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    fields_.push_back(
4620d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        new internal::FieldConverter<StructType, ScopedVector<bool> >(
4630d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko            field_name, field, new internal::RepeatedValueConverter<bool>));
4640d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
4650d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4660d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  template <class NestedType>
4670d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void RegisterRepeatedCustomValue(
4680d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const std::string& field_name,
4690d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      ScopedVector<NestedType> StructType::* field,
4700d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      bool (*convert_func)(const base::Value*, NestedType*)) {
4710d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    fields_.push_back(
4720d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        new internal::FieldConverter<StructType, ScopedVector<NestedType> >(
4730d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko            field_name,
4740d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko            field,
4750d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko            new internal::RepeatedCustomValueConverter<NestedType>(
4760d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                convert_func)));
4770d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
4780d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4790d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  template <class NestedType>
4800d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  void RegisterRepeatedMessage(const std::string& field_name,
4810d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                               ScopedVector<NestedType> StructType::* field) {
4820d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    fields_.push_back(
4830d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        new internal::FieldConverter<StructType, ScopedVector<NestedType> >(
4840d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko            field_name,
4850d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko            field,
4860d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko            new internal::RepeatedMessageConverter<NestedType>));
4870d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
4880d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4890d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  bool Convert(const base::Value& value, StructType* output) const {
4900d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    const DictionaryValue* dictionary_value = NULL;
4910d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    if (!value.GetAsDictionary(&dictionary_value))
4920d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      return false;
4930d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
4940d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    for(size_t i = 0; i < fields_.size(); ++i) {
4950d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const internal::FieldConverterBase<StructType>* field_converter =
4960d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko          fields_[i];
4970d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      const base::Value* field = NULL;
4980d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      if (dictionary_value->Get(field_converter->field_path(), &field)) {
4990d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        if (!field_converter->ConvertField(*field, output)) {
5000d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko          DVLOG(1) << "failure at field " << field_converter->field_path();
5010d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko          return false;
5020d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko        }
5030d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      }
5040d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    }
5050d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    return true;
5060d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
5070d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
5080d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko private:
5090d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  ScopedVector<internal::FieldConverterBase<StructType> > fields_;
5100d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
5110d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(JSONValueConverter);
5120d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko};
5130d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
5140d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko}  // namespace base
5150d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
5160d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#endif  // BASE_JSON_JSON_VALUE_CONVERTER_H_
517