浏览代码

* Patch from Giuliano Colla to fix tbits.size

git-svn-id: trunk@10095 -
michael 17 年之前
父节点
当前提交
6d5c3bbee6
共有 1 个文件被更改,包括 56 次插入25 次删除
  1. 56 25
      rtl/objpas/classes/bits.inc

+ 56 - 25
rtl/objpas/classes/bits.inc

@@ -1,6 +1,6 @@
 {
 {
     This file is part of the Free Component Library (FCL)
     This file is part of the Free Component Library (FCL)
-    Copyright (c) 1999-2000 by the Free Pascal development team
+    Copyright (c) 1999-2008 by the Free Pascal development team
 
 
     See the file COPYING.FPC, included in this distribution,
     See the file COPYING.FPC, included in this distribution,
     for details about the copyright.
     for details about the copyright.
@@ -26,29 +26,62 @@ begin
   Raise EBitsError.CreateFmt(Msg,args) at get_caller_addr(get_frame);
   Raise EBitsError.CreateFmt(Msg,args) at get_caller_addr(get_frame);
 end;
 end;
 
 
+{Min function for Longint}
+Function liMin(X, Y: Longint): Longint;
+  begin
+    Result := X;
+    if X > Y then Result := Y;
+  end;
+
 procedure TBits.CheckBitIndex (Bit : longint;CurrentSize : Boolean);
 procedure TBits.CheckBitIndex (Bit : longint;CurrentSize : Boolean);
 
 
 begin
 begin
- if (bit<0) or (CurrentSize and (Bit>Size)) then
+ if (bit<0) or (CurrentSize and (Bit >= FBSize)) then
    BitsErrorFmt(SErrInvalidBitIndex,[bit]);
    BitsErrorFmt(SErrInvalidBitIndex,[bit]);
  if (bit>=MaxBitFlags) then
  if (bit>=MaxBitFlags) then
    BitsErrorFmt(SErrIndexTooLarge,[bit])
    BitsErrorFmt(SErrIndexTooLarge,[bit])
 
 
 end;
 end;
 
 
+procedure TBits.Resize(Nbit: longint);
+var
+   newSize : longint;
+   loop : longint;
+begin
+   CheckBitindex(nbit,false);
+
+   newSize :=  (nbit shr BITSHIFT) + 1;
+
+   if newSize <> FSize then
+   begin
+      ReAllocMem(FBits, newSize * SizeOf(longint));
+      if FBits <> nil then
+        begin
+         if newSize > FSize then
+            for loop := FSize to newSize - 1 do
+               FBits^[loop] := 0;
+         FSize := newSize;
+         FBSize := nbit + 1;
+       end
+      else
+        BitsError(SErrOutOfMemory);
+   end;
+end;
+
 { ************* functions to match TBits class ************* }
 { ************* functions to match TBits class ************* }
 
 
 function TBits.getSize : longint;
 function TBits.getSize : longint;
 begin
 begin
-   result := (FSize shl BITSHIFT) - 1;
+   result := FBSize;
 end;
 end;
 
 
 procedure TBits.setSize(value : longint);
 procedure TBits.setSize(value : longint);
 begin
 begin
    if value=0 then
    if value=0 then
-    grow(0) // truncate
+    resize(0) // truncate
    else
    else
-    grow(value - 1);
+     Resize(value - 1);
+   FBSize:= value;
 end;
 end;
 
 
 procedure TBits.SetBit(bit : longint; value : Boolean);
 procedure TBits.SetBit(bit : longint; value : Boolean);
@@ -64,6 +97,7 @@ var
    loop : longint;
    loop : longint;
    loop2 : longint;
    loop2 : longint;
    startIndex : longint;
    startIndex : longint;
+   stopIndex : Longint;
 begin
 begin
    result := -1; {should only occur if the whole array is set}
    result := -1; {should only occur if the whole array is set}
    for loop := 0 to FSize - 1 do
    for loop := 0 to FSize - 1 do
@@ -71,7 +105,8 @@ begin
       if FBits^[loop] <> $FFFFFFFF then
       if FBits^[loop] <> $FFFFFFFF then
       begin
       begin
          startIndex := loop * 32;
          startIndex := loop * 32;
-         for loop2 := startIndex to startIndex + 31 do
+         stopIndex := liMin ( FBSize -1,startIndex + 31) ;
+         for loop2 := startIndex to stopIndex do
          begin
          begin
             if get(loop2) = False then
             if get(loop2) = False then
             begin
             begin
@@ -79,6 +114,10 @@ begin
                break; { use this as the index to return }
                break; { use this as the index to return }
             end;
             end;
          end;
          end;
+         if result = -1 then begin
+           result := FBSize;
+           inc(FBSize);
+           end;
          break;  {stop looking for empty bit in records }
          break;  {stop looking for empty bit in records }
       end;
       end;
    end;
    end;
@@ -93,10 +132,11 @@ end;
 constructor TBits.Create(theSize : longint = 0 );
 constructor TBits.Create(theSize : longint = 0 );
 begin
 begin
    FSize := 0;
    FSize := 0;
+   FBSize := 0;
    FBits := nil;
    FBits := nil;
    findIndex := -1;
    findIndex := -1;
    findState := True;  { no reason just setting it to something }
    findState := True;  { no reason just setting it to something }
-   grow(theSize);
+   if TheSize > 0 then grow(theSize-1);
 end;
 end;
 
 
 destructor TBits.Destroy;
 destructor TBits.Destroy;
@@ -111,25 +151,9 @@ end;
 procedure TBits.grow(nbit : longint);
 procedure TBits.grow(nbit : longint);
 var
 var
    newSize : longint;
    newSize : longint;
-   loop : longint;
 begin
 begin
-   CheckBitindex(nbit,false);
-
    newSize :=  (nbit shr BITSHIFT) + 1;
    newSize :=  (nbit shr BITSHIFT) + 1;
-
-   if newSize > FSize then
-   begin
-      ReAllocMem(FBits, newSize * SizeOf(longint));
-      if FBits <> nil then
-        begin
-         if newSize > FSize then
-            for loop := FSize to newSize - 1 do
-               FBits^[loop] := 0;
-         FSize := newSize;
-       end
-      else
-        BitsError(SErrOutOfMemory);
-   end;
+   if newSize > FSize then Resize(nbit);
 end;
 end;
 
 
 function TBits.getFSize : longint;
 function TBits.getFSize : longint;
@@ -144,6 +168,7 @@ begin
    n := bit shr BITSHIFT;
    n := bit shr BITSHIFT;
    grow(bit);
    grow(bit);
    FBits^[n] := FBits^[n] or (longint(1) shl (bit and MASK));
    FBits^[n] := FBits^[n] or (longint(1) shl (bit and MASK));
+   if bit >= FBSize then FBSize := bit;
 end;
 end;
 
 
 procedure TBits.clear(bit : longint);
 procedure TBits.clear(bit : longint);
@@ -154,6 +179,7 @@ begin
    n := bit shr BITSHIFT;
    n := bit shr BITSHIFT;
    grow(bit);
    grow(bit);
    FBits^[n] := FBits^[n] and not(longint(1) shl (bit and MASK));
    FBits^[n] := FBits^[n] and not(longint(1) shl (bit and MASK));
+   if bit >= FBSize then FBSize := bit + 1;
 end;
 end;
 
 
 procedure TBits.clearall;
 procedure TBits.clearall;
@@ -162,6 +188,8 @@ var
 begin
 begin
    for loop := 0 to FSize - 1 do
    for loop := 0 to FSize - 1 do
       FBits^[loop] := 0;
       FBits^[loop] := 0;
+   {Should FBSize be cleared too? - I think so}
+   FBSize := 0;
 end;
 end;
 
 
 function TBits.get(bit : longint) : Boolean;
 function TBits.get(bit : longint) : Boolean;
@@ -275,6 +303,7 @@ end;
 
 
 procedure TBits.SetIndex(index : longint);
 procedure TBits.SetIndex(index : longint);
 begin
 begin
+   CheckBitIndex(index,true);
    findIndex := index;
    findIndex := index;
 end;
 end;
 
 
@@ -288,6 +317,7 @@ var
    loop : longint;
    loop : longint;
    loop2 : longint;
    loop2 : longint;
    startIndex : longint;
    startIndex : longint;
+   stopIndex : Longint;
    compareVal : cardinal;
    compareVal : cardinal;
 begin
 begin
    result := -1; {should only occur if none are set}
    result := -1; {should only occur if none are set}
@@ -304,7 +334,8 @@ begin
       if FBits^[loop] <> compareVal then
       if FBits^[loop] <> compareVal then
       begin
       begin
          startIndex := loop * 32;
          startIndex := loop * 32;
-         for loop2 := startIndex to startIndex + 31 do
+         stopIndex:= liMin(StartIndex+31,FBSize -1);
+         for loop2 := startIndex to stopIndex do
          begin
          begin
             if get(loop2) = state then
             if get(loop2) = state then
             begin
             begin