From f3320ad2304c9cfb7e6ca918ce028f20fdbced1a Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Tue, 10 Aug 2004 12:00:09 +0000 Subject: [PATCH] Move bitmap functions to the shared rtl library. Implement RtlClearBit, RtlSetBit and RtlTestBit. svn path=/trunk/; revision=10470 --- reactos/lib/rtl/bit.c | 75 ++++ reactos/lib/rtl/bitmap.c | 821 +++++++++++++++++++++++++++++++++++++++ reactos/lib/rtl/makefile | 20 +- 3 files changed, 907 insertions(+), 9 deletions(-) create mode 100644 reactos/lib/rtl/bit.c create mode 100644 reactos/lib/rtl/bitmap.c diff --git a/reactos/lib/rtl/bit.c b/reactos/lib/rtl/bit.c new file mode 100644 index 00000000000..1a4bec9075b --- /dev/null +++ b/reactos/lib/rtl/bit.c @@ -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 + + +/* 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 */ diff --git a/reactos/lib/rtl/bitmap.c b/reactos/lib/rtl/bitmap.c new file mode 100644 index 00000000000..f7ca1a9493c --- /dev/null +++ b/reactos/lib/rtl/bitmap.c @@ -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 + +#define NDEBUG +#include + + +/* 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 */ diff --git a/reactos/lib/rtl/makefile b/reactos/lib/rtl/makefile index a3ed75bd710..4931e304571 100644 --- a/reactos/lib/rtl/makefile +++ b/reactos/lib/rtl/makefile @@ -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