123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434 |
- #ifndef _SP_UTILITY_JSON_CONVERT_HELPER_
- #define _SP_UTILITY_JSON_CONVERT_HELPER_
- #include "json/json.h"
- #include <string>
- #include <vector>
- #include <initializer_list>
- #define JSONCONVERT2OBJECT_MEMEBER_REGISTER(...) \
- bool JSONCONVERT2OBJECT_MEMEBER_REGISTER_RESERVERD_IMPLE(const Json::Value& jsonTypeValue, std::vector<std::string> &names) \
- { \
- if(names.size() <= 0) { \
- names = Member2KeyParseWithStr(#__VA_ARGS__); \
- } \
- return JsonParse(names, 0, jsonTypeValue, __VA_ARGS__); \
- } \
- bool OBJECTCONVERT2JSON_MEMEBER_REGISTER_RESERVERD_IMPLE(Json::Value& jsonTypeValue, std::vector<std::string> &names) const \
- { \
- if(names.size() <= 0) { \
- names = Member2KeyParseWithStr(#__VA_ARGS__); \
- } \
- return ParseJson(names, 0, jsonTypeValue, __VA_ARGS__); \
- }
- /*
- std::string GetOutputString() const\
- { \
- std::ostringstream str; \
- std::vector<std::string> names = Member2KeyParseWithStr(#__VA_ARGS__); \
- for(auto it=names.begin(); it!=names.end(); ++it) { if(it != names.begin()) { str << " | "; } str << *it; } \
- if (names.size() > 0) { str << "\r\n"; } \
- DbgPrint(str, __VA_ARGS__); \
- return str.str(); \
- }
- */
- #define JSONCONVERT2OBJECT_MEMEBER_RENAME_REGISTER(...) \
- std::vector<std::string> JSONCONVERT2OBJECT_MEMEBER_RENAME_REGISTER_RESERVERD_IMPLE() const \
- { \
- return Member2KeyParseWithMultiParam({ __VA_ARGS__ }); \
- }
- namespace SP
- {
- namespace Utility
- {
- namespace JSON
- {
- template <bool, class TYPE = void>
- struct enable_if
- {
- };
- template <class TYPE>
- struct enable_if<true, TYPE>
- {
- typedef TYPE type;
- };
- } //JSON
- } //Utility
- } //SP
- template <typename T>
- struct HasConverFunction
- {
- template <typename TT>
- static char func(decltype(&TT::JSONCONVERT2OBJECT_MEMEBER_REGISTER_RESERVERD_IMPLE)); //@1
-
- template <typename TT>
- static int func(...); //@2
- /*
- * 如果类型T没有 JSONCONVERT2OBJECT_MEMEBER_REGISTER_RESERVERD_IMPLE 方法,
- * func<T>(NULL) 匹配 @1 时会产生错误,由于 SFINAE 准则,只能匹配@2
- * 的func,此时返回值 4 个字节,has 变量为 false,反之,has 变量为 true
- */
- const static bool has = (sizeof(func<T>(NULL)) == sizeof(char));
- template <typename TT>
- static char func2(decltype(&TT::JSONCONVERT2OBJECT_MEMEBER_RENAME_REGISTER_RESERVERD_IMPLE)); //@1
- template <typename TT>
- static int func2(...); //@2
- const static bool has2 = (sizeof(func2<T>(NULL)) == sizeof(char));
- };
- static std::vector<std::string> Member2KeyParseWithMultiParam(std::initializer_list<std::string> il)
- {
- std::vector<std::string> result;
- for (auto it = il.begin(); it != il.end(); it++) {
- result.push_back(*it);
- }
- return result;
- }
- inline static std::string NormalStringTrim(std::string const& str)
- {
- static char const* whitespaceChars = "\n\r\t ";
- std::string::size_type start = str.find_first_not_of(whitespaceChars);
- std::string::size_type end = str.find_last_not_of(whitespaceChars);
- return start != std::string::npos ? str.substr(start, 1 + end - start) : std::string();
- }
- inline static std::vector<std::string> NormalStringSplit(std::string str, char splitElem)
- {
- std::vector<std::string> strs;
- std::string::size_type pos1, pos2;
- pos2 = str.find(splitElem);
- pos1 = 0;
- while (std::string::npos != pos2) {
- strs.push_back(str.substr(pos1, pos2 - pos1));
- pos1 = pos2 + 1;
- pos2 = str.find(splitElem, pos1);
- }
- strs.push_back(str.substr(pos1));
- return strs;
- }
- static std::vector<std::string> Member2KeyParseWithStr(const std::string& values)
- {
- std::vector<std::string> result;
- auto enumValues = NormalStringSplit(values, ',');
- result.reserve(enumValues.size());
- for (auto const& enumValue : enumValues) {
- /** 修复喜欢加空格或代码格式化导致的问题 [Gifur@2022122]*/
- result.push_back(NormalStringTrim(enumValue));
- }
- return result;
- }
- //////////////////////////////////////////////////////////////////////////////
- static bool Json2Object(bool& aimObj, const Json::Value& jsonTypeValue)
- {
- if (jsonTypeValue.isNull()) {
- aimObj = false;
- return true;
- }
- if (jsonTypeValue.isNull() || !jsonTypeValue.isBool()) {
- return false;
- } else {
- aimObj = jsonTypeValue.asBool();
- return true;
- }
- }
- static bool Object2Json(Json::Value& jsonTypeValue, const std::string& key, bool value)
- {
- jsonTypeValue[key] = value;
- return true;
- }
- static bool Json2Object(int& aimObj, const Json::Value& jsonTypeValue)
- {
- if (jsonTypeValue.isNull()) {
- aimObj = 0;
- return true;
- }
- if (jsonTypeValue.isNull() || !jsonTypeValue.isInt()) {
- return false;
- } else {
- aimObj = jsonTypeValue.asInt();
- return true;
- }
- }
- static bool Object2Json(Json::Value& jsonTypeValue, const std::string& key, const int& value)
- {
- jsonTypeValue[key] = value;
- return true;
- }
- static bool Json2Object(unsigned int& aimObj, const Json::Value& jsonTypeValue)
- {
- if (jsonTypeValue.isNull()) {
- aimObj = 0;
- return true;
- }
- if (jsonTypeValue.isNull() || !jsonTypeValue.isUInt()) {
- return false;
- } else {
- aimObj = jsonTypeValue.asUInt();
- return true;
- }
- }
- static bool Object2Json(Json::Value& jsonTypeValue, const std::string& key, const unsigned int& value)
- {
- jsonTypeValue[key] = value;
- return true;
- }
- static bool Json2Object(double& aimObj, const Json::Value& jsonTypeValue)
- {
- if (jsonTypeValue.isNull()) {
- aimObj = 0.0;
- return true;
- }
- if (jsonTypeValue.isNull() || !jsonTypeValue.isDouble()) {
- return false;
- } else {
- aimObj = jsonTypeValue.asDouble();
- return true;
- }
- }
- static bool Object2Json(Json::Value& jsonTypeValue, const std::string& key, const double& value)
- {
- jsonTypeValue[key] = value;
- return true;
- }
- static bool Json2Object(std::string& aimObj, const Json::Value& jsonTypeValue)
- {
- if (jsonTypeValue.isNull()) {
- aimObj.clear();
- return true;
- }
- if (jsonTypeValue.isNull() || !jsonTypeValue.isString()) {
- return false;
- } else {
- aimObj = jsonTypeValue.asString();
- return true;
- }
- }
- static bool Object2Json(Json::Value& jsonTypeValue, const std::string& key, const std::string& value)
- {
- jsonTypeValue[key] = value;
- return true;
- }
- template <typename TClass, typename SP::Utility::JSON::enable_if<HasConverFunction<TClass>::has2, int>::type = 0>
- static inline std::vector<std::string> PreGetCustomMemberNameIfExists(const TClass& aimObj)
- {
- return aimObj.JSONCONVERT2OBJECT_MEMEBER_RENAME_REGISTER_RESERVERD_IMPLE();
- }
- template <typename TClass, typename SP::Utility::JSON::enable_if<!HasConverFunction<TClass>::has2, int>::type = 0>
- static inline std::vector<std::string> PreGetCustomMemberNameIfExists(const TClass& aimObj)
- {
- return std::vector<std::string>();
- }
- template <typename TClass, typename SP::Utility::JSON::enable_if<HasConverFunction<TClass>::has, int>::type = 0>
- static inline bool Json2Object(TClass& aimObj, const Json::Value& jsonTypeValue)
- {
- std::vector<std::string> names = PreGetCustomMemberNameIfExists(aimObj);
- return aimObj.JSONCONVERT2OBJECT_MEMEBER_REGISTER_RESERVERD_IMPLE(jsonTypeValue, names);
- }
- template <typename TClass, typename SP::Utility::JSON::enable_if<!HasConverFunction<TClass>::has, int>::type = 0>
- static inline bool Json2Object(TClass& aimObj, const Json::Value& jsonTypeValue)
- {
- return false;
- }
- template <typename T>
- static bool Json2Object(std::vector<T>& aimObj, const Json::Value& jsonTypeValue)
- {
- if (jsonTypeValue.isNull() || !jsonTypeValue.isArray()) {
- return false;
- } else {
- aimObj.clear();
- bool result(true);
- for (int i = 0; i < jsonTypeValue.size(); ++i) {
- T item;
- if (!Json2Object(item, jsonTypeValue[i])) {
- result = false;
- }
- aimObj.push_back(item);
- }
- return result;
- }
- }
- template <typename T>
- static bool JsonParse(const std::vector<std::string>& names, int index, const Json::Value& jsonTypeValue, T& arg)
- {
- const auto key = names[index];
- if (!jsonTypeValue.isMember(key) || Json2Object(arg, jsonTypeValue[key])) {
- return true;
- } else {
- return false;
- }
- }
- template <typename T, typename... Args>
- static bool JsonParse(const std::vector<std::string>& names, int index, const Json::Value& jsonTypeValue, T& arg, Args&... args)
- {
- if (!JsonParse(names, index, jsonTypeValue, arg)) {
- return false;
- } else {
- return JsonParse(names, index + 1, jsonTypeValue, args...);
- }
- }
- /** Provider interface*/
- template<typename TClass>
- bool Json2Object(TClass& aimObj, const std::string& jsonTypeStr)
- {
- Json::Reader reader;
- Json::Value root;
- if (!reader.parse(jsonTypeStr, root) || root.isNull()) {
- return false;
- }
- return Json2Object(aimObj, root);
- }
- static bool GetJsonRootObject(Json::Value& root, const std::string& jsonTypeStr)
- {
- Json::Reader reader;
- if (!reader.parse(jsonTypeStr, root)) {
- return false;
- }
- return true;
- }
- ////////////////////////////////////////////////////////////////////////
- template <typename TClass, typename SP::Utility::JSON::enable_if<HasConverFunction<TClass>::has, int>::type = 0>
- static inline bool Object2Json(Json::Value& jsonTypeOutValue, const std::string& key, const TClass& objValue)
- {
- std::vector<std::string> names = PreGetCustomMemberNameIfExists(objValue);
- if (key.empty()) {
- return objValue.OBJECTCONVERT2JSON_MEMEBER_REGISTER_RESERVERD_IMPLE(jsonTypeOutValue, names);
- } else {
- Json::Value jsonTypeNewValue;
- const bool result = objValue.OBJECTCONVERT2JSON_MEMEBER_REGISTER_RESERVERD_IMPLE(jsonTypeNewValue, names);
- if (result) {
- jsonTypeOutValue[key] = jsonTypeNewValue;
- }
- return result;
- }
- }
- template <typename TClass, typename SP::Utility::JSON::enable_if<!HasConverFunction<TClass>::has, int>::type = 0>
- static inline bool Object2Json(Json::Value& jsonTypeOutValue, const std::string& key, const TClass& objValue)
- {
- return false;
- }
- template <typename T>
- static bool Object2Json(Json::Value& jsonTypeOutValue, const std::string& key, const std::vector<T>& objValue)
- {
- bool result(true);
- for (int i = 0; i < objValue.size(); ++i) {
- Json::Value item;
- if (!Object2Json(item, "", objValue[i])) {
- result = false;
- } else {
- if (key.empty()) jsonTypeOutValue.append(item);
- else jsonTypeOutValue[key].append(item);
- }
- }
- return result;
- }
- template <typename T>
- static bool ParseJson(const std::vector<std::string>& names, int index, Json::Value& jsonTypeValue, const T& arg)
- {
- if (names.size() > index) {
- const std::string key = names[index];
- ///**TODO(Gifur@1/22/2022): 需要扩展其他类型实现,这里不直接用 JsonCPP 的内容,要考虑到其他自定义结构体 */
- return Object2Json(jsonTypeValue, key, arg);
- } else {
- return false;
- }
- }
- template <typename T, typename... Args>
- static bool ParseJson(const std::vector<std::string>& names, int index, Json::Value& jsonTypeValue, T& arg, Args&... args)
- {
- if (names.size() - (index + 0) != 1 + sizeof...(Args)) {
- return false;
- }
- /** 通过低柜调用实现 [Gifur@2022122]*/
- const std::string key = names[index];
- Object2Json(jsonTypeValue, key, arg);
- return ParseJson(names, index + 1, jsonTypeValue, args...);
- }
- /** Provider interface*/
- template<typename T>
- bool Object2Json(std::string& jsonTypeStr, const T& obj)
- {
- //std::function<Json::Value()>placehoder = [&]()->Json::Value { return Json::Value(); };
- //auto func = [&](std::function<Json::Value()>f) { return f(); };
- //Json::Value val = func(placehoder);
- Json::StyledWriter writer;
- Json::Value root;
- const bool result = Object2Json(root, "", obj);
- if (result) {
- jsonTypeStr = writer.write(root);
- }
- return result;
- }
- template<typename T>
- std::ostringstream& DbgPrint(std::ostringstream& os, T& t)
- {
- return os << t;
- }
- template<typename T, typename... Args>
- std::ostringstream& DbgPrint(std::ostringstream& os, T& t, Args&... rest)
- {
- os << t << ", ";
- return DbgPrint(os, rest...);
- }
- #define __func_1(func,member) func(member);
- #define __func_2(func,member,...) __func_1(func,member) __func_1(func,__VA_ARGS__)
- #define __func_3(func,member,...) __func_1(func,member) __func_2(func,__VA_ARGS__)
- #define __func_4(func,member,...) __func_1(func,member) __func_3(func,__VA_ARGS__)
- #define __func_5(func,member,...) __func_1(func,member) __func_4(func,__VA_ARGS__)
- //eg: COUNT(a,b,c) === 3
- #define COUNT(...) __count__(0, ##__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
- #define __count__(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
- #define __macro_cat__(a,b) a##b
- #define MACRO_CAT(a,b) __macro_cat__(a,b)
- #define FOR_EACH(func,...) \
- MACRO_CAT(__func_,COUNT(__VA_ARGS__))(func, __VA_ARGS__)
- #define JSON2OBJECT_EACH_FILED__(field) \
- if(!::Json2Object(field, jsonTypeValue[#field])){ \
- result = false; \
- }
- #endif //_SP_UTILITY_JSON_CONVERT_HELPER_
|