Skip to content

Commit f409c9d

Browse files
committed
Temporary check-in for backup.
1 parent 2222fd0 commit f409c9d

File tree

1 file changed

+249
-0
lines changed

1 file changed

+249
-0
lines changed

src/include/ptk_serialization.h

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,255 @@ uint64_t ptk_bswap64(uint64_t value);
103103
bool ptk_is_little_endian(void);
104104
bool ptk_is_big_endian(void);
105105

106+
107+
108+
//=============================================================================
109+
// TYPE-SAFE SERIALIZATION API
110+
//=============================================================================
111+
112+
// Forward declarations for type-safe serialization
113+
typedef enum {
114+
PTK_BUF_TYPE_U8 = 1, // uint8_t
115+
PTK_BUF_TYPE_U16, // uint16_t
116+
PTK_BUF_TYPE_U32, // uint32_t
117+
PTK_BUF_TYPE_U64, // uint64_t
118+
PTK_BUF_TYPE_S8, // int8_t
119+
PTK_BUF_TYPE_S16, // int16_t
120+
PTK_BUF_TYPE_S32, // int32_t
121+
PTK_BUF_TYPE_S64, // int64_t
122+
PTK_BUF_TYPE_FLOAT, // float
123+
PTK_BUF_TYPE_DOUBLE, // double
124+
PTK_BUF_TYPE_SERIALIZABLE, // struct ptk_serializable*
125+
} ptk_buf_type_t;
126+
127+
typedef enum { PTK_BUF_LITTLE_ENDIAN = 0, PTK_BUF_BIG_ENDIAN = 1 } ptk_buf_endian_t;
128+
129+
/**
130+
* Implementation function for type-safe serialization
131+
*
132+
* Moves the cursor forward by the size of the serialized data.
133+
*
134+
* @param buf Buffer to write to
135+
* @param endian Endianness for multi-byte values
136+
* @param count Number of fields to serialize
137+
* @param ... Alternating type_enum, value pairs
138+
* @return Error code
139+
*/
140+
PTK_API extern ptk_err_t ptk_buf_serialize_impl(ptk_buf *buf, ptk_buf_endian_t endian, ptk_buf_size_t count, ...);
141+
142+
/**
143+
* Implementation function for type-safe deserialization
144+
*
145+
* Moves the cursor forward by the size of the deserialized data.
146+
*
147+
* Leaves the cursor unchanged if peek is true.
148+
*
149+
* Leaves the cursor unchanged if there is an error.
150+
*
151+
* @param buf Buffer to read from
152+
* @param peek Whether to peek (don't advance buffer position)
153+
* @param endian Endianness for multi-byte values
154+
* @param count Number of fields to deserialize
155+
* @param ... Alternating type_enum, pointer pairs
156+
* @return Error code
157+
*/
158+
PTK_API extern ptk_err_t ptk_buf_deserialize_impl(ptk_buf *buf, bool peek, ptk_buf_endian_t endian, ptk_buf_size_t count, ...);
159+
160+
/* byte swap helpers */
161+
162+
/**
163+
* @brief swap the bytes in each 16-bit word
164+
*
165+
* @param value
166+
* @return ptk_u32_t
167+
*/
168+
static inline ptk_u32_t ptk_buf_byte_swap_u32(ptk_u32_t value) {
169+
return ((value & 0x000000FF) << 24) | ((value & 0x0000FF00) << 8) | ((value & 0x00FF0000) >> 8)
170+
| ((value & 0xFF000000) >> 24);
171+
}
172+
173+
static inline ptk_u64_t ptk_buf_byte_swap_u64(ptk_u64_t value) {
174+
return ((value & 0x00000000000000FFULL) << 56) | ((value & 0x000000000000FF00ULL) << 40)
175+
| ((value & 0x0000000000FF0000ULL) << 24) | ((value & 0x00000000FF000000ULL) << 8)
176+
| ((value & 0x000000FF00000000ULL) >> 8) | ((value & 0x0000FF0000000000ULL) >> 24)
177+
| ((value & 0x00FF000000000000ULL) >> 40) | ((value & 0xFF00000000000000ULL) >> 56);
178+
}
179+
180+
//=============================================================================
181+
// TYPE-SAFE SERIALIZATION MACROS
182+
//=============================================================================
183+
184+
/**
185+
* Map C types to type enumeration using _Generic
186+
*/
187+
#define PTK_BUF_TYPE_OF(x) \
188+
_Generic((x), \
189+
uint8_t: PTK_BUF_TYPE_U8, \
190+
uint16_t: PTK_BUF_TYPE_U16, \
191+
uint32_t: PTK_BUF_TYPE_U32, \
192+
uint64_t: PTK_BUF_TYPE_U64, \
193+
int8_t: PTK_BUF_TYPE_S8, \
194+
int16_t: PTK_BUF_TYPE_S16, \
195+
int32_t: PTK_BUF_TYPE_S32, \
196+
int64_t: PTK_BUF_TYPE_S64, \
197+
float: PTK_BUF_TYPE_FLOAT, \
198+
double: PTK_BUF_TYPE_DOUBLE, \
199+
ptk_serializable_t *: PTK_BUF_TYPE_SERIALIZABLE, \
200+
ptk_serializable_t: PTK_BUF_TYPE_SERIALIZABLE, \
201+
default: 0)
202+
203+
/**
204+
* For pointers, handle serializable objects specially, dereference others
205+
*/
206+
#define PTK_BUF_TYPE_OF_PTR(ptr) \
207+
_Generic((ptr), ptk_serializable_t * *: PTK_BUF_TYPE_SERIALIZABLE, default: PTK_BUF_TYPE_OF(*(ptr)))
208+
209+
//=============================================================================
210+
// ARGUMENT COUNTING MACROS
211+
//=============================================================================
212+
213+
/**
214+
* Count arguments (up to 64 arguments, so 32 fields max)
215+
*/
216+
#define PTK_BUF_ARG_COUNT(...) \
217+
PTK_BUF_ARG_COUNT_IMPL(__VA_ARGS__, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, \
218+
42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, \
219+
17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
220+
221+
#define PTK_BUF_ARG_COUNT_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, \
222+
_22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
223+
_41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, \
224+
_60, _61, _62, _63, _64, N, ...) \
225+
N
226+
227+
//=============================================================================
228+
// TYPE ENUMERATION EXPANSION MACROS
229+
//=============================================================================
230+
231+
/**
232+
* Expand arguments to type, value pairs
233+
* For each argument, generate: PTK_BUF_TYPE_OF(arg), arg
234+
*/
235+
236+
// 1 argument
237+
#define PTK_BUF_EXPAND_1(a) PTK_BUF_TYPE_OF(a), (a)
238+
239+
// 2 arguments
240+
#define PTK_BUF_EXPAND_2(a, b) PTK_BUF_TYPE_OF(a), (a), PTK_BUF_TYPE_OF(b), (b)
241+
242+
// 3 arguments
243+
#define PTK_BUF_EXPAND_3(a, b, c) PTK_BUF_TYPE_OF(a), (a), PTK_BUF_TYPE_OF(b), (b), PTK_BUF_TYPE_OF(c), (c)
244+
245+
// 4 arguments
246+
#define PTK_BUF_EXPAND_4(a, b, c, d) \
247+
PTK_BUF_TYPE_OF(a), (a), PTK_BUF_TYPE_OF(b), (b), PTK_BUF_TYPE_OF(c), (c), PTK_BUF_TYPE_OF(d), (d)
248+
249+
// 5 arguments
250+
#define PTK_BUF_EXPAND_5(a, b, c, d, e) \
251+
PTK_BUF_TYPE_OF(a), (a), PTK_BUF_TYPE_OF(b), (b), PTK_BUF_TYPE_OF(c), (c), PTK_BUF_TYPE_OF(d), (d), PTK_BUF_TYPE_OF(e), (e)
252+
253+
// 6 arguments (EIP header size)
254+
#define PTK_BUF_EXPAND_6(a, b, c, d, e, f) \
255+
PTK_BUF_TYPE_OF(a), (a), PTK_BUF_TYPE_OF(b), (b), PTK_BUF_TYPE_OF(c), (c), PTK_BUF_TYPE_OF(d), (d), PTK_BUF_TYPE_OF(e), (e), \
256+
PTK_BUF_TYPE_OF(f), (f)
257+
258+
// 7 arguments
259+
#define PTK_BUF_EXPAND_7(a, b, c, d, e, f, g) \
260+
PTK_BUF_TYPE_OF(a), (a), PTK_BUF_TYPE_OF(b), (b), PTK_BUF_TYPE_OF(c), (c), PTK_BUF_TYPE_OF(d), (d), PTK_BUF_TYPE_OF(e), (e), \
261+
PTK_BUF_TYPE_OF(f), (f), PTK_BUF_TYPE_OF(g), (g)
262+
263+
// 8 arguments
264+
#define PTK_BUF_EXPAND_8(a, b, c, d, e, f, g, h) \
265+
PTK_BUF_TYPE_OF(a), (a), PTK_BUF_TYPE_OF(b), (b), PTK_BUF_TYPE_OF(c), (c), PTK_BUF_TYPE_OF(d), (d), PTK_BUF_TYPE_OF(e), (e), \
266+
PTK_BUF_TYPE_OF(f), (f), PTK_BUF_TYPE_OF(g), (g), PTK_BUF_TYPE_OF(h), (h)
267+
268+
// 10 arguments
269+
#define PTK_BUF_EXPAND_10(a, b, c, d, e, f, g, h, i, j) \
270+
PTK_BUF_TYPE_OF(a), (a), PTK_BUF_TYPE_OF(b), (b), PTK_BUF_TYPE_OF(c), (c), PTK_BUF_TYPE_OF(d), (d), PTK_BUF_TYPE_OF(e), (e), \
271+
PTK_BUF_TYPE_OF(f), (f), PTK_BUF_TYPE_OF(g), (g), PTK_BUF_TYPE_OF(h), (h), PTK_BUF_TYPE_OF(i), (i), PTK_BUF_TYPE_OF(j), \
272+
(j)
273+
274+
// Add more as needed up to 32 arguments...
275+
276+
/**
277+
* Select appropriate expansion macro based on argument count
278+
*/
279+
#define PTK_BUF_EXPAND_SELECT(N) PTK_BUF_EXPAND_##N
280+
#define PTK_BUF_EXPAND_DISPATCH(N) PTK_BUF_EXPAND_SELECT(N)
281+
#define PTK_BUF_EXPAND(...) PTK_BUF_EXPAND_DISPATCH(PTK_BUF_ARG_COUNT(__VA_ARGS__))(__VA_ARGS__)
282+
283+
//=============================================================================
284+
// POINTER TYPE ENUMERATION FOR DESERIALIZATION
285+
//=============================================================================
286+
287+
/**
288+
* Expand pointer arguments to type, pointer pairs
289+
* For each pointer argument, generate: PTK_BUF_TYPE_OF_PTR(ptr), ptr
290+
*/
291+
292+
// 1 pointer
293+
#define PTK_BUF_EXPAND_PTR_1(a) PTK_BUF_TYPE_OF_PTR(a), (a)
294+
295+
// 2 pointers
296+
#define PTK_BUF_EXPAND_PTR_2(a, b) PTK_BUF_TYPE_OF_PTR(a), (a), PTK_BUF_TYPE_OF_PTR(b), (b)
297+
298+
// 3 pointers
299+
#define PTK_BUF_EXPAND_PTR_3(a, b, c) PTK_BUF_TYPE_OF_PTR(a), (a), PTK_BUF_TYPE_OF_PTR(b), (b), PTK_BUF_TYPE_OF_PTR(c), (c)
300+
301+
// 4 pointers
302+
#define PTK_BUF_EXPAND_PTR_4(a, b, c, d) \
303+
PTK_BUF_TYPE_OF_PTR(a), (a), PTK_BUF_TYPE_OF_PTR(b), (b), PTK_BUF_TYPE_OF_PTR(c), (c), PTK_BUF_TYPE_OF_PTR(d), (d)
304+
305+
// 5 pointers
306+
#define PTK_BUF_EXPAND_PTR_5(a, b, c, d, e) \
307+
PTK_BUF_TYPE_OF_PTR(a), (a), PTK_BUF_TYPE_OF_PTR(b), (b), PTK_BUF_TYPE_OF_PTR(c), (c), PTK_BUF_TYPE_OF_PTR(d), (d), \
308+
PTK_BUF_TYPE_OF_PTR(e), (e)
309+
310+
// 6 pointers (EIP header size)
311+
#define PTK_BUF_EXPAND_PTR_6(a, b, c, d, e, f) \
312+
PTK_BUF_TYPE_OF_PTR(a), (a), PTK_BUF_TYPE_OF_PTR(b), (b), PTK_BUF_TYPE_OF_PTR(c), (c), PTK_BUF_TYPE_OF_PTR(d), (d), \
313+
PTK_BUF_TYPE_OF_PTR(e), (e), PTK_BUF_TYPE_OF_PTR(f), (f)
314+
315+
// 7 pointers
316+
#define PTK_BUF_EXPAND_PTR_7(a, b, c, d, e, f, g) \
317+
PTK_BUF_TYPE_OF_PTR(a), (a), PTK_BUF_TYPE_OF_PTR(b), (b), PTK_BUF_TYPE_OF_PTR(c), (c), PTK_BUF_TYPE_OF_PTR(d), (d), \
318+
PTK_BUF_TYPE_OF_PTR(e), (e), PTK_BUF_TYPE_OF_PTR(f), (f), PTK_BUF_TYPE_OF_PTR(g), (g)
319+
320+
// 8 pointers
321+
#define PTK_BUF_EXPAND_PTR_8(a, b, c, d, e, f, g, h) \
322+
PTK_BUF_TYPE_OF_PTR(a), (a), PTK_BUF_TYPE_OF_PTR(b), (b), PTK_BUF_TYPE_OF_PTR(c), (c), PTK_BUF_TYPE_OF_PTR(d), (d), \
323+
PTK_BUF_TYPE_OF_PTR(e), (e), PTK_BUF_TYPE_OF_PTR(f), (f), PTK_BUF_TYPE_OF_PTR(g), (g), PTK_BUF_TYPE_OF_PTR(h), (h)
324+
325+
// Add more as needed...
326+
327+
/**
328+
* Select appropriate pointer expansion macro
329+
*/
330+
#define PTK_BUF_EXPAND_PTR_SELECT(N) PTK_BUF_EXPAND_PTR_##N
331+
#define PTK_BUF_EXPAND_PTR_DISPATCH(N) PTK_BUF_EXPAND_PTR_SELECT(N)
332+
#define PTK_BUF_EXPAND_PTR(...) PTK_BUF_EXPAND_PTR_DISPATCH(PTK_BUF_ARG_COUNT(__VA_ARGS__))(__VA_ARGS__)
333+
334+
//=============================================================================
335+
// USER-FACING MACROS
336+
//=============================================================================
337+
338+
/**
339+
* Serialize variables to buffer with automatic type detection and counting
340+
*
341+
* Usage: ptk_buf_serialize(buffer, PTK_BUF_LITTLE_ENDIAN, var1, var2, var3, ...)
342+
*/
343+
#define ptk_buf_serialize(buf, endian, ...) \
344+
ptk_buf_serialize_impl((buf), (endian), PTK_BUF_ARG_COUNT(__VA_ARGS__), PTK_BUF_EXPAND(__VA_ARGS__))
345+
346+
/**
347+
* Deserialize from buffer to variables with automatic type detection and counting
348+
*
349+
* Usage: ptk_buf_deserialize(buffer, false, PTK_BUF_LITTLE_ENDIAN, &var1, &var2, &var3, ...)
350+
*/
351+
#define ptk_buf_deserialize(buf, peek, endian, ...) \
352+
ptk_buf_deserialize_impl((buf), (peek), (endian), PTK_BUF_ARG_COUNT(__VA_ARGS__), PTK_BUF_EXPAND_PTR(__VA_ARGS__))
353+
354+
106355
#ifdef __cplusplus
107356
}
108357
#endif

0 commit comments

Comments
 (0)