1cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// Use of this source code is governed by a BSD-style license that can be
3cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// found in the LICENSE file.
4cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
5cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#ifndef BASE_JSON_JSON_VALUE_CONVERTER_H_
6cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#define BASE_JSON_JSON_VALUE_CONVERTER_H_
7cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
8cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include <stddef.h>
9cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
10cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include <string>
11cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include <vector>
12cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
13cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include "base/base_export.h"
14cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include "base/logging.h"
15cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include "base/macros.h"
16cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include "base/memory/scoped_ptr.h"
17cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include "base/memory/scoped_vector.h"
18cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include "base/stl_util.h"
19cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include "base/strings/string16.h"
20cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include "base/strings/string_piece.h"
21cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include "base/values.h"
22cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
23cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// JSONValueConverter converts a JSON value into a C++ struct in a
24cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// lightweight way.
25cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//
26cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// Usage:
27cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// For real examples, you may want to refer to _unittest.cc file.
28cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//
29cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// Assume that you have a struct like this:
30cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//   struct Message {
31cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//     int foo;
32cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//     std::string bar;
33cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//     static void RegisterJSONConverter(
34cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//         JSONValueConverter<Message>* converter);
35cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//   };
36cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//
37cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// And you want to parse a json data into this struct.  First, you
38cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// need to declare RegisterJSONConverter() method in your struct.
39cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//   // static
40cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//   void Message::RegisterJSONConverter(
41cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//       JSONValueConverter<Message>* converter) {
42cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//     converter->RegisterIntField("foo", &Message::foo);
43cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//     converter->RegisterStringField("bar", &Message::bar);
44cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//   }
45cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//
46cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// Then, you just instantiate your JSONValueConverter of your type and call
47cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// Convert() method.
48cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//   Message message;
49cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//   JSONValueConverter<Message> converter;
50cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//   converter.Convert(json, &message);
51cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//
52cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// Convert() returns false when it fails.  Here "fail" means that the value is
53cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// structurally different from expected, such like a string value appears
54cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// for an int field.  Do not report failures for missing fields.
55cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// Also note that Convert() will modify the passed |message| even when it
56cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// fails for performance reason.
57cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//
58cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// For nested field, the internal message also has to implement the registration
59cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// method.  Then, just use RegisterNestedField() from the containing struct's
60cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// RegisterJSONConverter method.
61cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//   struct Nested {
62cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//     Message foo;
63cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//     static void RegisterJSONConverter(...) {
64cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//       ...
65cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//       converter->RegisterNestedField("foo", &Nested::foo);
66cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//     }
67cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//   };
68cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//
69cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// For repeated field, we just assume ScopedVector for its container
70cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// and you can put RegisterRepeatedInt or some other types.  Use
71cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// RegisterRepeatedMessage for nested repeated fields.
72cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//
73cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// Sometimes JSON format uses string representations for other types such
74cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// like enum, timestamp, or URL.  You can use RegisterCustomField method
75cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// and specify a function to convert a StringPiece to your type.
76cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//   bool ConvertFunc(const StringPiece& s, YourEnum* result) {
77cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//     // do something and return true if succeed...
78cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//   }
79cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//   struct Message {
80cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//     YourEnum ye;
81cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//     ...
82cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//     static void RegisterJSONConverter(...) {
83cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//       ...
84cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//       converter->RegsiterCustomField<YourEnum>(
85cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//           "your_enum", &Message::ye, &ConvertFunc);
86cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//     }
87cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko//   };
88cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
89cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkonamespace base {
90cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
91cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkotemplate <typename StructType>
92cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoclass JSONValueConverter;
93cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
94cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkonamespace internal {
95cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
96cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkotemplate<typename StructType>
97cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoclass FieldConverterBase {
98cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko public:
99cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  explicit FieldConverterBase(const std::string& path) : field_path_(path) {}
100cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  virtual ~FieldConverterBase() {}
101cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  virtual bool ConvertField(const base::Value& value, StructType* obj)
102cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      const = 0;
103cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  const std::string& field_path() const { return field_path_; }
104cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
105cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko private:
106cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  std::string field_path_;
107cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(FieldConverterBase);
108cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko};
109cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
110cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkotemplate <typename FieldType>
111cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoclass ValueConverter {
112cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko public:
113cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  virtual ~ValueConverter() {}
114cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  virtual bool Convert(const base::Value& value, FieldType* field) const = 0;
115cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko};
116cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
117cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkotemplate <typename StructType, typename FieldType>
118cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoclass FieldConverter : public FieldConverterBase<StructType> {
119cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko public:
120cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  explicit FieldConverter(const std::string& path,
121cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                          FieldType StructType::* field,
122cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                          ValueConverter<FieldType>* converter)
123cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      : FieldConverterBase<StructType>(path),
124cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        field_pointer_(field),
125cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        value_converter_(converter) {
126cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
127cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
128cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  bool ConvertField(const base::Value& value, StructType* dst) const override {
129cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    return value_converter_->Convert(value, &(dst->*field_pointer_));
130cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
131cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
132cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko private:
133cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  FieldType StructType::* field_pointer_;
134cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  scoped_ptr<ValueConverter<FieldType> > value_converter_;
135cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(FieldConverter);
136cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko};
137cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
138cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkotemplate <typename FieldType>
139cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoclass BasicValueConverter;
140cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
141cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkotemplate <>
142cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoclass BASE_EXPORT BasicValueConverter<int> : public ValueConverter<int> {
143cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko public:
144cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  BasicValueConverter() {}
145cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
146cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  bool Convert(const base::Value& value, int* field) const override;
147cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
148cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko private:
149cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
150cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko};
151cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
152cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkotemplate <>
153cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoclass BASE_EXPORT BasicValueConverter<std::string>
154cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    : public ValueConverter<std::string> {
155cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko public:
156cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  BasicValueConverter() {}
157cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
158cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  bool Convert(const base::Value& value, std::string* field) const override;
159cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
160cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko private:
161cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
162cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko};
163cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
164cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkotemplate <>
165cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoclass BASE_EXPORT BasicValueConverter<string16>
166cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    : public ValueConverter<string16> {
167cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko public:
168cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  BasicValueConverter() {}
169cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
170cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  bool Convert(const base::Value& value, string16* field) const override;
171cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
172cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko private:
173cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
174cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko};
175cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
176cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkotemplate <>
177cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoclass BASE_EXPORT BasicValueConverter<double> : public ValueConverter<double> {
178cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko public:
179cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  BasicValueConverter() {}
180cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
181cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  bool Convert(const base::Value& value, double* field) const override;
182cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
183cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko private:
184cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
185cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko};
186cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
187cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkotemplate <>
188cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoclass BASE_EXPORT BasicValueConverter<bool> : public ValueConverter<bool> {
189cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko public:
190cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  BasicValueConverter() {}
191cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
192cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  bool Convert(const base::Value& value, bool* field) const override;
193cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
194cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko private:
195cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
196cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko};
197cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
198cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkotemplate <typename FieldType>
199cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoclass ValueFieldConverter : public ValueConverter<FieldType> {
200cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko public:
201cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  typedef bool(*ConvertFunc)(const base::Value* value, FieldType* field);
202cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
203cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  ValueFieldConverter(ConvertFunc convert_func)
204cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      : convert_func_(convert_func) {}
205cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
206cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  bool Convert(const base::Value& value, FieldType* field) const override {
207cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    return convert_func_(&value, field);
208cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
209cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
210cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko private:
211cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  ConvertFunc convert_func_;
212cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
213cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(ValueFieldConverter);
214cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko};
215cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
216cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkotemplate <typename FieldType>
217cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoclass CustomFieldConverter : public ValueConverter<FieldType> {
218cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko public:
219cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  typedef bool(*ConvertFunc)(const StringPiece& value, FieldType* field);
220cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
221cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  CustomFieldConverter(ConvertFunc convert_func)
222cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      : convert_func_(convert_func) {}
223cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
224cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  bool Convert(const base::Value& value, FieldType* field) const override {
225cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    std::string string_value;
226cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    return value.GetAsString(&string_value) &&
227cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        convert_func_(string_value, field);
228cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
229cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
230cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko private:
231cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  ConvertFunc convert_func_;
232cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
233cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(CustomFieldConverter);
234cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko};
235cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
236cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkotemplate <typename NestedType>
237cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoclass NestedValueConverter : public ValueConverter<NestedType> {
238cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko public:
239cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  NestedValueConverter() {}
240cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
241cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  bool Convert(const base::Value& value, NestedType* field) const override {
242cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    return converter_.Convert(value, field);
243cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
244cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
245cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko private:
246cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  JSONValueConverter<NestedType> converter_;
247cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(NestedValueConverter);
248cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko};
249cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
250cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkotemplate <typename Element>
251cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoclass RepeatedValueConverter : public ValueConverter<ScopedVector<Element> > {
252cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko public:
253cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  RepeatedValueConverter() {}
254cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
255cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  bool Convert(const base::Value& value,
256cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko               ScopedVector<Element>* field) const override {
257cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    const base::ListValue* list = NULL;
258cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    if (!value.GetAsList(&list)) {
259cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      // The field is not a list.
260cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      return false;
261cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    }
262cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
263cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    field->reserve(list->GetSize());
264cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    for (size_t i = 0; i < list->GetSize(); ++i) {
265cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      const base::Value* element = NULL;
266cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      if (!list->Get(i, &element))
267cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        continue;
268cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
269cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      scoped_ptr<Element> e(new Element);
270cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      if (basic_converter_.Convert(*element, e.get())) {
271cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        field->push_back(e.release());
272cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      } else {
273cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        DVLOG(1) << "failure at " << i << "-th element";
274cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        return false;
275cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      }
276cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    }
277cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    return true;
278cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
279cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
280cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko private:
281cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  BasicValueConverter<Element> basic_converter_;
282cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(RepeatedValueConverter);
283cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko};
284cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
285cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkotemplate <typename NestedType>
286cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoclass RepeatedMessageConverter
287cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    : public ValueConverter<ScopedVector<NestedType> > {
288cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko public:
289cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  RepeatedMessageConverter() {}
290cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
291cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  bool Convert(const base::Value& value,
292cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko               ScopedVector<NestedType>* field) const override {
293cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    const base::ListValue* list = NULL;
294cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    if (!value.GetAsList(&list))
295cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      return false;
296cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
297cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    field->reserve(list->GetSize());
298cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    for (size_t i = 0; i < list->GetSize(); ++i) {
299cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      const base::Value* element = NULL;
300cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      if (!list->Get(i, &element))
301cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        continue;
302cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
303cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      scoped_ptr<NestedType> nested(new NestedType);
304cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      if (converter_.Convert(*element, nested.get())) {
305cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        field->push_back(nested.release());
306cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      } else {
307cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        DVLOG(1) << "failure at " << i << "-th element";
308cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        return false;
309cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      }
310cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    }
311cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    return true;
312cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
313cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
314cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko private:
315cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  JSONValueConverter<NestedType> converter_;
316cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(RepeatedMessageConverter);
317cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko};
318cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
319cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkotemplate <typename NestedType>
320cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoclass RepeatedCustomValueConverter
321cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    : public ValueConverter<ScopedVector<NestedType> > {
322cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko public:
323cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  typedef bool(*ConvertFunc)(const base::Value* value, NestedType* field);
324cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
325cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  RepeatedCustomValueConverter(ConvertFunc convert_func)
326cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      : convert_func_(convert_func) {}
327cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
328cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  bool Convert(const base::Value& value,
329cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko               ScopedVector<NestedType>* field) const override {
330cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    const base::ListValue* list = NULL;
331cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    if (!value.GetAsList(&list))
332cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      return false;
333cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
334cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    field->reserve(list->GetSize());
335cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    for (size_t i = 0; i < list->GetSize(); ++i) {
336cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      const base::Value* element = NULL;
337cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      if (!list->Get(i, &element))
338cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        continue;
339cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
340cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      scoped_ptr<NestedType> nested(new NestedType);
341cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      if ((*convert_func_)(element, nested.get())) {
342cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        field->push_back(nested.release());
343cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      } else {
344cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        DVLOG(1) << "failure at " << i << "-th element";
345cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        return false;
346cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      }
347cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    }
348cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    return true;
349cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
350cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
351cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko private:
352cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  ConvertFunc convert_func_;
353cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(RepeatedCustomValueConverter);
354cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko};
355cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
356cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
357cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko}  // namespace internal
358cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
359cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkotemplate <class StructType>
360cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoclass JSONValueConverter {
361cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko public:
362cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  JSONValueConverter() {
363cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    StructType::RegisterJSONConverter(this);
364cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
365cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
366cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  void RegisterIntField(const std::string& field_name,
367cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                        int StructType::* field) {
368cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    fields_.push_back(new internal::FieldConverter<StructType, int>(
369cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        field_name, field, new internal::BasicValueConverter<int>));
370cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
371cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
372cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  void RegisterStringField(const std::string& field_name,
373cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                           std::string StructType::* field) {
374cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    fields_.push_back(new internal::FieldConverter<StructType, std::string>(
375cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        field_name, field, new internal::BasicValueConverter<std::string>));
376cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
377cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
378cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  void RegisterStringField(const std::string& field_name,
379cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                           string16 StructType::* field) {
380cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    fields_.push_back(new internal::FieldConverter<StructType, string16>(
381cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        field_name, field, new internal::BasicValueConverter<string16>));
382cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
383cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
384cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  void RegisterBoolField(const std::string& field_name,
385cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                         bool StructType::* field) {
386cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    fields_.push_back(new internal::FieldConverter<StructType, bool>(
387cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        field_name, field, new internal::BasicValueConverter<bool>));
388cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
389cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
390cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  void RegisterDoubleField(const std::string& field_name,
391cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                           double StructType::* field) {
392cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    fields_.push_back(new internal::FieldConverter<StructType, double>(
393cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        field_name, field, new internal::BasicValueConverter<double>));
394cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
395cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
396cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  template <class NestedType>
397cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  void RegisterNestedField(
398cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      const std::string& field_name, NestedType StructType::* field) {
399cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    fields_.push_back(new internal::FieldConverter<StructType, NestedType>(
400cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko            field_name,
401cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko            field,
402cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko            new internal::NestedValueConverter<NestedType>));
403cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
404cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
405cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  template <typename FieldType>
406cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  void RegisterCustomField(
407cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      const std::string& field_name,
408cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      FieldType StructType::* field,
409cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      bool (*convert_func)(const StringPiece&, FieldType*)) {
410cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    fields_.push_back(new internal::FieldConverter<StructType, FieldType>(
411cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        field_name,
412cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        field,
413cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        new internal::CustomFieldConverter<FieldType>(convert_func)));
414cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
415cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
416cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  template <typename FieldType>
417cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  void RegisterCustomValueField(
418cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      const std::string& field_name,
419cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      FieldType StructType::* field,
420cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      bool (*convert_func)(const base::Value*, FieldType*)) {
421cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    fields_.push_back(new internal::FieldConverter<StructType, FieldType>(
422cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        field_name,
423cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        field,
424cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        new internal::ValueFieldConverter<FieldType>(convert_func)));
425cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
426cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
427cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  void RegisterRepeatedInt(const std::string& field_name,
428cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                           ScopedVector<int> StructType::* field) {
429cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    fields_.push_back(
430cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        new internal::FieldConverter<StructType, ScopedVector<int> >(
431cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko            field_name, field, new internal::RepeatedValueConverter<int>));
432cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
433cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
434cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  void RegisterRepeatedString(const std::string& field_name,
435cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                              ScopedVector<std::string> StructType::* field) {
436cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    fields_.push_back(
437cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        new internal::FieldConverter<StructType, ScopedVector<std::string> >(
438cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko            field_name,
439cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko            field,
440cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko            new internal::RepeatedValueConverter<std::string>));
441cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
442cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
443cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  void RegisterRepeatedString(const std::string& field_name,
444cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                              ScopedVector<string16> StructType::* field) {
445cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    fields_.push_back(
446cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        new internal::FieldConverter<StructType, ScopedVector<string16> >(
447cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko            field_name,
448cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko            field,
449cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko            new internal::RepeatedValueConverter<string16>));
450cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
451cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
452cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  void RegisterRepeatedDouble(const std::string& field_name,
453cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                              ScopedVector<double> StructType::* field) {
454cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    fields_.push_back(
455cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        new internal::FieldConverter<StructType, ScopedVector<double> >(
456cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko            field_name, field, new internal::RepeatedValueConverter<double>));
457cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
458cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
459cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  void RegisterRepeatedBool(const std::string& field_name,
460cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                            ScopedVector<bool> StructType::* field) {
461cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    fields_.push_back(
462cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        new internal::FieldConverter<StructType, ScopedVector<bool> >(
463cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko            field_name, field, new internal::RepeatedValueConverter<bool>));
464cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
465cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
466cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  template <class NestedType>
467cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  void RegisterRepeatedCustomValue(
468cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      const std::string& field_name,
469cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      ScopedVector<NestedType> StructType::* field,
470cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      bool (*convert_func)(const base::Value*, NestedType*)) {
471cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    fields_.push_back(
472cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        new internal::FieldConverter<StructType, ScopedVector<NestedType> >(
473cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko            field_name,
474cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko            field,
475cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko            new internal::RepeatedCustomValueConverter<NestedType>(
476cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                convert_func)));
477cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
478cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
479cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  template <class NestedType>
480cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  void RegisterRepeatedMessage(const std::string& field_name,
481cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                               ScopedVector<NestedType> StructType::* field) {
482cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    fields_.push_back(
483cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        new internal::FieldConverter<StructType, ScopedVector<NestedType> >(
484cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko            field_name,
485cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko            field,
486cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko            new internal::RepeatedMessageConverter<NestedType>));
487cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
488cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
489cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  bool Convert(const base::Value& value, StructType* output) const {
490cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    const DictionaryValue* dictionary_value = NULL;
491cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    if (!value.GetAsDictionary(&dictionary_value))
492cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      return false;
493cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
494cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    for(size_t i = 0; i < fields_.size(); ++i) {
495cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      const internal::FieldConverterBase<StructType>* field_converter =
496cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          fields_[i];
497cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      const base::Value* field = NULL;
498cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      if (dictionary_value->Get(field_converter->field_path(), &field)) {
499cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        if (!field_converter->ConvertField(*field, output)) {
500cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          DVLOG(1) << "failure at field " << field_converter->field_path();
501cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          return false;
502cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        }
503cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      }
504cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    }
505cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    return true;
506cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
507cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
508cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko private:
509cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  ScopedVector<internal::FieldConverterBase<StructType> > fields_;
510cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
511cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(JSONValueConverter);
512cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko};
513cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
514cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko}  // namespace base
515cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
516cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#endif  // BASE_JSON_JSON_VALUE_CONVERTER_H_
517