JsonConvertHelper.hpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. #ifndef _SP_UTILITY_JSON_CONVERT_HELPER_
  2. #define _SP_UTILITY_JSON_CONVERT_HELPER_
  3. #include "json/json.h"
  4. #include <string>
  5. #include <vector>
  6. #include <initializer_list>
  7. typedef BYTE byte, *PBYTE, *LPBYTE;
  8. static int StrBuf2HexBuf(const char* strBuf, PBYTE* hexBuf)
  9. {
  10. int len = strlen(strBuf);
  11. if (len == 0 || len % 2 != 0)
  12. return 0;
  13. BYTE* buf = new BYTE[len / 2];
  14. if (buf == NULL)
  15. return 0;
  16. int j = 0;
  17. for (int i = 0; i < len;) {
  18. int tmpVal;
  19. sscanf(strBuf + i, "%2X", &tmpVal);
  20. buf[j] = tmpVal;
  21. i += 2;
  22. j++;
  23. }
  24. *hexBuf = buf;
  25. return j;
  26. }
  27. static int HexBuf2StrBuf(PBYTE hexBuf, char** strBuf, DWORD len)
  28. {
  29. char* tmpStr = *strBuf;
  30. DWORD count = 0;
  31. for (DWORD i = 0; i < len; ++i) {
  32. sprintf(tmpStr + count, "%0.2X", hexBuf[i]);
  33. count += 2;
  34. }
  35. return 0;
  36. }
  37. #define JSONCONVERT2OBJECT_MEMEBER_REGISTER(...) \
  38. bool JSONCONVERT2OBJECT_MEMEBER_REGISTER_RESERVERD_IMPLE(const Json::Value& jsonTypeValue, std::vector<std::string> &names) \
  39. { \
  40. if(names.size() <= 0) { \
  41. names = Member2KeyParseWithStr(#__VA_ARGS__); \
  42. } \
  43. return JsonParse(names, 0, jsonTypeValue, __VA_ARGS__); \
  44. } \
  45. bool OBJECTCONVERT2JSON_MEMEBER_REGISTER_RESERVERD_IMPLE(Json::Value& jsonTypeValue, std::vector<std::string> &names) const \
  46. { \
  47. if(names.size() <= 0) { \
  48. names = Member2KeyParseWithStr(#__VA_ARGS__); \
  49. } \
  50. return ParseJson(names, 0, jsonTypeValue, __VA_ARGS__); \
  51. }
  52. /*
  53. std::string GetOutputString() const\
  54. { \
  55. std::ostringstream str; \
  56. std::vector<std::string> names = Member2KeyParseWithStr(#__VA_ARGS__); \
  57. for(auto it=names.begin(); it!=names.end(); ++it) { if(it != names.begin()) { str << " | "; } str << *it; } \
  58. if (names.size() > 0) { str << "\r\n"; } \
  59. DbgPrint(str, __VA_ARGS__); \
  60. return str.str(); \
  61. }
  62. */
  63. #define JSONCONVERT2OBJECT_MEMEBER_RENAME_REGISTER(...) \
  64. std::vector<std::string> JSONCONVERT2OBJECT_MEMEBER_RENAME_REGISTER_RESERVERD_IMPLE() const \
  65. { \
  66. return Member2KeyParseWithMultiParam({ __VA_ARGS__ }); \
  67. }
  68. namespace SP
  69. {
  70. namespace Utility
  71. {
  72. namespace JSON
  73. {
  74. template <bool, class TYPE = void>
  75. struct enable_if
  76. {
  77. };
  78. template <class TYPE>
  79. struct enable_if<true, TYPE>
  80. {
  81. typedef TYPE type;
  82. };
  83. } //JSON
  84. } //Utility
  85. } //SP
  86. template <typename T>
  87. struct HasConverFunction
  88. {
  89. template <typename TT>
  90. static char func(decltype(&TT::JSONCONVERT2OBJECT_MEMEBER_REGISTER_RESERVERD_IMPLE)); //@1
  91. template <typename TT>
  92. static int func(...); //@2
  93. /*
  94. * 如果类型T没有 JSONCONVERT2OBJECT_MEMEBER_REGISTER_RESERVERD_IMPLE 方法,
  95. * func<T>(NULL) 匹配 @1 时会产生错误,由于 SFINAE 准则,只能匹配@2
  96. * 的func,此时返回值 4 个字节,has 变量为 false,反之,has 变量为 true
  97. */
  98. const static bool has = (sizeof(func<T>(NULL)) == sizeof(char));
  99. template <typename TT>
  100. static char func2(decltype(&TT::JSONCONVERT2OBJECT_MEMEBER_RENAME_REGISTER_RESERVERD_IMPLE)); //@1
  101. template <typename TT>
  102. static int func2(...); //@2
  103. const static bool has2 = (sizeof(func2<T>(NULL)) == sizeof(char));
  104. };
  105. static std::vector<std::string> Member2KeyParseWithMultiParam(std::initializer_list<std::string> il)
  106. {
  107. std::vector<std::string> result;
  108. for (auto it = il.begin(); it != il.end(); it++) {
  109. result.push_back(*it);
  110. }
  111. return result;
  112. }
  113. inline static std::string NormalStringTrim(std::string const& str)
  114. {
  115. static char const* whitespaceChars = "\n\r\t ";
  116. std::string::size_type start = str.find_first_not_of(whitespaceChars);
  117. std::string::size_type end = str.find_last_not_of(whitespaceChars);
  118. return start != std::string::npos ? str.substr(start, 1 + end - start) : std::string();
  119. }
  120. inline static std::vector<std::string> NormalStringSplit(std::string str, char splitElem)
  121. {
  122. std::vector<std::string> strs;
  123. std::string::size_type pos1, pos2;
  124. pos2 = str.find(splitElem);
  125. pos1 = 0;
  126. while (std::string::npos != pos2) {
  127. strs.push_back(str.substr(pos1, pos2 - pos1));
  128. pos1 = pos2 + 1;
  129. pos2 = str.find(splitElem, pos1);
  130. }
  131. strs.push_back(str.substr(pos1));
  132. return strs;
  133. }
  134. static std::vector<std::string> Member2KeyParseWithStr(const std::string& values)
  135. {
  136. std::vector<std::string> result;
  137. auto enumValues = NormalStringSplit(values, ',');
  138. result.reserve(enumValues.size());
  139. for (auto const& enumValue : enumValues) {
  140. /** 修复喜欢加空格或代码格式化导致的问题 [Gifur@2022122]*/
  141. result.push_back(NormalStringTrim(enumValue));
  142. }
  143. return result;
  144. }
  145. //////////////////////////////////////////////////////////////////////////////
  146. static bool Json2Object(bool& aimObj, const Json::Value& jsonTypeValue)
  147. {
  148. if (jsonTypeValue.isNull()) {
  149. aimObj = false;
  150. return true;
  151. }
  152. if (jsonTypeValue.isNull() || !jsonTypeValue.isBool()) {
  153. return false;
  154. } else {
  155. aimObj = jsonTypeValue.asBool();
  156. return true;
  157. }
  158. }
  159. static bool Object2Json(Json::Value& jsonTypeValue, const std::string& key, bool value)
  160. {
  161. jsonTypeValue[key] = value;
  162. return true;
  163. }
  164. static bool Json2Object(int& aimObj, const Json::Value& jsonTypeValue)
  165. {
  166. if (jsonTypeValue.isNull()) {
  167. aimObj = 0;
  168. return true;
  169. }
  170. if (jsonTypeValue.isNull() || !jsonTypeValue.isInt()) {
  171. return false;
  172. } else {
  173. aimObj = jsonTypeValue.asInt();
  174. return true;
  175. }
  176. }
  177. static bool Object2Json(Json::Value& jsonTypeValue, const std::string& key, const int& value)
  178. {
  179. jsonTypeValue[key] = value;
  180. return true;
  181. }
  182. static bool Json2Object(unsigned int& aimObj, const Json::Value& jsonTypeValue)
  183. {
  184. if (jsonTypeValue.isNull()) {
  185. aimObj = 0;
  186. return true;
  187. }
  188. if (jsonTypeValue.isNull() || !jsonTypeValue.isUInt()) {
  189. return false;
  190. } else {
  191. aimObj = jsonTypeValue.asUInt();
  192. return true;
  193. }
  194. }
  195. static bool Object2Json(Json::Value& jsonTypeValue, const std::string& key, const unsigned int& value)
  196. {
  197. jsonTypeValue[key] = value;
  198. return true;
  199. }
  200. static bool Json2Object(double& aimObj, const Json::Value& jsonTypeValue)
  201. {
  202. if (jsonTypeValue.isNull()) {
  203. aimObj = 0.0;
  204. return true;
  205. }
  206. if (jsonTypeValue.isNull() || !jsonTypeValue.isDouble()) {
  207. return false;
  208. } else {
  209. aimObj = jsonTypeValue.asDouble();
  210. return true;
  211. }
  212. }
  213. static bool Object2Json(Json::Value& jsonTypeValue, const std::string& key, const double& value)
  214. {
  215. jsonTypeValue[key] = value;
  216. return true;
  217. }
  218. static bool Json2Object(std::string& aimObj, const Json::Value& jsonTypeValue)
  219. {
  220. if (jsonTypeValue.isNull()) {
  221. aimObj.clear();
  222. return true;
  223. }
  224. if (jsonTypeValue.isNull() || !jsonTypeValue.isString()) {
  225. return false;
  226. } else {
  227. aimObj = jsonTypeValue.asString();
  228. return true;
  229. }
  230. }
  231. static bool Object2Json(Json::Value& jsonTypeValue, const std::string& key, const std::string& value)
  232. {
  233. jsonTypeValue[key] = value;
  234. return true;
  235. }
  236. static bool Json2Object(BYTE* aimObj, const Json::Value& jsonTypeValue)
  237. {
  238. if (jsonTypeValue.isNull()) {
  239. return true;
  240. }
  241. if (jsonTypeValue.isNull() || !jsonTypeValue.isString()) {
  242. return false;
  243. }
  244. else {
  245. int len = StrBuf2HexBuf(jsonTypeValue.asString().c_str(), &aimObj);
  246. if (len == 0)
  247. {
  248. return false;
  249. }
  250. return true;
  251. }
  252. }
  253. template <typename TClass, typename SP::Utility::JSON::enable_if<HasConverFunction<TClass>::has2, int>::type = 0>
  254. static inline std::vector<std::string> PreGetCustomMemberNameIfExists(const TClass& aimObj)
  255. {
  256. return aimObj.JSONCONVERT2OBJECT_MEMEBER_RENAME_REGISTER_RESERVERD_IMPLE();
  257. }
  258. template <typename TClass, typename SP::Utility::JSON::enable_if<!HasConverFunction<TClass>::has2, int>::type = 0>
  259. static inline std::vector<std::string> PreGetCustomMemberNameIfExists(const TClass& aimObj)
  260. {
  261. return std::vector<std::string>();
  262. }
  263. template <typename TClass, typename SP::Utility::JSON::enable_if<HasConverFunction<TClass>::has, int>::type = 0>
  264. static inline bool Json2Object(TClass& aimObj, const Json::Value& jsonTypeValue)
  265. {
  266. std::vector<std::string> names = PreGetCustomMemberNameIfExists(aimObj);
  267. return aimObj.JSONCONVERT2OBJECT_MEMEBER_REGISTER_RESERVERD_IMPLE(jsonTypeValue, names);
  268. }
  269. template <typename TClass, typename SP::Utility::JSON::enable_if<!HasConverFunction<TClass>::has, int>::type = 0>
  270. static inline bool Json2Object(TClass& aimObj, const Json::Value& jsonTypeValue)
  271. {
  272. return false;
  273. }
  274. template <typename T>
  275. static bool Json2Object(std::vector<T>& aimObj, const Json::Value& jsonTypeValue)
  276. {
  277. if (jsonTypeValue.isNull() || !jsonTypeValue.isArray()) {
  278. return false;
  279. } else {
  280. aimObj.clear();
  281. bool result(true);
  282. for (int i = 0; i < jsonTypeValue.size(); ++i) {
  283. T item;
  284. if (!Json2Object(item, jsonTypeValue[i])) {
  285. result = false;
  286. }
  287. aimObj.push_back(item);
  288. }
  289. return result;
  290. }
  291. }
  292. template <typename T>
  293. static bool JsonParse(const std::vector<std::string>& names, int index, const Json::Value& jsonTypeValue, T& arg)
  294. {
  295. const auto key = names[index];
  296. if (!jsonTypeValue.isMember(key) || Json2Object(arg, jsonTypeValue[key])) {
  297. return true;
  298. } else {
  299. return false;
  300. }
  301. }
  302. template <typename T, typename... Args>
  303. static bool JsonParse(const std::vector<std::string>& names, int index, const Json::Value& jsonTypeValue, T& arg, Args&... args)
  304. {
  305. if (!JsonParse(names, index, jsonTypeValue, arg)) {
  306. return false;
  307. } else {
  308. return JsonParse(names, index + 1, jsonTypeValue, args...);
  309. }
  310. }
  311. /** Provider interface*/
  312. template<typename TClass>
  313. bool Json2Object(TClass& aimObj, const std::string& jsonTypeStr)
  314. {
  315. Json::Reader reader;
  316. Json::Value root;
  317. if (!reader.parse(jsonTypeStr, root) || root.isNull()) {
  318. return false;
  319. }
  320. return Json2Object(aimObj, root);
  321. }
  322. static bool GetJsonRootObject(Json::Value& root, const std::string& jsonTypeStr)
  323. {
  324. Json::Reader reader;
  325. if (!reader.parse(jsonTypeStr, root)) {
  326. return false;
  327. }
  328. return true;
  329. }
  330. ////////////////////////////////////////////////////////////////////////
  331. template <typename TClass, typename SP::Utility::JSON::enable_if<HasConverFunction<TClass>::has, int>::type = 0>
  332. static inline bool Object2Json(Json::Value& jsonTypeOutValue, const std::string& key, const TClass& objValue)
  333. {
  334. std::vector<std::string> names = PreGetCustomMemberNameIfExists(objValue);
  335. if (key.empty()) {
  336. return objValue.OBJECTCONVERT2JSON_MEMEBER_REGISTER_RESERVERD_IMPLE(jsonTypeOutValue, names);
  337. } else {
  338. Json::Value jsonTypeNewValue;
  339. const bool result = objValue.OBJECTCONVERT2JSON_MEMEBER_REGISTER_RESERVERD_IMPLE(jsonTypeNewValue, names);
  340. if (result) {
  341. jsonTypeOutValue[key] = jsonTypeNewValue;
  342. }
  343. return result;
  344. }
  345. }
  346. template <typename TClass, typename SP::Utility::JSON::enable_if<!HasConverFunction<TClass>::has, int>::type = 0>
  347. static inline bool Object2Json(Json::Value& jsonTypeOutValue, const std::string& key, const TClass& objValue)
  348. {
  349. return false;
  350. }
  351. template <typename T>
  352. static bool Object2Json(Json::Value& jsonTypeOutValue, const std::string& key, const std::vector<T>& objValue)
  353. {
  354. bool result(true);
  355. for (int i = 0; i < objValue.size(); ++i) {
  356. Json::Value item;
  357. if (!Object2Json(item, "", objValue[i])) {
  358. result = false;
  359. } else {
  360. if (key.empty()) jsonTypeOutValue.append(item);
  361. else jsonTypeOutValue[key].append(item);
  362. }
  363. }
  364. return result;
  365. }
  366. template <typename T>
  367. static bool ParseJson(const std::vector<std::string>& names, int index, Json::Value& jsonTypeValue, const T& arg)
  368. {
  369. if (names.size() > index) {
  370. const std::string key = names[index];
  371. ///**TODO(Gifur@1/22/2022): 需要扩展其他类型实现,这里不直接用 JsonCPP 的内容,要考虑到其他自定义结构体 */
  372. return Object2Json(jsonTypeValue, key, arg);
  373. } else {
  374. return false;
  375. }
  376. }
  377. template <typename T, typename... Args>
  378. static bool ParseJson(const std::vector<std::string>& names, int index, Json::Value& jsonTypeValue, T& arg, Args&... args)
  379. {
  380. if (names.size() - (index + 0) != 1 + sizeof...(Args)) {
  381. return false;
  382. }
  383. /** 通过低柜调用实现 [Gifur@2022122]*/
  384. const std::string key = names[index];
  385. Object2Json(jsonTypeValue, key, arg);
  386. return ParseJson(names, index + 1, jsonTypeValue, args...);
  387. }
  388. /** Provider interface*/
  389. template<typename T>
  390. bool Object2Json(std::string& jsonTypeStr, const T& obj)
  391. {
  392. //std::function<Json::Value()>placehoder = [&]()->Json::Value { return Json::Value(); };
  393. //auto func = [&](std::function<Json::Value()>f) { return f(); };
  394. //Json::Value val = func(placehoder);
  395. Json::StyledWriter writer;
  396. Json::Value root;
  397. const bool result = Object2Json(root, "", obj);
  398. if (result) {
  399. jsonTypeStr = writer.write(root);
  400. }
  401. return result;
  402. }
  403. template<typename T>
  404. std::ostringstream& DbgPrint(std::ostringstream& os, T& t)
  405. {
  406. return os << t;
  407. }
  408. template<typename T, typename... Args>
  409. std::ostringstream& DbgPrint(std::ostringstream& os, T& t, Args&... rest)
  410. {
  411. os << t << ", ";
  412. return DbgPrint(os, rest...);
  413. }
  414. #define __func_1(func,member) func(member);
  415. #define __func_2(func,member,...) __func_1(func,member) __func_1(func,__VA_ARGS__)
  416. #define __func_3(func,member,...) __func_1(func,member) __func_2(func,__VA_ARGS__)
  417. #define __func_4(func,member,...) __func_1(func,member) __func_3(func,__VA_ARGS__)
  418. #define __func_5(func,member,...) __func_1(func,member) __func_4(func,__VA_ARGS__)
  419. //eg: COUNT(a,b,c) === 3
  420. #define COUNT(...) __count__(0, ##__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
  421. #define __count__(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
  422. #define __macro_cat__(a,b) a##b
  423. #define MACRO_CAT(a,b) __macro_cat__(a,b)
  424. #define FOR_EACH(func,...) \
  425. MACRO_CAT(__func_,COUNT(__VA_ARGS__))(func, __VA_ARGS__)
  426. #define JSON2OBJECT_EACH_FILED__(field) \
  427. if(!::Json2Object(field, jsonTypeValue[#field])){ \
  428. result = false; \
  429. }
  430. #endif //_SP_UTILITY_JSON_CONVERT_HELPER_