2
This file is part of the Free Component Library (FCL)
3
Copyright (c) 1999-2000 by the Free Pascal development team
5
See the file COPYING.FPC, included in this distribution,
6
for details about the copyright.
8
This program is distributed in the hope that it will be useful,
9
but WITHOUT ANY WARRANTY; without even the implied warranty of
10
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
**********************************************************************}
13
{****************************************************************************}
15
{****************************************************************************}
17
Procedure BitsError (Msg : string);
20
Raise EBitsError.Create(Msg) at get_caller_addr(get_frame);
23
Procedure BitsErrorFmt (Msg : string; const Args : array of const);
26
Raise EBitsError.CreateFmt(Msg,args) at get_caller_addr(get_frame);
29
procedure TBits.CheckBitIndex (Bit : longint;CurrentSize : Boolean);
32
if (bit<0) or (CurrentSize and (Bit>Size)) then
33
BitsErrorFmt(SErrInvalidBitIndex,[bit]);
34
if (bit>=MaxBitFlags) then
35
BitsErrorFmt(SErrIndexTooLarge,[bit])
39
{ ************* functions to match TBits class ************* }
41
function TBits.getSize : longint;
43
result := (FSize shl BITSHIFT) - 1;
46
procedure TBits.setSize(value : longint);
51
procedure TBits.SetBit(bit : longint; value : Boolean);
59
function TBits.OpenBit : longint;
65
result := -1; {should only occur if the whole array is set}
66
for loop := 0 to FSize - 1 do
68
if FBits^[loop] <> $FFFFFFFF then
70
startIndex := loop * 32;
71
for loop2 := startIndex to startIndex + 31 do
73
if get(loop2) = False then
76
break; { use this as the index to return }
79
break; {stop looking for empty bit in records }
84
if FSize < MaxBitRec then
85
result := FSize * 32; {first bit of next record}
88
{ ******************** TBits ***************************** }
90
constructor TBits.Create(theSize : longint = 0 );
95
findState := True; { no reason just setting it to something }
99
destructor TBits.Destroy;
102
FreeMem(FBits, FSize * SizeOf(longint));
108
procedure TBits.grow(nbit : longint);
113
CheckBitindex(nbit,false);
115
newSize := (nbit shr BITSHIFT) + 1;
117
if newSize > FSize then
119
ReAllocMem(FBits, newSize * SizeOf(longint));
122
if newSize > FSize then
123
for loop := FSize to newSize - 1 do
128
BitsError(SErrOutOfMemory);
132
function TBits.getFSize : longint;
137
procedure TBits.seton(bit : longint);
141
n := bit shr BITSHIFT;
143
FBits^[n] := FBits^[n] or (longint(1) shl (bit and MASK));
146
procedure TBits.clear(bit : longint);
150
CheckBitIndex(bit,false);
151
n := bit shr BITSHIFT;
153
FBits^[n] := FBits^[n] and not(longint(1) shl (bit and MASK));
156
procedure TBits.clearall;
160
for loop := 0 to FSize - 1 do
164
function TBits.get(bit : longint) : Boolean;
168
CheckBitIndex(bit,true);
170
n := bit shr BITSHIFT;
172
result := (FBits^[n] and (longint(1) shl (bit and MASK))) <> 0;
175
procedure TBits.andbits(bitset : TBits);
180
if FSize < bitset.getFSize then
183
n := bitset.getFSize - 1;
185
for loop := 0 to n do
186
FBits^[loop] := FBits^[loop] and bitset.FBits^[loop];
188
for loop := n + 1 to FSize - 1 do
192
procedure TBits.notbits(bitset : TBits);
198
if FSize < bitset.getFSize then
201
n := bitset.getFSize - 1;
203
for loop := 0 to n do
206
FBits^[loop] := FBits^[loop] and (jj xor bitset.FBits^[loop]);
210
procedure TBits.orbits(bitset : TBits);
215
if FSize < bitset.getFSize then
216
n := bitset.getFSize - 1
220
grow(n shl BITSHIFT);
222
for loop := 0 to n do
223
FBits^[loop] := FBits^[loop] or bitset.FBits^[loop];
226
procedure TBits.xorbits(bitset : TBits);
231
if FSize < bitset.getFSize then
232
n := bitset.getFSize - 1
236
grow(n shl BITSHIFT);
238
for loop := 0 to n do
239
FBits^[loop] := FBits^[loop] xor bitset.FBits^[loop];
242
function TBits.equals(bitset : TBits) : Boolean;
249
if FSize < bitset.getFSize then
252
n := bitset.getFSize - 1;
254
for loop := 0 to n do
255
if FBits^[loop] <> bitset.FBits^[loop] then exit;
257
if FSize - 1 > n then
259
for loop := n to FSize - 1 do
260
if FBits^[loop] <> 0 then exit;
262
else if bitset.getFSize - 1 > n then
263
for loop := n to bitset.getFSize - 1 do
264
if bitset.FBits^[loop] <> 0 then exit;
266
result := True; {passed all tests}
270
{ us this in place of calling FindFirstBit. It sets the current }
271
{ index used by FindNextBit and FindPrevBit }
273
procedure TBits.SetIndex(index : longint);
279
{ When state is set to True it looks for bits that are turned On (1) }
280
{ and when it is set to False it looks for bits that are turned }
283
function TBits.FindFirstBit(state : boolean) : longint;
287
startIndex : longint;
288
compareVal : cardinal;
290
result := -1; {should only occur if none are set}
294
if state = False then
295
compareVal := $FFFFFFFF { looking for off bits }
297
compareVal := $00000000; { looking for on bits }
299
for loop := 0 to FSize - 1 do
301
if FBits^[loop] <> compareVal then
303
startIndex := loop * 32;
304
for loop2 := startIndex to startIndex + 31 do
306
if get(loop2) = state then
309
break; { use this as the index to return }
312
break; {stop looking for bit in records }
319
function TBits.FindNextBit : longint;
324
result := -1; { will occur only if no other bits set to }
325
{ current findState }
327
if findIndex > -1 then { must have called FindFirstBit first }
328
begin { or set the start index }
329
maxVal := (FSize * 32) - 1;
331
for loop := findIndex + 1 to maxVal do
333
if get(loop) = findState then
344
function TBits.FindPrevBit : longint;
348
result := -1; { will occur only if no other bits set to }
349
{ current findState }
351
if findIndex > -1 then { must have called FindFirstBit first }
352
begin { or set the start index }
353
for loop := findIndex - 1 downto 0 do
355
if get(loop) = findState then