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