Move bitmap functions to the shared rtl library.

Implement RtlClearBit, RtlSetBit and RtlTestBit.

svn path=/trunk/; revision=10470
This commit is contained in:
Eric Kohl 2004-08-10 12:00:09 +00:00
parent c4b330cce6
commit f3320ad230
3 changed files with 907 additions and 9 deletions

75
reactos/lib/rtl/bit.c Normal file
View file

@ -0,0 +1,75 @@
/*
* ReactOS kernel
* Copyright (C) 2004 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: bit.c,v 1.1 2004/08/10 12:00:09 ekohl Exp $
*
* PROJECT: ReactOS kernel
* PURPOSE: Runtime code
* FILE: lib/rtl/bit.c
* PROGRAMER: Eric Kohl
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
/* FUNCTIONS ****************************************************************/
/*
* @implemented
*/
CCHAR STDCALL
RtlFindLeastSignificantBit(IN ULONGLONG Set)
{
int i;
if (Set == 0ULL)
return -1;
for (i = 0; i < 64; i++)
{
if (Set & (1 << i))
return (CCHAR)i;
}
return -1;
}
/*
* @implemented
*/
CCHAR STDCALL
RtlFindMostSignificantBit(IN ULONGLONG Set)
{
int i;
if (Set == 0ULL)
return -1;
for (i = 63; i >= 0; i--)
{
if (Set & (1 << i))
return (CCHAR)i;
}
return -1;
}
/* EOF */

821
reactos/lib/rtl/bitmap.c Normal file
View file

