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