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> |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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_ |
OLD | NEW |