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

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

Issue 10440101: ABANDONED: Update base::JSONValueConverter to support custom actions. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rename constants in test Created 8 years, 6 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 | Annotate | Revision Log
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 #pragma once 7 #pragma once
8 8
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 // static void RegisterJSONConverter(...) { 61 // static void RegisterJSONConverter(...) {
62 // ... 62 // ...
63 // converter->RegisterNestedField("foo", &Nested::foo); 63 // converter->RegisterNestedField("foo", &Nested::foo);
64 // } 64 // }
65 // }; 65 // };
66 // 66 //
67 // For repeated field, we just assume ScopedVector for its container 67 // For repeated field, we just assume ScopedVector for its container
68 // and you can put RegisterRepeatedInt or some other types. Use 68 // and you can put RegisterRepeatedInt or some other types. Use
69 // RegisterRepeatedMessage for nested repeated fields. 69 // RegisterRepeatedMessage for nested repeated fields.
70 // 70 //
71 // Sometimes JSON format uses string representations for other types such 71 // Sometimes JSON format uses string representations for other types such like
72 // like enum, timestamp, or URL. You can use RegisterCustomField method 72 // enum, timestamp, or URL. You can use RegisterCustomField() and specify a
73 // and specify a function to convert a StringPiece to your type. 73 // function to convert a StringPiece to your type.
74 // bool ConvertFunc(const StringPiece& s, YourEnum* result) { 74 // bool ConvertFunc(const StringPiece& s, YourEnum* result) {
75 // // do something and return true if succeed... 75 // // do something and return true if succeed...
76 // } 76 // }
77 // struct Message { 77 // struct Message {
78 // YourEnum ye; 78 // YourEnum ye;
79 // ... 79 // ...
80 // static void RegisterJSONConverter(...) { 80 // static void RegisterJSONConverter(...) {
81 // ... 81 // ...
82 // converter->RegsiterCustomField<YourEnum>( 82 // converter->RegisterCustomField<YourEnum>(
83 // "your_enum", &Message::ye, &ConvertFunc); 83 // "your_enum", &Message::ye, &ConvertFunc);
84 // } 84 // }
85 // }; 85 // };
86 //
87 // If you want to perform an arbitrary action in response to a particular field
88 // (e.g. perhaps it's a dictionary and you want to conditionally save one of its
89 // fields to your message depending on the value of another of its fields),
90 // RegisterCustomAction() can be used. If the field contains a list,
91 // RegisterRepeatedCustomAction() can be used to specify that the handler
92 // function should be invoked for each value in the list. Note that the handler
93 // should still return true even if it takes no action; false should only be
94 // returned if the data is malformed and conversion has failed.
86 95
87 namespace base { 96 namespace base {
88 97
89 template <typename StructType> 98 template <typename StructType>
90 class JSONValueConverter; 99 class JSONValueConverter;
91 100
92 namespace internal { 101 namespace internal {
93 102
94 template<typename StructType> 103 // Interface for classes that handle a base::Value located at a particular path.
95 class FieldConverterBase { 104 template <typename StructType>
105 class FieldHandlerBase {
96 public: 106 public:
97 explicit FieldConverterBase(const std::string& path) : field_path_(path) {} 107 explicit FieldHandlerBase(const std::string& path) : field_path_(path) {}
98 virtual ~FieldConverterBase() {} 108 virtual ~FieldHandlerBase() {}
99 virtual bool ConvertField(const base::Value& value, StructType* obj) 109 virtual bool HandleField(const base::Value& value, StructType* obj)
100 const = 0; 110 const = 0;
101 const std::string& field_path() const { return field_path_; } 111 const std::string& field_path() const { return field_path_; }
102 112
103 private: 113 private:
104 std::string field_path_; 114 std::string field_path_;
105 DISALLOW_COPY_AND_ASSIGN(FieldConverterBase); 115 DISALLOW_COPY_AND_ASSIGN(FieldHandlerBase);
106 }; 116 };
107 117
118 // Interface for classes that convert base::Values as needed and write them to
119 // passed-in fields.
108 template <typename FieldType> 120 template <typename FieldType>
109 class ValueConverter { 121 class ValueConverterBase {
110 public: 122 public:
111 virtual ~ValueConverter() {} 123 virtual ~ValueConverterBase() {}
112 virtual bool Convert(const base::Value& value, FieldType* field) const = 0; 124 virtual bool Convert(const base::Value& value, FieldType* field) const = 0;
113 }; 125 };
114 126
127 // FieldHandlerBase implementation that uses a ValueConverterBase to convert a
128 // base::Value and write it to a passed-in field.
115 template <typename StructType, typename FieldType> 129 template <typename StructType, typename FieldType>
116 class FieldConverter : public FieldConverterBase<StructType> { 130 class FieldConverter : public FieldHandlerBase<StructType> {
117 public: 131 public:
118 explicit FieldConverter(const std::string& path, 132 FieldConverter(const std::string& path,
119 FieldType StructType::* field, 133 FieldType StructType::* field,
120 ValueConverter<FieldType>* converter) 134 ValueConverterBase<FieldType>* converter)
121 : FieldConverterBase<StructType>(path), 135 : FieldHandlerBase<StructType>(path),
122 field_pointer_(field), 136 field_pointer_(field),
123 value_converter_(converter) { 137 value_converter_(converter) {
124 } 138 }
125 139
126 virtual bool ConvertField( 140 virtual bool HandleField(
127 const base::Value& value, StructType* dst) const OVERRIDE { 141 const base::Value& value, StructType* dst) const OVERRIDE {
128 return value_converter_->Convert(value, &(dst->*field_pointer_)); 142 return value_converter_->Convert(value, &(dst->*field_pointer_));
129 } 143 }
130 144
131 private: 145 private:
132 FieldType StructType::* field_pointer_; 146 FieldType StructType::* field_pointer_;
133 scoped_ptr<ValueConverter<FieldType> > value_converter_; 147 scoped_ptr<ValueConverterBase<FieldType> > value_converter_;
134 DISALLOW_COPY_AND_ASSIGN(FieldConverter); 148 DISALLOW_COPY_AND_ASSIGN(FieldConverter);
135 }; 149 };
136 150
151 // FieldHandlerBase implementation that passes the bare base::Value and the
152 // destination object (as opposed to a field within the object) to a function
153 // that can process and apply the value however it wants.
154 template <typename StructType>
155 class FieldActionRunner : public FieldHandlerBase<StructType> {
156 public:
157 typedef bool(*ActionFunc)(const base::Value* value, StructType* obj);
158
159 // If |repeated| is true, the field is expected to contain a list.
160 // |action_func| will be invoked with each of its elements.
161 FieldActionRunner(const std::string& path,
162 bool repeated,
163 ActionFunc action_func)
164 : FieldHandlerBase<StructType>(path),
165 repeated_(repeated),
166 action_func_(action_func) {
167 }
168
169 virtual bool HandleField(const base::Value& value,
170 StructType* obj) const OVERRIDE {
171 if (!repeated_) {
172 return action_func_(&value, obj);
173 } else {
174 const base::ListValue* list = NULL;
175 if (!value.GetAsList(&list))
176 return false;
177
178 for (size_t i = 0; i < list->GetSize(); ++i) {
179 base::Value* element = NULL;
180 CHECK(list->Get(i, &element));
181 if (!action_func_(element, obj))
182 return false;
183 }
184 return true;
185 }
186 }
187
188 private:
189 bool repeated_;
190 ActionFunc action_func_;
191 DISALLOW_COPY_AND_ASSIGN(FieldActionRunner);
192 };
193
137 template <typename FieldType> 194 template <typename FieldType>
138 class BasicValueConverter; 195 class BasicValueConverter;
139 196
140 template <> 197 template <>
141 class BasicValueConverter<int> : public ValueConverter<int> { 198 class BasicValueConverter<int> : public ValueConverterBase<int> {
142 public: 199 public:
143 BasicValueConverter() {} 200 BasicValueConverter() {}
144 201
145 virtual bool Convert(const base::Value& value, int* field) const OVERRIDE { 202 virtual bool Convert(const base::Value& value, int* field) const OVERRIDE {
146 return value.GetAsInteger(field); 203 return value.GetAsInteger(field);
147 } 204 }
148 205
149 private: 206 private:
150 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter); 207 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
151 }; 208 };
152 209
153 template <> 210 template <>
154 class BasicValueConverter<std::string> : public ValueConverter<std::string> { 211 class BasicValueConverter<std::string>
212 : public ValueConverterBase<std::string> {
155 public: 213 public:
156 BasicValueConverter() {} 214 BasicValueConverter() {}
157 215
158 virtual bool Convert( 216 virtual bool Convert(
159 const base::Value& value, std::string* field) const OVERRIDE { 217 const base::Value& value, std::string* field) const OVERRIDE {
160 return value.GetAsString(field); 218 return value.GetAsString(field);
161 } 219 }
162 220
163 private: 221 private:
164 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter); 222 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
165 }; 223 };
166 224
167 template <> 225 template <>
168 class BasicValueConverter<string16> : public ValueConverter<string16> { 226 class BasicValueConverter<string16> : public ValueConverterBase<string16> {
169 public: 227 public:
170 BasicValueConverter() {} 228 BasicValueConverter() {}
171 229
172 virtual bool Convert( 230 virtual bool Convert(
173 const base::Value& value, string16* field) const OVERRIDE { 231 const base::Value& value, string16* field) const OVERRIDE {
174 return value.GetAsString(field); 232 return value.GetAsString(field);
175 } 233 }
176 234
177 private: 235 private:
178 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter); 236 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
179 }; 237 };
180 238
181 template <> 239 template <>
182 class BasicValueConverter<double> : public ValueConverter<double> { 240 class BasicValueConverter<double> : public ValueConverterBase<double> {
183 public: 241 public:
184 BasicValueConverter() {} 242 BasicValueConverter() {}
185 243
186 virtual bool Convert(const base::Value& value, double* field) const OVERRIDE { 244 virtual bool Convert(const base::Value& value, double* field) const OVERRIDE {
187 return value.GetAsDouble(field); 245 return value.GetAsDouble(field);
188 } 246 }
189 247
190 private: 248 private:
191 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter); 249 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
192 }; 250 };
193 251
194 template <> 252 template <>
195 class BasicValueConverter<bool> : public ValueConverter<bool> { 253 class BasicValueConverter<bool> : public ValueConverterBase<bool> {
196 public: 254 public:
197 BasicValueConverter() {} 255 BasicValueConverter() {}
198 256
199 virtual bool Convert(const base::Value& value, bool* field) const OVERRIDE { 257 virtual bool Convert(const base::Value& value, bool* field) const OVERRIDE {
200 return value.GetAsBoolean(field); 258 return value.GetAsBoolean(field);
201 } 259 }
202 260
203 private: 261 private:
204 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter); 262 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
205 }; 263 };
206 264
207 template <typename FieldType> 265 template <typename FieldType>
208 class ValueFieldConverter : public ValueConverter<FieldType> { 266 class ValueFieldConverter : public ValueConverterBase<FieldType> {
209 public: 267 public:
210 typedef bool(*ConvertFunc)(const base::Value* value, FieldType* field); 268 typedef bool(*ConvertFunc)(const base::Value* value, FieldType* field);
211 269
212 ValueFieldConverter(ConvertFunc convert_func) 270 ValueFieldConverter(ConvertFunc convert_func)
213 : convert_func_(convert_func) {} 271 : convert_func_(convert_func) {}
214 272
215 virtual bool Convert(const base::Value& value, 273 virtual bool Convert(const base::Value& value,
216 FieldType* field) const OVERRIDE { 274 FieldType* field) const OVERRIDE {
217 return convert_func_(&value, field); 275 return convert_func_(&value, field);
218 } 276 }
219 277
220 private: 278 private:
221 ConvertFunc convert_func_; 279 ConvertFunc convert_func_;
222 280
223 DISALLOW_COPY_AND_ASSIGN(ValueFieldConverter); 281 DISALLOW_COPY_AND_ASSIGN(ValueFieldConverter);
224 }; 282 };
225 283
226 template <typename FieldType> 284 template <typename FieldType>
227 class CustomFieldConverter : public ValueConverter<FieldType> { 285 class CustomFieldConverter : public ValueConverterBase<FieldType> {
228 public: 286 public:
229 typedef bool(*ConvertFunc)(const StringPiece& value, FieldType* field); 287 typedef bool(*ConvertFunc)(const StringPiece& value, FieldType* field);
230 288
231 CustomFieldConverter(ConvertFunc convert_func) 289 CustomFieldConverter(ConvertFunc convert_func)
232 : convert_func_(convert_func) {} 290 : convert_func_(convert_func) {}
233 291
234 virtual bool Convert(const base::Value& value, 292 virtual bool Convert(const base::Value& value,
235 FieldType* field) const OVERRIDE { 293 FieldType* field) const OVERRIDE {
236 std::string string_value; 294 std::string string_value;
237 return value.GetAsString(&string_value) && 295 return value.GetAsString(&string_value) &&
238 convert_func_(string_value, field); 296 convert_func_(string_value, field);
239 } 297 }
240 298
241 private: 299 private:
242 ConvertFunc convert_func_; 300 ConvertFunc convert_func_;
243 301
244 DISALLOW_COPY_AND_ASSIGN(CustomFieldConverter); 302 DISALLOW_COPY_AND_ASSIGN(CustomFieldConverter);
245 }; 303 };
246 304
247 template <typename NestedType> 305 template <typename NestedType>
248 class NestedValueConverter : public ValueConverter<NestedType> { 306 class NestedValueConverter : public ValueConverterBase<NestedType> {
249 public: 307 public:
250 NestedValueConverter() {} 308 NestedValueConverter() {}
251 309
252 virtual bool Convert( 310 virtual bool Convert(
253 const base::Value& value, NestedType* field) const OVERRIDE { 311 const base::Value& value, NestedType* field) const OVERRIDE {
254 return converter_.Convert(value, field); 312 return converter_.Convert(value, field);
255 } 313 }
256 314
257 private: 315 private:
258 JSONValueConverter<NestedType> converter_; 316 JSONValueConverter<NestedType> converter_;
259 DISALLOW_COPY_AND_ASSIGN(NestedValueConverter); 317 DISALLOW_COPY_AND_ASSIGN(NestedValueConverter);
260 }; 318 };
261 319
262 template <typename Element> 320 template <typename Element>
263 class RepeatedValueConverter : public ValueConverter<ScopedVector<Element> > { 321 class RepeatedValueConverter
322 : public ValueConverterBase<ScopedVector<Element> > {
264 public: 323 public:
265 RepeatedValueConverter() {} 324 RepeatedValueConverter() {}
266 325
267 virtual bool Convert( 326 virtual bool Convert(
268 const base::Value& value, ScopedVector<Element>* field) const OVERRIDE { 327 const base::Value& value, ScopedVector<Element>* field) const OVERRIDE {
269 const base::ListValue* list = NULL; 328 const base::ListValue* list = NULL;
270 if (!value.GetAsList(&list)) { 329 if (!value.GetAsList(&list)) {
271 // The field is not a list. 330 // The field is not a list.
272 return false; 331 return false;
273 } 332 }
274 333
275 field->reserve(list->GetSize()); 334 field->reserve(list->GetSize());
276 for (size_t i = 0; i < list->GetSize(); ++i) { 335 for (size_t i = 0; i < list->GetSize(); ++i) {
277 base::Value* element = NULL; 336 base::Value* element = NULL;
278 if (!list->Get(i, &element)) 337 CHECK(list->Get(i, &element));
279 continue;
280 338
281 scoped_ptr<Element> e(new Element); 339 scoped_ptr<Element> e(new Element);
282 if (basic_converter_.Convert(*element, e.get())) { 340 if (basic_converter_.Convert(*element, e.get())) {
283 field->push_back(e.release()); 341 field->push_back(e.release());
284 } else { 342 } else {
285 DVLOG(1) << "failure at " << i << "-th element"; 343 DVLOG(1) << "failure at " << i << "-th element";
286 return false; 344 return false;
287 } 345 }
288 } 346 }
289 return true; 347 return true;
290 } 348 }
291 349
292 private: 350 private:
293 BasicValueConverter<Element> basic_converter_; 351 BasicValueConverter<Element> basic_converter_;
294 DISALLOW_COPY_AND_ASSIGN(RepeatedValueConverter); 352 DISALLOW_COPY_AND_ASSIGN(RepeatedValueConverter);
295 }; 353 };
296 354
297 template <typename NestedType> 355 template <typename NestedType>
298 class RepeatedMessageConverter 356 class RepeatedMessageConverter
299 : public ValueConverter<ScopedVector<NestedType> > { 357 : public ValueConverterBase<ScopedVector<NestedType> > {
300 public: 358 public:
301 RepeatedMessageConverter() {} 359 RepeatedMessageConverter() {}
302 360
303 virtual bool Convert(const base::Value& value, 361 virtual bool Convert(const base::Value& value,
304 ScopedVector<NestedType>* field) const OVERRIDE { 362 ScopedVector<NestedType>* field) const OVERRIDE {
305 const base::ListValue* list = NULL; 363 const base::ListValue* list = NULL;
306 if (!value.GetAsList(&list)) 364 if (!value.GetAsList(&list))
307 return false; 365 return false;
308 366
309 field->reserve(list->GetSize()); 367 field->reserve(list->GetSize());
310 for (size_t i = 0; i < list->GetSize(); ++i) { 368 for (size_t i = 0; i < list->GetSize(); ++i) {
311 base::Value* element = NULL; 369 base::Value* element = NULL;
312 if (!list->Get(i, &element)) 370 CHECK(list->Get(i, &element));
313 continue;
314 371
315 scoped_ptr<NestedType> nested(new NestedType); 372 scoped_ptr<NestedType> nested(new NestedType);
316 if (converter_.Convert(*element, nested.get())) { 373 if (converter_.Convert(*element, nested.get())) {
317 field->push_back(nested.release()); 374 field->push_back(nested.release());
318 } else { 375 } else {
319 DVLOG(1) << "failure at " << i << "-th element"; 376 DVLOG(1) << "failure at " << i << "-th element";
320 return false; 377 return false;
321 } 378 }
322 } 379 }
323 return true; 380 return true;
324 } 381 }
325 382
326 private: 383 private:
327 JSONValueConverter<NestedType> converter_; 384 JSONValueConverter<NestedType> converter_;
328 DISALLOW_COPY_AND_ASSIGN(RepeatedMessageConverter); 385 DISALLOW_COPY_AND_ASSIGN(RepeatedMessageConverter);
329 }; 386 };
330 387
331 template <typename NestedType> 388 template <typename NestedType>
332 class RepeatedCustomValueConverter 389 class RepeatedCustomValueConverter
333 : public ValueConverter<ScopedVector<NestedType> > { 390 : public ValueConverterBase<ScopedVector<NestedType> > {
334 public: 391 public:
335 typedef bool(*ConvertFunc)(const base::Value* value, NestedType* field); 392 typedef bool(*ConvertFunc)(const base::Value* value, NestedType* field);
336 393
337 RepeatedCustomValueConverter(ConvertFunc convert_func) 394 RepeatedCustomValueConverter(ConvertFunc convert_func)
338 : convert_func_(convert_func) {} 395 : convert_func_(convert_func) {}
339 396
340 virtual bool Convert(const base::Value& value, 397 virtual bool Convert(const base::Value& value,
341 ScopedVector<NestedType>* field) const OVERRIDE { 398 ScopedVector<NestedType>* field) const OVERRIDE {
342 const base::ListValue* list = NULL; 399 const base::ListValue* list = NULL;
343 if (!value.GetAsList(&list)) 400 if (!value.GetAsList(&list))
344 return false; 401 return false;
345 402
346 field->reserve(list->GetSize()); 403 field->reserve(list->GetSize());
347 for (size_t i = 0; i < list->GetSize(); ++i) { 404 for (size_t i = 0; i < list->GetSize(); ++i) {
348 base::Value* element = NULL; 405 base::Value* element = NULL;
349 if (!list->Get(i, &element)) 406 CHECK(list->Get(i, &element));
350 continue;
351 407
352 scoped_ptr<NestedType> nested(new NestedType); 408 scoped_ptr<NestedType> nested(new NestedType);
353 if ((*convert_func_)(element, nested.get())) { 409 if ((*convert_func_)(element, nested.get())) {
354 field->push_back(nested.release()); 410 field->push_back(nested.release());
355 } else { 411 } else {
356 DVLOG(1) << "failure at " << i << "-th element"; 412 DVLOG(1) << "failure at " << i << "-th element";
357 return false; 413 return false;
358 } 414 }
359 } 415 }
360 return true; 416 return true;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 void RegisterCustomValueField( 485 void RegisterCustomValueField(
430 const std::string& field_name, 486 const std::string& field_name,
431 FieldType StructType::* field, 487 FieldType StructType::* field,
432 bool (*convert_func)(const base::Value*, FieldType*)) { 488 bool (*convert_func)(const base::Value*, FieldType*)) {
433 fields_.push_back(new internal::FieldConverter<StructType, FieldType>( 489 fields_.push_back(new internal::FieldConverter<StructType, FieldType>(
434 field_name, 490 field_name,
435 field, 491 field,
436 new internal::ValueFieldConverter<FieldType>(convert_func))); 492 new internal::ValueFieldConverter<FieldType>(convert_func)));
437 } 493 }
438 494
495 void RegisterCustomAction(
496 const std::string& field_name,
497 bool (*action_func)(const base::Value*, StructType*)) {
498 fields_.push_back(new internal::FieldActionRunner<StructType>(
499 field_name,
500 false, // repeated
501 action_func));
502 }
503
439 void RegisterRepeatedInt(const std::string& field_name, 504 void RegisterRepeatedInt(const std::string& field_name,
440 ScopedVector<int> StructType::* field) { 505 ScopedVector<int> StructType::* field) {
441 fields_.push_back( 506 fields_.push_back(
442 new internal::FieldConverter<StructType, ScopedVector<int> >( 507 new internal::FieldConverter<StructType, ScopedVector<int> >(
443 field_name, field, new internal::RepeatedValueConverter<int>)); 508 field_name, field, new internal::RepeatedValueConverter<int>));
444 } 509 }
445 510
446 void RegisterRepeatedString(const std::string& field_name, 511 void RegisterRepeatedString(const std::string& field_name,
447 ScopedVector<std::string> StructType::* field) { 512 ScopedVector<std::string> StructType::* field) {
448 fields_.push_back( 513 fields_.push_back(
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 template <class NestedType> 556 template <class NestedType>
492 void RegisterRepeatedMessage(const std::string& field_name, 557 void RegisterRepeatedMessage(const std::string& field_name,
493 ScopedVector<NestedType> StructType::* field) { 558 ScopedVector<NestedType> StructType::* field) {
494 fields_.push_back( 559 fields_.push_back(
495 new internal::FieldConverter<StructType, ScopedVector<NestedType> >( 560 new internal::FieldConverter<StructType, ScopedVector<NestedType> >(
496 field_name, 561 field_name,
497 field, 562 field,
498 new internal::RepeatedMessageConverter<NestedType>)); 563 new internal::RepeatedMessageConverter<NestedType>));
499 } 564 }
500 565
566 void RegisterRepeatedCustomAction(
567 const std::string& field_name,
568 bool (*action_func)(const base::Value*, StructType*)) {
569 fields_.push_back(new internal::FieldActionRunner<StructType>(
570 field_name,
571 true, // repeated
572 action_func));
573 }
574
501 bool Convert(const base::Value& value, StructType* output) const { 575 bool Convert(const base::Value& value, StructType* output) const {
502 const DictionaryValue* dictionary_value = NULL; 576 const DictionaryValue* dictionary_value = NULL;
503 if (!value.GetAsDictionary(&dictionary_value)) 577 if (!value.GetAsDictionary(&dictionary_value))
504 return false; 578 return false;
505 579
506 for(size_t i = 0; i < fields_.size(); ++i) { 580 for(size_t i = 0; i < fields_.size(); ++i) {
507 const internal::FieldConverterBase<StructType>* field_converter = 581 const internal::FieldHandlerBase<StructType>* field_handler = fields_[i];
508 fields_[i];
509 base::Value* field = NULL; 582 base::Value* field = NULL;
510 if (dictionary_value->Get(field_converter->field_path(), &field)) { 583 if (dictionary_value->Get(field_handler->field_path(), &field)) {
511 if (!field_converter->ConvertField(*field, output)) { 584 if (!field_handler->HandleField(*field, output)) {
512 DVLOG(1) << "failure at field " << field_converter->field_path(); 585 DVLOG(1) << "failure at field " << field_handler->field_path();
513 return false; 586 return false;
514 } 587 }
515 } 588 }
516 } 589 }
517 return true; 590 return true;
518 } 591 }
519 592
520 private: 593 private:
521 ScopedVector<internal::FieldConverterBase<StructType> > fields_; 594 ScopedVector<internal::FieldHandlerBase<StructType> > fields_;
522 595
523 DISALLOW_COPY_AND_ASSIGN(JSONValueConverter); 596 DISALLOW_COPY_AND_ASSIGN(JSONValueConverter);
524 }; 597 };
525 598
526 } // namespace base 599 } // namespace base
527 600
528 #endif // BASE_JSON_JSON_VALUE_CONVERTER_H_ 601 #endif // BASE_JSON_JSON_VALUE_CONVERTER_H_
OLDNEW
« no previous file with comments | « no previous file | base/json/json_value_converter_unittest.cc » ('j') | base/json/json_value_converter_unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698