c++结构体直接转成json字符串,代码示例
main.cpp
#include <iostream>
#include "global.h"
#include "client_param.h"
#include "md5.h"
#include "common_func.h"using namespace std;
using namespace demo;int main() {Global::GetInstance()->Init();LoginParams login_param;login_param.username = "ssss";login_param.password = "12345678";login_param.real_device_uuid = "8Ee7a3D5d2B18f6a5e2B34";login_param.device_uuid = md5("cheng@8Ee7a3D5d2B18f6a5e2B34");std::string post_json = Obj2Json(login_param);std::cout << post_json << endl << endl;std::vector<std::string> app_list;app_list.push_back("aaa");app_list.push_back("bbb");app_list.push_back("ccc");app_list.push_back("ddd");WatermarkContent watermark_content;watermark_content.font_size = 12;watermark_content.app_list = app_list;watermark_content.color = "yellow";watermark_content.content = "124312@dsafas";post_json.clear();post_json = Obj2Json(watermark_content);std::cout << post_json << endl;getchar();return 0;
}
global.h
/*************************************************
** Copyright: xxx公司
** Author: mmm
** Date: 2022-03-09
** Description: 全局通用函数
**************************************************/
#ifndef SDK_INCLUDE_GLOBAL_H_
#define SDK_INCLUDE_GLOBAL_H_#include <map>
#include <vector>
#include "RC4.h"namespace demo {
// websocket信息头,12字节长
struct WebSocketHead {uint32_t body_size = 0; // 消息体长度uint32_t seq = 0; // 序列号char msgType; // 消息类型char version; // 版本号char nonpersistent; // 暂未使用char opType; // 暂未使用
};// 获取撤回消息的限制时间接口 和 根据msgId获取阅后即焚消息的剩余时间 返回的json对应的结构体
struct HttpGetResponse {int32_t code = 0; // http错误码int32_t data = 0; // 接口返回的结果,限制时间(分钟) 或 阅后即焚剩余时间
};class Global {
public:static Global* GetInstance();// 初始化解析json到结构体所需的key值到内存void Init();int app_id();void set_app_id(const int& app_id);// 编码格式转换int PreNum(unsigned char byte);bool IsUtf8(unsigned char* data, int len);bool IsUtf8New(unsigned char* data, int len);std::string UTF8ToString(const std::string& data);bool UTF8ToUnicode(const std::string& data, std::wstring& output, bool force_change = false);std::string StringToUTF8(const std::string& data);bool UnicodeToUTF8(const std::wstring& data, std::string& output);// 流式加解密,同一个http返回的只用refresh一次key就行,换http调用需要重新refresh keyvoid RC4Decrypt(const std::string& encrypt_str, std::string& decrypt_str, bool refresh = false) {if (refresh) {rc4_.SetKey("ddd" + std::string("user_id_"));}rc4_.Decrypt(encrypt_str, decrypt_str);// decrypt_str = UTF8ToString(decrypt_str);}std::string GenUuid();private:int app_id_ = 0;RC4 rc4_;
};
}; // namespace im#endif // SDK_INCLUDE_GLOBAL_H_
global.cpp
#include "global.h"#include <codecvt>
#include <random>
#include <iomanip>
#include <thread>
#include "common_func.h"
#include "client_param.h"namespace demo {
std::map<std::string, std::vector<std::pair<std::string, ConverterBase*>>> json_to_object_map;
static void RegJsonObjInfo(const std::string& obj_name, const std::vector<std::pair<std::string, ConverterBase*> >& objinfo) {json_to_object_map.insert(std::make_pair(obj_name, objinfo));
}Global* Global::GetInstance()
{static Global global;return &global;
}int Global::app_id()
{return app_id_;
}void Global::set_app_id(const int& app_id)
{app_id_ = app_id;
}int Global::PreNum(unsigned char byte) {unsigned char mask = 0x80;int num = 0;for (int i = 0; i < 8; i++) {if ((byte & mask) == mask) {mask = mask >> 1;num++;} else {break;}}return num;
}bool Global::IsUtf8(unsigned char* data, int len) {int num = 0;int i = 0;while (i < len) {if ((data[i] & 0x80) == 0x00) {i++;continue;} else if ((num = PreNum(data[i])) > 2) {i++;for (int j = 0; j < num - 1; j++) {if ((data[i] & 0xc0) != 0x80) {return false;}i++;}} else {return false;}}return true;
}bool Global::IsUtf8New(unsigned char* data, int len)
{int i = 0;int nBytes = 0; //UTF8可用1 - 6个字节编码, ASCII用一个字节unsigned char ch = 0;bool bAllAscii = true;//如果全部都是ASCII,说明不是UTF-8while (i < len){ch = *(data + i);if ((ch & 0x80) != 0)bAllAscii = false;if (nBytes == 0){if ((ch & 0x80) != 0){while ((ch & 0x80) != 0){ch <<= 1;nBytes++;}if ((nBytes < 2) || (nBytes > 6)){return false;}nBytes--;}}else{if ((ch & 0xc0) != 0x80){return false;}nBytes--;}i++;}if (bAllAscii)return false;return (nBytes == 0);
}bool Global::UTF8ToUnicode(const std::string& data, std::wstring& output, bool force_change)
{
#ifndef __linux__if (!force_change) {if (!IsUtf8New((unsigned char*)data.c_str(), data.length())) return false;}// 将UTF-8转换成Unicodestd::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> conv;output = conv.from_bytes(data);return true;
#elsereturn false;
#endif
}bool Global::UnicodeToUTF8(const std::wstring& data, std::string& output)
{std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;output = conv.to_bytes(data);return true;
}std::string Global::UTF8ToString(const std::string& data)
{
#ifndef __linux__ if (!IsUtf8New((unsigned char*)data.c_str(), data.length())) return data;// 将UTF-8转换成Unicodestd::wstring_convert<std::codecvt_utf8<wchar_t>> conv;std::wstring w_data = conv.from_bytes(data);// 转换成stringint length = WideCharToMultiByte(CP_ACP, 0, w_data.c_str(), -1, NULL, 0, NULL, NULL);std::vector<char> vecText(length, '\0');WideCharToMultiByte(CP_ACP, 0, w_data.c_str(), -1, &(vecText[0]), length, NULL, NULL);return std::string(&(vecText[0]));
#elsereturn data;
#endif
}std::string Global::StringToUTF8(const std::string& data)
{
#ifndef __linux__ if (IsUtf8New((unsigned char*)data.c_str(), data.length())) return data;int nw_len = ::MultiByteToWideChar(CP_ACP, 0, data.c_str(), -1, NULL, 0);wchar_t* p_src = new wchar_t[nw_len + 1]();MultiByteToWideChar(CP_ACP, 0, data.c_str(), data.length(), p_src, nw_len);int length = WideCharToMultiByte(CP_UTF8, 0, p_src, -1, NULL, NULL, NULL, NULL);char* p_result = new char[length + 1]();WideCharToMultiByte(CP_UTF8, 0, p_src, nw_len, p_result, length, NULL, NULL);std::string result(p_result);if (nullptr != p_src) {delete[]p_src;p_src = nullptr;}if (nullptr != p_result) {delete[]p_result;p_result = nullptr;}return result;
#elsereturn data;
#endif
}void Global::Init()
{std::vector<std::pair<std::string, ConverterBase*>> vec;vec.push_back(std::make_pair("username", new JsonConverter<LoginParams, std::string>(&LoginParams::username)));vec.push_back(std::make_pair("password", new JsonConverter<LoginParams, std::string>(&LoginParams::password)));vec.push_back(std::make_pair("deviceUuid", new JsonConverter<LoginParams, std::string>(&LoginParams::device_uuid)));vec.push_back(std::make_pair("realDeviceUuid", new JsonConverter<LoginParams, std::string>(&LoginParams::real_device_uuid)));RegJsonObjInfo(typeid(LoginParams).name(), vec);vec.clear();vec.push_back(std::make_pair("content", new JsonConverter<WatermarkContent, std::string>(&WatermarkContent::content)));vec.push_back(std::make_pair("fontSize", new JsonConverter<WatermarkContent, int32_t>(&WatermarkContent::font_size)));vec.push_back(std::make_pair("color", new JsonConverter<WatermarkContent, std::string>(&WatermarkContent::color)));vec.push_back(std::make_pair("appList", new JsonConverter<WatermarkContent,std::vector<std::string>>(&WatermarkContent::app_list)));RegJsonObjInfo(typeid(WatermarkContent).name(), vec);vec.clear();}std::string Global::GenUuid()
{static std::random_device rd;static std::uniform_int_distribution<uint64_t> dist(0ULL, 0xFFFFFFFFFFFFFFFFULL);uint64_t ab = dist(rd);uint64_t cd = dist(rd);uint32_t a, b, c, d;std::stringstream ss;ab = (ab & 0xFFFFFFFFFFFF0FFFULL) | 0x0000000000004000ULL;cd = (cd & 0x3FFFFFFFFFFFFFFFULL) | 0x8000000000000000ULL;a = (ab >> 32U);b = (ab & 0xFFFFFFFFU);c = (cd >> 32U);d = (cd & 0xFFFFFFFFU);ss << std::hex << std::nouppercase << std::setfill('0');ss << std::setw(8) << (a) << '-';ss << std::setw(4) << (b >> 16U) << '-';ss << std::setw(4) << (b & 0xFFFFU) << '-';ss << std::setw(4) << (c >> 16U) << '-';ss << std::setw(4) << (c & 0xFFFFU);ss << std::setw(8) << d;return ss.str();//return "";
}} // namespace demo
common_func.h
/*************************************************
** Copyright: xxx公司
** Author: mmm
** Date:
** Description:
**************************************************/#ifndef SDK_INCLUDE_COMMON_FUNC_H_
#define SDK_INCLUDE_COMMON_FUNC_H_#include <string>
#include <vector>
#include <regex>#include "Poco/JSON/Parser.h"
#include "Poco/Dynamic/Var.h"
#include "Poco/Net/HTTPResponse.h"
#include "Poco/Net/HTTPRequest.h"
#include "Poco/Net/HTTPSClientSession.h"namespace demo{template<typename T>
class DumpHelper;class ConverterBase {
public:virtual ~ConverterBase() {}virtual void DumpToJson(Poco::JSON::Object& dst, const std::string& key, void* pObj) = 0;//virtual void DumpToJson(Poco::JSON::Array& dst, const std::string& key, void* pObj) = 0;virtual bool ConvertFromJson(Poco::Dynamic::Var& json_obj, void* pObj) = 0;virtual bool ConvertFromJson(Poco::JSON::Array::Ptr json_obj, void* pObj) = 0;
};extern std::map<std::string, std::vector<std::pair<std::string, ConverterBase *> > > json_to_object_map;template<typename T, typename M>
class JsonConverter : public ConverterBase {
public:explicit JsonConverter(M T::* p, bool opt = true) : pm_(p), optional_(opt) {}virtual void DumpToJson(Poco::JSON::Object& dst, const std::string& key, void* pObj) {T* pT = static_cast<T*>(pObj);DumpHelper<M>::DumpObj(dst, key, pT->*pm_);}// virtual void DumpToJson(Poco::JSON::Array& dst, const std::string& key, void* pObj) {// T* pT = static_cast<T*>(pObj);// DumpHelper<M>::DumpObj(dst, key, pT->*pm_);// }virtual bool ConvertFromJson(Poco::Dynamic::Var& json_obj, void* pObj) {T* pT = static_cast<T*>(pObj);return DumpHelper<M>::ConvertToObj(json_obj, pT->*pm_);}virtual bool ConvertFromJson(Poco::JSON::Array::Ptr json_obj, void* pObj) {T* pT = static_cast<T*>(pObj);return DumpHelper<M>::ConvertToObj(json_obj, pT->*pm_);}
private:M T::* pm_;const bool optional_;
};template<typename T>
class DumpHelper {
public:static void DumpObj(Poco::JSON::Object& dst, const std::string& key, const T& t) {std::map<std::string, std::vector<std::pair<std::string, ConverterBase *> > >::iterator it = json_to_object_map.find(typeid(t).name());if (it == json_to_object_map.end()) {return;}std::vector<std::pair<std::string, ConverterBase* > >& vec = it->second;std::vector<std::pair<std::string, ConverterBase* > >::iterator it2 = vec.begin();if (key.empty()) {for (; it2 != vec.end(); ++it2) {it2->second->DumpToJson(dst, it2->first, (void*)&t);}}else {Poco::JSON::Object child;for (; it2 != vec.end(); ++it2) {it2->second->DumpToJson(child, it2->first, (void*)&t);}dst.set(key, child);}}static void DumpObj(Poco::JSON::Array& dst, const std::string& key, const T& t) {std::map<std::string, std::vector<std::pair<std::string, ConverterBase *> > >::iterator it = json_to_object_map.find(typeid(t).name());if (it == json_to_object_map.end()) {return;}std::vector<std::pair<std::string, ConverterBase* > >& vec = it->second;std::vector<std::pair<std::string, ConverterBase* > >::iterator it2 = vec.begin();Poco::JSON::Object child;for (; it2 != vec.end(); ++it2) {it2->second->DumpToJson(child, it2->first, (void*)&t);}dst.add(child);}static bool ConvertToObj(Poco::Dynamic::Var& json_obj, T& t) {std::map<std::string, std::vector<std::pair<std::string, ConverterBase*> > >::iterator it = json_to_object_map.find(typeid(t).name());if (it == json_to_object_map.end()) {return false;}Poco::JSON::Object::Ptr pObj = json_obj.extract<Poco::JSON::Object::Ptr>();std::vector<std::pair<std::string, ConverterBase*> >& objinfo = it->second;std::vector<std::pair<std::string, ConverterBase*> >::iterator it2 = objinfo.begin();for (; it2 != objinfo.end(); ++it2) {Poco::Dynamic::Var ret = pObj->get(it2->first);if (ret.isEmpty()) {continue;}else if (ret.isArray()) {Poco::JSON::Array::Ptr pArray = pObj->getArray(it2->first);if (!it2->second->ConvertFromJson(pArray, &t)) {return false;}}else {if (!it2->second->ConvertFromJson(ret, &t)) {return false;}}}return true;}static bool ConvertToObj(Poco::JSON::Array::Ptr json_obj, T& t) {std::map<std::string, std::vector<std::pair<std::string, ConverterBase*> > >::iterator it = json_to_object_map.find(typeid(t).name());if (it == json_to_object_map.end()) {return false;}std::vector<std::pair<std::string, ConverterBase*> >& objinfo = it->second;std::vector<std::pair<std::string, ConverterBase*> >::iterator it2 = objinfo.begin();for (; it2 != objinfo.end(); ++it2) {for (unsigned int i = 0; i < json_obj->size(); i++) {Poco::Dynamic::Var e = json_obj->get(i);if (!it2->second->ConvertFromJson(e, &t)) {return false;}}}return true;}
};template<>
class DumpHelper<bool> {
public:static void DumpObj(Poco::JSON::Object& value, const std::string&key, bool t) {if (!key.empty()) {value.set(key, t);}}static void DumpObj(Poco::JSON::Array& dst, const std::string& key, const bool& t) {dst.add(t);}static bool ConvertToObj(Poco::Dynamic::Var& json_obj, bool& t) {t = json_obj.convert<bool>();return true;}static bool ConvertToObj(Poco::JSON::Array::Ptr json_obj, bool& t) {return true;}
};template<>
class DumpHelper<int8_t> {
public:static void DumpObj(Poco::JSON::Object& value, const std::string&key, int8_t t) {if (!key.empty()) {value.set(key, (int32_t)t);}}static void DumpObj(Poco::JSON::Array& dst, const std::string& key, const int8_t& t) {dst.add(t);}static bool ConvertToObj(Poco::Dynamic::Var& json_obj, int8_t& t) {t = json_obj.convert<int8_t>();return true;}static bool ConvertToObj(Poco::JSON::Array::Ptr json_obj, int8_t& t) {return true;}
};template<>
class DumpHelper<int32_t> {
public:static void DumpObj(Poco::JSON::Object& value, const std::string&key, int32_t n) {if (!key.empty()) {value.set(key, n);}}static void DumpObj(Poco::JSON::Array& dst, const std::string& key, const int32_t& t) {dst.add(t);}static bool ConvertToObj(Poco::Dynamic::Var& json_obj, int32_t& t) {t = json_obj.convert<int32_t>();return true;}static bool ConvertToObj(Poco::JSON::Array::Ptr json_obj, int32_t& t) {return true;}
};template<>
class DumpHelper<int64_t> {
public:static void DumpObj(Poco::JSON::Object& value, const std::string&key, int64_t n) {if (!key.empty()) {value.set(key, n);}}static void DumpObj(Poco::JSON::Array& dst, const std::string& key, const int64_t& t) {dst.add(t);}static bool ConvertToObj(Poco::Dynamic::Var& json_obj, int64_t& t) {t = json_obj.convert<int64_t>();return true;}static bool ConvertToObj(Poco::JSON::Array::Ptr json_obj, int64_t& t) {return true;}
};template<>
class DumpHelper<double> {
public:static void DumpObj(Poco::JSON::Object& value, const std::string&key, double n) {if (!key.empty()) {value.set(key, n);}}static void DumpObj(Poco::JSON::Array& dst, const std::string& key, const double& t) {dst.add(t);}static bool ConvertToObj(Poco::Dynamic::Var& json_obj, double& t) {t = json_obj.convert<double>();return true;}static bool ConvertToObj(Poco::JSON::Array::Ptr json_obj, double& t) {return true;}
};template<>
class DumpHelper<std::string> {
public:static void DumpObj(Poco::JSON::Object& value, const std::string&key, const std::string& v) {if (!key.empty()) {value.set(key, v);}}static void DumpObj(Poco::JSON::Array& dst, const std::string& key, const std::string& t) {dst.add(t);}static bool ConvertToObj(Poco::Dynamic::Var& json_obj, std::string& t) {if (!json_obj.isEmpty()) {t = json_obj.convert<std::string>();}return true;}static bool ConvertToObj(Poco::JSON::Array::Ptr json_obj, std::string& t) {return true;}
};template<typename T>
class DumpHelper<std::vector<T> > {
public:static void DumpObj(Poco::JSON::Object& value, const std::string& key, const std::vector<T>& m) {Poco::JSON::Array jsonArray;for (size_t i = 0; i < m.size(); ++i) {DumpHelper<T>::DumpObj(jsonArray, key, m[i]);}if (!key.empty()) {value.set(key, jsonArray);}}static void DumpObj(Poco::JSON::Array& dst, const std::string& key, const std::vector<T>& m) {for (size_t i = 0; i < m.size(); ++i) {DumpHelper<T>::DumpObj(dst, key, m[i]);}}static bool ConvertToObj(Poco::Dynamic::Var& json_obj, std::vector<T>& t) {return true;}static bool ConvertToObj(Poco::JSON::Array::Ptr json_obj, std::vector<T>& t) {if (json_obj->size() == 0) return true;for (unsigned int i = 0; i < json_obj->size(); ++i) {T element;Poco::Dynamic::Var singleVal = json_obj->get(i);if (!DumpHelper<T>::ConvertToObj(singleVal, element)) {return false;}t.push_back(element);}return true;}
};//KEY只支持整数和字符串,整数都转成字符串
template<typename KEY, typename VAL>
class DumpHelper<std::map<KEY, VAL> > {
public:static void DumpObj(Poco::JSON::Object& value, const std::string& key, const std::map<KEY, VAL>& m) {std::ostringstream os;Poco::JSON::Object jsonMap;typename std::map<KEY, VAL>::const_iterator it = m.begin();for (; it != m.end(); ++it) {os.str("");os << it->first;DumpHelper<VAL>::DumpObj(jsonMap, os.str(), it->second);}if (!key.empty()) {Poco::Dynamic::Var JsonStr(jsonMap);value.set(key, JsonStr);}}static bool ConvertToObj(Poco::Dynamic::Var& json_obj, std::map<KEY, VAL>& t) {Poco::JSON::Object::Ptr pObj = json_obj.extract<Poco::JSON::Object::Ptr>();std::vector<std::string> keys = pObj->getNames();t.clear();KEY key;VAL val;for (unsigned int i = 0; i < keys.size(); i++) {std::istringstream ist(keys[i]);ist >> key;Poco::Dynamic::Var value = pObj->get(keys[i]);if (value.isArray()) {Poco::JSON::Array::Ptr arrayPtr = pObj->getArray(keys[i]);if (!DumpHelper<VAL>::ConvertToObj(arrayPtr, val)) {return false;}}else {if (!DumpHelper<VAL>::ConvertToObj(value, val)) {return false;}}t.insert(std::make_pair(key, val));}return true;}static bool ConvertToObj(Poco::JSON::Array::Ptr json_obj, std::map<KEY, VAL>& t) {for (unsigned int i = 0; i < json_obj->size(); ++i) {Poco::Dynamic::Var singleVal = json_obj->get(i);if (!DumpHelper<std::map<KEY, VAL>>::ConvertToObj(singleVal, t)) {return false;}}return true;}
};// 把一个结构体或者类转成json字符串 所有结构体和类在使用改方法前必须要先注册,注册方法查看global.cpp
template<typename T>
std::string Obj2Json(const T& obj) {Poco::JSON::Object document;DumpHelper<T>::DumpObj(document, "", obj);Poco::Dynamic::Var JsonStr(document);return JsonStr.toString();
}// 把一个json字符串转成结构体 所有结构体和类在使用改方法前必须要先注册,注册方法查看global.cpp
template<typename T>
bool Json2Obj(T& obj, const std::string& json) {try {if (json.empty()) {return false;}Poco::JSON::Parser parse;Poco::Dynamic::Var jsonValue = parse.parse(json);return DumpHelper<T>::ConvertToObj(jsonValue, obj);} catch (const Poco::Exception& e) {std::cout << e.displayText() << std::endl;}return false;
}#ifndef __linux__
// http url编码
bool UrlEncode(const char* src, char* dst, int dst_length, bool upper_case = false);// 根据path和key获取注册表中的内容,目前获取的是HKEY_LOCAL_MACHINE里面的内容
std::string GetRegeditValue(const std::string& path, const std::string& key);#else
std::string UrlEncode(const std::string& url);
#endifstd::string UrlDecode(const std::string& str);// 分割字符串
std::vector<std::string> SplitString(const std::string& str, const std::string& s);
std::vector<std::wstring> SplitString(const std::wstring& str, const std::wstring& s);// base64编码
std::string Base64Encode(const std::string& str);// base64解码
std::string Base64Decode(const std::string& str);// 将dst中的所有子串substr替换为str
void replaceString(std::string& dst, const std::string& substr, const std::string& str);void trimstr2(std::string& str);// 用于消息同步,将string转为map,string格式minmsgid1-maxmsgid1;minmsgid2-maxmsgid2
// 每一个key,value都是已经同步了的消息段 其中key是已经同步的最小msgid,value是已经同步的最大msgid
void SplitStringToTreeMap(const std::string msg_segment_str, std::map<int64_t, int64_t>& msg_segment_map);// 合并已经同步的区间
void merge(std::map<int64_t, int64_t>& msg_segment_map, int64_t anchor_min, int64_t anchor_max);};#endif // SDK_INCLUDE_COMMON_FUNC_H_
common_func.cpp
#include "common_func.h"
#include "global.h"#include <string.h>
#include <sys/timeb.h>
#include <fstream>
#include <algorithm>
#include "md5.h"
#include "Poco/Net/Context.h"
#include "Poco/Base64Encoder.h"
#include "Poco/Base64Decoder.h"
#include "Poco/Path.h"
#include "Poco/File.h"
#include "Poco/FileStream.h"#ifndef __linux__
#include <direct.h>
#include <Windows.h>
#else
#include <unistd.h>
#endifnamespace demo {bool isFirstCall = true;
#ifndef __linux__
bool UrlEncode(const char* src, char* dst, int dst_length, bool upper_case)
{if (src == nullptr || dst == nullptr || dst_length <= 0) return false;size_t len_ascii = strlen(src);if (len_ascii == 0) {dst[0] = 0;return true;}// 先转换到UTF-8char base_char = upper_case ? 'A' : 'a';int cchWideChar = MultiByteToWideChar(CP_ACP, 0, src, len_ascii, nullptr, 0);LPWSTR p_unicode = (LPWSTR)malloc((cchWideChar + 1) * sizeof(WCHAR));if (p_unicode == nullptr)return false;MultiByteToWideChar(CP_ACP, 0, src, len_ascii, p_unicode, cchWideChar + 1);int cb_utf8 = WideCharToMultiByte(CP_UTF8, 0, p_unicode, cchWideChar, nullptr, 0, nullptr, nullptr);LPSTR p_utf8 = (LPSTR)malloc((cb_utf8 + 1) * sizeof(CHAR));if (p_utf8 == nullptr) {free(p_unicode);return false;}WideCharToMultiByte(CP_UTF8, 0, p_unicode, cchWideChar, p_utf8, cb_utf8 + 1, nullptr, nullptr);p_utf8[cb_utf8] = '\0';unsigned char c;int cb_dest = 0; //累加unsigned char *p_src = (unsigned char*)p_utf8;unsigned char *p_dest = (unsigned char*)dst;while (*p_src && cb_dest < dst_length - 1) {c = *p_src;if (isalpha(c) || isdigit(c) || c == '-' || c == '.' || c == '~') {*p_dest = c;++p_dest;++cb_dest;} else if (c == ' ') {*p_dest = '+';++p_dest;++cb_dest;} else {// 检查缓冲区大小是否够用if (cb_dest + 3 > dst_length - 1)break;p_dest[0] = '%';p_dest[1] = (c >= 0xA0) ? ((c >> 4) - 10 + base_char) : ((c >> 4) + '0');p_dest[2] = ((c & 0xF) >= 0xA) ? ((c & 0xF) - 10 + base_char) : ((c & 0xF) + '0');p_dest += 3;cb_dest += 3;}++p_src;}*p_dest = '\0';free(p_unicode);free(p_utf8);return true;
}
#endifvoid replaceString(std::string& dst, const std::string& substr, const std::string& str)
{std::string::size_type pos = 0;while ((pos = dst.find(substr)) != std::string::npos) {dst.replace(pos, substr.length(), str);}
}void trimstr2(std::string& str)
{size_t n = str.find_last_not_of(" \r\n\t");if (n != std::string::npos) {str.erase(n + 1, str.size() - n);}n = str.find_first_not_of(" \r\n\t");if (n != std::string::npos) {str.erase(0, n);}size_t nSize = str.size();while (true){size_t pos = str.find(" ");if (std::string::npos == pos) {return;}str.erase(pos, nSize);}
}void SplitStringToTreeMap(const std::string msg_segment_str, std::map<int64_t, int64_t>& msg_segment_map)
{std::vector<std::string> segment_vec = SplitString(msg_segment_str, ";");for (auto& it: segment_vec) {std::vector<std::string> msg_id_vec = SplitString(it, "-");if (msg_id_vec.size() >= 2) {msg_segment_map.insert(std::make_pair(std::stoll(msg_id_vec[0]), std::stoll(msg_id_vec[1])));}}
}void merge(std::map<int64_t, int64_t>& msg_segment_map, int64_t anchor_min, int64_t anchor_max)
{std::vector<std::vector<int64_t>> intervals;for (auto& it : msg_segment_map) {intervals.push_back(std::vector<int64_t>{it.first, it.second});}intervals.push_back(std::vector<int64_t>{anchor_min, anchor_max});std::sort(intervals.begin(), intervals.end());std::vector<std::vector<int64_t>> merged;for (int i = 0; i < intervals.size(); i++) {int64_t L = intervals[i][0], R = intervals[i][1];if (!merged.size() || merged.back()[1] < L) {merged.push_back({ L, R });} else {merged.back()[1] = std::max(merged.back()[1], R);}}msg_segment_map.clear();for (auto& it : merged) {msg_segment_map.insert(std::make_pair(it[0], it[1]));}
}unsigned char ToHex(unsigned char x)
{return x > 9 ? x + 55 : x + 48;
}unsigned char FromHex(unsigned char x)
{unsigned char y;if (x >= 'A' && x <= 'Z') y = x - 'A' + 10;else if (x >= 'a' && x <= 'z') y = x - 'a' + 10;else if (x >= '0' && x <= '9') y = x - '0';else assert(0);return y;
}std::string UrlEncode(const std::string& str)
{std::string strTemp = "";size_t length = str.length();for (size_t i = 0; i < length; i++) {if (isalnum((unsigned char)str[i]) ||(str[i] == '-') ||(str[i] == '_') ||(str[i] == '.') ||(str[i] == '~'))strTemp += str[i];else if (str[i] == ' ')strTemp += "+";else {strTemp += '%';strTemp += ToHex((unsigned char)str[i] >> 4);strTemp += ToHex((unsigned char)str[i] % 16);}}return strTemp;
}std::string UrlDecode(const std::string& str)
{std::string strTemp = "";size_t length = str.length();for (size_t i = 0; i < length; i++) {if (str[i] == '+') strTemp += ' ';else if (str[i] == '%'){assert(i + 2 < length);unsigned char high = FromHex((unsigned char)str[++i]);unsigned char low = FromHex((unsigned char)str[++i]);strTemp += high * 16 + low;}else strTemp += str[i];}return strTemp;
}std::vector<std::string> SplitString(const std::string& str, const std::string& s)
{if (str.empty()) {return std::vector<std::string>();}std::regex re(s);return std::vector<std::string>{std::sregex_token_iterator(str.begin(), str.end(), re, -1),std::sregex_token_iterator()};
}std::vector<std::wstring> SplitString(const std::wstring& str, const std::wstring& s)
{if (str.empty()) {return std::vector<std::wstring>();}std::wregex re(s);return std::vector<std::wstring>{std::wsregex_token_iterator(str.begin(), str.end(), re, -1),std::wsregex_token_iterator()};
}std::string Base64Encode(const std::string& str)
{std::ostringstream ostr;Poco::Base64Encoder encoder(ostr, Poco::BASE64_URL_ENCODING);encoder << str;encoder.close();return ostr.str();
}std::string Base64Decode(const std::string& str)
{std::istringstream istr(str);Poco::Base64Decoder decoder(istr, Poco::BASE64_URL_ENCODING);std::string s;decoder >> s;return s;
}#ifndef __linux__
std::string GetRegeditValue(const std::string& path, const std::string& key)
{HKEY hkey = nullptr;std::string sub_key = Global::GetInstance()->UTF8ToString(path);LSTATUS res = ::RegOpenKeyExA(HKEY_LOCAL_MACHINE, sub_key.c_str(), 0, KEY_READ, &hkey);if (res != ERROR_SUCCESS) {return "";}std::shared_ptr<void> close_key(nullptr, [&](void*) {if (hkey != nullptr) {::RegCloseKey(hkey);hkey = nullptr;}});DWORD type = REG_SZ;DWORD size = 0;res = ::RegQueryValueExA(hkey, key.c_str(), 0, &type, nullptr, &size);if (res != ERROR_SUCCESS || size <= 0) {return "";}std::vector<BYTE> value_data(size);res = ::RegQueryValueExA(hkey, key.c_str(), 0, &type, value_data.data(), &size);if (res != ERROR_SUCCESS) {return "";}std::string result(value_data.begin(), value_data.end());result.erase(result.find_last_not_of('\0') + 1);return result;
}
#endif}; // namespace demo
client_param.h
/*************************************************
** Copyright: xxx公司
** Author: mmm
** Date: 2022-03-09
** Description: Client相关参数
**************************************************/
#ifndef SDK_INCLUDE_CLIENT_PARAMETER_H_
#define SDK_INCLUDE_CLIENT_PARAMETER_H_#include <functional>
#include <ostream>
#include <vector>namespace demo
{
// 登录服务器请求结构体
struct LoginParams {std::string username; // 用户名std::string password; // 密码std::string device_uuid; // PC设备时为(设备+用户名)的唯一标识std::string real_device_uuid; // PC设备时为真实设备的唯一标识
};// 水印图片的内容
struct WatermarkContent {int font_size = 0; // 字体大小std::string content; // 水印内容std::string color; // 色号std::vector<std::string> app_list; // 所选应用包名
};} // namespace demo#endif // SDK_INCLUDE_CLIENT_PARAMETER_H_
全部源码
可以这里下载