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