json_value_converter.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  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. #ifndef BASE_JSON_JSON_VALUE_CONVERTER_H_
  5. #define BASE_JSON_JSON_VALUE_CONVERTER_H_
  6. #include <stddef.h>
  7. #include <memory>
  8. #include <string>
  9. #include <vector>
  10. #include "base/base_export.h"
  11. #include "base/logging.h"
  12. #include "base/macros.h"
  13. #include "base/memory/ptr_util.h"
  14. #include "base/strings/string16.h"
  15. #include "base/strings/string_piece.h"
  16. #include "base/values.h"
  17. // JSONValueConverter converts a JSON value into a C++ struct in a
  18. // lightweight way.
  19. //
  20. // Usage:
  21. // For real examples, you may want to refer to _unittest.cc file.
  22. //
  23. // Assume that you have a struct like this:
  24. // struct Message {
  25. // int foo;
  26. // std::string bar;
  27. // static void RegisterJSONConverter(
  28. // JSONValueConverter<Message>* converter);
  29. // };
  30. //
  31. // And you want to parse a json data into this struct. First, you
  32. // need to declare RegisterJSONConverter() method in your struct.
  33. // // static
  34. // void Message::RegisterJSONConverter(
  35. // JSONValueConverter<Message>* converter) {
  36. // converter->RegisterIntField("foo", &Message::foo);
  37. // converter->RegisterStringField("bar", &Message::bar);
  38. // }
  39. //
  40. // Then, you just instantiate your JSONValueConverter of your type and call
  41. // Convert() method.
  42. // Message message;
  43. // JSONValueConverter<Message> converter;
  44. // converter.Convert(json, &message);
  45. //
  46. // Convert() returns false when it fails. Here "fail" means that the value is
  47. // structurally different from expected, such like a string value appears
  48. // for an int field. Do not report failures for missing fields.
  49. // Also note that Convert() will modify the passed |message| even when it
  50. // fails for performance reason.
  51. //
  52. // For nested field, the internal message also has to implement the registration
  53. // method. Then, just use RegisterNestedField() from the containing struct's
  54. // RegisterJSONConverter method.
  55. // struct Nested {
  56. // Message foo;
  57. // static void RegisterJSONConverter(...) {
  58. // ...
  59. // converter->RegisterNestedField("foo", &Nested::foo);
  60. // }
  61. // };
  62. //
  63. // For repeated field, we just assume std::vector<std::unique_ptr<ElementType>>
  64. // for its container and you can put RegisterRepeatedInt or some other types.
  65. // Use RegisterRepeatedMessage for nested repeated fields.
  66. //
  67. // Sometimes JSON format uses string representations for other types such
  68. // like enum, timestamp, or URL. You can use RegisterCustomField method
  69. // and specify a function to convert a StringPiece to your type.
  70. // bool ConvertFunc(StringPiece s, YourEnum* result) {
  71. // // do something and return true if succeed...
  72. // }
  73. // struct Message {
  74. // YourEnum ye;
  75. // ...
  76. // static void RegisterJSONConverter(...) {
  77. // ...
  78. // converter->RegsiterCustomField<YourEnum>(
  79. // "your_enum", &Message::ye, &ConvertFunc);
  80. // }
  81. // };
  82. namespace base {
  83. template <typename StructType>
  84. class JSONValueConverter;
  85. namespace internal {
  86. template<typename StructType>
  87. class FieldConverterBase {
  88. public:
  89. explicit FieldConverterBase(const std::string& path) : field_path_(path) {}
  90. virtual ~FieldConverterBase() = default;
  91. virtual bool ConvertField(const base::Value& value, StructType* obj)
  92. const = 0;
  93. const std::string& field_path() const { return field_path_; }
  94. private:
  95. std::string field_path_;
  96. DISALLOW_COPY_AND_ASSIGN(FieldConverterBase);
  97. };
  98. template <typename FieldType>
  99. class ValueConverter {
  100. public:
  101. virtual ~ValueConverter() = default;
  102. virtual bool Convert(const base::Value& value, FieldType* field) const = 0;
  103. };
  104. template <typename StructType, typename FieldType>
  105. class FieldConverter : public FieldConverterBase<StructType> {
  106. public:
  107. explicit FieldConverter(const std::string& path,
  108. FieldType StructType::* field,
  109. ValueConverter<FieldType>* converter)
  110. : FieldConverterBase<StructType>(path),
  111. field_pointer_(field),
  112. value_converter_(converter) {
  113. }
  114. bool ConvertField(const base::Value& value, StructType* dst) const override {
  115. return value_converter_->Convert(value, &(dst->*field_pointer_));
  116. }
  117. private:
  118. FieldType StructType::* field_pointer_;
  119. std::unique_ptr<ValueConverter<FieldType>> value_converter_;
  120. DISALLOW_COPY_AND_ASSIGN(FieldConverter);
  121. };
  122. template <typename FieldType>
  123. class BasicValueConverter;
  124. template <>
  125. class BASE_EXPORT BasicValueConverter<int> : public ValueConverter<int> {
  126. public:
  127. BasicValueConverter() = default;
  128. bool Convert(const base::Value& value, int* field) const override;
  129. private:
  130. DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
  131. };
  132. template <>
  133. class BASE_EXPORT BasicValueConverter<std::string>
  134. : public ValueConverter<std::string> {
  135. public:
  136. BasicValueConverter() = default;
  137. bool Convert(const base::Value& value, std::string* field) const override;
  138. private:
  139. DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
  140. };
  141. template <>
  142. class BASE_EXPORT BasicValueConverter<string16>
  143. : public ValueConverter<string16> {
  144. public:
  145. BasicValueConverter() = default;
  146. bool Convert(const base::Value& value, string16* field) const override;
  147. private:
  148. DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
  149. };
  150. template <>
  151. class BASE_EXPORT BasicValueConverter<double> : public ValueConverter<double> {
  152. public:
  153. BasicValueConverter() = default;
  154. bool Convert(const base::Value& value, double* field) const override;
  155. private:
  156. DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
  157. };
  158. template <>
  159. class BASE_EXPORT BasicValueConverter<bool> : public ValueConverter<bool> {
  160. public:
  161. BasicValueConverter() = default;
  162. bool Convert(const base::Value& value, bool* field) const override;
  163. private:
  164. DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
  165. };
  166. template <typename FieldType>
  167. class ValueFieldConverter : public ValueConverter<FieldType> {
  168. public:
  169. typedef bool(*ConvertFunc)(const base::Value* value, FieldType* field);
  170. explicit ValueFieldConverter(ConvertFunc convert_func)
  171. : convert_func_(convert_func) {}
  172. bool Convert(const base::Value& value, FieldType* field) const override {
  173. return convert_func_(&value, field);
  174. }
  175. private:
  176. ConvertFunc convert_func_;
  177. DISALLOW_COPY_AND_ASSIGN(ValueFieldConverter);
  178. };
  179. template <typename FieldType>
  180. class CustomFieldConverter : public ValueConverter<FieldType> {
  181. public:
  182. typedef bool (*ConvertFunc)(StringPiece value, FieldType* field);
  183. explicit CustomFieldConverter(ConvertFunc convert_func)
  184. : convert_func_(convert_func) {}
  185. bool Convert(const base::Value& value, FieldType* field) const override {
  186. std::string string_value;
  187. return value.GetAsString(&string_value) &&
  188. convert_func_(string_value, field);
  189. }
  190. private:
  191. ConvertFunc convert_func_;
  192. DISALLOW_COPY_AND_ASSIGN(CustomFieldConverter);
  193. };
  194. template <typename NestedType>
  195. class NestedValueConverter : public ValueConverter<NestedType> {
  196. public:
  197. NestedValueConverter() = default;
  198. bool Convert(const base::Value& value, NestedType* field) const override {
  199. return converter_.Convert(value, field);
  200. }
  201. private:
  202. JSONValueConverter<NestedType> converter_;
  203. DISALLOW_COPY_AND_ASSIGN(NestedValueConverter);
  204. };
  205. template <typename Element>
  206. class RepeatedValueConverter
  207. : public ValueConverter<std::vector<std::unique_ptr<Element>>> {
  208. public:
  209. RepeatedValueConverter() = default;
  210. bool Convert(const base::Value& value,
  211. std::vector<std::unique_ptr<Element>>* field) const override {
  212. if (!value.is_list()) {
  213. // The field is not a list.
  214. return false;
  215. }
  216. field->reserve(value.GetList().size());
  217. size_t i = 0;
  218. for (const Value& element : value.GetList()) {
  219. auto e = std::make_unique<Element>();
  220. if (basic_converter_.Convert(element, e.get())) {
  221. field->push_back(std::move(e));
  222. } else {
  223. DVLOG(1) << "failure at " << i << "-th element";
  224. return false;
  225. }
  226. i++;
  227. }
  228. return true;
  229. }
  230. private:
  231. BasicValueConverter<Element> basic_converter_;
  232. DISALLOW_COPY_AND_ASSIGN(RepeatedValueConverter);
  233. };
  234. template <typename NestedType>
  235. class RepeatedMessageConverter
  236. : public ValueConverter<std::vector<std::unique_ptr<NestedType>>> {
  237. public:
  238. RepeatedMessageConverter() = default;
  239. bool Convert(const base::Value& value,
  240. std::vector<std::unique_ptr<NestedType>>* field) const override {
  241. if (!value.is_list())
  242. return false;
  243. field->reserve(value.GetList().size());
  244. size_t i = 0;
  245. for (const Value& element : value.GetList()) {
  246. auto nested = std::make_unique<NestedType>();
  247. if (converter_.Convert(element, nested.get())) {
  248. field->push_back(std::move(nested));
  249. } else {
  250. DVLOG(1) << "failure at " << i << "-th element";
  251. return false;
  252. }
  253. i++;
  254. }
  255. return true;
  256. }
  257. private:
  258. JSONValueConverter<NestedType> converter_;
  259. DISALLOW_COPY_AND_ASSIGN(RepeatedMessageConverter);
  260. };
  261. template <typename NestedType>
  262. class RepeatedCustomValueConverter
  263. : public ValueConverter<std::vector<std::unique_ptr<NestedType>>> {
  264. public:
  265. typedef bool(*ConvertFunc)(const base::Value* value, NestedType* field);
  266. explicit RepeatedCustomValueConverter(ConvertFunc convert_func)
  267. : convert_func_(convert_func) {}
  268. bool Convert(const base::Value& value,
  269. std::vector<std::unique_ptr<NestedType>>* field) const override {
  270. if (!value.is_list())
  271. return false;
  272. field->reserve(value.GetList().size());
  273. size_t i = 0;
  274. for (const Value& element : value.GetList()) {
  275. auto nested = std::make_unique<NestedType>();
  276. if ((*convert_func_)(&element, nested.get())) {
  277. field->push_back(std::move(nested));
  278. } else {
  279. DVLOG(1) << "failure at " << i << "-th element";
  280. return false;
  281. }
  282. i++;
  283. }
  284. return true;
  285. }
  286. private:
  287. ConvertFunc convert_func_;
  288. DISALLOW_COPY_AND_ASSIGN(RepeatedCustomValueConverter);
  289. };
  290. } // namespace internal
  291. template <class StructType>
  292. class JSONValueConverter {
  293. public:
  294. JSONValueConverter() {
  295. StructType::RegisterJSONConverter(this);
  296. }
  297. void RegisterIntField(const std::string& field_name,
  298. int StructType::* field) {
  299. fields_.push_back(
  300. std::make_unique<internal::FieldConverter<StructType, int>>(
  301. field_name, field, new internal::BasicValueConverter<int>));
  302. }
  303. void RegisterStringField(const std::string& field_name,
  304. std::string StructType::* field) {
  305. fields_.push_back(
  306. std::make_unique<internal::FieldConverter<StructType, std::string>>(
  307. field_name, field, new internal::BasicValueConverter<std::string>));
  308. }
  309. void RegisterStringField(const std::string& field_name,
  310. string16 StructType::* field) {
  311. fields_.push_back(
  312. std::make_unique<internal::FieldConverter<StructType, string16>>(
  313. field_name, field, new internal::BasicValueConverter<string16>));
  314. }
  315. void RegisterBoolField(const std::string& field_name,
  316. bool StructType::* field) {
  317. fields_.push_back(
  318. std::make_unique<internal::FieldConverter<StructType, bool>>(
  319. field_name, field, new internal::BasicValueConverter<bool>));
  320. }
  321. void RegisterDoubleField(const std::string& field_name,
  322. double StructType::* field) {
  323. fields_.push_back(
  324. std::make_unique<internal::FieldConverter<StructType, double>>(
  325. field_name, field, new internal::BasicValueConverter<double>));
  326. }
  327. template <class NestedType>
  328. void RegisterNestedField(
  329. const std::string& field_name, NestedType StructType::* field) {
  330. fields_.push_back(
  331. std::make_unique<internal::FieldConverter<StructType, NestedType>>(
  332. field_name, field, new internal::NestedValueConverter<NestedType>));
  333. }
  334. template <typename FieldType>
  335. void RegisterCustomField(const std::string& field_name,
  336. FieldType StructType::*field,
  337. bool (*convert_func)(StringPiece, FieldType*)) {
  338. fields_.push_back(
  339. std::make_unique<internal::FieldConverter<StructType, FieldType>>(
  340. field_name, field,
  341. new internal::CustomFieldConverter<FieldType>(convert_func)));
  342. }
  343. template <typename FieldType>
  344. void RegisterCustomValueField(
  345. const std::string& field_name,
  346. FieldType StructType::* field,
  347. bool (*convert_func)(const base::Value*, FieldType*)) {
  348. fields_.push_back(
  349. std::make_unique<internal::FieldConverter<StructType, FieldType>>(
  350. field_name, field,
  351. new internal::ValueFieldConverter<FieldType>(convert_func)));
  352. }
  353. void RegisterRepeatedInt(
  354. const std::string& field_name,
  355. std::vector<std::unique_ptr<int>> StructType::*field) {
  356. fields_.push_back(std::make_unique<internal::FieldConverter<
  357. StructType, std::vector<std::unique_ptr<int>>>>(
  358. field_name, field, new internal::RepeatedValueConverter<int>));
  359. }
  360. void RegisterRepeatedString(
  361. const std::string& field_name,
  362. std::vector<std::unique_ptr<std::string>> StructType::*field) {
  363. fields_.push_back(
  364. std::make_unique<internal::FieldConverter<
  365. StructType, std::vector<std::unique_ptr<std::string>>>>(
  366. field_name, field,
  367. new internal::RepeatedValueConverter<std::string>));
  368. }
  369. void RegisterRepeatedString(
  370. const std::string& field_name,
  371. std::vector<std::unique_ptr<string16>> StructType::*field) {
  372. fields_.push_back(std::make_unique<internal::FieldConverter<
  373. StructType, std::vector<std::unique_ptr<string16>>>>(
  374. field_name, field, new internal::RepeatedValueConverter<string16>));
  375. }
  376. void RegisterRepeatedDouble(
  377. const std::string& field_name,
  378. std::vector<std::unique_ptr<double>> StructType::*field) {
  379. fields_.push_back(std::make_unique<internal::FieldConverter<
  380. StructType, std::vector<std::unique_ptr<double>>>>(
  381. field_name, field, new internal::RepeatedValueConverter<double>));
  382. }
  383. void RegisterRepeatedBool(
  384. const std::string& field_name,
  385. std::vector<std::unique_ptr<bool>> StructType::*field) {
  386. fields_.push_back(std::make_unique<internal::FieldConverter<
  387. StructType, std::vector<std::unique_ptr<bool>>>>(
  388. field_name, field, new internal::RepeatedValueConverter<bool>));
  389. }
  390. template <class NestedType>
  391. void RegisterRepeatedCustomValue(
  392. const std::string& field_name,
  393. std::vector<std::unique_ptr<NestedType>> StructType::*field,
  394. bool (*convert_func)(const base::Value*, NestedType*)) {
  395. fields_.push_back(
  396. std::make_unique<internal::FieldConverter<
  397. StructType, std::vector<std::unique_ptr<NestedType>>>>(
  398. field_name, field,
  399. new internal::RepeatedCustomValueConverter<NestedType>(
  400. convert_func)));
  401. }
  402. template <class NestedType>
  403. void RegisterRepeatedMessage(
  404. const std::string& field_name,
  405. std::vector<std::unique_ptr<NestedType>> StructType::*field) {
  406. fields_.push_back(
  407. std::make_unique<internal::FieldConverter<
  408. StructType, std::vector<std::unique_ptr<NestedType>>>>(
  409. field_name, field,
  410. new internal::RepeatedMessageConverter<NestedType>));
  411. }
  412. bool Convert(const base::Value& value, StructType* output) const {
  413. if (!value.is_dict())
  414. return false;
  415. for (size_t i = 0; i < fields_.size(); ++i) {
  416. const internal::FieldConverterBase<StructType>* field_converter =
  417. fields_[i].get();
  418. const base::Value* field = value.FindPath(field_converter->field_path());
  419. if (field) {
  420. if (!field_converter->ConvertField(*field, output)) {
  421. DVLOG(1) << "failure at field " << field_converter->field_path();
  422. return false;
  423. }
  424. }
  425. }
  426. return true;
  427. }
  428. private:
  429. std::vector<std::unique_ptr<internal::FieldConverterBase<StructType>>>
  430. fields_;
  431. DISALLOW_COPY_AND_ASSIGN(JSONValueConverter);
  432. };
  433. } // namespace base
  434. #endif // BASE_JSON_JSON_VALUE_CONVERTER_H_