使用poco结构体转json

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 key
    void 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-8
    while (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转换成Unicode
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> conv;
    output = conv.from_bytes(data);
    return true;
#else
    return 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转换成Unicode
    std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
    std::wstring w_data = conv.from_bytes(data);
    // 转换成string
    int 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]));
#else
    return 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;
#else
    return 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);
#endif

std::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>
#endif

namespace 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-8
    char 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;
}
#endif

void 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_
全部源码

可以这里下载

相关推荐

  1. 使用poco结构json

    2024-04-03 19:38:01       17 阅读
  2. golang学习-golang结构Json相互转换

    2024-04-03 19:38:01       36 阅读
  3. Golang 自定义时间结构支持Json&Gorm

    2024-04-03 19:38:01       20 阅读
  4. 05-使用结构构建相关数据

    2024-04-03 19:38:01       27 阅读
  5. Golang gorm 结构定义使用

    2024-04-03 19:38:01       32 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-03 19:38:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-03 19:38:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-03 19:38:01       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-03 19:38:01       20 阅读

热门阅读

  1. 【Python基础知识点】Python的浅拷贝和深拷贝

    2024-04-03 19:38:01       16 阅读
  2. 当代深度学习模型介绍--Transformer模型

    2024-04-03 19:38:01       16 阅读
  3. 十八、Rust gRPC 多 proto 演示

    2024-04-03 19:38:01       15 阅读
  4. 入门级Python编程题(2)

    2024-04-03 19:38:01       16 阅读
  5. Transformer学习-最简DEMO实现字符串转置

    2024-04-03 19:38:01       15 阅读
  6. 【Linux】linux背景知识

    2024-04-03 19:38:01       15 阅读
  7. web蓝桥杯真题:健身大调查

    2024-04-03 19:38:01       16 阅读
  8. leetcode - 1248. Count Number of Nice Subarrays

    2024-04-03 19:38:01       14 阅读
  9. watch于watcheffect的区别

    2024-04-03 19:38:01       16 阅读
  10. STM32 GPIO输入检测——按键

    2024-04-03 19:38:01       19 阅读
  11. arm架构离线部署docker

    2024-04-03 19:38:01       17 阅读