-
Notifications
You must be signed in to change notification settings - Fork 0
/
bitmap.c
118 lines (95 loc) · 2.13 KB
/
bitmap.c
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
#include "bitmap.h"
#include <stdlib.h>
#include <string.h>
/*if return value < 0, return the return_value in argument.*/
typedef int (* op_block_t)(uint8_t* cur_tab, int mask, uintptr_t* return_value);
static inline uintptr_t bitmap_each_byte(uint8_t* tab, int start, int len, op_block_t op_block)
{
int end, mask, end1;
uintptr_t result = 0;
end = start + len;
tab += start >> 3;
mask = 0xff << (start & 7);
if ((start & ~7) == (end & ~7)) {
if (start < end) {
mask &= ~(0xff << (end & 7));
if (op_block(tab, mask, &result) < 0)
return result;
}
}
else {
if (op_block(tab, mask, &result) < 0)
return result;
++tab;
start = (start + 8) & ~7;
end1 = end & ~7;
while (start < end1) {
if (op_block(tab, 0xff, &result) < 0)
return result;
++tab;
start += 8;
}
if (start < end) {
mask = ~(0xff << (end & 7));
if (op_block(tab, mask, &result) < 0)
return result;
}
}
return result;
}
static inline int bitmap_clear(uint8_t* cur_tab, int mask, uintptr_t* return_value)
{
*cur_tab &= ~mask;
return 0;
}
static inline int bitmap_set(uint8_t* cur_tab, int mask, uintptr_t* return_value)
{
*cur_tab |= mask;
}
static inline int bitmap_get(uint8_t* cur_tab, int mask, uintptr_t* return_value)
{
if ((*cur_tab & mask) == 0) {
return 0;
} else {
*return_value = 1;
return -1;
}
}
uint8_t* build_bitmap(int bit_size)
{
const int bit_tab_length = (bit_size + 8) >> 3;
uint8_t* bit_tab = malloc(bit_tab_length);
if (0 == bit_tab)
return 0;
memset(bit_tab, 0, bit_tab_length);
return bit_tab;
}
void destroy_bitmap(uint8_t** _bit_tab)
{
uint8_t* bit_tab = 0;
if (0 == _bit_tab)
return;
bit_tab = *_bit_tab;
if (bit_tab)
{
free(bit_tab);
bit_tab = 0;
}
*_bit_tab = 0;
}
void clear_bits(uint8_t *tab, int start, int len)
{
bitmap_each_byte(tab, start, len, bitmap_clear);
}
void set_bits(uint8_t* tab, int start, int len)
{
bitmap_each_byte(tab, start, len, bitmap_set);
}
int get_bit(uint8_t* tab, int pos)
{
return bitmap_each_byte(tab, pos, 1, bitmap_get);
}
int is_any_bits_set(uint8_t* tab, int start, int len)
{
return bitmap_each_byte(tab, start, len, bitmap_get);
}