-
Notifications
You must be signed in to change notification settings - Fork 1
/
bitmap.c
100 lines (81 loc) · 1.99 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
#include <stdlib.h>
#include <windows.h>
#include "general.h"
#include "debug.h"
static unsigned MxfsCountWordBits(uint32_t v)
{
v = v - ((v >> 1) & 0x55555555); // reuse input as temporary
v = (v & 0x33333333) + ((v >> 2) & 0x33333333); // temp
return (((v + (v >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24; // count
}
unsigned MxfsCountBitsSet(MX_BITMAP *Bm)
{
unsigned i, Result = 0;
for(i = 0; i < Bm->Size; ++i)
Result += MxfsCountWordBits(Bm->Buffer[i]);
return Result;
}
void MxfsInitBitmap(MX_BITMAP *Bm, uint32_t *Buffer, unsigned BitsCount)
{
ASSERT(MxfsCountWordBits(0) == 0);
ASSERT(MxfsCountWordBits(0x11111111) == 8);
ASSERT(MxfsCountWordBits(0xFFFFFFFF) == 32);
Bm->Buffer = Buffer;
Bm->Size = BitsCount / 32;
Bm->Hint = 0;
}
void MxfsDestroyBitmap(MX_BITMAP *Bm)
{
MxfsFree(Bm->Buffer);
Bm->Buffer = NULL;
}
int MxfsFindClearBit(MX_BITMAP *Bm)
{
unsigned i, j;
for(i = 0; i < Bm->Size; ++i)
{
if(Bm->Buffer[i] != 0xFFFFFFFF)
break;
}
if(i == Bm->Size)
{
ERR("Bitmap is full!\n");
return -ERROR_DISK_FULL;
}
for(j = 0; j < 32; ++j)
{
unsigned Bit = Bm->Buffer[i] & (1 << j);
if(!Bit) break;
}
ASSERT(j < 32);
return i * 32 + j;
}
int MxfsSetBit(MX_BITMAP *Bm, unsigned Bit)
{
unsigned i = Bit / 32;
Bit = Bit & 31;
if(i >= Bm->Size)
return -ERROR_INVALID_PARAMETER;
Bm->Buffer[i] |= (1 << Bit);
return 0;
}
int MxfsClearBit(MX_BITMAP *Bm, unsigned Bit)
{
unsigned i = Bit / 32;
Bit = Bit & 31;
if(i >= Bm->Size)
return -ERROR_INVALID_PARAMETER;
Bm->Buffer[i] &= ~(1 << Bit);
return 0;
}
int MxfsGetBit(MX_BITMAP *Bm, unsigned Bit)
{
unsigned i = Bit / 32;
Bit = Bit & 31;
if(i >= Bm->Size)
return -ERROR_INVALID_PARAMETER;
if(Bm->Buffer[i] & (1 << Bit))
return 1;
else
return 0;
}