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 > ) {
- 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++中的通用结构定义,及相应的序列化、反序列化接口的更多相关文章
- ArcGIS中的坐标系统定义与投影转换【转】
ArcGIS中的坐标系统定义与投影转换 坐标系统是GIS数据重要的数学基础,用于表示地理要素.图像和观测结果的参照系统,坐标系统的定义能够保证地理数据在软件中正确的显示其位置.方向和距离,缺少坐标系统 ...
- 【转】+【举例】ArcGIS中的坐标系统定义与投影转换
背景知识: UTM (Universal Transverse Mercator)坐标系是由美国军方在1947提出的.虽然我们仍然将其看作与"高斯-克吕格"相似的坐标系统,但实际上 ...
- ArcGIS中的坐标系定义与转换 (转载)
原文:ArcGIS中的坐标系定义与转换 (转载) 1.基准面概念: GIS中的坐标系定义由基准面和地图投影两组参数确定,而基准面的定义则由特定椭球体及其对应的转换参数确定,因此欲正确定义GIS系统坐 ...
- C++中的一些定义
PS: 这篇博客用来记录一些一般的C++书中草草掠过的一些概念. 或者一些不太容易理解的概念的详细解释. 欢迎新手进入,欢迎高手指正! Orz . 引用: 为对象起了另外一个名字, 引用类型引用(re ...
- [C/C++]在头文件中使用static定义变量意味着什么
文章出处:http://www.cnblogs.com/zplutor/ 看到有一位同学在头文件中这么写: static const wchar_t* g_str1 = - static const ...
- switch的case中不能做定义
switch的case中不能做定义 只能给语句 error: a label can only be part of a statement and a declaration is not a st ...
- iOS 静态库中使用宏定义区分iPhone模拟器与真机---备用
问题描述 一般项目中,可以使用宏定义来判断模拟器还是真机,这无疑是有效的. #if TARGET_IPHONE_SIMULATOR #define SIMULATOR 1 #elif TARGET_O ...
- [转载]C++中声明与定义的区别
C++学了这么多年你知道为什么定义类时,类的定义放在.h文件中,而类的实现放在cpp文件中.它们为什么能够关联到一起呢?你知道什么东西可以放在.h文件中,什么不能.什么东西又可以放在cpp文件中.如果 ...
- (转载)php的类中可以不定义成员变量,直接在构造方法中使用并赋值吗?
(转载)http://s.yanghao.org/program/viewdetail.php?i=184313 php的类中可以不定义成员变量,直接在构造方法中使用并赋值吗? class block ...
随机推荐
- vue 防抖和节流
函数防抖(debounce):当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时. 函数节流(throttle):当持续触 ...
- redHat 安装mono 错误
make[6]: * [do-install] Error 2 make[6]: Leaving directory /root/lindexi/mono-2.11.3/mcs/class/Syste ...
- Result window is too large, from + size must be less than or equal to: [10000] but was [78440]. See the scroll api for a more efficient way to request large data sets
{"error":{"root_cause":[{"type":"query_phase_execution_exception& ...
- numpy中的range()
1.arange返回一个array对象,arange(5)=([0,1,2,3,4]) 2.如果是两个参数,第一个参数是起点,第二个参数是终点 3.如果是三个参数,那么第三个参数就是步长
- sed 流编辑命令
1.命令功能 sed非交互式的流编辑器,sed不会修改源文件内容,除非重定向来保存输出结果:默认情况下所有的输出行都将被打印到屏幕上. 2.语法格式 sed [option] {script-on ...
- 代理层Nginx限流(降级)预案
典型服务架构介绍 预案适用场景 监控指标 操作手册 相关文档 操作方法 配置语法 配置样例 配置解释 注意事项 典型服务架构介绍 典型的互联网服务访问链路都是分层结构的,从流量入口,到应用层,到后端资 ...
- spring 管理bean
目录结构: Person.java package com.wss.entity; import com.wss.service.doHomeWork; public class Person { p ...
- 【leetcode】1177. Can Make Palindrome from Substring
题目如下: Given a string s, we make queries on substrings of s. For each query queries[i] = [left, right ...
- 【leetcode】827. Making A Large Island
题目如下: 解题思路:这个题目可以进行拆分成几个子问题.第一,求出island的数量,其实就是 200. Number of Islands,这个很简单,DFS或者BFS都能搞定:第二,除了求出isl ...
- 文件打包压缩——tar
tar——压缩数据/解压数据内容 命令语法: tar zcvf 生成压缩包路径/压缩包.tar.gz 压缩数据01,02,03.... 巧记: 压缩名称为tar.gz,可以理解为tar命令,g ...