2 * NTDLL bitmap functions
4 * Copyright 2002 Jon Griffiths
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * Bitmaps are an efficient type for manipulating large arrays of bits. They
22 * are commonly used by device drivers (e.g. For holding dirty/free blocks),
23 * but are also available to applications that need this functionality.
25 * Bits are set LSB to MSB in each consecutive byte, making this implementation
26 * binary compatable with Win32.
28 * Note that to avoid unexpected behaviour, the size of a bitmap should be set
29 * to a multiple of 32.
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
39 /* Bits set from LSB to MSB; used as mask for runs < 8 bits */
40 static const BYTE NTDLL_maskBits[8] = { 0, 1, 3, 7, 15, 31, 63, 127 };
42 /* Number of set bits for each value of a nibble; used for counting */
43 static const BYTE NTDLL_nibbleBitCount[16] = {
44 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
47 /* First set bit in a nibble; used for determining least significant bit */
48 static const BYTE NTDLL_leastSignificant[16] = {
49 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
52 /* Last set bit in a nibble; used for determining most significant bit */
53 static const BYTE NTDLL_mostSignificant[16] = {
54 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
57 /*************************************************************************
58 * RtlInitializeBitMap [NTDLL.@]
60 * Initialise a new bitmap.
63 * lpBits [I] Bitmap pointer
64 * lpBuff [I] Memory for the bitmap
65 * ulSize [I] Size of lpBuff in bits
71 * lpBuff must be aligned on a ULONG suitable boundary, to a multiple of 32 bytes
72 * in size (irrespective of ulSize given).
74 #undef RtlInitializeBitMap
75 VOID WINAPI RtlInitializeBitMap(PRTL_BITMAP lpBits, LPBYTE lpBuff, ULONG ulSize)
77 TRACE("(%p,%p,%ld)\n", lpBits,lpBuff,ulSize);
78 lpBits->SizeOfBitMap = ulSize;
79 lpBits->BitMapBuffer = lpBuff;
82 /*************************************************************************
83 * RtlSetAllBits [NTDLL.@]
85 * Set all bits in a bitmap.
88 * lpBits [I] Bitmap pointer
94 VOID WINAPI RtlSetAllBits(PRTL_BITMAP lpBits)
96 TRACE("(%p)\n", lpBits);
97 memset(lpBits->BitMapBuffer, 0xff, ((lpBits->SizeOfBitMap + 31) & 0xffffffe0) >> 3);
100 /*************************************************************************
101 * RtlClearAllBits [NTDLL.@]
103 * Clear all bits in a bitmap.
106 * lpBit [I] Bitmap pointer
111 #undef RtlClearAllBits
112 VOID WINAPI RtlClearAllBits(PRTL_BITMAP lpBits)
114 TRACE("(%p)\n", lpBits);
115 memset(lpBits->BitMapBuffer, 0, ((lpBits->SizeOfBitMap + 31) & 0xffffffe0) >> 3);
118 /*************************************************************************
119 * RtlSetBits [NTDLL.@]
121 * Set a range of bits in a bitmap.
124 * lpBits [I] Bitmap pointer
125 * ulStart [I] First bit to set
126 * ulCount [I] Number of consecutive bits to set
131 VOID WINAPI RtlSetBits(PRTL_BITMAP lpBits, ULONG ulStart, ULONG ulCount)
135 TRACE("(%p,%ld,%ld)\n", lpBits, ulStart, ulCount);
137 if (!lpBits || !ulCount || ulStart + ulCount > lpBits->SizeOfBitMap)
140 lpOut = lpBits->BitMapBuffer + (ulStart >> 3u);
142 /* Set bits in first byte, if ulStart isn't a byte boundary */
147 /* Set from start bit to the end of the byte */
148 *lpOut++ |= 0xff << (ulStart & 7);
149 ulCount -= (8 - (ulStart & 7));
153 /* Set from the start bit, possibly into the next byte also */
154 USHORT initialWord = NTDLL_maskBits[ulCount] << (ulStart & 7);
156 *lpOut++ |= (initialWord & 0xff);
157 *lpOut |= (initialWord >> 8);
162 /* Set bits up to complete byte count */
165 memset(lpOut, 0xff, ulCount >> 3);
166 lpOut = lpOut + (ulCount >> 3);
169 /* Set remaining bits, if any */
170 *lpOut |= NTDLL_maskBits[ulCount & 0x7];
173 /*************************************************************************
174 * RtlClearBits [NTDLL.@]
176 * Clear bits in a bitmap.
179 * lpBits [I] Bitmap pointer
180 * ulStart [I] First bit to set
181 * ulCount [I] Number of consecutive bits to clear
186 VOID WINAPI RtlClearBits(PRTL_BITMAP lpBits, ULONG ulStart, ULONG ulCount)
190 TRACE("(%p,%ld,%ld)\n", lpBits, ulStart, ulCount);
192 if (!lpBits || !ulCount || ulStart + ulCount > lpBits->SizeOfBitMap)
195 lpOut = lpBits->BitMapBuffer + (ulStart >> 3u);
197 /* Clear bits in first byte, if ulStart isn't a byte boundary */
202 /* Clear from start bit to the end of the byte */
203 *lpOut++ &= ~(0xff << (ulStart & 7));
204 ulCount -= (8 - (ulStart & 7));
208 /* Clear from the start bit, possibly into the next byte also */
209 USHORT initialWord = ~(NTDLL_maskBits[ulCount] << (ulStart & 7));
211 *lpOut++ &= (initialWord & 0xff);
212 *lpOut &= (initialWord >> 8);
217 /* Clear bits (in blocks of 8) on whole byte boundaries */
220 memset(lpOut, 0, ulCount >> 3);
221 lpOut = lpOut + (ulCount >> 3);
224 /* Clear remaining bits, if any */
226 *lpOut &= ~NTDLL_maskBits[ulCount & 0x7];
229 /*************************************************************************
230 * RtlAreBitsSet [NTDLL.@]
232 * Determine if part of a bitmap is set.
235 * lpBits [I] Bitmap pointer
236 * ulStart [I] First bit to check from
237 * ulCount [I] Number of consecutive bits to check
240 * TRUE, If ulCount bits from ulStart are set.
243 BOOLEAN WINAPI RtlAreBitsSet(PCRTL_BITMAP lpBits, ULONG ulStart, ULONG ulCount)
248 TRACE("(%p,%ld,%ld)\n", lpBits, ulStart, ulCount);
250 if (!lpBits || !ulCount || ulStart + ulCount > lpBits->SizeOfBitMap)
253 lpOut = lpBits->BitMapBuffer + (ulStart >> 3u);
255 /* Check bits in first byte, if ulStart isn't a byte boundary */
260 /* Check from start bit to the end of the byte */
262 ((0xff << (ulStart & 7))) & 0xff) != ((0xff << (ulStart & 7) & 0xff)))
265 ulCount -= (8 - (ulStart & 7));
269 /* Check from the start bit, possibly into the next byte also */
270 USHORT initialWord = NTDLL_maskBits[ulCount] << (ulStart & 7);
272 if ((*lpOut & (initialWord & 0xff)) != (initialWord & 0xff))
274 if ((initialWord & 0xff00) &&
275 ((lpOut[1] & (initialWord >> 8)) != (initialWord >> 8)))
281 /* Check bits in blocks of 8 bytes */
282 ulRemainder = ulCount & 7;
286 if (*lpOut++ != 0xff)
290 /* Check remaining bits, if any */
292 (*lpOut & NTDLL_maskBits[ulRemainder]) != NTDLL_maskBits[ulRemainder])
297 /*************************************************************************
298 * RtlAreBitsClear [NTDLL.@]
300 * Determine if part of a bitmap is clear.
303 * lpBits [I] Bitmap pointer
304 * ulStart [I] First bit to check from
305 * ulCount [I] Number of consecutive bits to check
308 * TRUE, If ulCount bits from ulStart are clear.
311 BOOLEAN WINAPI RtlAreBitsClear(PCRTL_BITMAP lpBits, ULONG ulStart, ULONG ulCount)
316 TRACE("(%p,%ld,%ld)\n", lpBits, ulStart, ulCount);
318 if (!lpBits || !ulCount || ulStart + ulCount > lpBits->SizeOfBitMap)
321 lpOut = lpBits->BitMapBuffer + (ulStart >> 3u);
323 /* Check bits in first byte, if ulStart isn't a byte boundary */
328 /* Check from start bit to the end of the byte */
329 if (*lpOut & ((0xff << (ulStart & 7)) & 0xff))
332 ulCount -= (8 - (ulStart & 7));
336 /* Check from the start bit, possibly into the next byte also */
337 USHORT initialWord = NTDLL_maskBits[ulCount] << (ulStart & 7);
339 if (*lpOut & (initialWord & 0xff))
341 if ((initialWord & 0xff00) && (lpOut[1] & (initialWord >> 8)))
347 /* Check bits in blocks of 8 bytes */
348 ulRemainder = ulCount & 7;
356 /* Check remaining bits, if any */
357 if (ulRemainder && *lpOut & NTDLL_maskBits[ulRemainder])
362 /*************************************************************************
363 * RtlFindSetBits [NTDLL.@]
365 * Find a block of set bits in a bitmap.
368 * lpBits [I] Bitmap pointer
369 * ulCount [I] Number of consecutive set bits to find
370 * ulHint [I] Suggested starting position for set bits
373 * The bit at which the match was found, or -1 if no match was found.
375 ULONG WINAPI RtlFindSetBits(PCRTL_BITMAP lpBits, ULONG ulCount, ULONG ulHint)
379 TRACE("(%p,%ld,%ld)\n", lpBits, ulCount, ulHint);
381 if (!lpBits || !ulCount || ulCount > lpBits->SizeOfBitMap)
384 ulEnd = lpBits->SizeOfBitMap;
386 if (ulHint + ulCount > lpBits->SizeOfBitMap)
391 while (ulPos < ulEnd)
393 /* FIXME: This could be made a _lot_ more efficient */
394 if (RtlAreBitsSet(lpBits, ulPos, ulCount))
397 /* Start from the beginning if we hit the end and had a hint */
398 if (ulPos == ulEnd - 1 && ulHint)
409 /*************************************************************************
410 * RtlFindClearBits [NTDLL.@]
412 * Find a block of clear bits in a bitmap.
415 * lpBits [I] Bitmap pointer
416 * ulCount [I] Number of consecutive clear bits to find
417 * ulHint [I] Suggested starting position for clear bits
420 * The bit at which the match was found, or -1 if no match was found.
422 ULONG WINAPI RtlFindClearBits(PCRTL_BITMAP lpBits, ULONG ulCount, ULONG ulHint)
426 TRACE("(%p,%ld,%ld)\n", lpBits, ulCount, ulHint);
428 if (!lpBits || !ulCount || ulCount > lpBits->SizeOfBitMap)
431 ulEnd = lpBits->SizeOfBitMap;
433 if (ulHint + ulCount > lpBits->SizeOfBitMap)
438 while (ulPos < ulEnd)
440 /* FIXME: This could be made a _lot_ more efficient */
441 if (RtlAreBitsClear(lpBits, ulPos, ulCount))
444 /* Start from the beginning if we hit the end and started from ulHint */
445 if (ulPos == ulEnd - 1 && ulHint)
456 /*************************************************************************
457 * RtlFindSetBitsAndClear [NTDLL.@]
459 * Find a block of set bits in a bitmap, and clear them if found.
462 * lpBits [I] Bitmap pointer
463 * ulCount [I] Number of consecutive set bits to find
464 * ulHint [I] Suggested starting position for set bits
467 * The bit at which the match was found, or -1 if no match was found.
469 ULONG WINAPI RtlFindSetBitsAndClear(PRTL_BITMAP lpBits, ULONG ulCount, ULONG ulHint)
473 TRACE("(%p,%ld,%ld)\n", lpBits, ulCount, ulHint);
475 ulPos = RtlFindSetBits(lpBits, ulCount, ulHint);
477 RtlClearBits(lpBits, ulPos, ulCount);
481 /*************************************************************************
482 * RtlFindClearBitsAndSet [NTDLL.@]
484 * Find a block of clear bits in a bitmap, and set them if found.
487 * lpBits [I] Bitmap pointer
488 * ulCount [I] Number of consecutive clear bits to find
489 * ulHint [I] Suggested starting position for clear bits
492 * The bit at which the match was found, or -1 if no match was found.
494 ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP lpBits, ULONG ulCount, ULONG ulHint)
498 TRACE("(%p,%ld,%ld)\n", lpBits, ulCount, ulHint);
500 ulPos = RtlFindClearBits(lpBits, ulCount, ulHint);
502 RtlSetBits(lpBits, ulPos, ulCount);
506 /*************************************************************************
507 * RtlNumberOfSetBits [NTDLL.@]
509 * Find the number of set bits in a bitmap.
512 * lpBits [I] Bitmap pointer
515 * The number of set bits.
517 ULONG WINAPI RtlNumberOfSetBits(PCRTL_BITMAP lpBits)
521 TRACE("(%p)\n", lpBits);
525 LPBYTE lpOut = lpBits->BitMapBuffer;
526 ULONG ulCount, ulRemainder;
529 ulCount = lpBits->SizeOfBitMap >> 3;
530 ulRemainder = lpBits->SizeOfBitMap & 0x7;
534 ulSet += NTDLL_nibbleBitCount[*lpOut >> 4];
535 ulSet += NTDLL_nibbleBitCount[*lpOut & 0xf];
539 bMasked = *lpOut & NTDLL_maskBits[ulRemainder];
540 ulSet += NTDLL_nibbleBitCount[bMasked >> 4];
541 ulSet += NTDLL_nibbleBitCount[bMasked & 0xf];
546 /*************************************************************************
547 * RtlNumberOfClearBits [NTDLL.@]
549 * Find the number of clear bits in a bitmap.
552 * lpBits [I] Bitmap pointer
555 * The number of clear bits.
557 ULONG WINAPI RtlNumberOfClearBits(PCRTL_BITMAP lpBits)
559 TRACE("(%p)\n", lpBits);
562 return lpBits->SizeOfBitMap - RtlNumberOfSetBits(lpBits);
566 /*************************************************************************
567 * RtlFindMostSignificantBit [NTDLL.@]
569 * Find the most significant bit in a 64 bit integer.
572 * lpBits [I] Bitmap pointer
573 * ulStart [I] First bit to search from
576 * The position of the most significant bit.
578 CCHAR WINAPI RtlFindMostSignificantBit(ULONGLONG ulLong)
581 LPBYTE lpOut = (LPBYTE)&ulLong + 7;
583 TRACE("(%lld)\n", ulLong);
585 if (!(ulLong & 0xffffffff00000000ul))
591 for (; lCount > 0; lCount -= 8)
596 return lCount - 8 + NTDLL_mostSignificant[*lpOut & 0x0f];
597 return lCount - 4 + NTDLL_mostSignificant[*lpOut >> 4];
604 /*************************************************************************
605 * RtlFindLeastSignificantBit [NTDLL.@]
607 * Find the least significant bit in a 64 bit integer.
610 * lpBits [I] Bitmap pointer
611 * ulStart [I] First bit to search from
614 * The position of the least significant bit.
616 CCHAR WINAPI RtlFindLeastSignificantBit(ULONGLONG ulLong)
619 LPBYTE lpOut = (LPBYTE)&ulLong;
621 TRACE("(%lld)\n", ulLong);
623 if (!(ulLong & 0xffffffff))
629 for (; ulCount < 64; ulCount += 8)
634 return ulCount + NTDLL_leastSignificant[*lpOut & 0x0f];
635 return ulCount + 4 + NTDLL_leastSignificant[*lpOut >> 4];
642 /*************************************************************************
645 * Internal helper: qsort comparason function for RTL_BITMAP_RUN arrays
647 static int NTDLL_RunSortFn(const void *lhs, const void *rhs)
649 if (((PCRTL_BITMAP_RUN)lhs)->SizeOfRun > ((PRTL_BITMAP_RUN)rhs)->SizeOfRun)
654 /*************************************************************************
657 * Internal helper: Find the next run of set bits in a bitmap.
659 static ULONG NTDLL_FindSetRun(PCRTL_BITMAP lpBits, ULONG ulStart, PULONG lpSize)
662 ULONG ulFoundAt = 0, ulCount = 0;
664 lpOut = lpBits->BitMapBuffer + (ulStart >> 3u);
668 /* Check bits in first byte */
669 const BYTE bMask = (0xff << (ulStart & 7)) & 0xff;
670 const BYTE bFirst = *lpOut & bMask;
674 /* Have a set bit in first byte */
677 /* Not every bit is set */
681 ulOffset = NTDLL_leastSignificant[bFirst & 0x0f];
683 ulOffset = 4 + NTDLL_leastSignificant[bFirst >> 4];
686 for (;ulOffset < 8; ulOffset++)
688 if (!(bFirst & (1 << ulOffset)))
691 return ulFoundAt; /* Set from start, but not until the end */
696 /* Set to the end - go on to count further bits */
700 /* every bit from start until the end of the byte is set */
702 ulCount = 8 - (ulStart & 7);
703 ulStart = (ulStart & ~7u) + 8;
707 ulStart = (ulStart & ~7u) + 8;
709 if (ulStart >= lpBits->SizeOfBitMap)
713 /* Count blocks of 8 set bits */
714 while (*lpOut == 0xff)
718 if (ulStart >= lpBits->SizeOfBitMap)
720 *lpSize = ulCount - (ulStart - lpBits->SizeOfBitMap);
726 /* Count remaining contigious bits, if any */
731 for (;ulOffset < 7u; ulOffset++)
733 if (!(*lpOut & (1 << ulOffset)))
742 /*************************************************************************
745 * Internal helper: Find the next run of set bits in a bitmap.
747 static ULONG NTDLL_FindClearRun(PCRTL_BITMAP lpBits, ULONG ulStart, PULONG lpSize)
750 ULONG ulFoundAt = 0, ulCount = 0;
752 lpOut = lpBits->BitMapBuffer + (ulStart >> 3u);
756 /* Check bits in first byte */
757 const BYTE bMask = (0xff << (ulStart & 7)) & 0xff;
758 const BYTE bFirst = (~*lpOut) & bMask;
762 /* Have a clear bit in first byte */
765 /* Not every bit is clear */
769 ulOffset = NTDLL_leastSignificant[bFirst & 0x0f];
771 ulOffset = 4 + NTDLL_leastSignificant[bFirst >> 4];
774 for (;ulOffset < 8; ulOffset++)
776 if (!(bFirst & (1 << ulOffset)))
779 return ulFoundAt; /* Clear from start, but not until the end */
784 /* Clear to the end - go on to count further bits */
788 /* Every bit from start until the end of the byte is clear */
790 ulCount = 8 - (ulStart & 7);
791 ulStart = (ulStart & ~7u) + 8;
795 ulStart = (ulStart & ~7u) + 8;
797 if (ulStart >= lpBits->SizeOfBitMap)
801 /* Count blocks of 8 clear bits */
806 if (ulStart >= lpBits->SizeOfBitMap)
808 *lpSize = ulCount - (ulStart - lpBits->SizeOfBitMap);
814 /* Count remaining contigious bits, if any */
819 for (;ulOffset < 7u; ulOffset++)
821 if (*lpOut & (1 << ulOffset))
830 /*************************************************************************
831 * RtlFindNextForwardRunSet [NTDLL.@]
833 * Find the next run of set bits in a bitmap.
836 * lpBits [I] Bitmap pointer
837 * ulStart [I] Bit position to start searching from
838 * lpPos [O] Start of run
841 * Success: The length of the next set run in the bitmap. lpPos is set to
842 * the start of the run.
843 * Failure: 0, if no run is found or any parameters are invalid.
845 ULONG WINAPI RtlFindNextForwardRunSet(PCRTL_BITMAP lpBits, ULONG ulStart, PULONG lpPos)
849 TRACE("(%p,%ld,%p)\n", lpBits, ulStart, lpPos);
851 if (lpBits && ulStart < lpBits->SizeOfBitMap && lpPos)
852 *lpPos = NTDLL_FindSetRun(lpBits, ulStart, &ulSize);
857 /*************************************************************************
858 * RtlFindNextForwardRunClear [NTDLL.@]
860 * Find the next run of clear bits in a bitmap.
863 * lpBits [I] Bitmap pointer
864 * ulStart [I] Bit position to start searching from
865 * lpPos [O] Start of run
868 * Success: The length of the next clear run in the bitmap. lpPos is set to
869 * the start of the run.
870 * Failure: 0, if no run is found or any parameters are invalid.
872 ULONG WINAPI RtlFindNextForwardRunClear(PCRTL_BITMAP lpBits, ULONG ulStart, PULONG lpPos)
876 TRACE("(%p,%ld,%p)\n", lpBits, ulStart, lpPos);
878 if (lpBits && ulStart < lpBits->SizeOfBitMap && lpPos)
879 *lpPos = NTDLL_FindClearRun(lpBits, ulStart, &ulSize);
884 /*************************************************************************
885 * RtlFindLastBackwardRunSet [NTDLL.@]
887 * Find a previous run of set bits in a bitmap.
890 * lpBits [I] Bitmap pointer
891 * ulStart [I] Bit position to start searching from
892 * lpPos [O] Start of run
895 * Success: The length of the previous set run in the bitmap. lpPos is set to
896 * the start of the run.
897 * Failure: 0, if no run is found or any parameters are invalid.
899 ULONG WINAPI RtlFindLastBackwardRunSet(PCRTL_BITMAP lpBits, ULONG ulStart, PULONG lpPos)
901 FIXME("(%p,%ld,%p)-stub!\n", lpBits, ulStart, lpPos);
905 /*************************************************************************
906 * RtlFindLastBackwardRunClear [NTDLL.@]
908 * Find a previous run of clear bits in a bitmap.
911 * lpBits [I] Bitmap pointer
912 * ulStart [I] Bit position to start searching from
913 * lpPos [O] Start of run
916 * Success: The length of the previous clear run in the bitmap. lpPos is set
917 * to the start of the run.
918 * Failure: 0, if no run is found or any parameters are invalid.
920 ULONG WINAPI RtlFindLastBackwardRunClear(PCRTL_BITMAP lpBits, ULONG ulStart, PULONG lpPos)
922 FIXME("(%p,%ld,%p)-stub!\n", lpBits, ulStart, lpPos);
926 /*************************************************************************
929 * Internal implementation of RtlFindSetRuns/RtlFindClearRuns.
931 static ULONG WINAPI NTDLL_FindRuns(PCRTL_BITMAP lpBits, PRTL_BITMAP_RUN lpSeries,
932 ULONG ulCount, BOOLEAN bLongest,
933 ULONG (*fn)(PCRTL_BITMAP,ULONG,PULONG))
935 BOOL bNeedSort = ulCount > 1 ? TRUE : FALSE;
936 ULONG ulPos = 0, ulRuns = 0;
938 TRACE("(%p,%p,%ld,%d)\n", lpBits, lpSeries, ulCount, bLongest);
943 while (ulPos < lpBits->SizeOfBitMap)
945 /* Find next set/clear run */
946 ULONG ulSize, ulNextPos = fn(lpBits, ulPos, &ulSize);
948 if (ulNextPos == -1u)
951 if (bLongest && ulRuns == ulCount)
953 /* Sort runs with shortest at end, if they are out of order */
955 qsort(lpSeries, ulRuns, sizeof(RTL_BITMAP_RUN), NTDLL_RunSortFn);
957 /* Replace last run if this one is bigger */
958 if (ulSize > lpSeries[ulRuns - 1].SizeOfRun)
960 lpSeries[ulRuns - 1].StartOfRun = ulNextPos;
961 lpSeries[ulRuns - 1].SizeOfRun = ulSize;
963 /* We need to re-sort the array, _if_ we didn't leave it sorted */
964 if (ulRuns > 1 && ulSize > lpSeries[ulRuns - 2].SizeOfRun)
970 /* Append to found runs */
971 lpSeries[ulRuns].StartOfRun = ulNextPos;
972 lpSeries[ulRuns].SizeOfRun = ulSize;
975 if (!bLongest && ulRuns == ulCount)
978 ulPos = ulNextPos + ulSize;
983 /*************************************************************************
984 * RtlFindSetRuns [NTDLL.@]
986 * Find a series of set runs in a bitmap.
989 * lpBits [I] Bitmap pointer
990 * ulSeries [O] Array for each run found
991 * ulCount [I] Number of runs to find
992 * bLongest [I] Whether to find the very longest runs or not
995 * The number of set runs found.
997 ULONG WINAPI RtlFindSetRuns(PCRTL_BITMAP lpBits, PRTL_BITMAP_RUN lpSeries,
998 ULONG ulCount, BOOLEAN bLongest)
1000 TRACE("(%p,%p,%ld,%d)\n", lpBits, lpSeries, ulCount, bLongest);
1002 return NTDLL_FindRuns(lpBits, lpSeries, ulCount, bLongest, NTDLL_FindSetRun);
1005 /*************************************************************************
1006 * RtlFindClearRuns [NTDLL.@]
1008 * Find a series of clear runs in a bitmap.
1011 * lpBits [I] Bitmap pointer
1012 * ulSeries [O] Array for each run found
1013 * ulCount [I] Number of runs to find
1014 * bLongest [I] Whether to find the very longest runs or not
1017 * The number of clear runs found.
1019 ULONG WINAPI RtlFindClearRuns(PCRTL_BITMAP lpBits, PRTL_BITMAP_RUN lpSeries,
1020 ULONG ulCount, BOOLEAN bLongest)
1022 TRACE("(%p,%p,%ld,%d)\n", lpBits, lpSeries, ulCount, bLongest);
1024 return NTDLL_FindRuns(lpBits, lpSeries, ulCount, bLongest, NTDLL_FindClearRun);
1027 /*************************************************************************
1028 * RtlFindLongestRunSet [NTDLL.@]
1030 * Find the longest set run in a bitmap.
1033 * lpBits [I] Bitmap pointer
1034 * pulStart [O] Destination for start of run
1037 * The length of the run found, or 0 if no run is found.
1039 ULONG WINAPI RtlFindLongestRunSet(PCRTL_BITMAP lpBits, PULONG pulStart)
1043 TRACE("(%p,%p)\n", lpBits, pulStart);
1045 if (RtlFindSetRuns(lpBits, &br, 1, TRUE) == 1)
1048 *pulStart = br.StartOfRun;
1049 return br.SizeOfRun;
1054 /*************************************************************************
1055 * RtlFindLongestRunClear [NTDLL.@]
1057 * Find the longest clear run in a bitmap.
1060 * lpBits [I] Bitmap pointer
1061 * pulStart [O] Destination for start of run
1064 * The length of the run found, or 0 if no run is found.
1066 ULONG WINAPI RtlFindLongestRunClear(PCRTL_BITMAP lpBits, PULONG pulStart)
1070 TRACE("(%p,%p)\n", lpBits, pulStart);
1072 if (RtlFindClearRuns(lpBits, &br, 1, TRUE) == 1)
1075 *pulStart = br.StartOfRun;
1076 return br.SizeOfRun;