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

  1. typedef struct tagCommonStruct {
  2. long len;
  3. void* buff;
  4. }CommonStruct_st;

此接口对应的普通序列化、反序列化接口如下:

  1. unsigned char* EncodeCommonStruct(const CommonStruct_st& CommonSt)
  2. {
  3. //分配内存
  4. unsigned char* strBuff = (unsigned char*)malloc(CALC_COMMON_ST_LEN(&CommonSt));
  5. if (NULL == strBuff)
  6. {
  7. return NULL;
  8. }
  9.  
  10. //填充内容
  11. *(long*)strBuff = CommonSt.len;
  12. if (CommonSt.len > ) {
  13. memcpy(strBuff + sizeof(long), CommonSt.buff, CommonSt.len);
  14. }
  15.  
  16. return strBuff;
  17. }
  18.  
  19. BOOL DecodeCommonStruct(const unsigned char* strBuff, long len, CommonStruct_st& CommonSt)
  20. {
  21. long st_len;
  22. if (NULL == strBuff)
  23. {
  24. return FALSE;
  25. }
  26.  
  27. //获取到当前长度
  28. st_len = *(const long*)strBuff;
  29. //校验BUFF内容合法性
  30. if (st_len + sizeof(long) > len) {
  31. return FALSE;
  32. }
  33. CommonSt.len = st_len;
  34. CommonSt.buff = (void*)malloc(st_len);
  35. memcpy(CommonSt.buff, strBuff + sizeof(long), st_len);
  36. return TRUE;
  37. }
  38.  
  39. void EncodeCommonStruct_S(const CommonStruct_st& CommonSt, std::string& strOut)
  40. {
  41. //分配内存
  42. strOut.resize(CALC_COMMON_ST_LEN(&CommonSt));
  43.  
  44. //填充内容
  45. *(long*)&(strOut[]) = CommonSt.len;
  46. if (CommonSt.len > ) {
  47. memcpy(&(strOut[]) + sizeof(long), CommonSt.buff, CommonSt.len);
  48. }
  49.  
  50. return;
  51. }
  52.  
  53. BOOL DecodeCommonStruct_S(const unsigned char* strBuff, long len, CommonStruct_st& pCommonSt, std::string& strInnBuff)
  54. {
  55. long st_len;
  56. if (NULL == strBuff)
  57. {
  58. return FALSE;
  59. }
  60.  
  61. //获取到当前长度
  62. st_len = *(const long*)strBuff;
  63. //校验BUFF内容合法性
  64. if (st_len + sizeof(long) > len) {
  65. return FALSE;
  66. }
  67. pCommonSt.len = st_len;
  68. strInnBuff.resize(st_len);
  69. //pCommonSt.buff = (void*)malloc(st_len);
  70. pCommonSt.buff = &strInnBuff[];
  71. memcpy(pCommonSt.buff, strBuff + sizeof(long), st_len);
  72. return TRUE;
  73. }

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

  1. #define MAX_COMMON_STRUCT_PARAM_NUMBER (16)
  2.  
  3. void EncodeCommonStructV(std::string& strOut, int nStNum, ...)
  4. {
  5. int index = ;
  6. int nBufLen;
  7. unsigned char* strTemp;
  8. //最多允许16个
  9. va_list arg_ptr;
  10. CommonStruct_st CommStructStArray[MAX_COMMON_STRUCT_PARAM_NUMBER];
  11.  
  12. //
  13. if (nStNum > MAX_COMMON_STRUCT_PARAM_NUMBER) {
  14. return;
  15. }
  16.  
  17. //依次取出相应的结构、指针位置
  18. nBufLen = ;
  19. va_start(arg_ptr, nStNum);
  20. for(index = ; index < nStNum; index ++){
  21. CommStructStArray[index].len = va_arg(arg_ptr, int);
  22. CommStructStArray[index].buff = va_arg(arg_ptr, void*);
  23. nBufLen += CALC_COMMON_ST_LEN(&CommStructStArray[index]);
  24. }
  25. va_end(arg_ptr);
  26.  
  27. //计算总字符长度
  28. strOut.resize(nBufLen, '\0');
  29. strTemp = (unsigned char*)&strOut[];
  30.  
  31. //依次格式化
  32. std::string strTmpBuf;
  33. for(index = ; index < nStNum; index ++){
  34. #if 0
  35. EncodeCommonStruct_S(CommStructStArray[index], strTmpBuf);
  36. memcpy(strTemp, strTmpBuf.c_str(), CALC_COMMON_ST_LEN(&CommStructStArray[index]);
  37. #else
  38. *(long*)strTemp = CommStructStArray[index].len;
  39. if (CommStructStArray[index].len > ) {
  40. memcpy(strTemp + sizeof(long), CommStructStArray[index].buff, CommStructStArray[index].len);
  41. }
  42. #endif
  43.  
  44. strTemp += CALC_COMMON_ST_LEN(&CommStructStArray[index]);
  45. }
  46. }
  1. BOOL DecodeCommonStructV(const unsigned char* strBuff, long len, ...)
  2. {
  3. va_list arg_ptr;
  4. long leave_len, st_len;
  5. CommonStruct_st *pstCommonStruct;
  6. const unsigned char* strTemp;
  7. if (NULL == strBuff)
  8. {
  9. return FALSE;
  10. }
  11.  
  12. leave_len = len;
  13. strTemp = strBuff;
  14. va_start(arg_ptr, len);
  15. while(leave_len > ){
  16. pstCommonStruct = va_arg(arg_ptr, CommonStruct_st *);
  17.  
  18. //允许BUFF中的内容更长,但只取前面一部分
  19. if (NULL == pstCommonStruct){
  20. break;
  21. }
  22.  
  23. //获取到当前长度
  24. st_len = *(const long*)strTemp;
  25. //校验BUFF内容合法性
  26. if (st_len + sizeof(long) > leave_len) {
  27. return FALSE;
  28. }
  29.  
  30. //填充一块结构体的内容
  31. pstCommonStruct->len = st_len;
  32. memcpy(pstCommonStruct->buff, strTemp + sizeof(long), st_len);
  33.  
  34. //偏移位置
  35. strTemp += st_len + sizeof(long);
  36. leave_len -= st_len + sizeof(long);
  37. }
  38. va_end(arg_ptr);
  39.  
  40. return TRUE;
  41. }

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

  1. void EncodeCommonStructV2(std::string& strOut, int nStNum, ...)
  2. {
  3. int index = ;
  4. int nBufLen;
  5. va_list arg_ptr;
  6. unsigned char* strTemp;
  7. CommonStruct_st stCommStruct;
  8.  
  9. //依次取出相应的结构、指针位置
  10. nBufLen = ;
  11. va_start(arg_ptr, nStNum);
  12. for(index = ; index < nStNum; index ++){
  13. stCommStruct.len = va_arg(arg_ptr, int);
  14. stCommStruct.buff = va_arg(arg_ptr, void*);
  15. nBufLen += CALC_COMMON_ST_LEN(&stCommStruct);
  16. }
  17. va_end(arg_ptr);
  18.  
  19. //计算总字符长度
  20. strOut.resize(nBufLen, '\0');
  21. strTemp = (unsigned char*)&strOut[];
  22.  
  23. //依次格式化
  24. std::string strTmpBuf;
  25. va_start(arg_ptr, nStNum);
  26. for(index = ; index < nStNum; index ++){
  27. stCommStruct.len = va_arg(arg_ptr, int);
  28. stCommStruct.buff = va_arg(arg_ptr, void*);
  29. *(long*)strTemp = stCommStruct.len;
  30. if (stCommStruct.len > ) {
  31. memcpy(strTemp + sizeof(long), stCommStruct.buff, stCommStruct.len);
  32. }
  33.  
  34. strTemp += CALC_COMMON_ST_LEN(&stCommStruct);
  35. }
  36. va_end(arg_ptr);
  37. }

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

  1. BOOL DecodeCommonStructV2(const unsigned char* strBuff, std::string& strInnBuff, long len, ...)
  2. {
  3. va_list arg_ptr;
  4. long leave_len, st_len, all_st_len;
  5. CommonStruct_st *pstCommonStruct;
  6. const unsigned char* strTemp;
  7. unsigned char* strDest;
  8. if (NULL == strBuff)
  9. {
  10. return FALSE;
  11. }
  12.  
  13. //计算strBuff中总共需要多少内存来存放
  14. all_st_len = ;
  15. leave_len = len;
  16. strTemp = strBuff;
  17. while (leave_len > ){
  18. //获取到当前长度
  19. st_len = *(const long*)strTemp;
  20. //校验BUFF内容合法性
  21. if (st_len + sizeof(long) > leave_len) {
  22. return FALSE;
  23. }
  24. //每个都用\0隔开吧
  25. all_st_len += st_len + ;
  26.  
  27. strTemp += st_len + sizeof(long);
  28. leave_len -= st_len + sizeof(long);
  29. }
  30.  
  31. //分配内存
  32. strInnBuff.resize(all_st_len, '\0');
  33. strDest = (unsigned char*)&strInnBuff[];
  34.  
  35. strTemp = strBuff;
  36. leave_len = len;
  37. va_start(arg_ptr, len);
  38. while(leave_len > ){
  39. pstCommonStruct = va_arg(arg_ptr, CommonStruct_st *);
  40.  
  41. //允许BUFF中的内容更长,但只取前面一部分
  42. if (NULL == pstCommonStruct){
  43. break;
  44. }
  45.  
  46. //获取到当前长度
  47. st_len = *(const long*)strTemp;
  48.  
  49. //填充一块结构体的内容
  50. pstCommonStruct->len = st_len;
  51. pstCommonStruct->buff = strDest;
  52. //拷贝至缓冲区中
  53. memcpy(strDest, strTemp + sizeof(long), st_len);
  54.  
  55. //偏移位置
  56. strTemp += st_len + sizeof(long);
  57. leave_len -= st_len + sizeof(long);
  58. strDest += st_len + ;
  59. }
  60. va_end(arg_ptr);
  61.  
  62. return TRUE;
  63. }

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. vue 防抖和节流

    函数防抖(debounce):当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时. 函数节流(throttle):当持续触 ...

  2. redHat 安装mono 错误

    make[6]: * [do-install] Error 2 make[6]: Leaving directory /root/lindexi/mono-2.11.3/mcs/class/Syste ...

  3. 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& ...

  4. numpy中的range()

    1.arange返回一个array对象,arange(5)=([0,1,2,3,4]) 2.如果是两个参数,第一个参数是起点,第二个参数是终点 3.如果是三个参数,那么第三个参数就是步长

  5. sed 流编辑命令

    1.命令功能 sed非交互式的流编辑器,sed不会修改源文件内容,除非重定向来保存输出结果:默认情况下所有的输出行都将被打印到屏幕上. 2.语法格式 sed  [option]  {script-on ...

  6. 代理层Nginx限流(降级)预案

    典型服务架构介绍 预案适用场景 监控指标 操作手册 相关文档 操作方法 配置语法 配置样例 配置解释 注意事项 典型服务架构介绍 典型的互联网服务访问链路都是分层结构的,从流量入口,到应用层,到后端资 ...

  7. spring 管理bean

    目录结构: Person.java package com.wss.entity; import com.wss.service.doHomeWork; public class Person { p ...

  8. 【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 ...

  9. 【leetcode】827. Making A Large Island

    题目如下: 解题思路:这个题目可以进行拆分成几个子问题.第一,求出island的数量,其实就是 200. Number of Islands,这个很简单,DFS或者BFS都能搞定:第二,除了求出isl ...

  10. 文件打包压缩——tar

    tar——压缩数据/解压数据内容 命令语法: tar zcvf  生成压缩包路径/压缩包.tar.gz    压缩数据01,02,03.... 巧记: 压缩名称为tar.gz,可以理解为tar命令,g ...