From 7db1a3565ea6b6d56a14d85c7014aa2b2a6b6861 Mon Sep 17 00:00:00 2001 From: coffee Date: Mon, 30 Jun 2025 18:06:31 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E5=A2=9E=E5=8A=A0=E5=BA=8F=E5=88=97?= =?UTF-8?q?=E5=8C=96=E5=87=BD=E6=95=B0=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/HStructConvByte.h | 147 ++++++++++++++++++++++++++++++++++++++ src/HStructConvByte.c | 59 +++++++++++++++ 2 files changed, 206 insertions(+) create mode 100644 include/HStructConvByte.h create mode 100644 src/HStructConvByte.c diff --git a/include/HStructConvByte.h b/include/HStructConvByte.h new file mode 100644 index 0000000..e125ac8 --- /dev/null +++ b/include/HStructConvByte.h @@ -0,0 +1,147 @@ +/** + * 日期: 2025-06-30 + * 作者: coffee + * 描述: 用于结构序列化和反序列数据, 支持任意数据, 自定义类型需要自行实现 HSTRUCT_CONV_DEFINE 和 HSTRUCT_FROM_DEFINE + */ + + +#ifndef __HSTRUCT_CONV_BYTE_H__ +#define __HSTRUCT_CONV_BYTE_H__ + +/** + * demo: + * // 定义或声明序列化对象函数 + * HSTRUCT_CONV_DEFINE(uint8_t) + * { + * // 初始化序列化对象类型 + * HSTRUCT_CONV_BEGIN(uint8_t); + * // 更新需要长度 + * HSTRUCT_UPDATE(sizeof(uint8_t)); + * // 将当前类型的数据转换成字节数据 + * HSTRUCT_GET_DATA(uint8_t) = HSTRUCT_GET_TYPE(); + * // 如果你需要memcpy内存操作, 那么应该提取原始类型 HSTRUCT_GET_DATA_RAW(uint8_t *) + * // 转换结束 + * HSTRUCT_END(); + * } + * // 定义或声明反序列化对象函数 + * HSTRUCT_FROM_DEFINE(uint8_t) + * { + * // 初始化序列化对象类型 + * HSTRUCT_FROM_BEGIN(uint8_t); + * HSTRUCT_UPDATE(sizeof(uint8_t)); + * // 将字节数据转换成当前类型 + * HSTRUCT_GET_TYPE() = HSTRUCT_GET_DATA(uint8_t); + * HSTRUCT_END(); + * } + */ + +#include + +// 固定函数名 _HStructConvXXX + +/** + * @brief 类型数据转换成字节数据 + * @param type 固定函数名增加的后缀 + * @param var 变量名 + * @param data 数据指针 + * @param len 数据长度 + */ +#define HSTRUCT_CONV_BYTE(type, var, data, len) _HStructConv_##type((const void *)&var, data, len) + +/** + * @brief 字节数据转换成类型数据 + * @param type 固定函数名增加的后缀 + * @param var 变量名 + * @param data 数据指针 + * @param len 数据长度 + */ +#define HSTRUCT_FROM_BYTE(type, var, data, len) _HStructFrom_##type((void *)&var, data, len) + + +// 定义或生命该类型的转换函数 +#define HSTRUCT_CONV_DEFINE(type) int _HStructConv_##type(const void *_var, char *_data, int _len) +#define HSTRUCT_FROM_DEFINE(type) int _HStructFrom_##type(void *_var, const char *_data, int _len) + +// 给已有的类型取别名 +#define HSTRUCT_CONV_ALIAS(type, aliasType) \ + static inline int _HStructConv_##type(const void *_var, char *_data, int _len) { return _HStructConv_##aliasType(_var, _data, _len); } +#define HSTRUCT_FROM_ALIAS(type, aliasType) \ + static inline int _HStructFrom_##type(void *_var, const char *_data, int _len) { return _HStructFrom_##aliasType(_var, _data, _len); } + +// 对应参数获取方法 +#define HSTRUCT_GET_TYPE_RAW() (_convVar) +#define HSTRUCT_GET_TYPE() (*_convVar) +#define HSTRUCT_GET_LEN() (_len) +#define HSTRUCT_GET_DATA_RAW(type) ((type)_convData) +#define HSTRUCT_GET_DATA(type) (*((type *)_convData)) + +// 函数实现的开始和结束 +#define HSTRUCT_FROM_BEGIN(type) \ + type *_convVar = (type *)_var; \ + const void *_convData = _data; \ + int _useLen = 0; +#define HSTRUCT_CONV_BEGIN(type) \ + const type *_convVar = (const type *)_var; \ + char *_convData = (char *)_data; \ + int _useLen = 0; +#define HSTRUCT_END() return _useLen + +// 函数的检查数据是否足够 +#define HSTRUCT_CHECK_LEN(len) \ + if (HSTRUCT_GET_LEN() < len + _useLen) \ + { \ + LogD("data len[%d], use[%d]", __FILE_NAME__, __FUNCTION__, __LINE__, HSTRUCT_GET_LEN(), _useLen); \ + return _useLen; \ + } + +// 更新长度数据 +#define HSTRUCT_UPDATE(nextLen) \ + _convData = (_data + _useLen); \ + HSTRUCT_CHECK_LEN(nextLen) \ + _useLen += nextLen + +/** + * @brief 在序列化函数中使用已有的序列化类型的宏 + */ +#define HSTRUCT_USE_CONV_FUNC(type, typeLen, var) \ + HSTRUCT_UPDATE(typeLen); \ + HSTRUCT_CONV_BYTE(type, var, _convData, _len - (_useLen - typeLen)) + +/** + * @brief 在反序列化函数中使用已有的反序列化类型的宏 + */ +#define HSTRUCT_USE_FROM_FUNC(type, typeLen, var) \ + HSTRUCT_UPDATE(typeLen); \ + HSTRUCT_FROM_BYTE(type, var, _convData, _len - (_useLen - typeLen)) + +///< 预设转换函数 +HSTRUCT_CONV_DEFINE(uint8_t); +HSTRUCT_CONV_DEFINE(uint16_t); +HSTRUCT_CONV_DEFINE(uint32_t); + +HSTRUCT_FROM_DEFINE(uint8_t); +HSTRUCT_FROM_DEFINE(uint16_t); +HSTRUCT_FROM_DEFINE(uint32_t); + +///< 预设别名转换 +HSTRUCT_CONV_ALIAS(char, uint8_t); +HSTRUCT_CONV_ALIAS(u8, uint8_t); +HSTRUCT_CONV_ALIAS(s8, uint8_t); +HSTRUCT_CONV_ALIAS(short, uint16_t); +HSTRUCT_CONV_ALIAS(u16, uint16_t); +HSTRUCT_CONV_ALIAS(s16, uint16_t); +HSTRUCT_CONV_ALIAS(int, uint32_t); +HSTRUCT_CONV_ALIAS(u32, uint32_t); +HSTRUCT_CONV_ALIAS(s32, uint32_t); + +HSTRUCT_FROM_ALIAS(char, uint8_t); +HSTRUCT_FROM_ALIAS(u8, uint8_t); +HSTRUCT_FROM_ALIAS(s8, uint8_t); +HSTRUCT_FROM_ALIAS(short, uint16_t); +HSTRUCT_FROM_ALIAS(u16, uint16_t); +HSTRUCT_FROM_ALIAS(s16, uint16_t); +HSTRUCT_FROM_ALIAS(int, uint32_t); +HSTRUCT_FROM_ALIAS(u32, uint32_t); +HSTRUCT_FROM_ALIAS(s32, uint32_t); + +#endif // __HSTRUCT_CONV_BYTE_H__ diff --git a/src/HStructConvByte.c b/src/HStructConvByte.c new file mode 100644 index 0000000..9815f5e --- /dev/null +++ b/src/HStructConvByte.c @@ -0,0 +1,59 @@ + + +#include "HStructConvByte.h" +#include "HDLog.h" +#include + + +HSTRUCT_CONV_DEFINE(uint8_t) +{ + HSTRUCT_CONV_BEGIN(uint8_t); + HSTRUCT_UPDATE(sizeof(uint8_t)); + HSTRUCT_GET_DATA(uint8_t) = HSTRUCT_GET_TYPE(); + HSTRUCT_END(); +} + +HSTRUCT_CONV_DEFINE(uint16_t) +{ + HSTRUCT_CONV_BEGIN(uint16_t); + HSTRUCT_UPDATE(sizeof(uint16_t)); + HSTRUCT_GET_DATA_RAW(uint8_t *)[0] = (HSTRUCT_GET_TYPE() >> 8) & 0xFF; + HSTRUCT_GET_DATA_RAW(uint8_t *)[1] = HSTRUCT_GET_TYPE() & 0xFF; + HSTRUCT_END(); +} + +HSTRUCT_CONV_DEFINE(uint32_t) +{ + HSTRUCT_CONV_BEGIN(uint32_t); + HSTRUCT_UPDATE(sizeof(uint32_t)); + HSTRUCT_GET_DATA_RAW(uint8_t *)[0] = (HSTRUCT_GET_TYPE() >> 24) & 0xFF; + HSTRUCT_GET_DATA_RAW(uint8_t *)[1] = (HSTRUCT_GET_TYPE() >> 16) & 0xFF; + HSTRUCT_GET_DATA_RAW(uint8_t *)[2] = (HSTRUCT_GET_TYPE() >> 8) & 0xFF; + HSTRUCT_GET_DATA_RAW(uint8_t *)[3] = HSTRUCT_GET_TYPE() & 0xFF; + HSTRUCT_END(); +} + +HSTRUCT_FROM_DEFINE(uint8_t) +{ + HSTRUCT_FROM_BEGIN(uint8_t); + HSTRUCT_UPDATE(sizeof(uint8_t)); + HSTRUCT_GET_TYPE() = HSTRUCT_GET_DATA(uint8_t); + HSTRUCT_END(); +} + +HSTRUCT_FROM_DEFINE(uint16_t) +{ + HSTRUCT_FROM_BEGIN(uint16_t); + HSTRUCT_UPDATE(sizeof(uint16_t)); + HSTRUCT_GET_TYPE() = (HSTRUCT_GET_DATA_RAW(uint8_t *)[0] << 8) | HSTRUCT_GET_DATA_RAW(uint8_t *)[1]; + HSTRUCT_END(); +} + +HSTRUCT_FROM_DEFINE(uint32_t) +{ + HSTRUCT_FROM_BEGIN(uint32_t); + HSTRUCT_UPDATE(sizeof(uint32_t)); + HSTRUCT_GET_TYPE() = (HSTRUCT_GET_DATA_RAW(uint8_t *)[0] << 24) | (HSTRUCT_GET_DATA_RAW(uint8_t *)[1] << 16) | + (HSTRUCT_GET_DATA_RAW(uint8_t *)[2] << 8) | HSTRUCT_GET_DATA_RAW(uint8_t *)[3]; + HSTRUCT_END(); +}