| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef BASE_JSON_JSON_VALUE_CONVERTER_H_ | 5 #ifndef BASE_JSON_JSON_VALUE_CONVERTER_H_ |
| 6 #define BASE_JSON_JSON_VALUE_CONVERTER_H_ | 6 #define BASE_JSON_JSON_VALUE_CONVERTER_H_ |
| 7 | 7 |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 | 9 |
| 10 #include <memory> | 10 #include <memory> |
| 11 #include <string> | 11 #include <string> |
| 12 #include <vector> | 12 #include <vector> |
| 13 | 13 |
| 14 #include "base/base_export.h" | 14 #include "base/base_export.h" |
| 15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "base/macros.h" | 16 #include "base/macros.h" |
| 17 #include "base/memory/scoped_vector.h" | 17 #include "base/memory/ptr_util.h" |
| 18 #include "base/strings/string16.h" | 18 #include "base/strings/string16.h" |
| 19 #include "base/strings/string_piece.h" | 19 #include "base/strings/string_piece.h" |
| 20 #include "base/values.h" | 20 #include "base/values.h" |
| 21 | 21 |
| 22 // JSONValueConverter converts a JSON value into a C++ struct in a | 22 // JSONValueConverter converts a JSON value into a C++ struct in a |
| 23 // lightweight way. | 23 // lightweight way. |
| 24 // | 24 // |
| 25 // Usage: | 25 // Usage: |
| 26 // For real examples, you may want to refer to _unittest.cc file. | 26 // For real examples, you may want to refer to _unittest.cc file. |
| 27 // | 27 // |
| (...skipping 30 matching lines...) Expand all Loading... |
| 58 // method. Then, just use RegisterNestedField() from the containing struct's | 58 // method. Then, just use RegisterNestedField() from the containing struct's |
| 59 // RegisterJSONConverter method. | 59 // RegisterJSONConverter method. |
| 60 // struct Nested { | 60 // struct Nested { |
| 61 // Message foo; | 61 // Message foo; |
| 62 // static void RegisterJSONConverter(...) { | 62 // static void RegisterJSONConverter(...) { |
| 63 // ... | 63 // ... |
| 64 // converter->RegisterNestedField("foo", &Nested::foo); | 64 // converter->RegisterNestedField("foo", &Nested::foo); |
| 65 // } | 65 // } |
| 66 // }; | 66 // }; |
| 67 // | 67 // |
| 68 // For repeated field, we just assume ScopedVector for its container | 68 // For repeated field, we just assume std::vector<std::unique_ptr<ElementType>> |
| 69 // and you can put RegisterRepeatedInt or some other types. Use | 69 // for its container and you can put RegisterRepeatedInt or some other types. |
| 70 // RegisterRepeatedMessage for nested repeated fields. | 70 // Use RegisterRepeatedMessage for nested repeated fields. |
| 71 // | 71 // |
| 72 // Sometimes JSON format uses string representations for other types such | 72 // Sometimes JSON format uses string representations for other types such |
| 73 // like enum, timestamp, or URL. You can use RegisterCustomField method | 73 // like enum, timestamp, or URL. You can use RegisterCustomField method |
| 74 // and specify a function to convert a StringPiece to your type. | 74 // and specify a function to convert a StringPiece to your type. |
| 75 // bool ConvertFunc(const StringPiece& s, YourEnum* result) { | 75 // bool ConvertFunc(const StringPiece& s, YourEnum* result) { |
| 76 // // do something and return true if succeed... | 76 // // do something and return true if succeed... |
| 77 // } | 77 // } |
| 78 // struct Message { | 78 // struct Message { |
| 79 // YourEnum ye; | 79 // YourEnum ye; |
| 80 // ... | 80 // ... |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 bool Convert(const base::Value& value, NestedType* field) const override { | 240 bool Convert(const base::Value& value, NestedType* field) const override { |
| 241 return converter_.Convert(value, field); | 241 return converter_.Convert(value, field); |
| 242 } | 242 } |
| 243 | 243 |
| 244 private: | 244 private: |
| 245 JSONValueConverter<NestedType> converter_; | 245 JSONValueConverter<NestedType> converter_; |
| 246 DISALLOW_COPY_AND_ASSIGN(NestedValueConverter); | 246 DISALLOW_COPY_AND_ASSIGN(NestedValueConverter); |
| 247 }; | 247 }; |
| 248 | 248 |
| 249 template <typename Element> | 249 template <typename Element> |
| 250 class RepeatedValueConverter : public ValueConverter<ScopedVector<Element> > { | 250 class RepeatedValueConverter |
| 251 : public ValueConverter<std::vector<std::unique_ptr<Element>>> { |
| 251 public: | 252 public: |
| 252 RepeatedValueConverter() {} | 253 RepeatedValueConverter() {} |
| 253 | 254 |
| 254 bool Convert(const base::Value& value, | 255 bool Convert(const base::Value& value, |
| 255 ScopedVector<Element>* field) const override { | 256 std::vector<std::unique_ptr<Element>>* field) const override { |
| 256 const base::ListValue* list = NULL; | 257 const base::ListValue* list = NULL; |
| 257 if (!value.GetAsList(&list)) { | 258 if (!value.GetAsList(&list)) { |
| 258 // The field is not a list. | 259 // The field is not a list. |
| 259 return false; | 260 return false; |
| 260 } | 261 } |
| 261 | 262 |
| 262 field->reserve(list->GetSize()); | 263 field->reserve(list->GetSize()); |
| 263 for (size_t i = 0; i < list->GetSize(); ++i) { | 264 for (size_t i = 0; i < list->GetSize(); ++i) { |
| 264 const base::Value* element = NULL; | 265 const base::Value* element = NULL; |
| 265 if (!list->Get(i, &element)) | 266 if (!list->Get(i, &element)) |
| 266 continue; | 267 continue; |
| 267 | 268 |
| 268 std::unique_ptr<Element> e(new Element); | 269 std::unique_ptr<Element> e(new Element); |
| 269 if (basic_converter_.Convert(*element, e.get())) { | 270 if (basic_converter_.Convert(*element, e.get())) { |
| 270 field->push_back(e.release()); | 271 field->push_back(std::move(e)); |
| 271 } else { | 272 } else { |
| 272 DVLOG(1) << "failure at " << i << "-th element"; | 273 DVLOG(1) << "failure at " << i << "-th element"; |
| 273 return false; | 274 return false; |
| 274 } | 275 } |
| 275 } | 276 } |
| 276 return true; | 277 return true; |
| 277 } | 278 } |
| 278 | 279 |
| 279 private: | 280 private: |
| 280 BasicValueConverter<Element> basic_converter_; | 281 BasicValueConverter<Element> basic_converter_; |
| 281 DISALLOW_COPY_AND_ASSIGN(RepeatedValueConverter); | 282 DISALLOW_COPY_AND_ASSIGN(RepeatedValueConverter); |
| 282 }; | 283 }; |
| 283 | 284 |
| 284 template <typename NestedType> | 285 template <typename NestedType> |
| 285 class RepeatedMessageConverter | 286 class RepeatedMessageConverter |
| 286 : public ValueConverter<ScopedVector<NestedType> > { | 287 : public ValueConverter<std::vector<std::unique_ptr<NestedType>>> { |
| 287 public: | 288 public: |
| 288 RepeatedMessageConverter() {} | 289 RepeatedMessageConverter() {} |
| 289 | 290 |
| 290 bool Convert(const base::Value& value, | 291 bool Convert(const base::Value& value, |
| 291 ScopedVector<NestedType>* field) const override { | 292 std::vector<std::unique_ptr<NestedType>>* field) const override { |
| 292 const base::ListValue* list = NULL; | 293 const base::ListValue* list = NULL; |
| 293 if (!value.GetAsList(&list)) | 294 if (!value.GetAsList(&list)) |
| 294 return false; | 295 return false; |
| 295 | 296 |
| 296 field->reserve(list->GetSize()); | 297 field->reserve(list->GetSize()); |
| 297 for (size_t i = 0; i < list->GetSize(); ++i) { | 298 for (size_t i = 0; i < list->GetSize(); ++i) { |
| 298 const base::Value* element = NULL; | 299 const base::Value* element = NULL; |
| 299 if (!list->Get(i, &element)) | 300 if (!list->Get(i, &element)) |
| 300 continue; | 301 continue; |
| 301 | 302 |
| 302 std::unique_ptr<NestedType> nested(new NestedType); | 303 std::unique_ptr<NestedType> nested(new NestedType); |
| 303 if (converter_.Convert(*element, nested.get())) { | 304 if (converter_.Convert(*element, nested.get())) { |
| 304 field->push_back(nested.release()); | 305 field->push_back(std::move(nested)); |
| 305 } else { | 306 } else { |
| 306 DVLOG(1) << "failure at " << i << "-th element"; | 307 DVLOG(1) << "failure at " << i << "-th element"; |
| 307 return false; | 308 return false; |
| 308 } | 309 } |
| 309 } | 310 } |
| 310 return true; | 311 return true; |
| 311 } | 312 } |
| 312 | 313 |
| 313 private: | 314 private: |
| 314 JSONValueConverter<NestedType> converter_; | 315 JSONValueConverter<NestedType> converter_; |
| 315 DISALLOW_COPY_AND_ASSIGN(RepeatedMessageConverter); | 316 DISALLOW_COPY_AND_ASSIGN(RepeatedMessageConverter); |
| 316 }; | 317 }; |
| 317 | 318 |
| 318 template <typename NestedType> | 319 template <typename NestedType> |
| 319 class RepeatedCustomValueConverter | 320 class RepeatedCustomValueConverter |
| 320 : public ValueConverter<ScopedVector<NestedType> > { | 321 : public ValueConverter<std::vector<std::unique_ptr<NestedType>>> { |
| 321 public: | 322 public: |
| 322 typedef bool(*ConvertFunc)(const base::Value* value, NestedType* field); | 323 typedef bool(*ConvertFunc)(const base::Value* value, NestedType* field); |
| 323 | 324 |
| 324 explicit RepeatedCustomValueConverter(ConvertFunc convert_func) | 325 explicit RepeatedCustomValueConverter(ConvertFunc convert_func) |
| 325 : convert_func_(convert_func) {} | 326 : convert_func_(convert_func) {} |
| 326 | 327 |
| 327 bool Convert(const base::Value& value, | 328 bool Convert(const base::Value& value, |
| 328 ScopedVector<NestedType>* field) const override { | 329 std::vector<std::unique_ptr<NestedType>>* field) const override { |
| 329 const base::ListValue* list = NULL; | 330 const base::ListValue* list = NULL; |
| 330 if (!value.GetAsList(&list)) | 331 if (!value.GetAsList(&list)) |
| 331 return false; | 332 return false; |
| 332 | 333 |
| 333 field->reserve(list->GetSize()); | 334 field->reserve(list->GetSize()); |
| 334 for (size_t i = 0; i < list->GetSize(); ++i) { | 335 for (size_t i = 0; i < list->GetSize(); ++i) { |
| 335 const base::Value* element = NULL; | 336 const base::Value* element = NULL; |
| 336 if (!list->Get(i, &element)) | 337 if (!list->Get(i, &element)) |
| 337 continue; | 338 continue; |
| 338 | 339 |
| 339 std::unique_ptr<NestedType> nested(new NestedType); | 340 std::unique_ptr<NestedType> nested(new NestedType); |
| 340 if ((*convert_func_)(element, nested.get())) { | 341 if ((*convert_func_)(element, nested.get())) { |
| 341 field->push_back(nested.release()); | 342 field->push_back(std::move(nested)); |
| 342 } else { | 343 } else { |
| 343 DVLOG(1) << "failure at " << i << "-th element"; | 344 DVLOG(1) << "failure at " << i << "-th element"; |
| 344 return false; | 345 return false; |
| 345 } | 346 } |
| 346 } | 347 } |
| 347 return true; | 348 return true; |
| 348 } | 349 } |
| 349 | 350 |
| 350 private: | 351 private: |
| 351 ConvertFunc convert_func_; | 352 ConvertFunc convert_func_; |
| 352 DISALLOW_COPY_AND_ASSIGN(RepeatedCustomValueConverter); | 353 DISALLOW_COPY_AND_ASSIGN(RepeatedCustomValueConverter); |
| 353 }; | 354 }; |
| 354 | 355 |
| 355 | 356 |
| 356 } // namespace internal | 357 } // namespace internal |
| 357 | 358 |
| 358 template <class StructType> | 359 template <class StructType> |
| 359 class JSONValueConverter { | 360 class JSONValueConverter { |
| 360 public: | 361 public: |
| 361 JSONValueConverter() { | 362 JSONValueConverter() { |
| 362 StructType::RegisterJSONConverter(this); | 363 StructType::RegisterJSONConverter(this); |
| 363 } | 364 } |
| 364 | 365 |
| 365 void RegisterIntField(const std::string& field_name, | 366 void RegisterIntField(const std::string& field_name, |
| 366 int StructType::* field) { | 367 int StructType::* field) { |
| 367 fields_.push_back(new internal::FieldConverter<StructType, int>( | 368 fields_.push_back(MakeUnique<internal::FieldConverter<StructType, int>>( |
| 368 field_name, field, new internal::BasicValueConverter<int>)); | 369 field_name, field, new internal::BasicValueConverter<int>)); |
| 369 } | 370 } |
| 370 | 371 |
| 371 void RegisterStringField(const std::string& field_name, | 372 void RegisterStringField(const std::string& field_name, |
| 372 std::string StructType::* field) { | 373 std::string StructType::* field) { |
| 373 fields_.push_back(new internal::FieldConverter<StructType, std::string>( | 374 fields_.push_back( |
| 374 field_name, field, new internal::BasicValueConverter<std::string>)); | 375 MakeUnique<internal::FieldConverter<StructType, std::string>>( |
| 376 field_name, field, new internal::BasicValueConverter<std::string>)); |
| 375 } | 377 } |
| 376 | 378 |
| 377 void RegisterStringField(const std::string& field_name, | 379 void RegisterStringField(const std::string& field_name, |
| 378 string16 StructType::* field) { | 380 string16 StructType::* field) { |
| 379 fields_.push_back(new internal::FieldConverter<StructType, string16>( | 381 fields_.push_back( |
| 380 field_name, field, new internal::BasicValueConverter<string16>)); | 382 MakeUnique<internal::FieldConverter<StructType, string16>>( |
| 383 field_name, field, new internal::BasicValueConverter<string16>)); |
| 381 } | 384 } |
| 382 | 385 |
| 383 void RegisterBoolField(const std::string& field_name, | 386 void RegisterBoolField(const std::string& field_name, |
| 384 bool StructType::* field) { | 387 bool StructType::* field) { |
| 385 fields_.push_back(new internal::FieldConverter<StructType, bool>( | 388 fields_.push_back(MakeUnique<internal::FieldConverter<StructType, bool>>( |
| 386 field_name, field, new internal::BasicValueConverter<bool>)); | 389 field_name, field, new internal::BasicValueConverter<bool>)); |
| 387 } | 390 } |
| 388 | 391 |
| 389 void RegisterDoubleField(const std::string& field_name, | 392 void RegisterDoubleField(const std::string& field_name, |
| 390 double StructType::* field) { | 393 double StructType::* field) { |
| 391 fields_.push_back(new internal::FieldConverter<StructType, double>( | 394 fields_.push_back(MakeUnique<internal::FieldConverter<StructType, double>>( |
| 392 field_name, field, new internal::BasicValueConverter<double>)); | 395 field_name, field, new internal::BasicValueConverter<double>)); |
| 393 } | 396 } |
| 394 | 397 |
| 395 template <class NestedType> | 398 template <class NestedType> |
| 396 void RegisterNestedField( | 399 void RegisterNestedField( |
| 397 const std::string& field_name, NestedType StructType::* field) { | 400 const std::string& field_name, NestedType StructType::* field) { |
| 398 fields_.push_back(new internal::FieldConverter<StructType, NestedType>( | 401 fields_.push_back( |
| 399 field_name, | 402 MakeUnique<internal::FieldConverter<StructType, NestedType>>( |
| 400 field, | 403 field_name, field, new internal::NestedValueConverter<NestedType>)); |
| 401 new internal::NestedValueConverter<NestedType>)); | |
| 402 } | 404 } |
| 403 | 405 |
| 404 template <typename FieldType> | 406 template <typename FieldType> |
| 405 void RegisterCustomField( | 407 void RegisterCustomField( |
| 406 const std::string& field_name, | 408 const std::string& field_name, |
| 407 FieldType StructType::* field, | 409 FieldType StructType::* field, |
| 408 bool (*convert_func)(const StringPiece&, FieldType*)) { | 410 bool (*convert_func)(const StringPiece&, FieldType*)) { |
| 409 fields_.push_back(new internal::FieldConverter<StructType, FieldType>( | 411 fields_.push_back( |
| 410 field_name, | 412 MakeUnique<internal::FieldConverter<StructType, FieldType>>( |
| 411 field, | 413 field_name, field, |
| 412 new internal::CustomFieldConverter<FieldType>(convert_func))); | 414 new internal::CustomFieldConverter<FieldType>(convert_func))); |
| 413 } | 415 } |
| 414 | 416 |
| 415 template <typename FieldType> | 417 template <typename FieldType> |
| 416 void RegisterCustomValueField( | 418 void RegisterCustomValueField( |
| 417 const std::string& field_name, | 419 const std::string& field_name, |
| 418 FieldType StructType::* field, | 420 FieldType StructType::* field, |
| 419 bool (*convert_func)(const base::Value*, FieldType*)) { | 421 bool (*convert_func)(const base::Value*, FieldType*)) { |
| 420 fields_.push_back(new internal::FieldConverter<StructType, FieldType>( | 422 fields_.push_back( |
| 421 field_name, | 423 MakeUnique<internal::FieldConverter<StructType, FieldType>>( |
| 422 field, | 424 field_name, field, |
| 423 new internal::ValueFieldConverter<FieldType>(convert_func))); | 425 new internal::ValueFieldConverter<FieldType>(convert_func))); |
| 424 } | 426 } |
| 425 | 427 |
| 426 void RegisterRepeatedInt(const std::string& field_name, | 428 void RegisterRepeatedInt( |
| 427 ScopedVector<int> StructType::* field) { | 429 const std::string& field_name, |
| 430 std::vector<std::unique_ptr<int>> StructType::*field) { |
| 428 fields_.push_back( | 431 fields_.push_back( |
| 429 new internal::FieldConverter<StructType, ScopedVector<int> >( | 432 MakeUnique<internal::FieldConverter<StructType, |
| 433 std::vector<std::unique_ptr<int>>>>( |
| 430 field_name, field, new internal::RepeatedValueConverter<int>)); | 434 field_name, field, new internal::RepeatedValueConverter<int>)); |
| 431 } | 435 } |
| 432 | 436 |
| 433 void RegisterRepeatedString(const std::string& field_name, | 437 void RegisterRepeatedString( |
| 434 ScopedVector<std::string> StructType::* field) { | 438 const std::string& field_name, |
| 439 std::vector<std::unique_ptr<std::string>> StructType::*field) { |
| 435 fields_.push_back( | 440 fields_.push_back( |
| 436 new internal::FieldConverter<StructType, ScopedVector<std::string> >( | 441 MakeUnique<internal::FieldConverter< |
| 437 field_name, | 442 StructType, std::vector<std::unique_ptr<std::string>>>>( |
| 438 field, | 443 field_name, field, |
| 439 new internal::RepeatedValueConverter<std::string>)); | 444 new internal::RepeatedValueConverter<std::string>)); |
| 440 } | 445 } |
| 441 | 446 |
| 442 void RegisterRepeatedString(const std::string& field_name, | 447 void RegisterRepeatedString( |
| 443 ScopedVector<string16> StructType::* field) { | 448 const std::string& field_name, |
| 444 fields_.push_back( | 449 std::vector<std::unique_ptr<string16>> StructType::*field) { |
| 445 new internal::FieldConverter<StructType, ScopedVector<string16> >( | 450 fields_.push_back(MakeUnique<internal::FieldConverter< |
| 446 field_name, | 451 StructType, std::vector<std::unique_ptr<string16>>>>( |
| 447 field, | 452 field_name, field, new internal::RepeatedValueConverter<string16>)); |
| 448 new internal::RepeatedValueConverter<string16>)); | |
| 449 } | 453 } |
| 450 | 454 |
| 451 void RegisterRepeatedDouble(const std::string& field_name, | 455 void RegisterRepeatedDouble( |
| 452 ScopedVector<double> StructType::* field) { | 456 const std::string& field_name, |
| 453 fields_.push_back( | 457 std::vector<std::unique_ptr<double>> StructType::*field) { |
| 454 new internal::FieldConverter<StructType, ScopedVector<double> >( | 458 fields_.push_back(MakeUnique<internal::FieldConverter< |
| 455 field_name, field, new internal::RepeatedValueConverter<double>)); | 459 StructType, std::vector<std::unique_ptr<double>>>>( |
| 460 field_name, field, new internal::RepeatedValueConverter<double>)); |
| 456 } | 461 } |
| 457 | 462 |
| 458 void RegisterRepeatedBool(const std::string& field_name, | 463 void RegisterRepeatedBool( |
| 459 ScopedVector<bool> StructType::* field) { | 464 const std::string& field_name, |
| 460 fields_.push_back( | 465 std::vector<std::unique_ptr<bool>> StructType::*field) { |
| 461 new internal::FieldConverter<StructType, ScopedVector<bool> >( | 466 fields_.push_back(MakeUnique<internal::FieldConverter< |
| 462 field_name, field, new internal::RepeatedValueConverter<bool>)); | 467 StructType, std::vector<std::unique_ptr<bool>>>>( |
| 468 field_name, field, new internal::RepeatedValueConverter<bool>)); |
| 463 } | 469 } |
| 464 | 470 |
| 465 template <class NestedType> | 471 template <class NestedType> |
| 466 void RegisterRepeatedCustomValue( | 472 void RegisterRepeatedCustomValue( |
| 467 const std::string& field_name, | 473 const std::string& field_name, |
| 468 ScopedVector<NestedType> StructType::* field, | 474 std::vector<std::unique_ptr<NestedType>> StructType::*field, |
| 469 bool (*convert_func)(const base::Value*, NestedType*)) { | 475 bool (*convert_func)(const base::Value*, NestedType*)) { |
| 470 fields_.push_back( | 476 fields_.push_back( |
| 471 new internal::FieldConverter<StructType, ScopedVector<NestedType> >( | 477 MakeUnique<internal::FieldConverter< |
| 472 field_name, | 478 StructType, std::vector<std::unique_ptr<NestedType>>>>( |
| 473 field, | 479 field_name, field, |
| 474 new internal::RepeatedCustomValueConverter<NestedType>( | 480 new internal::RepeatedCustomValueConverter<NestedType>( |
| 475 convert_func))); | 481 convert_func))); |
| 476 } | 482 } |
| 477 | 483 |
| 478 template <class NestedType> | 484 template <class NestedType> |
| 479 void RegisterRepeatedMessage(const std::string& field_name, | 485 void RegisterRepeatedMessage( |
| 480 ScopedVector<NestedType> StructType::* field) { | 486 const std::string& field_name, |
| 487 std::vector<std::unique_ptr<NestedType>> StructType::*field) { |
| 481 fields_.push_back( | 488 fields_.push_back( |
| 482 new internal::FieldConverter<StructType, ScopedVector<NestedType> >( | 489 MakeUnique<internal::FieldConverter< |
| 483 field_name, | 490 StructType, std::vector<std::unique_ptr<NestedType>>>>( |
| 484 field, | 491 field_name, field, |
| 485 new internal::RepeatedMessageConverter<NestedType>)); | 492 new internal::RepeatedMessageConverter<NestedType>)); |
| 486 } | 493 } |
| 487 | 494 |
| 488 bool Convert(const base::Value& value, StructType* output) const { | 495 bool Convert(const base::Value& value, StructType* output) const { |
| 489 const DictionaryValue* dictionary_value = NULL; | 496 const DictionaryValue* dictionary_value = NULL; |
| 490 if (!value.GetAsDictionary(&dictionary_value)) | 497 if (!value.GetAsDictionary(&dictionary_value)) |
| 491 return false; | 498 return false; |
| 492 | 499 |
| 493 for (size_t i = 0; i < fields_.size(); ++i) { | 500 for (size_t i = 0; i < fields_.size(); ++i) { |
| 494 const internal::FieldConverterBase<StructType>* field_converter = | 501 const internal::FieldConverterBase<StructType>* field_converter = |
| 495 fields_[i]; | 502 fields_[i].get(); |
| 496 const base::Value* field = NULL; | 503 const base::Value* field = NULL; |
| 497 if (dictionary_value->Get(field_converter->field_path(), &field)) { | 504 if (dictionary_value->Get(field_converter->field_path(), &field)) { |
| 498 if (!field_converter->ConvertField(*field, output)) { | 505 if (!field_converter->ConvertField(*field, output)) { |
| 499 DVLOG(1) << "failure at field " << field_converter->field_path(); | 506 DVLOG(1) << "failure at field " << field_converter->field_path(); |
| 500 return false; | 507 return false; |
| 501 } | 508 } |
| 502 } | 509 } |
| 503 } | 510 } |
| 504 return true; | 511 return true; |
| 505 } | 512 } |
| 506 | 513 |
| 507 private: | 514 private: |
| 508 ScopedVector<internal::FieldConverterBase<StructType> > fields_; | 515 std::vector<std::unique_ptr<internal::FieldConverterBase<StructType>>> |
| 516 fields_; |
| 509 | 517 |
| 510 DISALLOW_COPY_AND_ASSIGN(JSONValueConverter); | 518 DISALLOW_COPY_AND_ASSIGN(JSONValueConverter); |
| 511 }; | 519 }; |
| 512 | 520 |
| 513 } // namespace base | 521 } // namespace base |
| 514 | 522 |
| 515 #endif // BASE_JSON_JSON_VALUE_CONVERTER_H_ | 523 #endif // BASE_JSON_JSON_VALUE_CONVERTER_H_ |
| OLD | NEW |