Fix sort order of unlaunched apps on app list start page.
[chromium-blink-merge.git] / base / json / json_value_converter.h
blobc4bfe61e9d38a5056951efd27e6a45d3a5bb570c
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
3 // found in the LICENSE file.
5 #ifndef BASE_JSON_JSON_VALUE_CONVERTER_H_
6 #define BASE_JSON_JSON_VALUE_CONVERTER_H_
8 #include <string>
9 #include <vector>
11 #include "base/base_export.h"
12 #include "base/basictypes.h"
13 #include "base/logging.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/scoped_vector.h"
16 #include "base/stl_util.h"
17 #include "base/strings/string16.h"
18 #include "base/strings/string_piece.h"
19 #include "base/values.h"
21 // JSONValueConverter converts a JSON value into a C++ struct in a
22 // lightweight way.
24 // Usage:
25 // For real examples, you may want to refer to _unittest.cc file.
27 // Assume that you have a struct like this:
28 // struct Message {
29 // int foo;
30 // std::string bar;
31 // static void RegisterJSONConverter(
32 // JSONValueConverter<Message>* converter);
33 // };
35 // And you want to parse a json data into this struct. First, you
36 // need to declare RegisterJSONConverter() method in your struct.
37 // // static
38 // void Message::RegisterJSONConverter(
39 // JSONValueConverter<Message>* converter) {
40 // converter->RegisterIntField("foo", &Message::foo);
41 // converter->RegisterStringField("bar", &Message::bar);
42 // }
44 // Then, you just instantiate your JSONValueConverter of your type and call
45 // Convert() method.
46 // Message message;
47 // JSONValueConverter<Message> converter;
48 // converter.Convert(json, &message);
50 // Convert() returns false when it fails. Here "fail" means that the value is
51 // structurally different from expected, such like a string value appears
52 // for an int field. Do not report failures for missing fields.
53 // Also note that Convert() will modify the passed |message| even when it
54 // fails for performance reason.
56 // For nested field, the internal message also has to implement the registration
57 // method. Then, just use RegisterNestedField() from the containing struct's
58 // RegisterJSONConverter method.
59 // struct Nested {
60 // Message foo;
61 // static void RegisterJSONConverter(...) {
62 // ...
63 // converter->RegisterNestedField("foo", &Nested::foo);
64 // }
65 // };
67 // For repeated field, we just assume ScopedVector for its container
68 // and you can put RegisterRepeatedInt or some other types. Use
69 // RegisterRepeatedMessage for nested repeated fields.
71 // Sometimes JSON format uses string representations for other types such
72 // like enum, timestamp, or URL. You can use RegisterCustomField method
73 // and specify a function to convert a StringPiece to your type.
74 // bool ConvertFunc(const StringPiece& s, YourEnum* result) {
75 // // do something and return true if succeed...
76 // }
77 // struct Message {
78 // YourEnum ye;
79 // ...
80 // static void RegisterJSONConverter(...) {
81 // ...
82 // converter->RegsiterCustomField<YourEnum>(
83 // "your_enum", &Message::ye, &ConvertFunc);
84 // }
85 // };
87 namespace base {
89 template <typename StructType>
90 class JSONValueConverter;
92 namespace internal {
94 template<typename StructType>
95 class FieldConverterBase {
96 public:
97 explicit FieldConverterBase(const std::string& path) : field_path_(path) {}
98 virtual ~FieldConverterBase() {}
99 virtual bool ConvertField(const base::Value& value, StructType* obj)
100 const = 0;
101 const std::string& field_path() const { return field_path_; }
103 private:
104 std::string field_path_;
105 DISALLOW_COPY_AND_ASSIGN(FieldConverterBase);
108 template <typename FieldType>
109 class ValueConverter {
110 public:
111 virtual ~ValueConverter() {}
112 virtual bool Convert(const base::Value& value, FieldType* field) const = 0;
115 template <typename StructType, typename FieldType>
116 class FieldConverter : public FieldConverterBase<StructType> {
117 public:
118 explicit FieldConverter(const std::string& path,
119 FieldType StructType::* field,
120 ValueConverter<FieldType>* converter)
121 : FieldConverterBase<StructType>(path),
122 field_pointer_(field),
123 value_converter_(converter) {
126 virtual bool ConvertField(
127 const base::Value& value, StructType* dst) const override {
128 return value_converter_->Convert(value, &(dst->*field_pointer_));
131 private:
132 FieldType StructType::* field_pointer_;
133 scoped_ptr<ValueConverter<FieldType> > value_converter_;
134 DISALLOW_COPY_AND_ASSIGN(FieldConverter);
137 template <typename FieldType>
138 class BasicValueConverter;
140 template <>
141 class BASE_EXPORT BasicValueConverter<int> : public ValueConverter<int> {
142 public:
143 BasicValueConverter() {}
145 bool Convert(const base::Value& value, int* field) const override;
147 private:
148 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
151 template <>
152 class BASE_EXPORT BasicValueConverter<std::string>
153 : public ValueConverter<std::string> {
154 public:
155 BasicValueConverter() {}
157 bool Convert(const base::Value& value, std::string* field) const override;
159 private:
160 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
163 template <>
164 class BASE_EXPORT BasicValueConverter<string16>
165 : public ValueConverter<string16> {
166 public:
167 BasicValueConverter() {}
169 bool Convert(const base::Value& value, string16* field) const override;
171 private:
172 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
175 template <>
176 class BASE_EXPORT BasicValueConverter<double> : public ValueConverter<double> {
177 public:
178 BasicValueConverter() {}
180 bool Convert(const base::Value& value, double* field) const override;
182 private:
183 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
186 template <>
187 class BASE_EXPORT BasicValueConverter<bool> : public ValueConverter<bool> {
188 public:
189 BasicValueConverter() {}
191 bool Convert(const base::Value& value, bool* field) const override;
193 private:
194 DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
197 template <typename FieldType>
198 class ValueFieldConverter : public ValueConverter<FieldType> {
199 public:
200 typedef bool(*ConvertFunc)(const base::Value* value, FieldType* field);
202 ValueFieldConverter(ConvertFunc convert_func)
203 : convert_func_(convert_func) {}
205 virtual bool Convert(const base::Value& value,
206 FieldType* field) const override {
207 return convert_func_(&value, field);
210 private:
211 ConvertFunc convert_func_;
213 DISALLOW_COPY_AND_ASSIGN(ValueFieldConverter);
216 template <typename FieldType>
217 class CustomFieldConverter : public ValueConverter<FieldType> {
218 public:
219 typedef bool(*ConvertFunc)(const StringPiece& value, FieldType* field);
221 CustomFieldConverter(ConvertFunc convert_func)
222 : convert_func_(convert_func) {}
224 virtual bool Convert(const base::Value& value,
225 FieldType* field) const override {
226 std::string string_value;
227 return value.GetAsString(&string_value) &&
228 convert_func_(string_value, field);
231 private:
232 ConvertFunc convert_func_;
234 DISALLOW_COPY_AND_ASSIGN(CustomFieldConverter);
237 template <typename NestedType>
238 class NestedValueConverter : public ValueConverter<NestedType> {
239 public:
240 NestedValueConverter() {}
242 virtual bool Convert(
243 const base::Value& value, NestedType* field) const override {
244 return converter_.Convert(value, field);
247 private:
248 JSONValueConverter<NestedType> converter_;
249 DISALLOW_COPY_AND_ASSIGN(NestedValueConverter);
252 template <typename Element>
253 class RepeatedValueConverter : public ValueConverter<ScopedVector<Element> > {
254 public:
255 RepeatedValueConverter() {}
257 virtual bool Convert(
258 const base::Value& value, ScopedVector<Element>* field) const override {
259 const base::ListValue* list = NULL;
260 if (!value.GetAsList(&list)) {
261 // The field is not a list.
262 return false;
265 field->reserve(list->GetSize());
266 for (size_t i = 0; i < list->GetSize(); ++i) {
267 const base::Value* element = NULL;
268 if (!list->Get(i, &element))
269 continue;
271 scoped_ptr<Element> e(new Element);
272 if (basic_converter_.Convert(*element, e.get())) {
273 field->push_back(e.release());
274 } else {
275 DVLOG(1) << "failure at " << i << "-th element";
276 return false;
279 return true;
282 private:
283 BasicValueConverter<Element> basic_converter_;
284 DISALLOW_COPY_AND_ASSIGN(RepeatedValueConverter);
287 template <typename NestedType>
288 class RepeatedMessageConverter
289 : public ValueConverter<ScopedVector<NestedType> > {
290 public:
291 RepeatedMessageConverter() {}
293 virtual bool Convert(const base::Value& value,
294 ScopedVector<NestedType>* field) const override {
295 const base::ListValue* list = NULL;
296 if (!value.GetAsList(&list))
297 return false;
299 field->reserve(list->GetSize());
300 for (size_t i = 0; i < list->GetSize(); ++i) {
301 const base::Value* element = NULL;
302 if (!list->Get(i, &element))
303 continue;
305 scoped_ptr<NestedType> nested(new NestedType);
306 if (converter_.Convert(*element, nested.get())) {
307 field->push_back(nested.release());
308 } else {
309 DVLOG(1) << "failure at " << i << "-th element";
310 return false;
313 return true;
316 private:
317 JSONValueConverter<NestedType> converter_;
318 DISALLOW_COPY_AND_ASSIGN(RepeatedMessageConverter);
321 template <typename NestedType>
322 class RepeatedCustomValueConverter
323 : public ValueConverter<ScopedVector<NestedType> > {
324 public:
325 typedef bool(*ConvertFunc)(const base::Value* value, NestedType* field);
327 RepeatedCustomValueConverter(ConvertFunc convert_func)
328 : convert_func_(convert_func) {}
330 virtual bool Convert(const base::Value& value,
331 ScopedVector<NestedType>* field) const override {
332 const base::ListValue* list = NULL;
333 if (!value.GetAsList(&list))
334 return false;
336 field->reserve(list->GetSize());
337 for (size_t i = 0; i < list->GetSize(); ++i) {
338 const base::Value* element = NULL;
339 if (!list->Get(i, &element))
340 continue;
342 scoped_ptr<NestedType> nested(new NestedType);
343 if ((*convert_func_)(element, nested.get())) {
344 field->push_back(nested.release());
345 } else {
346 DVLOG(1) << "failure at " << i << "-th element";
347 return false;
350 return true;
353 private:
354 ConvertFunc convert_func_;
355 DISALLOW_COPY_AND_ASSIGN(RepeatedCustomValueConverter);
359 } // namespace internal
361 template <class StructType>
362 class JSONValueConverter {
363 public:
364 JSONValueConverter() {
365 StructType::RegisterJSONConverter(this);
368 void RegisterIntField(const std::string& field_name,
369 int StructType::* field) {
370 fields_.push_back(new internal::FieldConverter<StructType, int>(
371 field_name, field, new internal::BasicValueConverter<int>));
374 void RegisterStringField(const std::string& field_name,
375 std::string StructType::* field) {
376 fields_.push_back(new internal::FieldConverter<StructType, std::string>(
377 field_name, field, new internal::BasicValueConverter<std::string>));
380 void RegisterStringField(const std::string& field_name,
381 string16 StructType::* field) {
382 fields_.push_back(new internal::FieldConverter<StructType, string16>(
383 field_name, field, new internal::BasicValueConverter<string16>));
386 void RegisterBoolField(const std::string& field_name,
387 bool StructType::* field) {
388 fields_.push_back(new internal::FieldConverter<StructType, bool>(
389 field_name, field, new internal::BasicValueConverter<bool>));
392 void RegisterDoubleField(const std::string& field_name,
393 double StructType::* field) {
394 fields_.push_back(new internal::FieldConverter<StructType, double>(
395 field_name, field, new internal::BasicValueConverter<double>));
398 template <class NestedType>
399 void RegisterNestedField(
400 const std::string& field_name, NestedType StructType::* field) {
401 fields_.push_back(new internal::FieldConverter<StructType, NestedType>(
402 field_name,
403 field,
404 new internal::NestedValueConverter<NestedType>));
407 template <typename FieldType>
408 void RegisterCustomField(
409 const std::string& field_name,
410 FieldType StructType::* field,
411 bool (*convert_func)(const StringPiece&, FieldType*)) {
412 fields_.push_back(new internal::FieldConverter<StructType, FieldType>(
413 field_name,
414 field,
415 new internal::CustomFieldConverter<FieldType>(convert_func)));
418 template <typename FieldType>
419 void RegisterCustomValueField(
420 const std::string& field_name,
421 FieldType StructType::* field,
422 bool (*convert_func)(const base::Value*, FieldType*)) {
423 fields_.push_back(new internal::FieldConverter<StructType, FieldType>(
424 field_name,
425 field,
426 new internal::ValueFieldConverter<FieldType>(convert_func)));
429 void RegisterRepeatedInt(const std::string& field_name,
430 ScopedVector<int> StructType::* field) {
431 fields_.push_back(
432 new internal::FieldConverter<StructType, ScopedVector<int> >(
433 field_name, field, new internal::RepeatedValueConverter<int>));
436 void RegisterRepeatedString(const std::string& field_name,
437 ScopedVector<std::string> StructType::* field) {
438 fields_.push_back(
439 new internal::FieldConverter<StructType, ScopedVector<std::string> >(
440 field_name,
441 field,
442 new internal::RepeatedValueConverter<std::string>));
445 void RegisterRepeatedString(const std::string& field_name,
446 ScopedVector<string16> StructType::* field) {
447 fields_.push_back(
448 new internal::FieldConverter<StructType, ScopedVector<string16> >(
449 field_name,
450 field,
451 new internal::RepeatedValueConverter<string16>));
454 void RegisterRepeatedDouble(const std::string& field_name,
455 ScopedVector<double> StructType::* field) {
456 fields_.push_back(
457 new internal::FieldConverter<StructType, ScopedVector<double> >(
458 field_name, field, new internal::RepeatedValueConverter<double>));
461 void RegisterRepeatedBool(const std::string& field_name,
462 ScopedVector<bool> StructType::* field) {
463 fields_.push_back(
464 new internal::FieldConverter<StructType, ScopedVector<bool> >(
465 field_name, field, new internal::RepeatedValueConverter<bool>));
468 template <class NestedType>
469 void RegisterRepeatedCustomValue(
470 const std::string& field_name,
471 ScopedVector<NestedType> StructType::* field,
472 bool (*convert_func)(const base::Value*, NestedType*)) {
473 fields_.push_back(
474 new internal::FieldConverter<StructType, ScopedVector<NestedType> >(
475 field_name,
476 field,
477 new internal::RepeatedCustomValueConverter<NestedType>(
478 convert_func)));
481 template <class NestedType>
482 void RegisterRepeatedMessage(const std::string& field_name,
483 ScopedVector<NestedType> StructType::* field) {
484 fields_.push_back(
485 new internal::FieldConverter<StructType, ScopedVector<NestedType> >(
486 field_name,
487 field,
488 new internal::RepeatedMessageConverter<NestedType>));
491 bool Convert(const base::Value& value, StructType* output) const {
492 const DictionaryValue* dictionary_value = NULL;
493 if (!value.GetAsDictionary(&dictionary_value))
494 return false;
496 for(size_t i = 0; i < fields_.size(); ++i) {
497 const internal::FieldConverterBase<StructType>* field_converter =
498 fields_[i];
499 const base::Value* field = NULL;
500 if (dictionary_value->Get(field_converter->field_path(), &field)) {
501 if (!field_converter->ConvertField(*field, output)) {
502 DVLOG(1) << "failure at field " << field_converter->field_path();
503 return false;
507 return true;
510 private:
511 ScopedVector<internal::FieldConverterBase<StructType> > fields_;
513 DISALLOW_COPY_AND_ASSIGN(JSONValueConverter);
516 } // namespace base
518 #endif // BASE_JSON_JSON_VALUE_CONVERTER_H_