genclibs/describe.h
2024-10-14 15:26:57 +02:00

74 lines
2.2 KiB
C

#pragma once
#include <stddef.h>
#include <stdarg.h>
#include <stdint.h>
#include "network_byte_order.h"
typedef uint8_t uint8;
#define ARRAY_OF uint8
#include "array.h"
typedef struct struct_descriptor_s struct_descriptor_t;
typedef void (*serializer_function_t)(uint8_t *);
typedef struct field_descriptor{
char const *name;
ptrdiff_t offset;
size_t size;
serializer_function_t serializer;
} field_descriptor_t;
#define ARRAY_OF struct field_descriptor
#include "array.h"
typedef struct struct_descriptor_s{
char const *name;
size_t size;
field_descriptor_arr_t fields;
} struct_descriptor_t;
#include "narg.h"
#include "for_each.h"
#define default_serializer_function(s) __extension__({ \
(s == 64) ? serialize_64bits : ( \
(s == 32) ? serialize_32bits : ( \
(s == 16) ? serialize_16bits : \
serialize_generic ));\
})
#define sizeof_field(T, field) sizeof(((T *)NULL)->field)
#define describe_field(T, field) ((field_descriptor_t) {.name = #field, .offset = offsetof(T, field), .size = sizeof_field(T, field), .serializer = default_serializer_function(sizeof_field(T, field))})
#define describe_fields(T, ...) for_each_pair(describe_field, T, __VA_ARGS__)
#define describe_type(T, ...) struct_descriptor_init(#T, sizeof(T), NARG(__VA_ARGS__) __VA_OPT__(, describe_fields(T, __VA_ARGS__)))
struct_descriptor_t *struct_descriptor_init(char const *name, size_t size, size_t count, ...);
#define register_type(T, ...) struct_descriptor_register(#T, sizeof(T), NARG(__VA_ARGS__) __VA_OPT__(, describe_fields(T, __VA_ARGS__)))
void struct_descriptor_register(char const *name, size_t size, size_t count, ...);
#define serialize_type(T, data) struct_descriptor_serialize_data(#T, data)
uint8_arr_t *struct_descriptor_serialize_data(char const *name, void *data);
#define deserialize_data(T, data) (T *) struct_descriptor_deserialize_data(#T, data)
void *struct_descriptor_deserialize_data(char const *name, uint8_arr_t *data);
bool struct_descriptor_set_serializer(char const *name, char const *field, serializer_function_t serializer);
void print_struct_descriptor(struct_descriptor_t *descriptor);
void serialize_64bits(void *data);
void serialize_32bits(void *data);
void serialize_16bits(void *data);
void serialize_generic(void *data);