/** * 日期: 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(); * } * // 使用已有的来序列化和反序列化 * typedef struct Demo { * uint8_t a; * } Demo; * HSTRUCT_CONV_DEFINE(Demo) * { * // 初始化对象 * HSTRUCT_CONV_BEGIN(Demo); * // 使用uint8_t来序列化Demo.a * HSTRUCT_USE_CONV_FUNC(uint8_t, sizeof(uint8_t), HSTRUCT_GET_TYPE().a); * HSTRUCT_END(); * } */ #include // 固定函数名 _HStructConv_XXX | _HStructFrom_XXX /** * @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) /** * @brief 在序列化函数中使用已有的序列化类型的宏 * @param type 序列化类型 * @param typeLen 序列化类型长度 * @param var 变量 */ #define HSTRUCT_USE_CONV_FUNC(type, typeLen, var) \ do \ { \ int useLen = HSTRUCT_CONV_BYTE(type, var, _convData, _len - (_useLen - typeLen)); \ if (useLen <= 0) \ { \ LogD("conv is empty, len[%d], useLen[%d][%d]", _len, _useLen, useLen); \ return _useLen; \ } \ _useLen += useLen; \ HSTRUCT_UPDATE(0); \ } while (0) /** * @brief 在反序列化函数中使用已有的反序列化类型的宏 * @param type 反序列化类型 * @param typeLen 反序列化类型长度 * @param var 变量 */ #define HSTRUCT_USE_FROM_FUNC(type, typeLen, var) \ do \ { \ int useLen = HSTRUCT_FROM_BYTE(type, var, _convData, _len - (_useLen - typeLen)); \ if (useLen <= 0) \ { \ LogD("from is empty, len[%d], useLen[%d][%d]", _len, _useLen, useLen); \ return _useLen; \ } \ _useLen += useLen; \ HSTRUCT_UPDATE(0); \ } while (0) // 定义或声明该类型的转换函数 #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 ///< 预设转换函数 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(short, uint16_t); HSTRUCT_CONV_ALIAS(int, uint32_t); HSTRUCT_FROM_ALIAS(char, uint8_t); HSTRUCT_FROM_ALIAS(short, uint16_t); HSTRUCT_FROM_ALIAS(int, uint32_t); #ifdef _HSTRUCT_USE_ALIAS HSTRUCT_CONV_ALIAS(u8, uint8_t); HSTRUCT_CONV_ALIAS(s8, uint8_t); HSTRUCT_CONV_ALIAS(u16, uint16_t); HSTRUCT_CONV_ALIAS(s16, uint16_t); HSTRUCT_CONV_ALIAS(u32, uint32_t); HSTRUCT_CONV_ALIAS(s32, uint32_t); HSTRUCT_FROM_ALIAS(u8, uint8_t); HSTRUCT_FROM_ALIAS(s8, uint8_t); HSTRUCT_FROM_ALIAS(u16, uint16_t); HSTRUCT_FROM_ALIAS(s16, uint16_t); HSTRUCT_FROM_ALIAS(u32, uint32_t); HSTRUCT_FROM_ALIAS(s32, uint32_t); #endif #endif // __HSTRUCT_CONV_BYTE_H__