unaligned.h 2.76 KB
Newer Older
1
/* SPDX-License-Identifier: LGPL-2.1+ */
Dan Winship's avatar
Dan Winship committed
2 3
#pragma once

4
#include <endian.h>
Dan Winship's avatar
Dan Winship committed
5 6
#include <stdint.h>

7 8
/* BE */

Dan Winship's avatar
Dan Winship committed
9
static inline uint16_t unaligned_read_be16(const void *_u) {
10
        const struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u;
Dan Winship's avatar
Dan Winship committed
11

12
        return be16toh(u->x);
Dan Winship's avatar
Dan Winship committed
13 14 15
}

static inline uint32_t unaligned_read_be32(const void *_u) {
16
        const struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u;
Dan Winship's avatar
Dan Winship committed
17

18
        return be32toh(u->x);
Dan Winship's avatar
Dan Winship committed
19 20 21
}

static inline uint64_t unaligned_read_be64(const void *_u) {
22
        const struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u;
Dan Winship's avatar
Dan Winship committed
23

24
        return be64toh(u->x);
Dan Winship's avatar
Dan Winship committed
25 26 27
}

static inline void unaligned_write_be16(void *_u, uint16_t a) {
28
        struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u;
Dan Winship's avatar
Dan Winship committed
29

30
        u->x = be16toh(a);
Dan Winship's avatar
Dan Winship committed
31 32 33
}

static inline void unaligned_write_be32(void *_u, uint32_t a) {
34
        struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u;
Dan Winship's avatar
Dan Winship committed
35

36
        u->x = be32toh(a);
Dan Winship's avatar
Dan Winship committed
37 38 39
}

static inline void unaligned_write_be64(void *_u, uint64_t a) {
40
        struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u;
Dan Winship's avatar
Dan Winship committed
41

42
        u->x = be64toh(a);
Dan Winship's avatar
Dan Winship committed
43
}
44 45 46 47

/* LE */

static inline uint16_t unaligned_read_le16(const void *_u) {
48
        const struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u;
49

50
        return le16toh(u->x);
51 52 53
}

static inline uint32_t unaligned_read_le32(const void *_u) {
54
        const struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u;
55

56
        return le32toh(u->x);
57 58 59
}

static inline uint64_t unaligned_read_le64(const void *_u) {
60
        const struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u;
61

62
        return le64toh(u->x);
63 64 65
}

static inline void unaligned_write_le16(void *_u, uint16_t a) {
66
        struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u;
67

68
        u->x = le16toh(a);
69 70 71
}

static inline void unaligned_write_le32(void *_u, uint32_t a) {
72
        struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u;
73

74
        u->x = le32toh(a);
75 76 77
}

static inline void unaligned_write_le64(void *_u, uint64_t a) {
78
        struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u;
79

80
        u->x = le64toh(a);
81
}
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99

#if __BYTE_ORDER == __BIG_ENDIAN
#define unaligned_read_ne16 unaligned_read_be16
#define unaligned_read_ne32 unaligned_read_be32
#define unaligned_read_ne64 unaligned_read_be64

#define unaligned_write_ne16 unaligned_write_be16
#define unaligned_write_ne32 unaligned_write_be32
#define unaligned_write_ne64 unaligned_write_be64
#else
#define unaligned_read_ne16 unaligned_read_le16
#define unaligned_read_ne32 unaligned_read_le32
#define unaligned_read_ne64 unaligned_read_le64

#define unaligned_write_ne16 unaligned_write_le16
#define unaligned_write_ne32 unaligned_write_le32
#define unaligned_write_ne64 unaligned_write_le64
#endif