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

typedef structtagCommonStruct {longlen;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)
{
returnNULL;
}
//填充内容 *(long*)strBuff =CommonSt.len;if (CommonSt.len > 0) {
memcpy(strBuff
+ sizeof(long), CommonSt.buff, CommonSt.len);
}
returnstrBuff;
}

BOOL DecodeCommonStruct(
const unsigned char* strBuff, long len, CommonStruct_st&CommonSt)
{
longst_len;if (NULL ==strBuff)
{
returnFALSE;
}
//获取到当前长度 st_len = *(const long*)strBuff;//校验BUFF内容合法性 if (st_len + sizeof(long) >len) {returnFALSE;
}
CommonSt.len
=st_len;
CommonSt.buff
= (void*)malloc(st_len);
memcpy(CommonSt.buff, strBuff
+ sizeof(long), st_len);returnTRUE;
}
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)
{
longst_len;if (NULL ==strBuff)
{
returnFALSE;
}
//获取到当前长度 st_len = *(const long*)strBuff;//校验BUFF内容合法性 if (st_len + sizeof(long) >len) {returnFALSE;
}
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);returnTRUE;
}

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

#define MAX_COMMON_STRUCT_PARAM_NUMBER (16)

void EncodeCommonStructV(std::string& strOut, intnStNum, ...)
{
int index = 0;intnBufLen;
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, '\0');
strTemp
= (unsigned char*)&strOut[0];//依次格式化 std::stringstrTmpBuf;for(index = 0; index < nStNum; index ++){#if 0EncodeCommonStruct_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);
}
#endifstrTemp+= CALC_COMMON_ST_LEN(&CommStructStArray[index]);
}
}
BOOL DecodeCommonStructV(const unsigned char* strBuff, longlen, ...)
{
va_list arg_ptr;
longleave_len, st_len;
CommonStruct_st
*pstCommonStruct;const unsigned char*strTemp;if (NULL ==strBuff)
{
returnFALSE;
}

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) {returnFALSE;
}
//填充一块结构体的内容 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);
returnTRUE;
}

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

void EncodeCommonStructV2(std::string& strOut, intnStNum, ...)
{
int index = 0;intnBufLen;
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, '\0');
strTemp
= (unsigned char*)&strOut[0];//依次格式化 std::stringstrTmpBuf;
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, longlen, ...)
{
va_list arg_ptr;
longleave_len, st_len, all_st_len;
CommonStruct_st
*pstCommonStruct;const unsigned char*strTemp;
unsigned
char*strDest;if (NULL ==strBuff)
{
returnFALSE;
}
//计算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) {returnFALSE;
}
//每个都用\0隔开吧 all_st_len += st_len + 1;

strTemp
+= st_len + sizeof(long);
leave_len
-= st_len + sizeof(long);
}
//分配内存 strInnBuff.resize(all_st_len, '\0');
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);
returnTRUE;
}

 

标签: none

添加新评论