Chromium Code Reviews| 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 #pragma once | 7 #pragma once |
| 8 | 8 |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/base_export.h" | 12 #include "base/base_export.h" |
| 13 #include "base/basictypes.h" | 13 #include "base/basictypes.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
| 16 #include "base/memory/scoped_vector.h" | |
| 16 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
| 17 #include "base/string16.h" | 18 #include "base/string16.h" |
| 18 #include "base/values.h" | 19 #include "base/values.h" |
| 19 | 20 |
| 20 // JSONValueConverter converts a JSON value into a C++ struct in a | 21 // JSONValueConverter converts a JSON value into a C++ struct in a |
| 21 // lightweight way. | 22 // lightweight way. |
| 22 // | 23 // |
| 23 // Usage: | 24 // Usage: |
| 24 // For real examples, you may want to refer to _unittest.cc file. | 25 // For real examples, you may want to refer to _unittest.cc file. |
| 25 // | 26 // |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 56 // method. Then, just use RegisterNestedField() from the containing struct's | 57 // method. Then, just use RegisterNestedField() from the containing struct's |
| 57 // RegisterJSONConverter method. | 58 // RegisterJSONConverter method. |
| 58 // struct Nested { | 59 // struct Nested { |
| 59 // Message foo; | 60 // Message foo; |
| 60 // static void RegisterJSONConverter(...) { | 61 // static void RegisterJSONConverter(...) { |
| 61 // ... | 62 // ... |
| 62 // converter->RegisterNestedField("foo", &Nested::foo); | 63 // converter->RegisterNestedField("foo", &Nested::foo); |
| 63 // } | 64 // } |
| 64 // }; | 65 // }; |
| 65 // | 66 // |
| 66 // For repeated field, we just assume std::vector for its container | 67 // For repeated field, we just assume ScopedVector for its container |
| 67 // and you can put RegisterRepeatedInt or some other types. Use | 68 // and you can use RegisterRepeatedMessage (not std::vector to avoid |
| 68 // RegisterRepeatedMessage for nested repeated fields. | 69 // copy constructors). For repeated fields of basic types such like |
| 70 // int, we assume std::vector for its container and you can use | |
| 71 // RegisterRepeatedInt and so on. | |
| 69 // | 72 // |
| 70 | 73 |
| 71 namespace base { | 74 namespace base { |
| 72 | 75 |
| 73 template <typename StructType> | 76 template <typename StructType> |
| 74 class JSONValueConverter; | 77 class JSONValueConverter; |
| 75 | 78 |
| 76 namespace internal { | 79 namespace internal { |
| 77 | 80 |
| 78 class FieldConverterBase { | 81 class FieldConverterBase { |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 201 JSONValueConverter<NestedType> converter_; | 204 JSONValueConverter<NestedType> converter_; |
| 202 DISALLOW_COPY_AND_ASSIGN(NestedValueConverter); | 205 DISALLOW_COPY_AND_ASSIGN(NestedValueConverter); |
| 203 }; | 206 }; |
| 204 | 207 |
| 205 template <typename Element> | 208 template <typename Element> |
| 206 class RepeatedValueConverter : public ValueConverter<std::vector<Element> > { | 209 class RepeatedValueConverter : public ValueConverter<std::vector<Element> > { |
| 207 public: | 210 public: |
| 208 RepeatedValueConverter() {} | 211 RepeatedValueConverter() {} |
| 209 | 212 |
| 210 virtual bool Convert( | 213 virtual bool Convert( |
| 211 const base::Value& value, std::vector<Element>* field) const OVERRIDE { | 214 const base::Value& value, std::vector<Element>* field) const OVERRIDE { |
|
awong
2012/01/13 00:27:55
Why do we still use a std::vector<> here?
Jun Mukai
2012/01/13 01:09:21
Either is fine but I don't have a strong motivatio
Jun Mukai
2012/01/13 02:10:37
Done.
satorux1
2012/01/13 02:13:51
nice. ints and doubles are cheap to copy but strin
| |
| 212 const base::ListValue* list = NULL; | 215 const base::ListValue* list = NULL; |
| 213 if (!value.GetAsList(&list)) { | 216 if (!value.GetAsList(&list)) { |
| 214 // The field is not a list. | 217 // The field is not a list. |
| 215 return false; | 218 return false; |
| 216 } | 219 } |
| 217 | 220 |
| 218 field->reserve(list->GetSize()); | 221 field->reserve(list->GetSize()); |
| 219 for (size_t i = 0; i < list->GetSize(); ++i) { | 222 for (size_t i = 0; i < list->GetSize(); ++i) { |
| 220 base::Value* element = NULL; | 223 base::Value* element = NULL; |
| 221 if (!list->Get(i, &element)) | 224 if (!list->Get(i, &element)) |
| 222 continue; | 225 continue; |
| 223 | 226 |
| 224 Element e; | 227 Element e; |
| 225 if (!basic_converter_.Convert(*element, &e)) { | 228 if (basic_converter_.Convert(*element, &e)) { |
| 229 field->push_back(e); | |
| 230 } else { | |
| 226 DVLOG(1) << "failure at " << i << "-th element"; | 231 DVLOG(1) << "failure at " << i << "-th element"; |
| 227 return false; | 232 return false; |
| 228 } | 233 } |
| 229 field->push_back(e); | |
| 230 } | 234 } |
| 231 return true; | 235 return true; |
| 232 } | 236 } |
| 233 | 237 |
| 234 private: | 238 private: |
| 235 BasicValueConverter<Element> basic_converter_; | 239 BasicValueConverter<Element> basic_converter_; |
| 236 DISALLOW_COPY_AND_ASSIGN(RepeatedValueConverter); | 240 DISALLOW_COPY_AND_ASSIGN(RepeatedValueConverter); |
| 237 }; | 241 }; |
| 238 | 242 |
| 239 template <typename NestedType> | 243 template <typename NestedType> |
| 240 class RepeatedMessageConverter | 244 class RepeatedMessageConverter |
| 241 : public ValueConverter<std::vector<NestedType> > { | 245 : public ValueConverter<ScopedVector<NestedType> > { |
| 242 public: | 246 public: |
| 243 RepeatedMessageConverter() {} | 247 RepeatedMessageConverter() {} |
| 244 | 248 |
| 245 virtual bool Convert( | 249 virtual bool Convert(const base::Value& value, |
| 246 const base::Value& value, std::vector<NestedType>* field) const OVERRIDE { | 250 ScopedVector<NestedType>* field) const OVERRIDE { |
| 247 const base::ListValue* list = NULL; | 251 const base::ListValue* list = NULL; |
| 248 if (!value.GetAsList(&list)) | 252 if (!value.GetAsList(&list)) |
| 249 return false; | 253 return false; |
| 250 | 254 |
| 251 field->reserve(list->GetSize()); | 255 field->reserve(list->GetSize()); |
| 252 for (size_t i = 0; i < list->GetSize(); ++i) { | 256 for (size_t i = 0; i < list->GetSize(); ++i) { |
| 253 base::Value* element = NULL; | 257 base::Value* element = NULL; |
| 254 if (!list->Get(i, &element)) | 258 if (!list->Get(i, &element)) |
| 255 continue; | 259 continue; |
| 256 | 260 |
| 257 field->push_back(NestedType()); | 261 NestedType* nested = new NestedType(); |
| 258 if (!converter_.Convert(*element, &field->back())) { | 262 if (converter_.Convert(*element, nested)) { |
| 263 field->push_back(nested); | |
| 264 } else { | |
| 259 DVLOG(1) << "failure at " << i << "-th element"; | 265 DVLOG(1) << "failure at " << i << "-th element"; |
| 260 return false; | 266 return false; |
| 261 } | 267 } |
| 262 } | 268 } |
| 263 return true; | 269 return true; |
| 264 } | 270 } |
| 265 | 271 |
| 266 private: | 272 private: |
| 267 JSONValueConverter<NestedType> converter_; | 273 JSONValueConverter<NestedType> converter_; |
| 268 DISALLOW_COPY_AND_ASSIGN(RepeatedMessageConverter); | 274 DISALLOW_COPY_AND_ASSIGN(RepeatedMessageConverter); |
| 269 }; | 275 }; |
| 270 | 276 |
| 271 } // namespace internal | 277 } // namespace internal |
| 272 | 278 |
| 273 template <class StructType> | 279 template <class StructType> |
| 274 class JSONValueConverter { | 280 class JSONValueConverter { |
| 275 public: | 281 public: |
| 276 JSONValueConverter() { | 282 JSONValueConverter() { |
| 277 StructType::RegisterJSONConverter(this); | 283 StructType::RegisterJSONConverter(this); |
| 278 } | 284 } |
| 279 | 285 |
| 280 ~JSONValueConverter() { | |
| 281 STLDeleteContainerPointers(fields_.begin(), fields_.end()); | |
| 282 } | |
| 283 | |
| 284 void RegisterIntField(const std::string& field_name, | 286 void RegisterIntField(const std::string& field_name, |
| 285 int StructType::* field) { | 287 int StructType::* field) { |
| 286 fields_.push_back(new internal::FieldConverter<StructType, int>( | 288 fields_.push_back(new internal::FieldConverter<StructType, int>( |
| 287 field_name, field, new internal::BasicValueConverter<int>)); | 289 field_name, field, new internal::BasicValueConverter<int>)); |
| 288 } | 290 } |
| 289 | 291 |
| 290 void RegisterStringField(const std::string& field_name, | 292 void RegisterStringField(const std::string& field_name, |
| 291 std::string StructType::* field) { | 293 std::string StructType::* field) { |
| 292 fields_.push_back(new internal::FieldConverter<StructType, std::string>( | 294 fields_.push_back(new internal::FieldConverter<StructType, std::string>( |
| 293 field_name, field, new internal::BasicValueConverter<std::string>)); | 295 field_name, field, new internal::BasicValueConverter<std::string>)); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 354 | 356 |
| 355 void RegisterRepeatedBool(const std::string& field_name, | 357 void RegisterRepeatedBool(const std::string& field_name, |
| 356 std::vector<bool> StructType::* field) { | 358 std::vector<bool> StructType::* field) { |
| 357 fields_.push_back( | 359 fields_.push_back( |
| 358 new internal::FieldConverter<StructType, std::vector<bool> >( | 360 new internal::FieldConverter<StructType, std::vector<bool> >( |
| 359 field_name, field, new internal::RepeatedValueConverter<bool>)); | 361 field_name, field, new internal::RepeatedValueConverter<bool>)); |
| 360 } | 362 } |
| 361 | 363 |
| 362 template <class NestedType> | 364 template <class NestedType> |
| 363 void RegisterRepeatedMessage(const std::string& field_name, | 365 void RegisterRepeatedMessage(const std::string& field_name, |
| 364 std::vector<NestedType> StructType::* field) { | 366 ScopedVector<NestedType> StructType::* field) { |
| 365 fields_.push_back( | 367 fields_.push_back( |
| 366 new internal::FieldConverter<StructType, std::vector<NestedType> >( | 368 new internal::FieldConverter<StructType, ScopedVector<NestedType> >( |
| 367 field_name, | 369 field_name, |
| 368 field, | 370 field, |
| 369 new internal::RepeatedMessageConverter<NestedType>)); | 371 new internal::RepeatedMessageConverter<NestedType>)); |
| 370 } | 372 } |
| 371 | 373 |
| 372 bool Convert(const base::Value& value, StructType* output) const { | 374 bool Convert(const base::Value& value, StructType* output) const { |
| 373 const DictionaryValue* dictionary_value = NULL; | 375 const DictionaryValue* dictionary_value = NULL; |
| 374 if (!value.GetAsDictionary(&dictionary_value)) | 376 if (!value.GetAsDictionary(&dictionary_value)) |
| 375 return false; | 377 return false; |
| 376 | 378 |
| 377 for(std::vector<internal::FieldConverterBase*>::const_iterator it = | 379 for(size_t i = 0; i < fields_.size(); ++i) { |
| 378 fields_.begin(); it != fields_.end(); ++it) { | 380 const internal::FieldConverterBase* field_converter = fields_[i]; |
| 379 base::Value* field = NULL; | 381 base::Value* field = NULL; |
| 380 if (dictionary_value->Get((*it)->field_path(), &field)) { | 382 if (dictionary_value->Get(field_converter->field_path(), &field)) { |
| 381 if (!(*it)->ConvertField(*field, output)) { | 383 if (!field_converter->ConvertField(*field, output)) { |
| 382 DVLOG(1) << "failure at field " << (*it)->field_path(); | 384 DVLOG(1) << "failure at field " << field_converter->field_path(); |
| 383 return false; | 385 return false; |
| 384 } | 386 } |
| 385 } | 387 } |
| 386 } | 388 } |
| 387 return true; | 389 return true; |
| 388 } | 390 } |
| 389 | 391 |
| 390 private: | 392 private: |
| 391 std::vector<internal::FieldConverterBase*> fields_; | 393 ScopedVector<internal::FieldConverterBase> fields_; |
| 392 | 394 |
| 393 DISALLOW_COPY_AND_ASSIGN(JSONValueConverter); | 395 DISALLOW_COPY_AND_ASSIGN(JSONValueConverter); |
| 394 }; | 396 }; |
| 395 | 397 |
| 396 } // namespace base | 398 } // namespace base |
| 397 | 399 |
| 398 #endif // BASE_JSON_JSON_VALUE_CONVERTER_H_ | 400 #endif // BASE_JSON_JSON_VALUE_CONVERTER_H_ |
| OLD | NEW |