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 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
/*
* Unaligned Data Accesses -- Generic Version, Network Order
*
* (c) 2000 Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#ifndef _BIRD_UNALIGNED_H_
#define _BIRD_UNALIGNED_H_
/*
* We don't do any clever tricks with unaligned accesses since it's
* virtually impossible to figure out what alignment does the CPU want
* (unaligned accesses can be emulated by the OS which makes them work,
* but unusably slow). We use memcpy and hope GCC will optimize it out
* if possible.
*/
#include "sysdep/unix/endian.h"
#include "lib/string.h"
static inline u8
get_u8(const void *p)
{
return * (u8 *) p;
}
static inline u16
get_u16(const void *p)
{
u16 x;
memcpy(&x, p, 2);
return ntohs(x);
}
static inline u32
get_u24(const void *P)
{
const byte *p = P;
return (p[0] << 16) + (p[1] << 8) + p[2];
}
static inline u32
get_u32(const void *p)
{
u32 x;
memcpy(&x, p, 4);
return ntohl(x);
}
static inline u64
get_u64(const void *p)
{
u32 xh, xl;
memcpy(&xh, p, 4);
memcpy(&xl, p+4, 4);
return (((u64) ntohl(xh)) << 32) | ntohl(xl);
}
static inline void
put_u8(void *p, u8 x)
{
memcpy(p, &x, 1);
}
static inline void
put_u16(void *p, u16 x)
{
x = htons(x);
memcpy(p, &x, 2);
}
static inline void
put_u24(void *p, u32 x)
{
x = htonl(x);
memcpy(p, ((char *) &x) + 1, 3);
}
static inline void
put_u32(void *p, u32 x)
{
x = htonl(x);
memcpy(p, &x, 4);
}
static inline void
put_u64(void *p, u64 x)
{
u32 xh, xl;
xh = htonl(x >> 32);
xl = htonl((u32) x);
memcpy(p, &xh, 4);
memcpy(p+4, &xl, 4);
}
static inline void
get_u32s(const void *p, u32 *x, int n)
{
int i;
memcpy(x, p, 4*n);
for (i = 0; i < n; i++)
x[i] = ntohl(x[i]);
}
static inline void
put_u32s(void *p, const u32 *x, int n)
{
int i;
for (i = 0; i < n; i++)
put_u32((byte *) p + 4*i, x[i]);
}
static inline u32
get_u32he(const void *p)
{
u32 x;
memcpy(&x, p, 4);
return x;
}
static inline void
put_u32he(void *p, u32 x)
{
memcpy(p, &x, 4);
}
#endif
|