#ifndef JSON_VC_WRAPPER_H #define JSON_VC_WRAPPER_H #include "_nlohmann_json_wrapper.h" #include // for CString #include // for CPoint, CSize, CRect #include "StringHelper.h" // wchar_t定义to_json没用,直接用j["keyname"] = utf16_8(wstr); // GDCPP_API void to_json(jsonobj& j, const wchar_t * p); // wstring定义to_json没用,直接用j["keyname"] = utf16_8(wstr); // GDCPP_API void to_json(jsonobj& j, const std::wstring& p); // std::wstring用from_josn会报错,用下面的toWstring //GDCPP_API void from_json(const jsonobj& j, std::wstring& p); bool toWstring(const jsonobj& j, std::wstring& dst); template ::Type> int readWstring(const jsonobj& j, KeyT key, std::wstring& dst) { auto it = j.find(key); if (it == j.end() || it->is_null()) {//没找到 return 0; } if (it->is_string()) { // 判断是否为string类型的数据,避免get函数抛出异常 dst = utf8_16(it->get()); return 1; } else { return -1; } } template ::Type> int readWstringVector(const jsonobj& j, KeyT key, std::vector& dst, bool clearbeforeread) { if (clearbeforeread) { dst.clear(); } auto it = j.find(key); if (it == j.end() || it->is_null()) {//没找到 return 0; } if (!it->is_array()) { //not array return -1; } std::string str; for (auto& i : *it) { str = i.get(); dst.push_back(utf8_16(str)); } return int(it->size()); } template ::Type> int readWstring(const jsonobj& j, KeyT key, std::wstring& dst, const std::wstring &def) { auto it = j.find(key); if (it == j.end() || it->is_null()) {//没找到 dst = def; return 0; } if (it->is_string()) { // 判断是否为string类型的数据,避免get函数抛出异常 dst = utf8_16(it->get()); return 1; } else { return -1; } } void to_json(jsonobj& j, const CString& p); void from_json(const jsonobj& j, CString& p); void to_json(jsonobj& j, const CPoint& p); void from_json(const jsonobj& j, CPoint& p); void to_json(jsonobj& j, const CSize& p); void from_json(const jsonobj& j, CSize& p); void to_json(jsonobj& j, const CRect& p); void from_json(const jsonobj& j, CRect& p); /** @addtogroup Vector * @brief std::vector <---> jsonobj * @{*/ /// \brief std::vector -> json,T不要是指针类型,模板匹配有问题 /// \details 注意会先清空j,如果j之前不是array也会强制变成array. template void to_json(jsonobj& j, const std::vector & p) { j = jsonobj::array(); //先清空 int num = int(p.size()); for (int i = 0; i < num; i++) { j.push_back(p.at(i)); } } /// \brief json -> std::vector ,T不要是指针类型,模板匹配有问题 /// \details 注意会先清空p!不想清空就用\ref readVector template void from_json(const jsonobj& j, std::vector & p) { p.clear(); //先清空 if (j.is_array()) { size_t num = j.size(); for (size_t i = 0; i < num; i++) { p.push_back(j.at(i).get()); } } } /// \brief json --> std::vector,不会清除原有数据。注意没有判断json里的数据是否与ValueT类型匹配,需要应用层保证 /// /// \param j nlohmann::json对象 /// \param key 键值,类型KeyT支持类型const char *, std::string /// \param dst 目标变量。 /// \return 没找到返回0,找到但不是数组类型-1,有数据返回读到的数据类型。 template ::Type, typename = JsonKey::Type, typename ValueT> int readVector(const jsonobj& j, KeyT key, std::vector& dst) { auto it = j.find(key); if (it == j.end() || it->is_null()) {//没找到 return 0; } if (!it->is_array()) { //not array return -1; } int num = int(it->size()); for (int i = 0; i < num; i++) { // 基础类不能用from_json,只能用get_to dst.push_back(it->at(i).template get()); } return num; } template ::Type, typename = JsonKey::Type, typename ValueT> int readVector2D(const jsonobj& j, std::vector< std::vector>& dst) { if (!j.is_array()) { //not array return -1; } int num = int(j.size()); for (int i = 0; i < num; i++) { std::vector sub; readVector(j.at(i), sub); dst.push_back(sub); } return num; } template ::Type, typename = JsonKey::Type, typename ValueT> int readVector2D(const jsonobj& j, KeyT key, std::vector< std::vector>& dst) { auto it = j.find(key); if (it == j.end() || it->is_null()) {//没找到 return 0; } if (!it->is_array()) { //not array return -1; } int num = int(it->size()); for (int i = 0; i < num; i++) { std::vector sub; readVector(it->at(i), sub); dst.push_back(sub); } return num; } /// \brief json --> std::vector,不会清除原有数据。注意没有判断json里的数据是否与ValueT类型匹配,需要应用层保证 /// /// \param j nlohmann::json对象 /// \param dst 目标变量。 /// \return 没找到返回0,找到但不是数组类型-1,有数据返回读到的数据类型。 template int readVector(const jsonobj& j, std::vector& dst) { if (!j.is_array()) { //not array return -1; } int num = int(j.size()); for (int i = 0; i < num; i++) { ValueT tmp; j.at(i).template get_to(tmp); dst.push_back(tmp); } return num; } /// \brief json --> std::vector,不会清除原有数据。注意没有判断json里的数据是否与ValueT类型匹配,需要应用层保证 /// /// \param j nlohmann::json对象 /// \param key 键值,类型KeyT支持类型const char *, std::string /// \param dst 目标变量。 /// \return 没找到返回0,找到但不是数组类型-1,有数据返回读到的数据类型。 template ::Type, typename ValueT> int readPtrVector(const jsonobj& j, KeyT key, std::vector& dst) { auto it = j.find(key); if (it == j.end() || it->is_null()) {//没找到 return 0; } if (!it->is_array()) { //not array return -1; } int num = int(it->size()); for (int i = 0; i < num; i++) { auto* item = new ValueT(); it->at(i).template get_to(*item); dst.push_back(item); } return num; } /// \brief json --> std::vector,不会清除原有数据。注意没有判断json里的数据是否与ValueT类型匹配,需要应用层保证 /// /// \param j nlohmann::json对象 /// \param dst 目标变量。 /// \return 没找到返回0,找到但不是数组类型-1,有数据返回读到的数据类型。 template int readPtrVector(const jsonobj& j, std::vector& dst) { if (!j.is_array()) { //not array return -1; } int num = int(j.size()); for (int i = 0; i < num; i++) { auto* item = new ValueT(); j.at(i).template get_to(*item); dst.push_back(item); } return num; } /// \brief std::vector -> json /// \details template int writeVector(jsonobj& j, const std::vector& p, bool clean=false) { if (clean) {//写入前强制清空 j = jsonobj::array(); }else if (!j.is_array()) { return -1; } int num = int(p.size()); for (int i = 0; i < num; i++) { jsonobj x; to_json(x, p.at(i)); j.push_back(x); } return num; } /// \brief std::vector -> json /// \details template ::Type, typename T> int writeVector(jsonobj& j, KeyT key, const std::vector& p, bool clean = false) { auto it = j.find(key); if (it == j.end() || it->is_null() || clean) {//没找到或强制清空 j[key] = jsonobj::array(); //先清空 } else if (!it->is_array()) { return -1; } int num = int(p.size()); for (int i = 0; i < num; i++) { jsonobj x; to_json(x, p.at(i)); j[key].push_back(x); } return num; } /// \brief std::vector -> json /// \details template int writePtrVector(jsonobj& j, const std::vector& p, bool clean = false) { if (clean) {//写入前强制清空 j = jsonobj::array(); } else if (!j.is_array()) { return -1; } int num = int(p.size()); for (int i = 0; i < num; i++) { jsonobj x; to_json(x, *p.at(i)); j.push_back(x); } return num; } /// \brief std::vector -> json /// \details template ::Type, typename T> int writePtrVector(jsonobj& j, KeyT key, const std::vector& p, bool clean=false) { auto it = j.find(key); if (it == j.end() || it->is_null() || clean) {//没找到或强制清空 j[key] = jsonobj::array(); //先清空 } else if (!it->is_array()) { return -1; } int num = int(p.size()); for (int i = 0; i < num; i++) { jsonobj x; to_json(x, *p.at(i)); j[key].push_back(x); } return num; } /// \brief json --> std::vector>,不会清除原有数据。注意没有判断json里的数据是否与ValueT类型匹配,需要应用层保证 /// /// \param j nlohmann::json对象 /// \param key 键值,类型KeyT支持类型const char *, std::string /// \param dst 目标变量。 /// \return 没找到返回0,找到但不是数组类型-1,有数据返回读到的数据类型。 template ::Type, typename ValueT> int readSharedPtrVector(const jsonobj& j, KeyT key, std::vector>& dst) { auto it = j.find(key); if (it == j.end() || it->is_null()) {//没找到 return 0; } if (!it->is_array()) { //not array return -1; } int num = int(it->size()); for (int i = 0; i < num; i++) { auto item = std::shared_ptr::create(); it->at(i).template get_to(*item); dst.append(item); } return num; } /// \brief json --> std::vector>,不会清除原有数据。注意没有判断json里的数据是否与ValueT类型匹配,需要应用层保证 /// /// \param j nlohmann::json对象 /// \param dst 目标变量。 /// \return 没找到返回0,找到但不是数组类型-1,有数据返回读到的数据类型。 template int readSharedPtrVector(const jsonobj& j, std::vector>& dst) { if (!j.is_array()) { //not array return -1; } int num = int(j.size()); for (int i = 0; i < num; i++) { auto item = std::shared_ptr::create(); j.at(i).template get_to(*item); dst.append(item); } return num; } /// \brief std::vector> -> json /// \details template int writeSharedPtrVector(jsonobj& j, const std::vector>& p) { if (!j.is_array()) { return -1; } int num = int(p.count()); for (int i = 0; i < num; i++) { jsonobj x; to_json(x, *p.at(i)); j.push_back(x); } return num; } /// \brief std::vector> -> json /// \details template ::Type, typename T> int writeSharedPtrVector(jsonobj& j, KeyT key, const std::vector>& p) { auto it = j.find(key); if (it == j.end() || it->is_null()) {//没找到 j[key] = jsonobj::array(); //先清空 } else if (!it->is_array()) { return -1; } int num = int(p.count()); for (int i = 0; i < num; i++) { jsonobj x; to_json(x, *p.at(i)); j[key].push_back(x); } return num; } /** @} vector*/ /** @addtogroup Array * @brief Array <---> jsonobj * @{*/ /// \brief json --> 数组ValueT dst[maxnum] /// 如果json中的数量超过maxnum,只读maxnum个,不报错。 /// \return 返回读到数据个数。
/// 0表示没有找到key或数值为空,
/// -1表示json[key]不是数组,
template ::Type, typename ValueT> int readArray(const jsonobj &j, KeyT key, ValueT* dst, unsigned maxnum) { auto it = j.find(key); if(it == j.end() || it->is_null()) {//没找到 return 0; } if(!it->is_array()){ //not array return -1; } uint32_t num = uint32_t(it->size()); uint32_t readnum = (num > maxnum) ? maxnum : num; for(uint32_t i=0; i< readnum; i++){ it->at(i).template get_to(dst[i]); } return int(readnum); } /// \brief json --> 数组ValueT dst[maxnum] /// 如果json中的数量超过maxnum,只读maxnum个,不报错。 /// \return 返回读到数据个数。
/// 0表示没有找到key或数值为空,
/// -1表示json[key]不是数组,
template ::Type, typename ValueT> int readAnyArray(const jsonobj& j, KeyT key, ValueT* dst, unsigned maxnum) { auto it = j.find(key); if (it == j.end() || it->is_null()) {//没找到 return 0; } if (!it->is_array()) { //not array return -1; } uint32_t num = uint32_t(it->size()); uint32_t readnum = (num > maxnum) ? maxnum : num; for (uint32_t i = 0; i < readnum; i++) { from_json(it->at(i), dst[i]); } return int(readnum); } template ::Type> int readWStringArray(const jsonobj& j, KeyT key, std::wstring* dst, unsigned maxnum) { auto it = j.find(key); if (it == j.end() || it->is_null()) {//没找到 return 0; } if (!it->is_array()) { //not array return -1; } uint32_t num = uint32_t(it->size()); uint32_t readnum = (num > maxnum) ? maxnum : num; std::string str; for (uint32_t i = 0; i < readnum; i++) { it->at(i).get_to(str); dst[i] = utf8_16(str); } return int(readnum); } ///获取json中名为key的数组长度,不存在或null返回0,不是数组返回-1,数组返回数组长度 template ::Type> int readArrayNum(const jsonobj &j, KeyT key) { auto it = j.find(key); if(it == j.end() || it->is_null()) {//没找到 return 0; } if(!it->is_array()){ //not array return -1; } return int(it->size()); } /// \brief 数组 ValueT src[num] -> json template ::Type, typename ValueT> int writeArray(jsonobj &j, KeyT key, const ValueT* src, size_t num) { auto tmp = jsonobj::array(); for (size_t i = 0; i < num; i++) { tmp.push_back(src[i]); } j[key] = tmp; return int(num); } /// \brief 数组 ValueT src[num] -> json template ::Type, typename ValueT> int writeAnyArray(jsonobj& j, KeyT key, const ValueT* src, size_t num) { auto tmp = jsonobj::array(); jsonobj sub; for (size_t i = 0; i < num; i++) { to_json(sub, src[i]); tmp.push_back(sub); } j[key] = tmp; return int(num); } template ::Type> int writeWStringArray(jsonobj& j, KeyT key, const std::wstring* src, size_t num) { j[key] = jsonobj::array(); auto& it = j[key]; std::string str; for (size_t i = 0; i < num; i++) { str=utf16_8(src[i]); it.push_back(str); } return int(num); } /// \brief 数组 ValueT src[num] -> json template ::Type> int writeArray(jsonobj& j, KeyT key, const wchar_t ** src, size_t num) { j[key] = jsonobj::array(); auto& it = j[key]; USES_CONVERSION; for (size_t i = 0; i < num; i++) { it.push_back(W2A(src[i])); } return int(num); } /// \brief 数组 ValueT src[num] -> json template ::Type> int writeArray(jsonobj& j, KeyT key, const char** src, size_t num) { j[key] = jsonobj::array(); auto& it = j[key]; USES_CONVERSION; for (size_t i = 0; i < num; i++) { it.push_back(src[i]); } return int(num); } /** @} Array*/ #endif // JSON_VC_WRAPPER_H