一个通用的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. Codeforces Round #426 (Div. 2) - D

    题目链接:http://codeforces.com/contest/834/problem/D 题意:给定一个长度为n的序列和一个k,现在让你把这个序列分成刚好k段,并且k段的贡献之和最大.对于每一 ...

  2. Python核心技术与实战——六|异常处理

    和其他语言一样,Python中的异常处理是很重要的机制和代码规范. 一.错误与异常 通常来说程序中的错误分为两种,一种是语法错误,另一种是异常.首先要了解错误和异常的区别和联系. 语法错误比较容易理解 ...

  3. 刷PTA这一周的感悟

    在慕课上报名了浙江大学的<数据结构>这门课,主讲人陈越老师,何钦铭老师,两位老师讲的很好,课后有配套的PTA可以用来做题,练习. 最近在PTA上刷题,发现自己代码实现能力是真的差劲,一开始 ...

  4. python笔记(3)---列表

    lst = ["bob","jack","马云","马化腾","王健林"] del lst[1:3] ...

  5. VCL界面控件DevExpress VCL Controls发布v18.2.7|附下载

    DevExpress VCL Controls是 Devexpress公司旗下最老牌的用户界面套包.所包含的控件有:数据录入,图表,数据分析,导航,布局,网格,日程管理,样式,打印和工作流等,让您快速 ...

  6. Scrat

    前端工程化集成:Scrat UC团队在百度FIS基础上二次开发的模块化开发框架,可以与vue配合使用

  7. 前端之JavaScript:JS之DOM对象二

    继续JS之DOM对象二 前面在JS之DOM中我们知道了属性操作,下面我们来了解一下节点操作.很重要!! 一.节点操作 创建节点:var ele_a = document.createElement(' ...

  8. 如何提高SMTP邮件的安全性?从而不被黑客窃听

    简单邮件传输协议(SMTP)用于在邮件服务器之间进行邮件传输,并且传统上是不安全的,因此容易被黑客窃听.命名实体的基于DNS的认证(国家统计局)用于SMTP提供了邮件传输更安全的方法,并逐渐变得越来越 ...

  9. Android PdfViewer案例使用

    今天按项目要求找了一个android的PDF控件,各种操作效果都非常好,在这里和大家分享一下. com.joanzapata.pdfview:android-pdfview  该PDF控件加载大存储的 ...

  10. OCP

    desc dba_objects; select * from dba_objects where rownum = 6; select owner, object_id from dba_objec ...