一个通用的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 > ) {
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[]) = CommonSt.len;
if (CommonSt.len > ) {
memcpy(&(strOut[]) + 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[];
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 = ;
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 = ;
va_start(arg_ptr, nStNum);
for(index = ; 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, '\0');
strTemp = (unsigned char*)&strOut[]; //依次格式化
std::string strTmpBuf;
for(index = ; 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 > ) {
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 > ){
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 = ;
int nBufLen;
va_list arg_ptr;
unsigned char* strTemp;
CommonStruct_st stCommStruct; //依次取出相应的结构、指针位置
nBufLen = ;
va_start(arg_ptr, nStNum);
for(index = ; 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, '\0');
strTemp = (unsigned char*)&strOut[]; //依次格式化
std::string strTmpBuf;
va_start(arg_ptr, nStNum);
for(index = ; index < nStNum; index ++){
stCommStruct.len = va_arg(arg_ptr, int);
stCommStruct.buff = va_arg(arg_ptr, void*);
*(long*)strTemp = stCommStruct.len;
if (stCommStruct.len > ) {
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 = ;
leave_len = len;
strTemp = strBuff;
while (leave_len > ){
//获取到当前长度
st_len = *(const long*)strTemp;
//校验BUFF内容合法性
if (st_len + sizeof(long) > leave_len) {
return FALSE;
}
//每个都用\0隔开吧
all_st_len += st_len + ; strTemp += st_len + sizeof(long);
leave_len -= st_len + sizeof(long);
} //分配内存
strInnBuff.resize(all_st_len, '\0');
strDest = (unsigned char*)&strInnBuff[]; strTemp = strBuff;
leave_len = len;
va_start(arg_ptr, len);
while(leave_len > ){
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 + ;
}
va_end(arg_ptr); return TRUE;
}

C++中的通用结构定义,及相应的序列化、反序列化接口的更多相关文章

  1. ArcGIS中的坐标系统定义与投影转换【转】

    ArcGIS中的坐标系统定义与投影转换 坐标系统是GIS数据重要的数学基础,用于表示地理要素.图像和观测结果的参照系统,坐标系统的定义能够保证地理数据在软件中正确的显示其位置.方向和距离,缺少坐标系统 ...

  2. 【转】+【举例】ArcGIS中的坐标系统定义与投影转换

    背景知识: UTM (Universal Transverse Mercator)坐标系是由美国军方在1947提出的.虽然我们仍然将其看作与"高斯-克吕格"相似的坐标系统,但实际上 ...

  3. ArcGIS中的坐标系定义与转换 (转载)

    原文:ArcGIS中的坐标系定义与转换 (转载) 1.基准面概念:  GIS中的坐标系定义由基准面和地图投影两组参数确定,而基准面的定义则由特定椭球体及其对应的转换参数确定,因此欲正确定义GIS系统坐 ...

  4. C++中的一些定义

    PS: 这篇博客用来记录一些一般的C++书中草草掠过的一些概念. 或者一些不太容易理解的概念的详细解释. 欢迎新手进入,欢迎高手指正! Orz . 引用: 为对象起了另外一个名字, 引用类型引用(re ...

  5. [C/C++]在头文件中使用static定义变量意味着什么

    文章出处:http://www.cnblogs.com/zplutor/ 看到有一位同学在头文件中这么写: static const wchar_t* g_str1 = - static const ...

  6. switch的case中不能做定义

    switch的case中不能做定义 只能给语句 error: a label can only be part of a statement and a declaration is not a st ...

  7. iOS 静态库中使用宏定义区分iPhone模拟器与真机---备用

    问题描述 一般项目中,可以使用宏定义来判断模拟器还是真机,这无疑是有效的. #if TARGET_IPHONE_SIMULATOR #define SIMULATOR 1 #elif TARGET_O ...

  8. [转载]C++中声明与定义的区别

    C++学了这么多年你知道为什么定义类时,类的定义放在.h文件中,而类的实现放在cpp文件中.它们为什么能够关联到一起呢?你知道什么东西可以放在.h文件中,什么不能.什么东西又可以放在cpp文件中.如果 ...

  9. (转载)php的类中可以不定义成员变量,直接在构造方法中使用并赋值吗?

    (转载)http://s.yanghao.org/program/viewdetail.php?i=184313 php的类中可以不定义成员变量,直接在构造方法中使用并赋值吗? class block ...

随机推荐

  1. IBM公司面试题

    进入IBM差不多是每一个IT人的梦想.IBM公司向来以高素质人才作为企业持续竞争力的保证,所以经常出一些千奇百怪的面试题,来考验一个人的综合能力,以下是5道IBM曾经出过的面试题,看看你能作出几道:  ...

  2. 【学习总结】快速上手Linux玩转典型应用-第2章-linux简介

    课程目录链接 快速上手Linux玩转典型应用-目录 目录 1. 什么是Linux 2. Linux能够做什么事情 3. Linux的学习方法 4. 忘掉Windows的所有东西 1. 什么是Linux ...

  3. 《CSS权威指南》双鱼书详解——第二章选择器

    一.基本规则 CSS的核心特性就是能向文档中的一组元素类型应用某些规则. 二.规则结构 选择器+声明块. h1{ color:red;background:yellow;} ,声明块由一个或多个声明组 ...

  4. 【转】UBOOT——启动内核

    转自:https://www.cnblogs.com/biaohc/p/6403863.html 1:什么是UBOOT,为什么要有UBOOT? UBOOT的主要作用是用来启动linux内核,因为CPU ...

  5. 计蒜客 蓝桥模拟 A. 结果填空:矩阵求和

    给你一个从 n×nn \times nn×n 的矩阵,里面填充 111 到 n×nn \times nn×n .例如当 nnn 等于 333 的时候,填充的矩阵如下.   1 1 2 3 2 4 5 ...

  6. 特殊字符(包括emoji)梳理和UTF8编码解码原理(转)

    转自:https://www.jianshu.com/p/57c27d67a8a8 背景知识 emoji表情符号,是20世纪90年代由NTT Docomo栗田穣崇(Shigetaka Kurit)创建 ...

  7. 前端每日实战:126# 视频演示如何用纯 CSS 创作小球变矩形背景的按钮悬停效果

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/yxbEzJ 可交互视频 此视频是可 ...

  8. zip(), dict(), itertools.repeat(), list(迭代器)

    *. zip(), dict() def demo_zip_dict(): keys = ['a', 'b', 'c'] values = [1, 2, 3] entrys = zip(keys, v ...

  9. Python---进阶---常用模块os、jso

    一.写一个6位随机验证码程序(使用 random模块),要求验证码中至少包含一个数字.一个小写字母.一个大写字母 import randomimport string #help(string) co ...

  10. Day_04-数组,元组,列表

    # for i in range(5): # for j in range(5): # print(i,j) # import re # def rm(): # a = ' 1 2 3 4 5 ' # ...