C++中的通用结构定义,及相应的序列化、反序列化接口
一个通用的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;
unsignedchar*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;
unsignedchar*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;
unsignedchar*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;
}