@ -0,0 +1,821 @@
/*
* ReactOS kernel
* Copyright (C) 1999-2004 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: bitmap.c,v 1.1 2004/08/10 12:00:09 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: lib/rtl/bitmap.c
* PURPOSE: Bitmap functions
* UPDATE HISTORY:
* 20/08/99 Created by Eric Kohl
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#define NDEBUG
#include <debug.h>
/* MACROS *******************************************************************/
#define ALIGN(x,align) \
(((x)+(align)-1) / (align))
#define MASK(Count, Shift) \
((Count) == 32 ? 0xFFFFFFFF : ~(0xFFFFFFFF << (Count)) << (Shift))
/* FUNCTIONS ****************************************************************/
/*
* @implemented
*/
VOID STDCALL
RtlInitializeBitMap(PRTL_BITMAP BitMapHeader,
PULONG BitMapBuffer,
ULONG SizeOfBitMap)
{
BitMapHeader->SizeOfBitMap = SizeOfBitMap;
BitMapHeader->Buffer = BitMapBuffer;
}
/*
* @implemented
*/
BOOLEAN STDCALL
RtlAreBitsClear(PRTL_BITMAP BitMapHeader,
ULONG StartingIndex,
ULONG Length)
{
ULONG Size;
ULONG Shift;
ULONG Count;
PULONG Ptr;
Size = BitMapHeader->SizeOfBitMap;
if (StartingIndex >= Size ||
!Length ||
(StartingIndex + Length > Size))
return FALSE;
Ptr = (PULONG)BitMapHeader->Buffer + (StartingIndex / 32);
while (Length)
{
/* Get bit shift in current ulong */
Shift = StartingIndex & 0x1F;
/* Get number of bits to check in current ulong */
Count = (Length > 32 - Shift) ? 32 - Shift : Length;
/* Check ulong */
if (*Ptr++ & MASK(Count, Shift))
return FALSE;
Length -= Count;
StartingIndex += Count;
}
return TRUE;
}
/*
* @implemented
*/
BOOLEAN STDCALL
RtlAreBitsSet(PRTL_BITMAP BitMapHeader,
ULONG StartingIndex,
ULONG Length)
{
ULONG Size;
ULONG Shift;
ULONG Count;
PULONG Ptr;
Size = BitMapHeader->SizeOfBitMap;
if (StartingIndex >= Size ||
Length == 0 ||
(StartingIndex + Length > Size))
return FALSE;
Ptr = (PULONG)BitMapHeader->Buffer + (StartingIndex / 32);
while (Length)
{
/* Get bit shift in current ulong */
Shift = StartingIndex & 0x1F;
/* Get number of bits to check in current ulong */
Count = (Length > 32 - Shift) ? 32 - Shift : Length;
/* Check ulong */
if (~*Ptr++ & MASK(Count, Shift))
return FALSE;
Length -= Count;
StartingIndex += Count;
}
return TRUE;
}
/*
* @implemented
*/
VOID STDCALL
RtlClearAllBits(IN OUT PRTL_BITMAP BitMapHeader)
{
memset(BitMapHeader->Buffer,
0x00,
ALIGN(BitMapHeader->SizeOfBitMap, 8));
}
/*
* @implemented
*/
VOID STDCALL
RtlClearBit(PRTL_BITMAP BitMapHeader,
ULONG BitNumber)
{
PULONG Ptr;
if (BitNumber >= BitMapHeader->SizeOfBitMap)
return;
Ptr = (PULONG)BitMapHeader->Buffer + (BitNumber / 32);
*Ptr &= ~(1 << (BitNumber % 32));
}
/*
* @implemented
*/
VOID STDCALL
RtlClearBits(PRTL_BITMAP BitMapHeader,
ULONG StartingIndex,
ULONG NumberToClear)
{
ULONG Size;
ULONG Count;
ULONG Shift;
PULONG Ptr;
Size = BitMapHeader->SizeOfBitMap;
if (StartingIndex >= Size || NumberToClear == 0)
return;
if (StartingIndex + NumberToClear > Size)
NumberToClear = Size - StartingIndex;
Ptr = (PULONG)BitMapHeader->Buffer + (StartingIndex / 32);
while (NumberToClear)
{
/* Bit shift in current ulong */
Shift = StartingIndex & 0x1F;
/* Number of bits to change in current ulong */
Count = (NumberToClear > 32 - Shift ) ? 32 - Shift : NumberToClear;
/* Adjust ulong */
*Ptr++ &= ~MASK(Count, Shift);
NumberToClear -= Count;
StartingIndex += Count;
}
}
/*
* @implemented
*/
ULONG STDCALL
RtlFindClearBits(PRTL_BITMAP BitMapHeader,
ULONG NumberToFind,
ULONG HintIndex)
{
ULONG Size;
ULONG Index;
ULONG Count;
PULONG Ptr;
ULONG Mask;
Size = BitMapHeader->SizeOfBitMap;
if (NumberToFind > Size || NumberToFind == 0)
return -1;
if (HintIndex >= Size)
HintIndex = 0;
Index = HintIndex;
Ptr = (PULONG)BitMapHeader->Buffer + (Index / 32);
Mask = 1 << (Index & 0x1F);
while (HintIndex < Size)
{
/* Count clear bits */
for (Count = 0; Index < Size && ~*Ptr & Mask; Index++)
{
if (++Count >= NumberToFind)
return HintIndex;
Mask <<= 1;
if (Mask == 0)
{
Mask = 1;
Ptr++;
}
}
/* Skip set bits */
for (; Index < Size && *Ptr & Mask; Index++)
{
Mask <<= 1;
if (Mask == 0)
{
Mask = 1;
Ptr++;
}
}
HintIndex = Index;
}
return (ULONG)-1;
}
/*
* @implemented
*/
ULONG STDCALL
RtlFindClearBitsAndSet(PRTL_BITMAP BitMapHeader,
ULONG NumberToFind,
ULONG HintIndex)
{
ULONG Index;
Index = RtlFindClearBits(BitMapHeader,
NumberToFind,
HintIndex);
if (Index != (ULONG)-1)
{
RtlSetBits(BitMapHeader,
Index,
NumberToFind);
}
return Index;
}
/*
* @implemented
*/
ULONG STDCALL
RtlFindFirstRunClear(PRTL_BITMAP BitMapHeader,
PULONG StartingIndex)
{
ULONG Size;
ULONG Index;
ULONG Count;
PULONG Ptr;
ULONG Mask;
Size = BitMapHeader->SizeOfBitMap;
if (*StartingIndex > Size)
{
*StartingIndex = (ULONG)-1;
return 0;
}
Index = *StartingIndex;
Ptr = (PULONG)BitMapHeader->Buffer + (Index / 32);
Mask = 1 << (Index & 0x1F);
/* Skip set bits */
for (; Index < Size && *Ptr & Mask; Index++)
{
Mask <<= 1;
if (Mask == 0)
{
Mask = 1;
Ptr++;
}
}
/* Return index of first clear bit */
if (Index >= Size)
{
*StartingIndex = (ULONG)-1;
return 0;
}
else
{
*StartingIndex = Index;
}
/* Count clear bits */
for (Count = 0; Index < Size && ~*Ptr & Mask; Index++)
{
Count++;
Mask <<= 1;
if (Mask == 0)
{
Mask = 1;
Ptr++;
}
}
return Count;
}
/*
* @unimplemented
*/
ULONG STDCALL
RtlFindClearRuns(PRTL_BITMAP BitMapHeader,
PRTL_BITMAP_RUN RunArray,
ULONG SizeOfRunArray,
BOOLEAN LocateLongestRuns)
{
UNIMPLEMENTED;
return 0;
}
/*
* @unimplemented
*/
ULONG STDCALL
RtlFindLastBackwardRunClear(IN PRTL_BITMAP BitMapHeader,
IN ULONG FromIndex,
IN PULONG StartingRunIndex)
{
UNIMPLEMENTED;
return 0;
}
/*
* @unimplemented
*/
ULONG STDCALL
RtlFindNextForwardRunClear(IN PRTL_BITMAP BitMapHeader,
IN ULONG FromIndex,
IN PULONG StartingRunIndex)
{
UNIMPLEMENTED;
return 0;
}
/*
* @implemented
*/
ULONG STDCALL
RtlFindFirstRunSet(IN PRTL_BITMAP BitMapHeader,
IN PULONG StartingIndex)
{
ULONG Size;
ULONG Index;
ULONG Count;
PULONG Ptr;
ULONG Mask;
Size = BitMapHeader->SizeOfBitMap;
if (*StartingIndex > Size)
{
*StartingIndex = (ULONG)-1;
return 0;
}
Index = *StartingIndex;
Ptr = (PULONG)BitMapHeader->Buffer + (Index / 32);
Mask = 1 << (Index & 0x1F);
/* Skip clear bits */
for (; Index < Size && ~*Ptr & Mask; Index++)
{
Mask <<= 1;
if (Mask == 0)
{
Mask = 1;
Ptr++;
}
}
/* Return index of first set bit */
if (Index >= Size)
{
*StartingIndex = (ULONG)-1;
return 0;
}
else
{
*StartingIndex = Index;
}
/* Count set bits */
for (Count = 0; Index < Size && *Ptr & Mask; Index++)
{
Count++;
Mask <<= 1;
if (Mask == 0)
{
Mask = 1;
Ptr++;
}
}
return Count;
}
/*
* @implemented
*/
ULONG STDCALL
RtlFindLongestRunClear(PRTL_BITMAP BitMapHeader,
PULONG StartingIndex)
{
ULONG Size;
PULONG Ptr;
ULONG Index = 0;
ULONG Count;
ULONG Max = 0;
ULONG Start;
ULONG Maxstart = 0;
ULONG Mask = 1;
Size = BitMapHeader->SizeOfBitMap;
Ptr = (PULONG)BitMapHeader->Buffer;
while (Index < Size)
{
Start = Index;
/* Count clear bits */
for (Count = 0; Index < Size && ~*Ptr & Mask; Index++)
{
Count++;
Mask <<= 1;
if (Mask == 0)
{
Mask = 1;
Ptr++;
}
}
/* Skip set bits */
for (; Index < Size && *Ptr & Mask; Index++)
{
Mask <<= 1;
if (Mask == 0)
{
Mask = 1;
Ptr++;
}
}
if (Count > Max)
{
Max = Count;
Maxstart = Start;
}
}
if (StartingIndex != NULL)
{
*StartingIndex = Maxstart;
}
return Max;
}
/*
* @implemented
*/
ULONG STDCALL
RtlFindLongestRunSet(PRTL_BITMAP BitMapHeader,
PULONG StartingIndex)
{
ULONG Size;
PULONG Ptr;
ULONG Index = 0;
ULONG Count;
ULONG Max = 0;
ULONG Start;
ULONG Maxstart = 0;
ULONG Mask = 1;
Size = BitMapHeader->SizeOfBitMap;
Ptr = (PULONG)BitMapHeader->Buffer;
while (Index < Size)
{
Start = Index;
/* Count set bits */
for (Count = 0; Index < Size && *Ptr & Mask; Index++)
{
Count++;
Mask <<= 1;
if (Mask == 0)
{
Mask = 1;
Ptr++;
}
}
/* Skip clear bits */
for (; Index < Size && ~*Ptr & Mask; Index++)
{
Mask <<= 1;
if (Mask == 0)
{
Mask = 1;
Ptr++;
}
}
if (Count > Max)
{
Max = Count;
Maxstart = Start;
}
}
if (StartingIndex != NULL)
{
*StartingIndex = Maxstart;
}
return Max;
}
/*
* @implemented
*/
ULONG STDCALL
RtlFindSetBits(PRTL_BITMAP BitMapHeader,
ULONG NumberToFind,
ULONG HintIndex)
{
ULONG Size;
ULONG Index;
ULONG Count;
PULONG Ptr;
ULONG Mask;
Size = BitMapHeader->SizeOfBitMap;
if (NumberToFind > Size || NumberToFind == 0)
return (ULONG)-1;
if (HintIndex >= Size)
HintIndex = 0;
Index = HintIndex;
Ptr = (PULONG)BitMapHeader->Buffer + (Index / 32);
Mask = 1 << (Index & 0x1F);
while (HintIndex < Size)
{
/* Count set bits */
for (Count = 0; Index < Size && *Ptr & Mask; Index++)
{
if (++Count >= NumberToFind)
return HintIndex;
Mask <<= 1;
if (Mask == 0)
{
Mask = 1;
Ptr++;
}
}
/* Skip clear bits */
for (; Index < Size && ~*Ptr & Mask; Index++)
{
Mask <<= 1;
if (Mask == 0)
{
Mask = 1;
Ptr++;
}
}
HintIndex = Index;
}
return (ULONG)-1;
}
/*
* @implemented
*/
ULONG STDCALL
RtlFindSetBitsAndClear(PRTL_BITMAP BitMapHeader,
ULONG NumberToFind,
ULONG HintIndex)
{
ULONG Index;
Index = RtlFindSetBits(BitMapHeader,
NumberToFind,
HintIndex);
if (Index != (ULONG)-1)
{
RtlClearBits(BitMapHeader,
Index,
NumberToFind);
}
return Index;
}
/*
* @implemented
*/
ULONG STDCALL
RtlNumberOfClearBits(PRTL_BITMAP BitMapHeader)
{
PULONG Ptr;
ULONG Size;
ULONG Index;
ULONG Count;
ULONG Mask;
Size = BitMapHeader->SizeOfBitMap;
Ptr = (PULONG)BitMapHeader->Buffer;
for (Mask = 1, Index = 0, Count = 0; Index < Size; Index++)
{
if (~*Ptr & Mask)
Count++;
Mask <<= 1;
if (Mask == 0)
{
Mask = 1;
Ptr++;
}
}
return Count;
}
/*
* @implemented
*/
ULONG STDCALL
RtlNumberOfSetBits(PRTL_BITMAP BitMapHeader)
{
PULONG Ptr;
ULONG Size;
ULONG Index;
ULONG Count;
ULONG Mask;
Ptr = (PULONG)BitMapHeader->Buffer;
Size = BitMapHeader->SizeOfBitMap;
for (Mask = 1, Index = 0, Count = 0; Index < Size; Index++)
{
if (*Ptr & Mask)
Count++;
Mask <<= 1;
if (Mask == 0)
{
Mask = 1;
Ptr++;
}
}
return Count;
}
/*
* @implemented
*/
VOID STDCALL
RtlSetAllBits(IN OUT PRTL_BITMAP BitMapHeader)
{
memset(BitMapHeader->Buffer,
0xFF,
ALIGN(BitMapHeader->SizeOfBitMap, 8));
}
/*
* @implemented
*/
VOID STDCALL
RtlSetBit(PRTL_BITMAP BitMapHeader,
ULONG BitNumber)
{
PULONG Ptr;
if (BitNumber >= BitMapHeader->SizeOfBitMap)
return;
Ptr = (PULONG)BitMapHeader->Buffer + (BitNumber / 32);
*Ptr |= (1 << (BitNumber % 32));
}
/*
* @implemented
*/
VOID STDCALL
RtlSetBits(PRTL_BITMAP BitMapHeader,
ULONG StartingIndex,
ULONG NumberToSet)
{
ULONG Size;
ULONG Count;
ULONG Shift;
PULONG Ptr;
Size = BitMapHeader->SizeOfBitMap;
if (StartingIndex >= Size || NumberToSet == 0)
return;
if (StartingIndex + NumberToSet > Size)
NumberToSet = Size - StartingIndex;
Ptr = (PULONG)BitMapHeader->Buffer + (StartingIndex / 32);
while (NumberToSet)
{
/* Bit shift in current ulong */
Shift = StartingIndex & 0x1F;
/* Number of bits to change in current ulong */
Count = (NumberToSet > 32 - Shift) ? 32 - Shift : NumberToSet;
/* Adjust ulong */
*Ptr++ |= MASK(Count, Shift);
NumberToSet -= Count;
StartingIndex += Count;
}
}
/*
* @implemented
*/
BOOLEAN STDCALL
RtlTestBit(PRTL_BITMAP BitMapHeader,
ULONG BitNumber)
{
PULONG Ptr;
if (BitNumber >= BitMapHeader->SizeOfBitMap)
return FALSE;
Ptr = (PULONG)BitMapHeader->Buffer + (BitNumber / 32);
return (*Ptr & (1 << (BitNumber % 32)));
}
/* EOF */

View file

@ -14,13 +14,18 @@ TARGET_CFLAGS += -D_DISABLE_TIDENTS
TARGET_OBJECTS = \
acl.o \
bit.o \
bitmap.o \
bootdata.o \
compress.o \
dos8dot3.o \
encode.o \
env.o \
error.o \
heap.o \
exception.o \
generictable.o \
heap.o \
image.o \
largeint.o \
luid.o \
mem.o \
@ -30,21 +35,18 @@ TARGET_OBJECTS = \
sd.o \
security.o \
sid.o \
splaytree.o \
time.o \
timezone.o \
unicode.o \
version.o \
encode.o \
image.o \
splaytree.o \
unicodeprefix.o \
exception.o \
i386/exception.o \
i386/except.o
version.o \
i386/exception.o \
i386/except.o
# atom
# registry
include $(PATH_TO_TOP)/rules.mak