Add serialize library for binary serialization with dynamic allocation
- serialize.h/c: universal binary serialization for structures with variable-length fields (ASCIIZ, ARRAY) using pointers - Auto allocation via u_malloc during deserialization - Support for header (arbitrary bytes at buffer start) - serialize_encode(): serialize structure to buffer - serialize_decode(): deserialize from buffer (without header) - serialize_free(): free structure and all its pointers - tests/test_serialize.c: unit tests
This commit is contained in:
1 parent
3b31821316
commit
dba092d88b
3 files changed
+510
No files matched your search
+102
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* @file serialize.h
|
||||
* @brief Бинарная сериализация структур с динамическим выделением памяти
|
||||
*
|
||||
* Поддерживает структуры с полями переменной длины (ASCIIZ, ARRAY) через указатели.
|
||||
* При десериализации автоматически выделяет память через u_malloc.
|
||||
*
|
||||
* Формат буфера:
|
||||
* [header_len байт][сериализованные данные]
|
||||
*
|
||||
* Пример использования:
|
||||
* @code
|
||||
* // Сериализация
|
||||
* uint8_t header[] = {0x01, 0x02, 0x03, 0x04};
|
||||
* serialize_encode(&orig, &schema, header, &buf, &len);
|
||||
*
|
||||
* // Десериализация (данные без заголовка)
|
||||
* uint8_t* data = buf + schema.header_len;
|
||||
* serialize_decode(data, len - schema.header_len, &schema, &restored);
|
||||
*
|
||||
* // Освобождение
|
||||
* serialize_free(&schema, &restored);
|
||||
* u_free(buf);
|
||||
* @endcode
|
||||
*/
|
||||
#ifndef SERIALIZE_H
|
||||
#define SERIALIZE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "../lib/mem.h"
|
||||
|
||||
/**
|
||||
* @brief Описание одного поля структуры для сериализации
|
||||
*/
|
||||
struct SerializeField {
|
||||
uint16_t offset; ///< смещение указателя в структуре
|
||||
uint8_t elem_size; ///< 0=fixed, 1=ASCIIZ, >1=ARRAY (размер элемента в байтах)
|
||||
uint16_t max_size; ///< макс. длина для ASCIIZ / макс. кол-во для ARRAY
|
||||
uint8_t has_len; ///< 1 если есть length field
|
||||
uint8_t len_type; ///< 1=UINT8, 2=UINT16
|
||||
uint16_t len_offset; ///< смещение length поля в структуре
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Схема структуры для сериализации
|
||||
*/
|
||||
struct SerializeSchema {
|
||||
uint16_t field_count; ///< число полей
|
||||
uint16_t struct_size; ///< размер структуры для allocate
|
||||
uint16_t header_len; ///< длина заголовка (произвольные байты в начале)
|
||||
const struct SerializeField* fields; ///< массив описаний полей
|
||||
};
|
||||
|
||||
#define SERIALIZE_ERR_OK 0 ///< успех
|
||||
#define SERIALIZE_ERR_BUF -1 ///< ошибка выделения памяти
|
||||
#define SERIALIZE_ERR_NULL -2 ///< null указатель
|
||||
|
||||
/**
|
||||
* @brief Сериализация структуры в бинарный буфер
|
||||
* @param structure указатель на исходную структуру
|
||||
* @param schema схема структуры
|
||||
* @param header заголовок (или NULL если header_len=0)
|
||||
* @param out_buf [out] выходной буфер (выделяется через u_malloc)
|
||||
* @param out_len [out] размер буфера
|
||||
* @return SERIALIZE_ERR_OK или код ошибки
|
||||
*
|
||||
* Формат выходного буфера:
|
||||
* [header_len байт][сериализованные данные]
|
||||
*/
|
||||
int serialize_encode(const void* structure,
|
||||
const struct SerializeSchema* schema,
|
||||
const uint8_t* header,
|
||||
uint8_t** out_buf,
|
||||
size_t* out_len);
|
||||
|
||||
/**
|
||||
* @brief Десериализация из буфера в структуру
|
||||
* @param in_buf буфер БЕЗ заголовка (уже смещённый на header_len)
|
||||
* @param in_len размер данных (без header)
|
||||
* @param schema схема структуры
|
||||
* @param structure [out] указатель на восстановленную структуру
|
||||
* @return SERIALIZE_ERR_OK или код ошибки
|
||||
*
|
||||
* Внимание: in_buf должен быть без заголовка!
|
||||
* Буфер со смещением: uint8_t* data = buf + schema.header_len;
|
||||
* Длина без header: size_t data_len = total_len - schema.header_len;
|
||||
*/
|
||||
int serialize_decode(const uint8_t* in_buf, size_t in_len,
|
||||
const struct SerializeSchema* schema,
|
||||
void** structure);
|
||||
|
||||
/**
|
||||
* @brief Освобождение структуры и всех её указателей
|
||||
* @param schema схема структуры
|
||||
* @param structure [inout] указатель на структуру (устанавливается в NULL)
|
||||
*
|
||||
* Освобождает структуру и все её динамические указатели (ASCIIZ, ARRAY).
|
||||
*/
|
||||
void serialize_free(const struct SerializeSchema* schema, void** structure);
|
||||
|
||||
#endif // SERIALIZE_H
|
||||
Reference in new issue
Block a user