1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
#pragma once
/** @file bin.h */
/**
* helper file for binary data
*
* - fix endianness with functions inspired by UNIX arpa/inet.h
* - convert uint16_t and uint32_t to cd_s_bin
*/
#include <stdint.h>
#include <stdlib.h>
#include "memory.h"
#ifdef __cplusplus
extern "C" {
#endif
extern uint8_t g_cd_endianness;
/** @brief cast `in.data` to `type out` */
#define CD_CAST_BIN(type, in, out) type *out = (type *)&in->data;
#define CD_CREATE_MSG_BIN(type, normal, bin) CD_CREATE_MSG_SIZE_BIN(type, sizeof(type), normal, bin)
/** @brief create cd_s_bin struct with space for struct and cast data field of cd_s_bin to struct pointer */
#define CD_CREATE_MSG_SIZE_BIN(type, size, normal, bin) \
cd_s_bin *bin = CD_MALLOC(sizeof(cd_s_bin) + size); \
bin->bytes = size; \
type *normal = (type *)&bin->data;
// TODO: document above macro but better
/** @brief hold binary data with fixed size */
typedef struct {
uint16_t bytes; /** @brief data size */
uint8_t data[]; /** @brief data */
} cd_s_bin;
/** @brief allocate new cd_s_bin struct and fill with `*data` for `bytes` bytes */
cd_s_bin *cd_bin_s_alloc(uint16_t bytes, uint8_t *data);
/** @brief concatenate 2 cd_s_bin structs, deallocates `a` and `b` */
cd_s_bin *cd_bin_s_cat(cd_s_bin *a, cd_s_bin *b);
cd_s_bin *cd_bin_from_uint8_t(uint8_t data);
cd_s_bin *cd_bin_from_uint16_t(uint16_t data);
cd_s_bin *cd_bin_from_uint32_t(uint32_t data);
/** @brief convert 32-bit value from host endian to network (big-endian) */
uint32_t cd_bin_hton32(uint32_t h32);
/** @brief convert 16-bit value from host endian to network (big-endian) */
uint16_t cd_bin_hton16(uint16_t h16);
/** @brief convert 32-bit value from network (big-endian) to host endian */
uint32_t cd_bin_ntoh32(uint32_t n32);
/** @brief convert 16-bit value from network (big-endian) to host endian */
uint16_t cd_bin_ntoh16(uint16_t n16);
/**
* @brief convert (8*s)-bit value from network (big-endian) to host endian
* (dynamic size)
*
* @param n pointer to number
* @param s size of number in bytes
*
* @return 32-bit integer regardless of `s`
*
* this function is exclusively used by the CD_DYN_MEMBER_SIZEOF macro in
* shared/protocol.c
*/
uint32_t cd_bin_ntohd(uint8_t *n, size_t s);
uint32_t cd_bin_htond(uint8_t *h, size_t s);
/** @brief replace 32-bit value from host endian to network (big-endian) */
void cd_bin_repl_hton32(uint32_t *h32);
/** @brief replace 16-bit value from host endian to network (big-endian) */
void cd_bin_repl_hton16(uint16_t *h16);
/** @brief replace 32-bit value from network (big-endian) to host endian */
void cd_bin_repl_ntoh32(uint32_t *n32);
/** @brief replace 16-bit value from network (big-endian) to host endian */
void cd_bin_repl_ntoh16(uint16_t *n16);
#ifdef __cplusplus
}
#endif
|