Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Side by Side Diff: base/json/json_value_converter.h

Issue 2613223002: Remove ScopedVector from base::JSONValueConverter (Closed)
Patch Set: Rebase and address comments from mmenke@ Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | base/json/json_value_converter_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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_
OLDNEW
« no previous file with comments | « no previous file | base/json/json_value_converter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698