]> git.ipfire.org Git - thirdparty/bird.git/blob - lib/unaligned.h
Merge remote-tracking branch 'origin/master' into mq-filter-stack
[thirdparty/bird.git] / lib / unaligned.h
1 /*
2 * Unaligned Data Accesses -- Generic Version, Network Order
3 *
4 * (c) 2000 Martin Mares <mj@ucw.cz>
5 *
6 * Can be freely distributed and used under the terms of the GNU GPL.
7 */
8
9 #ifndef _BIRD_UNALIGNED_H_
10 #define _BIRD_UNALIGNED_H_
11
12 /*
13 * We don't do any clever tricks with unaligned accesses since it's
14 * virtually impossible to figure out what alignment does the CPU want
15 * (unaligned accesses can be emulated by the OS which makes them work,
16 * but unusably slow). We use memcpy and hope GCC will optimize it out
17 * if possible.
18 */
19
20 #include "sysdep/unix/endian.h"
21 #include "lib/string.h"
22
23 static inline u8
24 get_u8(const void *p)
25 {
26 return * (u8 *) p;
27 }
28
29 static inline u16
30 get_u16(const void *p)
31 {
32 u16 x;
33 memcpy(&x, p, 2);
34 return ntohs(x);
35 }
36
37 static inline u32
38 get_u24(const void *P)
39 {
40 const byte *p = P;
41 return (p[0] << 16) + (p[1] << 8) + p[2];
42 }
43
44 static inline u32
45 get_u32(const void *p)
46 {
47 u32 x;
48 memcpy(&x, p, 4);
49 return ntohl(x);
50 }
51
52 static inline u64
53 get_u64(const void *p)
54 {
55 u32 xh, xl;
56 memcpy(&xh, p, 4);
57 memcpy(&xl, p+4, 4);
58 return (((u64) ntohl(xh)) << 32) | ntohl(xl);
59 }
60
61 static inline void
62 put_u8(void *p, u8 x)
63 {
64 memcpy(p, &x, 1);
65 }
66
67 static inline void
68 put_u16(void *p, u16 x)
69 {
70 x = htons(x);
71 memcpy(p, &x, 2);
72 }
73
74 static inline void
75 put_u24(void *p, u32 x)
76 {
77 x = htonl(x);
78 memcpy(p, ((char *) &x) + 1, 3);
79 }
80
81 static inline void
82 put_u32(void *p, u32 x)
83 {
84 x = htonl(x);
85 memcpy(p, &x, 4);
86 }
87
88 static inline void
89 put_u64(void *p, u64 x)
90 {
91 u32 xh, xl;
92 xh = htonl(x >> 32);
93 xl = htonl((u32) x);
94 memcpy(p, &xh, 4);
95 memcpy(p+4, &xl, 4);
96 }
97
98 static inline void
99 get_u32s(const void *p, u32 *x, int n)
100 {
101 int i;
102 memcpy(x, p, 4*n);
103 for (i = 0; i < n; i++)
104 x[i] = ntohl(x[i]);
105 }
106
107 static inline void
108 put_u32s(void *p, const u32 *x, int n)
109 {
110 int i;
111 for (i = 0; i < n; i++)
112 put_u32((byte *) p + 4*i, x[i]);
113 }
114
115
116 #endif