3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: lib/ntdll/rtl/bitmap.c
6 * PURPOSE: Bitmap functions
8 * 20/08/99 Created by Eric Kohl
11 #include <ddk/ntddk.h>
15 #include <ntdll/ntdll.h>
17 #define ALIGN(x,align) (((x)+(align)-1) / (align))
20 /* FUNCTIONS *****************************************************************/
28 PRTL_BITMAP BitMapHeader,
33 BitMapHeader->SizeOfBitMap = SizeOfBitMap;
34 BitMapHeader->Buffer = BitMapBuffer;
44 PRTL_BITMAP BitMapHeader,
49 ULONG Size = BitMapHeader->SizeOfBitMap;
54 if (StartingIndex >= Size ||
56 (StartingIndex + Length > Size))
59 Ptr = (PUCHAR)BitMapHeader->Buffer + (StartingIndex / 8);
62 /* get bit shift in current byte */
63 Shift = StartingIndex & 7;
65 /* get number of bits to check in current byte */
66 Count = (Length > 8 - Shift) ? 8 - Shift : Length;
69 if (*Ptr & (~(0xFF << Count) << Shift))
74 StartingIndex += Count;
87 PRTL_BITMAP BitMapHeader,
92 ULONG Size = BitMapHeader->SizeOfBitMap;
98 if (StartingIndex >= Size ||
100 (StartingIndex + Length > Size))
103 Ptr = (PUCHAR)BitMapHeader->Buffer + (StartingIndex / 8);
106 /* get bit shift in current byte */
107 Shift = StartingIndex & 7;
109 /* get number of bits to check in current byte */
110 Count = (Length > 8 - Shift) ? 8 - Shift : Length;
112 /* bulid check byte */
113 Check = ~(0xFF << Count) << Shift;
116 if ((*Ptr & Check) != Check)
121 StartingIndex += Count;
134 IN OUT PRTL_BITMAP BitMapHeader
137 memset (BitMapHeader->Buffer,
139 ALIGN(BitMapHeader->SizeOfBitMap, 8));
149 PRTL_BITMAP BitMapHeader,
154 ULONG Size = BitMapHeader->SizeOfBitMap;
159 if (StartingIndex >= Size || NumberToClear == 0)
162 if (StartingIndex + NumberToClear > Size)
163 NumberToClear = Size - StartingIndex;
165 Ptr = (PCHAR)(BitMapHeader->Buffer + (StartingIndex / 8));
166 while (NumberToClear)
168 /* bit shift in current byte */
169 Shift = StartingIndex & 7;
171 /* number of bits to change in current byte */
172 Count = (NumberToClear > 8 - Shift ) ? 8 - Shift : NumberToClear;
175 *Ptr &= ~(~(0xFF << Count) << Shift);
178 NumberToClear -= Count;
179 StartingIndex += Count;
190 PRTL_BITMAP BitMapHeader,
195 ULONG Size = BitMapHeader->SizeOfBitMap;
201 if (NumberToFind > Size || NumberToFind == 0)
204 if (HintIndex >= Size)
208 Ptr = (PCHAR)BitMapHeader->Buffer + (Index / 8);
209 Mask = 1 << (Index & 7);
211 while (HintIndex < Size)
213 /* count clear bits */
214 for (Count = 0; Index < Size && ~*Ptr & Mask; Index++)
216 if (++Count >= NumberToFind)
227 for (; Index < Size && *Ptr & Mask; Index++)
248 RtlFindClearBitsAndSet (
249 PRTL_BITMAP BitMapHeader,
256 Index = RtlFindClearBits (BitMapHeader,
259 if (Index != (ULONG)-1)
260 RtlSetBits (BitMapHeader,
270 RtlFindFirstRunClear (
271 PRTL_BITMAP BitMapHeader,
275 ULONG Size = BitMapHeader->SizeOfBitMap;
281 if (*StartingIndex > Size)
283 *StartingIndex = (ULONG)-1;
287 Index = *StartingIndex;
288 Ptr = (PCHAR)BitMapHeader->Buffer + (Index / 8);
289 Mask = 1 << (Index & 7);
292 for (; Index < Size && *Ptr & Mask; Index++)
302 /* return index of first clear bit */
305 *StartingIndex = (ULONG)-1;
309 *StartingIndex = Index;
311 /* count clear bits */
312 for (Count = 0; Index < Size && ~*Ptr & Mask; Index++)
330 PRTL_BITMAP BitMapHeader,
334 ULONG Size = BitMapHeader->SizeOfBitMap;
340 if (*StartingIndex > Size)
342 *StartingIndex = (ULONG)-1;
346 Index = *StartingIndex;
347 Ptr = (PCHAR)BitMapHeader->Buffer + (Index / 8);
348 Mask = 1 << (Index & 7);
350 /* skip clear bits */
351 for (; Index < Size && ~*Ptr & Mask; Index++)
361 /* return index of first set bit */
364 *StartingIndex = (ULONG)-1;
368 *StartingIndex = Index;
371 for (Count = 0; Index < Size && *Ptr & Mask; Index++)
391 RtlFindLongestRunClear (
392 PRTL_BITMAP BitMapHeader,
396 ULONG Size = BitMapHeader->SizeOfBitMap;
397 PCHAR Ptr = (PCHAR)BitMapHeader->Buffer;
409 /* count clear bits */
410 for (Count = 0; Index < Size && ~*Ptr & Mask; Index++)
422 for (; Index < Size && *Ptr & Mask; Index++)
440 *StartingIndex = Maxstart;
451 RtlFindLongestRunSet (
452 PRTL_BITMAP BitMapHeader,
456 ULONG Size = BitMapHeader->SizeOfBitMap;
457 PCHAR Ptr = (PCHAR)BitMapHeader->Buffer;
470 for (Count = 0; Index < Size && *Ptr & Mask; Index++)
481 /* skip clear bits */
482 for (; Index < Size && ~*Ptr & Mask; Index++)
500 *StartingIndex = Maxstart;
512 PRTL_BITMAP BitMapHeader,
517 ULONG Size = BitMapHeader->SizeOfBitMap;
523 if (NumberToFind > Size || NumberToFind == 0)
526 if (HintIndex >= Size)
530 Ptr = (PCHAR)BitMapHeader->Buffer + (Index / 8);
531 Mask = 1 << (Index & 7);
533 while (HintIndex < Size)
536 for (Count = 0; Index < Size && *Ptr & Mask; Index++)
538 if (++Count >= NumberToFind)
548 /* skip clear bits */
549 for (; Index < Size && ~*Ptr & Mask; Index++)
570 RtlFindSetBitsAndClear (
571 PRTL_BITMAP BitMapHeader,
578 Index = RtlFindSetBits (BitMapHeader,
581 if (Index != (ULONG)-1)
582 RtlClearBits (BitMapHeader,
595 RtlNumberOfClearBits (
596 PRTL_BITMAP BitMapHeader
599 PCHAR Ptr = (PCHAR)BitMapHeader->Buffer;
600 ULONG Size = BitMapHeader->SizeOfBitMap;
605 for (Mask = 1, Index = 0, Count = 0; Index < Size; Index++)
628 PRTL_BITMAP BitMapHeader
631 PCHAR Ptr = (PCHAR)BitMapHeader->Buffer;
632 ULONG Size = BitMapHeader->SizeOfBitMap;
637 for (Mask = 1, Index = 0, Count = 0; Index < Size; Index++)
660 IN OUT PRTL_BITMAP BitMapHeader
663 memset (BitMapHeader->Buffer,
665 ALIGN(BitMapHeader->SizeOfBitMap, 8));
675 PRTL_BITMAP BitMapHeader,
680 ULONG Size = BitMapHeader->SizeOfBitMap;
685 if (StartingIndex >= Size || NumberToSet == 0)
688 if (StartingIndex + NumberToSet > Size)
689 NumberToSet = Size - StartingIndex;
691 Ptr = (PCHAR)BitMapHeader->Buffer + (StartingIndex / 8);
694 /* bit shift in current byte */
695 Shift = StartingIndex & 7;
697 /* number of bits to change in current byte */
698 Count = (NumberToSet > 8 - Shift) ? 8 - Shift : NumberToSet;
701 *Ptr |= ~(0xFF << Count) << Shift;
704 NumberToSet -= Count;
705 StartingIndex += Count;