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
|
/* bits.c - bitfield extraction code
*
* This file is Copyright (c)2010 by the GPSD project
* BSD terms apply: see the file COPYING in the distribution root for details.
*
* Bitfield extraction functions. In each, start is a bit index - not
* a byte index - and width is a bit width. The width is bounded above by
* 64 bits.
*
* The sbebits() function assumes twos-complement
* arithmetic. ubebits() and sbebits() assume no padding in
* integers.
*/
#include <assert.h>
#include <stdint.h>
#include "bits.h"
#define BITS_PER_BYTE 8
uint64_t ubebits(char buf[], unsigned int start, unsigned int width)
/* extract a (zero-origin) bitfield from the buffer as an unsigned big-endian uint64_t */
{
uint64_t fld = 0;
unsigned int i;
unsigned end;
/*@i1@*/ assert(width <= sizeof(uint64_t) * BITS_PER_BYTE);
for (i = start / BITS_PER_BYTE;
i < (start + width + BITS_PER_BYTE - 1) / BITS_PER_BYTE; i++) {
fld <<= BITS_PER_BYTE;
fld |= (unsigned char)buf[i];
}
end = (start + width) % BITS_PER_BYTE;
if (end != 0) {
fld >>= (BITS_PER_BYTE - end);
}
/*@ -shiftimplementation @*/
fld &= ~(-1LL << width);
/*@ +shiftimplementation @*/
return fld;
}
int64_t sbebits(char buf[], unsigned int start, unsigned int width)
/* extract a bitfield from the buffer as a signed big-endian long */
{
uint64_t fld = ubebits(buf, start, width);
/*@ +relaxtypes */
if (fld & (1LL << (width - 1))) {
/*@ -shiftimplementation @*/
fld |= (-1LL << (width - 1));
/*@ +shiftimplementation @*/
}
return (int64_t)fld;
/*@ -relaxtypes */
}
#ifdef __UNUSED__
u_int16_t swap_u16(u_int16_t i)
/* byte-swap a 16-bit unsigned int */
{
u_int8_t c1, c2;
c1 = i & 255;
c2 = (i >> 8) & 255;
return (c1 << 8) + c2;
}
u_int32_t swap_u32(u_int32_t i)
/* byte-swap a 32-bit unsigned int */
{
u_int8_t c1, c2, c3, c4;
c1 = i & 255;
c2 = (i >> 8) & 255;
c3 = (i >> 16) & 255;
c4 = (i >> 24) & 255;
return ((u_int32_t)c1 << 24) + ((u_int32_t)c2 << 16) + ((u_int32_t)c3 << 8) + c4;
}
u_int64_t swap_u64(u_int64_t i)
/* byte-swap a 64-bit unsigned int */
{
u_int8_t c1, c2, c3, c4, c5, c6, c7, c8;
c1 = i & 255;
c2 = (i >> 8) & 255;
c3 = (i >> 16) & 255;
c4 = (i >> 24) & 255;
c5 = (i >> 32) & 255;
c6 = (i >> 40) & 255;
c7 = (i >> 48) & 255;
c8 = (i >> 56) & 255;
return ((u_int64_t)c1 << 56) +
((u_int64_t)c2 << 48) +
((u_int64_t)c3 << 40) +
((u_int64_t)c4 << 32) +
((u_int64_t)c5 << 24) +
((u_int64_t)c6 << 16) +
((u_int64_t)c7 << 8) +
c8;
}
#endif /* __UNUSED__ */
|