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