Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / base / json / json_value_converter.h
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.
4
5 #ifndef BASE_JSON_JSON_VALUE_CONVERTER_H_
6 #define BASE_JSON_JSON_VALUE_CONVERTER_H_
7
8 #include <string>
9 #include <vector>
10
11 #include "base/basictypes.h"
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/scoped_vector.h"
15 #include "base/stl_util.h"
16 #include "base/strings/string16.h"
17 #include "base/strings/string_piece.h"
18 #include "base/values.h"
19
20 // JSONValueConverter converts a JSON value into a C++ struct in a
21 // lightweight way.
22 //
23 // Usage:
24 // For real examples, you may want to refer to _unittest.cc file.
25 //
26 // Assume that you have a struct like this:
27 //   struct Message {
28 //     int foo;
29 //     std::string bar;
30 //     static void RegisterJSONConverter(
31 //         JSONValueConverter<Message>* converter);
32 //   };
33 //
34 // And you want to parse a json data into this struct.  First, you
35 // need to declare RegisterJSONConverter() method in your struct.
36 //   // static
37 //   void Message::RegisterJSONConverter(
38 //       JSONValueConverter<Message>* converter) {
39 //     converter->RegisterIntField("foo", &Message::foo);
40 //     converter->RegisterStringField("bar", &Message::bar);
41 //   }
42 //
43 // Then, you just instantiate your JSONValueConverter of your type and call
44 // Convert() method.
45 //   Message message;
46 //   JSONValueConverter<Message> converter;
47 //   converter.Convert(json, &message);
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 //
55 // For nested field, the internal message also has to implement the registration
56 // method.  Then, just use RegisterNestedField() from the containing struct's
57 // RegisterJSONConverter method.
58 //   struct Nested {
59 //     Message foo;
60 //     static void RegisterJSONConverter(...) {
61 //       ...
62 //       converter->RegisterNestedField("foo", &Nested::foo);
63 //     }
64 //   };
65 //
66 // For repeated field, we just assume ScopedVector for its container
67 // and you can put RegisterRepeatedInt or some other types.  Use
68 // RegisterRepeatedMessage for nested repeated fields.
69 //
70 // Sometimes JSON format uses string representations for other types such
71 // like enum, timestamp, or URL.  You can use RegisterCustomField method
72 // and specify a function to convert a StringPiece to your type.
73 //   bool ConvertFunc(const StringPiece& s, YourEnum* result) {
74 //     // do something and return true if succeed...
75 //   }
76 //   struct Message {
77 //     YourEnum ye;
78 //     ...
79 //     static void RegisterJSONConverter(...) {
80 //       ...
81 //       converter->RegsiterCustomField<YourEnum>(
82 //           "your_enum", &Message::ye, &ConvertFunc);
83 //     }
84 //   };
85
86 namespace base {
87
88 template <typename StructType>
89 class JSONValueConverter;
90
91 namespace internal {
92
93 template<typename StructType>
94 class FieldConverterBase {
95  public:
96   explicit FieldConverterBase(const std::string& path) : field_path_(path) {}
97   virtual ~FieldConverterBase() {}
98   virtual bool ConvertField(const base::Value& value, StructType* obj)
99       const = 0;
100   const std::string& field_path() const { return field_path_; }
101
102  private:
103   std::string field_path_;
104   DISALLOW_COPY_AND_ASSIGN(FieldConverterBase);
105 };
106
107 template <typename FieldType>
108 class ValueConverter {
109  public:
110   virtual ~ValueConverter() {}
111   virtual bool Convert(const base::Value& value, FieldType* field) const = 0;
112 };
113
114 template <typename StructType, typename FieldType>
115 class FieldConverter : public FieldConverterBase<StructType> {
116  public:
117   explicit FieldConverter(const std::string& path,
118                           FieldType StructType::* field,
119                           ValueConverter<FieldType>* converter)
120       : FieldConverterBase<StructType>(path),
121         field_pointer_(field),
122         value_converter_(converter) {
123   }
124
125   virtual bool ConvertField(
126       const base::Value& value, StructType* dst) const override {
127     return value_converter_->Convert(value, &(dst->*field_pointer_));
128   }
129
130  private:
131   FieldType StructType::* field_pointer_;
132   scoped_ptr<ValueConverter<FieldType> > value_converter_;
133   DISALLOW_COPY_AND_ASSIGN(FieldConverter);
134 };
135
136 template <typename FieldType>
137 class BasicValueConverter;
138
139 template <>
140 class BasicValueConverter<int> : public ValueConverter<int> {
141  public:
142   BasicValueConverter() {}
143
144   virtual bool Convert(const base::Value& value, int* field) const override {
145     return value.GetAsInteger(field);
146   }
147
148  private:
149   DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
150 };
151
152 template <>
153 class BasicValueConverter<std::string> : public ValueConverter<std::string> {
154  public:
155   BasicValueConverter() {}
156
157   virtual bool Convert(
158       const base::Value& value, std::string* field) const override {
159     return value.GetAsString(field);
160   }
161
162  private:
163   DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
164 };
165
166 template <>
167 class BasicValueConverter<string16> : public ValueConverter<string16> {
168  public:
169   BasicValueConverter() {}
170
171   virtual bool Convert(
172       const base::Value& value, string16* field) const override {
173     return value.GetAsString(field);
174   }
175
176  private:
177   DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
178 };
179
180 template <>
181 class BasicValueConverter<double> : public ValueConverter<double> {
182  public:
183   BasicValueConverter() {}
184
185   virtual bool Convert(const base::Value& value, double* field) const override {
186     return value.GetAsDouble(field);
187   }
188
189  private:
190   DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
191 };
192
193 template <>
194 class BasicValueConverter<bool> : public ValueConverter<bool> {
195  public:
196   BasicValueConverter() {}
197
198   virtual bool Convert(const base::Value& value, bool* field) const override {
199     return value.GetAsBoolean(field);
200   }
201
202  private:
203   DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
204 };
205
206 template <typename FieldType>
207 class ValueFieldConverter : public ValueConverter<FieldType> {
208  public:
209   typedef bool(*ConvertFunc)(const base::Value* value, FieldType* field);
210
211   ValueFieldConverter(ConvertFunc convert_func)
212       : convert_func_(convert_func) {}
213
214   virtual bool Convert(const base::Value& value,
215                        FieldType* field) const override {
216     return convert_func_(&value, field);
217   }
218
219  private:
220   ConvertFunc convert_func_;
221
222   DISALLOW_COPY_AND_ASSIGN(ValueFieldConverter);
223 };
224
225 template <typename FieldType>
226 class CustomFieldConverter : public ValueConverter<FieldType> {
227  public:
228   typedef bool(*ConvertFunc)(const StringPiece& value, FieldType* field);
229
230   CustomFieldConverter(ConvertFunc convert_func)
231       : convert_func_(convert_func) {}
232
233   virtual bool Convert(const base::Value& value,
234                        FieldType* field) const override {
235     std::string string_value;
236     return value.GetAsString(&string_value) &&
237         convert_func_(string_value, field);
238   }
239
240  private:
241   ConvertFunc convert_func_;
242
243   DISALLOW_COPY_AND_ASSIGN(CustomFieldConverter);
244 };
245
246 template <typename NestedType>
247 class NestedValueConverter : public ValueConverter<NestedType> {
248  public:
249   NestedValueConverter() {}
250
251   virtual bool Convert(
252       const base::Value& value, NestedType* field) const override {
253     return converter_.Convert(value, field);
254   }
255
256  private:
257   JSONValueConverter<NestedType> converter_;
258   DISALLOW_COPY_AND_ASSIGN(NestedValueConverter);
259 };
260
261 template <typename Element>
262 class RepeatedValueConverter : public ValueConverter<ScopedVector<Element> > {
263  public:
264   RepeatedValueConverter() {}
265
266   virtual bool Convert(
267       const base::Value& value, ScopedVector<Element>* field) const override {
268     const base::ListValue* list = NULL;
269     if (!value.GetAsList(&list)) {
270       // The field is not a list.
271       return false;
272     }
273
274     field->reserve(list->GetSize());
275     for (size_t i = 0; i < list->GetSize(); ++i) {
276       const base::Value* element = NULL;
277       if (!list->Get(i, &element))
278         continue;
279
280       scoped_ptr<Element> e(new Element);
281       if (basic_converter_.Convert(*element, e.get())) {
282         field->push_back(e.release());
283       } else {
284         DVLOG(1) << "failure at " << i << "-th element";
285         return false;
286       }
287     }
288     return true;
289   }
290
291  private:
292   BasicValueConverter<Element> basic_converter_;
293   DISALLOW_COPY_AND_ASSIGN(RepeatedValueConverter);
294 };
295
296 template <typename NestedType>
297 class RepeatedMessageConverter
298     : public ValueConverter<ScopedVector<NestedType> > {
299  public:
300   RepeatedMessageConverter() {}
301
302   virtual bool Convert(const base::Value& value,
303                        ScopedVector<NestedType>* field) const override {
304     const base::ListValue* list = NULL;
305     if (!value.GetAsList(&list))
306       return false;
307
308     field->reserve(list->GetSize());
309     for (size_t i = 0; i < list->GetSize(); ++i) {
310       const base::Value* element = NULL;
311       if (!list->Get(i, &element))
312         continue;
313
314       scoped_ptr<NestedType> nested(new NestedType);
315       if (converter_.Convert(*element, nested.get())) {
316         field->push_back(nested.release());
317       } else {
318         DVLOG(1) << "failure at " << i << "-th element";
319         return false;
320       }
321     }
322     return true;
323   }
324
325  private:
326   JSONValueConverter<NestedType> converter_;
327   DISALLOW_COPY_AND_ASSIGN(RepeatedMessageConverter);
328 };
329
330 template <typename NestedType>
331 class RepeatedCustomValueConverter
332     : public ValueConverter<ScopedVector<NestedType> > {
333  public:
334   typedef bool(*ConvertFunc)(const base::Value* value, NestedType* field);
335
336   RepeatedCustomValueConverter(ConvertFunc convert_func)
337       : convert_func_(convert_func) {}
338
339   virtual bool Convert(const base::Value& value,
340                        ScopedVector<NestedType>* field) const override {
341     const base::ListValue* list = NULL;
342     if (!value.GetAsList(&list))
343       return false;
344
345     field->reserve(list->GetSize());
346     for (size_t i = 0; i < list->GetSize(); ++i) {
347       const base::Value* element = NULL;
348       if (!list->Get(i, &element))
349         continue;
350
351       scoped_ptr<NestedType> nested(new NestedType);
352       if ((*convert_func_)(element, nested.get())) {
353         field->push_back(nested.release());
354       } else {
355         DVLOG(1) << "failure at " << i << "-th element";
356         return false;
357       }
358     }
359     return true;
360   }
361
362  private:
363   ConvertFunc convert_func_;
364   DISALLOW_COPY_AND_ASSIGN(RepeatedCustomValueConverter);
365 };
366
367
368 }  // namespace internal
369
370 template <class StructType>
371 class JSONValueConverter {
372  public:
373   JSONValueConverter() {
374     StructType::RegisterJSONConverter(this);
375   }
376
377   void RegisterIntField(const std::string& field_name,
378                         int StructType::* field) {
379     fields_.push_back(new internal::FieldConverter<StructType, int>(
380         field_name, field, new internal::BasicValueConverter<int>));
381   }
382
383   void RegisterStringField(const std::string& field_name,
384                            std::string StructType::* field) {
385     fields_.push_back(new internal::FieldConverter<StructType, std::string>(
386         field_name, field, new internal::BasicValueConverter<std::string>));
387   }
388
389   void RegisterStringField(const std::string& field_name,
390                            string16 StructType::* field) {
391     fields_.push_back(new internal::FieldConverter<StructType, string16>(
392         field_name, field, new internal::BasicValueConverter<string16>));
393   }
394
395   void RegisterBoolField(const std::string& field_name,
396                          bool StructType::* field) {
397     fields_.push_back(new internal::FieldConverter<StructType, bool>(
398         field_name, field, new internal::BasicValueConverter<bool>));
399   }
400
401   void RegisterDoubleField(const std::string& field_name,
402                            double StructType::* field) {
403     fields_.push_back(new internal::FieldConverter<StructType, double>(
404         field_name, field, new internal::BasicValueConverter<double>));
405   }
406
407   template <class NestedType>
408   void RegisterNestedField(
409       const std::string& field_name, NestedType StructType::* field) {
410     fields_.push_back(new internal::FieldConverter<StructType, NestedType>(
411             field_name,
412             field,
413             new internal::NestedValueConverter<NestedType>));
414   }
415
416   template <typename FieldType>
417   void RegisterCustomField(
418       const std::string& field_name,
419       FieldType StructType::* field,
420       bool (*convert_func)(const StringPiece&, FieldType*)) {
421     fields_.push_back(new internal::FieldConverter<StructType, FieldType>(
422         field_name,
423         field,
424         new internal::CustomFieldConverter<FieldType>(convert_func)));
425   }
426
427   template <typename FieldType>
428   void RegisterCustomValueField(
429       const std::string& field_name,
430       FieldType StructType::* field,
431       bool (*convert_func)(const base::Value*, FieldType*)) {
432     fields_.push_back(new internal::FieldConverter<StructType, FieldType>(
433         field_name,
434         field,
435         new internal::ValueFieldConverter<FieldType>(convert_func)));
436   }
437
438   void RegisterRepeatedInt(const std::string& field_name,
439                            ScopedVector<int> StructType::* field) {
440     fields_.push_back(
441         new internal::FieldConverter<StructType, ScopedVector<int> >(
442             field_name, field, new internal::RepeatedValueConverter<int>));
443   }
444
445   void RegisterRepeatedString(const std::string& field_name,
446                               ScopedVector<std::string> StructType::* field) {
447     fields_.push_back(
448         new internal::FieldConverter<StructType, ScopedVector<std::string> >(
449             field_name,
450             field,
451             new internal::RepeatedValueConverter<std::string>));
452   }
453
454   void RegisterRepeatedString(const std::string& field_name,
455                               ScopedVector<string16> StructType::* field) {
456     fields_.push_back(
457         new internal::FieldConverter<StructType, ScopedVector<string16> >(
458             field_name,
459             field,
460             new internal::RepeatedValueConverter<string16>));
461   }
462
463   void RegisterRepeatedDouble(const std::string& field_name,
464                               ScopedVector<double> StructType::* field) {
465     fields_.push_back(
466         new internal::FieldConverter<StructType, ScopedVector<double> >(
467             field_name, field, new internal::RepeatedValueConverter<double>));
468   }
469
470   void RegisterRepeatedBool(const std::string& field_name,
471                             ScopedVector<bool> StructType::* field) {
472     fields_.push_back(
473         new internal::FieldConverter<StructType, ScopedVector<bool> >(
474             field_name, field, new internal::RepeatedValueConverter<bool>));
475   }
476
477   template <class NestedType>
478   void RegisterRepeatedCustomValue(
479       const std::string& field_name,
480       ScopedVector<NestedType> StructType::* field,
481       bool (*convert_func)(const base::Value*, NestedType*)) {
482     fields_.push_back(
483         new internal::FieldConverter<StructType, ScopedVector<NestedType> >(
484             field_name,
485             field,
486             new internal::RepeatedCustomValueConverter<NestedType>(
487                 convert_func)));
488   }
489
490   template <class NestedType>
491   void RegisterRepeatedMessage(const std::string& field_name,
492                                ScopedVector<NestedType> StructType::* field) {
493     fields_.push_back(
494         new internal::FieldConverter<StructType, ScopedVector<NestedType> >(
495             field_name,
496             field,
497             new internal::RepeatedMessageConverter<NestedType>));
498   }
499
500   bool Convert(const base::Value& value, StructType* output) const {
501     const DictionaryValue* dictionary_value = NULL;
502     if (!value.GetAsDictionary(&dictionary_value))
503       return false;
504
505     for(size_t i = 0; i < fields_.size(); ++i) {
506       const internal::FieldConverterBase<StructType>* field_converter =
507           fields_[i];
508       const base::Value* field = NULL;
509       if (dictionary_value->Get(field_converter->field_path(), &field)) {
510         if (!field_converter->ConvertField(*field, output)) {
511           DVLOG(1) << "failure at field " << field_converter->field_path();
512           return false;
513         }
514       }
515     }
516     return true;
517   }
518
519  private:
520   ScopedVector<internal::FieldConverterBase<StructType> > fields_;
521
522   DISALLOW_COPY_AND_ASSIGN(JSONValueConverter);
523 };
524
525 }  // namespace base
526
527 #endif  // BASE_JSON_JSON_VALUE_CONVERTER_H_