zoukankan      html  css  js  c++  java
  • C++中的通用结构定义,及相应的序列化、反序列化接口

    一个通用的C++结构定义如下:

    typedef struct tagCommonStruct {
        long len;
        void* buff;
    }CommonStruct_st;

    此接口对应的普通序列化、反序列化接口如下:

    unsigned char* EncodeCommonStruct(const CommonStruct_st& CommonSt)
    {
        //分配内存
        unsigned char* strBuff = (unsigned char*)malloc(CALC_COMMON_ST_LEN(&CommonSt));
        if (NULL == strBuff) 
        {
            return NULL;
        }
    
        //填充内容
        *(long*)strBuff = CommonSt.len;
        if (CommonSt.len > 0) {
            memcpy(strBuff + sizeof(long), CommonSt.buff, CommonSt.len);
        }
    
        return strBuff;
    }
    
    BOOL DecodeCommonStruct(const unsigned char* strBuff, long len, CommonStruct_st& CommonSt)
    {
        long st_len;
        if (NULL == strBuff) 
        {
            return FALSE;
        }
    
        //获取到当前长度
        st_len = *(const long*)strBuff;
        //校验BUFF内容合法性
        if (st_len + sizeof(long) > len) {
            return FALSE;
        }
        CommonSt.len = st_len;
        CommonSt.buff = (void*)malloc(st_len);
        memcpy(CommonSt.buff, strBuff + sizeof(long), st_len);
        return TRUE;
    }
    
    void EncodeCommonStruct_S(const CommonStruct_st& CommonSt, std::string& strOut)
    {
        //分配内存
        strOut.resize(CALC_COMMON_ST_LEN(&CommonSt));
    
        //填充内容
        *(long*)&(strOut[0]) = CommonSt.len;
        if (CommonSt.len > 0) {
            memcpy(&(strOut[0]) + sizeof(long), CommonSt.buff, CommonSt.len);
        }
    
        return;
    }
    
    BOOL DecodeCommonStruct_S(const unsigned char* strBuff, long len, CommonStruct_st& pCommonSt, std::string& strInnBuff)
    {
        long st_len;
        if (NULL == strBuff) 
        {
            return FALSE;
        }
    
        //获取到当前长度
        st_len = *(const long*)strBuff;
        //校验BUFF内容合法性
        if (st_len + sizeof(long) > len) {
            return FALSE;
        }
        pCommonSt.len = st_len;
        strInnBuff.resize(st_len);
        //pCommonSt.buff = (void*)malloc(st_len);
        pCommonSt.buff = &strInnBuff[0];
        memcpy(pCommonSt.buff, strBuff + sizeof(long), st_len);
        return TRUE;
    }

    支持批量操作的序列化、反序列化接口:

    #define MAX_COMMON_STRUCT_PARAM_NUMBER (16)
    
    void EncodeCommonStructV(std::string& strOut, int nStNum, ...)
    {
        int index = 0;
        int nBufLen;
        unsigned char* strTemp;
        //最多允许16个
        va_list arg_ptr;
        CommonStruct_st CommStructStArray[MAX_COMMON_STRUCT_PARAM_NUMBER];
    
        //
        if (nStNum > MAX_COMMON_STRUCT_PARAM_NUMBER) {
            return;
        }
    
        //依次取出相应的结构、指针位置
        nBufLen = 0;
        va_start(arg_ptr, nStNum);
        for(index = 0; index < nStNum; index ++){
            CommStructStArray[index].len = va_arg(arg_ptr, int);
            CommStructStArray[index].buff = va_arg(arg_ptr, void*);
            nBufLen += CALC_COMMON_ST_LEN(&CommStructStArray[index]);
        }
        va_end(arg_ptr);
    
        //计算总字符长度
        strOut.resize(nBufLen, '');
        strTemp = (unsigned char*)&strOut[0];
    
        //依次格式化
        std::string strTmpBuf;
        for(index = 0; index < nStNum; index ++){
    #if 0
            EncodeCommonStruct_S(CommStructStArray[index],  strTmpBuf);
            memcpy(strTemp, strTmpBuf.c_str(), CALC_COMMON_ST_LEN(&CommStructStArray[index]);
    #else
            *(long*)strTemp = CommStructStArray[index].len;
            if (CommStructStArray[index].len > 0) {
                memcpy(strTemp + sizeof(long), CommStructStArray[index].buff, CommStructStArray[index].len);
            }
    #endif
    
            strTemp += CALC_COMMON_ST_LEN(&CommStructStArray[index]);
        }
    }
    BOOL DecodeCommonStructV(const unsigned char* strBuff, long len, ...)
    {
        va_list arg_ptr;
        long leave_len, st_len;
        CommonStruct_st *pstCommonStruct;
        const unsigned char* strTemp;
        if (NULL == strBuff) 
        {
            return FALSE;
        }
    
        leave_len = len;
        strTemp = strBuff;
        va_start(arg_ptr, len);
        while(leave_len > 0){
            pstCommonStruct = va_arg(arg_ptr, CommonStruct_st *);
    
            //允许BUFF中的内容更长,但只取前面一部分
            if (NULL == pstCommonStruct){
                break;
            }
    
            //获取到当前长度
            st_len = *(const long*)strTemp;
            //校验BUFF内容合法性
            if (st_len + sizeof(long) > leave_len) {
                return FALSE;
            }
    
            //填充一块结构体的内容
            pstCommonStruct->len = st_len;
            memcpy(pstCommonStruct->buff, strTemp + sizeof(long), st_len);
    
            //偏移位置
            strTemp += st_len + sizeof(long);
            leave_len -= st_len + sizeof(long);
        }
        va_end(arg_ptr);
    
        return TRUE;
    }

    V2版本的 EncodeCommonStruct,不再限制传入参数的最多个数

    void EncodeCommonStructV2(std::string& strOut, int nStNum, ...)
    {
        int index = 0;
        int nBufLen;
        va_list arg_ptr;
        unsigned char* strTemp;
        CommonStruct_st stCommStruct;
    
        //依次取出相应的结构、指针位置
        nBufLen = 0;
        va_start(arg_ptr, nStNum);
        for(index = 0; index < nStNum; index ++){
            stCommStruct.len = va_arg(arg_ptr, int);
            stCommStruct.buff = va_arg(arg_ptr, void*);
            nBufLen += CALC_COMMON_ST_LEN(&stCommStruct);
        }
        va_end(arg_ptr);
    
        //计算总字符长度
        strOut.resize(nBufLen, '');
        strTemp = (unsigned char*)&strOut[0];
    
        //依次格式化
        std::string strTmpBuf;
        va_start(arg_ptr, nStNum);
        for(index = 0; index < nStNum; index ++){
            stCommStruct.len = va_arg(arg_ptr, int);
            stCommStruct.buff = va_arg(arg_ptr, void*);
            *(long*)strTemp = stCommStruct.len;
            if (stCommStruct.len > 0) {
                memcpy(strTemp + sizeof(long), stCommStruct.buff, stCommStruct.len);
            }
    
            strTemp += CALC_COMMON_ST_LEN(&stCommStruct);
        }
        va_end(arg_ptr);
    }

     V2版本的 DecodeCommonStruct,不再限制传入参数的最多个数

    BOOL DecodeCommonStructV2(const unsigned char* strBuff, std::string& strInnBuff, long len, ...)
    {
        va_list arg_ptr;
        long leave_len, st_len, all_st_len;
        CommonStruct_st *pstCommonStruct;
        const unsigned char* strTemp;
        unsigned char* strDest;
        if (NULL == strBuff) 
        {
            return FALSE;
        }
    
        //计算strBuff中总共需要多少内存来存放
        all_st_len = 0;
        leave_len = len;
        strTemp = strBuff;
        while (leave_len > 0){
            //获取到当前长度
            st_len = *(const long*)strTemp;
            //校验BUFF内容合法性
            if (st_len + sizeof(long) > leave_len) {
                return FALSE;
            }
            //每个都用隔开吧
            all_st_len += st_len + 1;
    
            strTemp += st_len + sizeof(long);
            leave_len -= st_len + sizeof(long);
        }
    
        //分配内存
        strInnBuff.resize(all_st_len, '');
        strDest = (unsigned char*)&strInnBuff[0];
    
        strTemp = strBuff;
        leave_len = len;
        va_start(arg_ptr, len);
        while(leave_len > 0){
            pstCommonStruct = va_arg(arg_ptr, CommonStruct_st *);
    
            //允许BUFF中的内容更长,但只取前面一部分
            if (NULL == pstCommonStruct){
                break;
            }
    
            //获取到当前长度
            st_len = *(const long*)strTemp;
    
            //填充一块结构体的内容
            pstCommonStruct->len = st_len;
            pstCommonStruct->buff = strDest;
            //拷贝至缓冲区中
            memcpy(strDest, strTemp + sizeof(long), st_len);
    
            //偏移位置
            strTemp += st_len + sizeof(long);
            leave_len -= st_len + sizeof(long);
            strDest += st_len + 1;
        }
        va_end(arg_ptr);
    
        return TRUE;
    }
  • 相关阅读:
    lnmp vhost 虚拟目录配置
    vi 编辑器常用命令(转)
    centos7 nginx 加入开机启动
    centos7 编译安装mysql
    IE8以下支持css3 border-radius渲染方法
    html5 web 摇一摇切换歌曲
    L0、L1与L2范数
    c++多线程编程:常见面试题
    核函数以及SVM相关知识(重点)
    梯度下降法的三种形式BGD、SGD以及MBGD
  • 原文地址:https://www.cnblogs.com/eaglexmw/p/11165995.html
Copyright © 2011-2022 走看看