| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/stl_util.h" | 16 #include "base/stl_util.h" |
| 17 #include "base/string16.h" |
| 17 #include "base/values.h" | 18 #include "base/values.h" |
| 18 | 19 |
| 19 // JSONValueConverter converts a JSON value into a C++ struct in a | 20 // JSONValueConverter converts a JSON value into a C++ struct in a |
| 20 // lightweight way. | 21 // lightweight way. |
| 21 // | 22 // |
| 22 // Usage: | 23 // Usage: |
| 23 // For real examples, you may want to refer to _unittest.cc file. | 24 // For real examples, you may want to refer to _unittest.cc file. |
| 24 // | 25 // |
| 25 // Assume that you have a struct like this: | 26 // Assume that you have a struct like this: |
| 26 // struct Message { | 27 // struct Message { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 38 // converter->RegisterIntField("foo", &Message::foo); | 39 // converter->RegisterIntField("foo", &Message::foo); |
| 39 // converter->RegisterStringField("bar", &Message::bar); | 40 // converter->RegisterStringField("bar", &Message::bar); |
| 40 // } | 41 // } |
| 41 // | 42 // |
| 42 // Then, you just instantiate your JSONValueConverter of your type and call | 43 // Then, you just instantiate your JSONValueConverter of your type and call |
| 43 // Convert() method. | 44 // Convert() method. |
| 44 // Message message; | 45 // Message message; |
| 45 // JSONValueConverter<Message> converter; | 46 // JSONValueConverter<Message> converter; |
| 46 // converter.Convert(json, &message); | 47 // converter.Convert(json, &message); |
| 47 // | 48 // |
| 49 // Convert() returns false when it fails. Here "fail" means that the value is |
| 50 // structurally different from expected, such like a string value appears |
| 51 // for an int field. Do not report failures for missing fields. |
| 52 // Also note that Convert() will modify the passed |message| even when it |
| 53 // fails for performance reason. |
| 54 // |
| 48 // For nested field, the internal message also has to implement the registration | 55 // For nested field, the internal message also has to implement the registration |
| 49 // method. Then, just use RegisterNestedField() from the containing struct's | 56 // method. Then, just use RegisterNestedField() from the containing struct's |
| 50 // RegisterJSONConverter method. | 57 // RegisterJSONConverter method. |
| 51 // struct Nested { | 58 // struct Nested { |
| 52 // Message foo; | 59 // Message foo; |
| 53 // void RegisterJSONConverter(...) { | 60 // static void RegisterJSONConverter(...) { |
| 54 // ... | 61 // ... |
| 55 // converter->RegisterNestedField("foo", &Nested::foo); | 62 // converter->RegisterNestedField("foo", &Nested::foo); |
| 56 // } | 63 // } |
| 57 // }; | 64 // }; |
| 58 // | 65 // |
| 59 // For repeated field, we just assume std::vector for its container | 66 // For repeated field, we just assume std::vector for its container |
| 60 // and you can put RegisterRepeatedInt or some other types. Use | 67 // and you can put RegisterRepeatedInt or some other types. Use |
| 61 // RegisterRepeatedMessage for nested repeated fields. | 68 // RegisterRepeatedMessage for nested repeated fields. |
| 62 // | 69 // |
| 63 | 70 |
| 64 namespace base { | 71 namespace base { |
| 65 | 72 |
| 66 template <typename StructType> | 73 template <typename StructType> |
| 67 class JSONValueConverter; | 74 class JSONValueConverter; |
| 68 | 75 |
| 69 namespace internal { | 76 namespace internal { |
| 70 | 77 |
| 71 class FieldConverterBase { | 78 class FieldConverterBase { |
| 72 public: | 79 public: |
| 73 BASE_EXPORT explicit FieldConverterBase(const std::string& path); | 80 BASE_EXPORT explicit FieldConverterBase(const std::string& path); |
| 74 BASE_EXPORT virtual ~FieldConverterBase(); | 81 BASE_EXPORT virtual ~FieldConverterBase(); |
| 75 virtual void ConvertField(const base::Value& value, void* obj) const = 0; | 82 virtual bool ConvertField(const base::Value& value, void* obj) const = 0; |
| 76 const std::string& field_path() const { return field_path_; } | 83 const std::string& field_path() const { return field_path_; } |
| 77 | 84 |
| 78 private: | 85 private: |
| 79 std::string field_path_; | 86 std::string field_path_; |
| 80 DISALLOW_COPY_AND_ASSIGN(FieldConverterBase); | 87 DISALLOW_COPY_AND_ASSIGN(FieldConverterBase); |
| 81 }; | 88 }; |
| 82 | 89 |
| 83 template <typename FieldType> | 90 template <typename FieldType> |
| 84 class ValueConverter { | 91 class ValueConverter { |
| 85 public: | 92 public: |
| 86 virtual ~ValueConverter() {} | 93 virtual ~ValueConverter() {} |
| 87 virtual void Convert(const base::Value& value, FieldType* field) const = 0; | 94 virtual bool Convert(const base::Value& value, FieldType* field) const = 0; |
| 88 }; | 95 }; |
| 89 | 96 |
| 90 template <typename StructType, typename FieldType> | 97 template <typename StructType, typename FieldType> |
| 91 class FieldConverter : public FieldConverterBase { | 98 class FieldConverter : public FieldConverterBase { |
| 92 public: | 99 public: |
| 93 explicit FieldConverter(const std::string& path, | 100 explicit FieldConverter(const std::string& path, |
| 94 FieldType StructType::* field, | 101 FieldType StructType::* field, |
| 95 ValueConverter<FieldType>* converter) | 102 ValueConverter<FieldType>* converter) |
| 96 : FieldConverterBase(path), | 103 : FieldConverterBase(path), |
| 97 field_pointer_(field), | 104 field_pointer_(field), |
| 98 value_converter_(converter) { | 105 value_converter_(converter) { |
| 99 } | 106 } |
| 100 | 107 |
| 101 virtual void ConvertField( | 108 virtual bool ConvertField( |
| 102 const base::Value& value, void* obj) const OVERRIDE { | 109 const base::Value& value, void* obj) const OVERRIDE { |
| 103 StructType* dst = reinterpret_cast<StructType*>(obj); | 110 StructType* dst = reinterpret_cast<StructType*>(obj); |
| 104 value_converter_->Convert(value, &(dst->*field_pointer_)); | 111 return value_converter_->Convert(value, &(dst->*field_pointer_)); |
| 105 } | 112 } |
| 106 | 113 |
| 107 private: | 114 private: |
| 108 FieldType StructType::* field_pointer_; | 115 FieldType StructType::* field_pointer_; |
| 109 scoped_ptr<ValueConverter<FieldType> > value_converter_; | 116 scoped_ptr<ValueConverter<FieldType> > value_converter_; |
| 110 DISALLOW_COPY_AND_ASSIGN(FieldConverter); | 117 DISALLOW_COPY_AND_ASSIGN(FieldConverter); |
| 111 }; | 118 }; |
| 112 | 119 |
| 113 template <typename FieldType> | 120 template <typename FieldType> |
| 114 class BasicValueConverter; | 121 class BasicValueConverter; |
| 115 | 122 |
| 116 template <> | 123 template <> |
| 117 class BasicValueConverter<int> : public ValueConverter<int> { | 124 class BasicValueConverter<int> : public ValueConverter<int> { |
| 118 public: | 125 public: |
| 119 BasicValueConverter() {} | 126 BasicValueConverter() {} |
| 120 | 127 |
| 121 virtual void Convert(const base::Value& value, int* field) const OVERRIDE { | 128 virtual bool Convert(const base::Value& value, int* field) const OVERRIDE { |
| 122 value.GetAsInteger(field); | 129 return value.GetAsInteger(field); |
| 123 } | 130 } |
| 124 | 131 |
| 125 private: | 132 private: |
| 126 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter); | 133 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter); |
| 127 }; | 134 }; |
| 128 | 135 |
| 129 template <> | 136 template <> |
| 130 class BasicValueConverter<std::string> : public ValueConverter<std::string> { | 137 class BasicValueConverter<std::string> : public ValueConverter<std::string> { |
| 131 public: | 138 public: |
| 132 BasicValueConverter() {} | 139 BasicValueConverter() {} |
| 133 | 140 |
| 134 virtual void Convert( | 141 virtual bool Convert( |
| 135 const base::Value& value, std::string* field) const OVERRIDE { | 142 const base::Value& value, std::string* field) const OVERRIDE { |
| 136 value.GetAsString(field); | 143 return value.GetAsString(field); |
| 137 } | 144 } |
| 138 | 145 |
| 139 private: | 146 private: |
| 147 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter); |
| 148 }; |
| 149 |
| 150 template <> |
| 151 class BasicValueConverter<string16> : public ValueConverter<string16> { |
| 152 public: |
| 153 BasicValueConverter() {} |
| 154 |
| 155 virtual bool Convert( |
| 156 const base::Value& value, string16* field) const OVERRIDE { |
| 157 return value.GetAsString(field); |
| 158 } |
| 159 |
| 160 private: |
| 140 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter); | 161 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter); |
| 141 }; | 162 }; |
| 142 | 163 |
| 143 template <> | 164 template <> |
| 144 class BasicValueConverter<double> : public ValueConverter<double> { | 165 class BasicValueConverter<double> : public ValueConverter<double> { |
| 145 public: | 166 public: |
| 146 BasicValueConverter() {} | 167 BasicValueConverter() {} |
| 147 | 168 |
| 148 virtual void Convert(const base::Value& value, double* field) const OVERRIDE { | 169 virtual bool Convert(const base::Value& value, double* field) const OVERRIDE { |
| 149 value.GetAsDouble(field); | 170 return value.GetAsDouble(field); |
| 150 } | 171 } |
| 151 | 172 |
| 152 private: | 173 private: |
| 153 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter); | 174 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter); |
| 154 }; | 175 }; |
| 155 | 176 |
| 156 template <> | 177 template <> |
| 157 class BasicValueConverter<bool> : public ValueConverter<bool> { | 178 class BasicValueConverter<bool> : public ValueConverter<bool> { |
| 158 public: | 179 public: |
| 159 BasicValueConverter() {} | 180 BasicValueConverter() {} |
| 160 | 181 |
| 161 virtual void Convert(const base::Value& value, bool* field) const OVERRIDE { | 182 virtual bool Convert(const base::Value& value, bool* field) const OVERRIDE { |
| 162 value.GetAsBoolean(field); | 183 return value.GetAsBoolean(field); |
| 163 } | 184 } |
| 164 | 185 |
| 165 private: | 186 private: |
| 166 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter); | 187 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter); |
| 167 }; | 188 }; |
| 168 | 189 |
| 169 template <typename NestedType> | 190 template <typename NestedType> |
| 170 class NestedValueConverter : public ValueConverter<NestedType> { | 191 class NestedValueConverter : public ValueConverter<NestedType> { |
| 171 public: | 192 public: |
| 172 NestedValueConverter() {} | 193 NestedValueConverter() {} |
| 173 | 194 |
| 174 virtual void Convert( | 195 virtual bool Convert( |
| 175 const base::Value& value, NestedType* field) const OVERRIDE { | 196 const base::Value& value, NestedType* field) const OVERRIDE { |
| 176 converter_.Convert(value, field); | 197 return converter_.Convert(value, field); |
| 177 } | 198 } |
| 178 | 199 |
| 179 private: | 200 private: |
| 180 JSONValueConverter<NestedType> converter_; | 201 JSONValueConverter<NestedType> converter_; |
| 181 DISALLOW_COPY_AND_ASSIGN(NestedValueConverter); | 202 DISALLOW_COPY_AND_ASSIGN(NestedValueConverter); |
| 182 }; | 203 }; |
| 183 | 204 |
| 184 template <typename Element> | 205 template <typename Element> |
| 185 class RepeatedValueConverter : public ValueConverter<std::vector<Element> > { | 206 class RepeatedValueConverter : public ValueConverter<std::vector<Element> > { |
| 186 public: | 207 public: |
| 187 RepeatedValueConverter() {} | 208 RepeatedValueConverter() {} |
| 188 | 209 |
| 189 virtual void Convert( | 210 virtual bool Convert( |
| 190 const base::Value& value, std::vector<Element>* field) const OVERRIDE { | 211 const base::Value& value, std::vector<Element>* field) const OVERRIDE { |
| 191 const base::ListValue* list = NULL; | 212 const base::ListValue* list = NULL; |
| 192 if (!value.GetAsList(&list)) { | 213 if (!value.GetAsList(&list)) { |
| 193 // The field is not a list. | 214 // The field is not a list. |
| 194 return; | 215 return false; |
| 195 } | 216 } |
| 196 | 217 |
| 197 field->reserve(list->GetSize()); | 218 field->reserve(list->GetSize()); |
| 198 for (size_t i = 0; i < list->GetSize(); ++i) { | 219 for (size_t i = 0; i < list->GetSize(); ++i) { |
| 199 base::Value* element = NULL; | 220 base::Value* element = NULL; |
| 200 if (!list->Get(i, &element)) | 221 if (!list->Get(i, &element)) |
| 201 continue; | 222 continue; |
| 202 | 223 |
| 203 Element e; | 224 Element e; |
| 204 basic_converter_.Convert(*element, &e); | 225 if (!basic_converter_.Convert(*element, &e)) { |
| 226 DVLOG(1) << "failure at " << i << "-th element"; |
| 227 return false; |
| 228 } |
| 205 field->push_back(e); | 229 field->push_back(e); |
| 206 } | 230 } |
| 231 return true; |
| 207 } | 232 } |
| 208 | 233 |
| 209 private: | 234 private: |
| 210 BasicValueConverter<Element> basic_converter_; | 235 BasicValueConverter<Element> basic_converter_; |
| 211 DISALLOW_COPY_AND_ASSIGN(RepeatedValueConverter); | 236 DISALLOW_COPY_AND_ASSIGN(RepeatedValueConverter); |
| 212 }; | 237 }; |
| 213 | 238 |
| 214 template <typename NestedType> | 239 template <typename NestedType> |
| 215 class RepeatedMessageConverter | 240 class RepeatedMessageConverter |
| 216 : public ValueConverter<std::vector<NestedType> > { | 241 : public ValueConverter<std::vector<NestedType> > { |
| 217 public: | 242 public: |
| 218 RepeatedMessageConverter() {} | 243 RepeatedMessageConverter() {} |
| 219 | 244 |
| 220 virtual void Convert( | 245 virtual bool Convert( |
| 221 const base::Value& value, std::vector<NestedType>* field) const OVERRIDE { | 246 const base::Value& value, std::vector<NestedType>* field) const OVERRIDE { |
| 222 const base::ListValue* list = NULL; | 247 const base::ListValue* list = NULL; |
| 223 if (!value.GetAsList(&list)) | 248 if (!value.GetAsList(&list)) |
| 224 return; | 249 return false; |
| 225 | 250 |
| 226 field->reserve(list->GetSize()); | 251 field->reserve(list->GetSize()); |
| 227 for (size_t i = 0; i < list->GetSize(); ++i) { | 252 for (size_t i = 0; i < list->GetSize(); ++i) { |
| 228 base::Value* element = NULL; | 253 base::Value* element = NULL; |
| 229 if (!list->Get(i, &element)) | 254 if (!list->Get(i, &element)) |
| 230 continue; | 255 continue; |
| 231 | 256 |
| 232 field->push_back(NestedType()); | 257 field->push_back(NestedType()); |
| 233 converter_.Convert(*element, &field->back()); | 258 if (!converter_.Convert(*element, &field->back())) { |
| 259 DVLOG(1) << "failure at " << i << "-th element"; |
| 260 return false; |
| 261 } |
| 234 } | 262 } |
| 263 return true; |
| 235 } | 264 } |
| 236 | 265 |
| 237 private: | 266 private: |
| 238 JSONValueConverter<NestedType> converter_; | 267 JSONValueConverter<NestedType> converter_; |
| 239 DISALLOW_COPY_AND_ASSIGN(RepeatedMessageConverter); | 268 DISALLOW_COPY_AND_ASSIGN(RepeatedMessageConverter); |
| 240 }; | 269 }; |
| 241 | 270 |
| 242 } // namespace internal | 271 } // namespace internal |
| 243 | 272 |
| 244 template <class StructType> | 273 template <class StructType> |
| 245 class JSONValueConverter { | 274 class JSONValueConverter { |
| 246 public: | 275 public: |
| 247 JSONValueConverter() { | 276 JSONValueConverter() { |
| 248 StructType::RegisterJSONConverter(this); | 277 StructType::RegisterJSONConverter(this); |
| 249 } | 278 } |
| 250 | 279 |
| 251 ~JSONValueConverter() { | 280 ~JSONValueConverter() { |
| 252 STLDeleteContainerPointers(fields_.begin(), fields_.end()); | 281 STLDeleteContainerPointers(fields_.begin(), fields_.end()); |
| 253 } | 282 } |
| 254 | 283 |
| 255 void RegisterIntField(const std::string& field_name, | 284 void RegisterIntField(const std::string& field_name, |
| 256 int StructType::* field) { | 285 int StructType::* field) { |
| 257 fields_.push_back(new internal::FieldConverter<StructType, int>( | 286 fields_.push_back(new internal::FieldConverter<StructType, int>( |
| 258 field_name, field, new internal::BasicValueConverter<int>)); | 287 field_name, field, new internal::BasicValueConverter<int>)); |
| 259 } | 288 } |
| 260 | 289 |
| 261 void RegisterStringField(const std::string& field_name, | 290 void RegisterStringField(const std::string& field_name, |
| 262 std::string StructType::* field) { | 291 std::string StructType::* field) { |
| 263 fields_.push_back(new internal::FieldConverter<StructType, std::string>( | 292 fields_.push_back(new internal::FieldConverter<StructType, std::string>( |
| 264 field_name, field, new internal::BasicValueConverter<std::string>)); | 293 field_name, field, new internal::BasicValueConverter<std::string>)); |
| 265 } | 294 } |
| 266 | 295 |
| 296 void RegisterStringField(const std::string& field_name, |
| 297 string16 StructType::* field) { |
| 298 fields_.push_back(new internal::FieldConverter<StructType, string16>( |
| 299 field_name, field, new internal::BasicValueConverter<string16>)); |
| 300 } |
| 301 |
| 267 void RegisterBoolField(const std::string& field_name, | 302 void RegisterBoolField(const std::string& field_name, |
| 268 bool StructType::* field) { | 303 bool StructType::* field) { |
| 269 fields_.push_back(new internal::FieldConverter<StructType, bool>( | 304 fields_.push_back(new internal::FieldConverter<StructType, bool>( |
| 270 field_name, field, new internal::BasicValueConverter<bool>)); | 305 field_name, field, new internal::BasicValueConverter<bool>)); |
| 271 } | 306 } |
| 272 | 307 |
| 273 void RegisterDoubleField(const std::string& field_name, | 308 void RegisterDoubleField(const std::string& field_name, |
| 274 double StructType::* field) { | 309 double StructType::* field) { |
| 275 fields_.push_back(new internal::FieldConverter<StructType, double>( | 310 fields_.push_back(new internal::FieldConverter<StructType, double>( |
| 276 field_name, field, new internal::BasicValueConverter<double>)); | 311 field_name, field, new internal::BasicValueConverter<double>)); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 294 | 329 |
| 295 void RegisterRepeatedString(const std::string& field_name, | 330 void RegisterRepeatedString(const std::string& field_name, |
| 296 std::vector<std::string> StructType::* field) { | 331 std::vector<std::string> StructType::* field) { |
| 297 fields_.push_back( | 332 fields_.push_back( |
| 298 new internal::FieldConverter<StructType, std::vector<std::string> >( | 333 new internal::FieldConverter<StructType, std::vector<std::string> >( |
| 299 field_name, | 334 field_name, |
| 300 field, | 335 field, |
| 301 new internal::RepeatedValueConverter<std::string>)); | 336 new internal::RepeatedValueConverter<std::string>)); |
| 302 } | 337 } |
| 303 | 338 |
| 339 void RegisterRepeatedString(const std::string& field_name, |
| 340 std::vector<string16> StructType::* field) { |
| 341 fields_.push_back( |
| 342 new internal::FieldConverter<StructType, std::vector<string16> >( |
| 343 field_name, |
| 344 field, |
| 345 new internal::RepeatedValueConverter<string16>)); |
| 346 } |
| 347 |
| 304 void RegisterRepeatedDouble(const std::string& field_name, | 348 void RegisterRepeatedDouble(const std::string& field_name, |
| 305 std::vector<double> StructType::* field) { | 349 std::vector<double> StructType::* field) { |
| 306 fields_.push_back( | 350 fields_.push_back( |
| 307 new internal::FieldConverter<StructType, std::vector<double> >( | 351 new internal::FieldConverter<StructType, std::vector<double> >( |
| 308 field_name, field, new internal::RepeatedValueConverter<double>)); | 352 field_name, field, new internal::RepeatedValueConverter<double>)); |
| 309 } | 353 } |
| 310 | 354 |
| 311 void RegisterRepeatedBool(const std::string& field_name, | 355 void RegisterRepeatedBool(const std::string& field_name, |
| 312 std::vector<bool> StructType::* field) { | 356 std::vector<bool> StructType::* field) { |
| 313 fields_.push_back( | 357 fields_.push_back( |
| 314 new internal::FieldConverter<StructType, std::vector<bool> >( | 358 new internal::FieldConverter<StructType, std::vector<bool> >( |
| 315 field_name, field, new internal::RepeatedValueConverter<bool>)); | 359 field_name, field, new internal::RepeatedValueConverter<bool>)); |
| 316 } | 360 } |
| 317 | 361 |
| 318 template <class NestedType> | 362 template <class NestedType> |
| 319 void RegisterRepeatedMessage(const std::string& field_name, | 363 void RegisterRepeatedMessage(const std::string& field_name, |
| 320 std::vector<NestedType> StructType::* field) { | 364 std::vector<NestedType> StructType::* field) { |
| 321 fields_.push_back( | 365 fields_.push_back( |
| 322 new internal::FieldConverter<StructType, std::vector<NestedType> >( | 366 new internal::FieldConverter<StructType, std::vector<NestedType> >( |
| 323 field_name, | 367 field_name, |
| 324 field, | 368 field, |
| 325 new internal::RepeatedMessageConverter<NestedType>)); | 369 new internal::RepeatedMessageConverter<NestedType>)); |
| 326 } | 370 } |
| 327 | 371 |
| 328 void Convert(const base::Value& value, StructType* output) const { | 372 bool Convert(const base::Value& value, StructType* output) const { |
| 329 const DictionaryValue* dictionary_value = NULL; | 373 const DictionaryValue* dictionary_value = NULL; |
| 330 if (!value.GetAsDictionary(&dictionary_value)) | 374 if (!value.GetAsDictionary(&dictionary_value)) |
| 331 return; | 375 return false; |
| 332 | 376 |
| 333 for(std::vector<internal::FieldConverterBase*>::const_iterator it = | 377 for(std::vector<internal::FieldConverterBase*>::const_iterator it = |
| 334 fields_.begin(); it != fields_.end(); ++it) { | 378 fields_.begin(); it != fields_.end(); ++it) { |
| 335 base::Value* field = NULL; | 379 base::Value* field = NULL; |
| 336 if (dictionary_value->Get((*it)->field_path(), &field)) { | 380 if (dictionary_value->Get((*it)->field_path(), &field)) { |
| 337 (*it)->ConvertField(*field, output); | 381 if (!(*it)->ConvertField(*field, output)) { |
| 382 DVLOG(1) << "failure at field " << (*it)->field_path(); |
| 383 return false; |
| 384 } |
| 338 } | 385 } |
| 339 } | 386 } |
| 387 return true; |
| 340 } | 388 } |
| 341 | 389 |
| 342 private: | 390 private: |
| 343 std::vector<internal::FieldConverterBase*> fields_; | 391 std::vector<internal::FieldConverterBase*> fields_; |
| 344 | 392 |
| 345 DISALLOW_COPY_AND_ASSIGN(JSONValueConverter); | 393 DISALLOW_COPY_AND_ASSIGN(JSONValueConverter); |
| 346 }; | 394 }; |
| 347 | 395 |
| 348 } // namespace base | 396 } // namespace base |
| 349 | 397 |
| 350 #endif // BASE_JSON_JSON_VALUE_CONVERTER_H_ | 398 #endif // BASE_JSON_JSON_VALUE_CONVERTER_H_ |
| OLD | NEW |