123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- unit dbf_prssupp;
- // parse support
- {$I dbf_common.inc}
- interface
- uses
- Classes;
- type
- {TOCollection interfaces between OWL TCollection and VCL TList}
- TOCollection = class(TList)
- public
- procedure AtFree(Index: Integer);
- procedure FreeAll;
- procedure DoFree(Item: Pointer);
- procedure FreeItem(Item: Pointer); virtual;
- destructor Destroy; override;
- end;
- TNoOwnerCollection = class(TOCollection)
- public
- procedure FreeItem(Item: Pointer); override;
- end;
- { TSortedCollection object }
- TSortedCollection = class(TOCollection)
- public
- function Compare(Key1, Key2: Pointer): Integer; virtual; abstract;
- function IndexOf(Item: Pointer): Integer; virtual;
- procedure Add(Item: Pointer); virtual;
- procedure AddReplace(Item: Pointer); virtual;
- procedure AddList(Source: TList; FromIndex, ToIndex: Integer);
- {if duplicate then replace the duplicate else add}
- function KeyOf(Item: Pointer): Pointer; virtual;
- function Search(Key: Pointer; var Index: Integer): Boolean; virtual;
- end;
- { TStrCollection object }
- TStrCollection = class(TSortedCollection)
- public
- function Compare(Key1, Key2: Pointer): Integer; override;
- procedure FreeItem(Item: Pointer); override;
- end;
- implementation
- uses SysUtils;
- destructor TOCollection.Destroy;
- begin
- FreeAll;
- inherited Destroy;
- end;
- procedure TOCollection.AtFree(Index: Integer);
- var
- Item: Pointer;
- begin
- Item := Items[Index];
- Delete(Index);
- FreeItem(Item);
- end;
- procedure TOCollection.FreeAll;
- var
- I: Integer;
- begin
- try
- for I := 0 to Count - 1 do
- FreeItem(Items[I]);
- finally
- Count := 0;
- end;
- end;
- procedure TOCollection.DoFree(Item: Pointer);
- begin
- AtFree(IndexOf(Item));
- end;
- procedure TOCollection.FreeItem(Item: Pointer);
- begin
- if (Item <> nil) then
- with TObject(Item) as TObject do
- Free;
- end;
- {----------------------------------------------------------------virtual;
- Implementing TNoOwnerCollection
- -----------------------------------------------------------------}
- procedure TNoOwnerCollection.FreeItem(Item: Pointer);
- begin
- end;
- { TSortedCollection }
- function TSortedCollection.IndexOf(Item: Pointer): Integer;
- var
- I: Integer;
- begin
- IndexOf := -1;
- if Search(KeyOf(Item), I) then
- begin
- while (I < Count) and (Item <> Items[I]) do
- Inc(I);
- if I < Count then IndexOf := I;
- end;
- end;
- procedure TSortedCollection.AddReplace(Item: Pointer);
- var
- Index: Integer;
- begin
- if Search(KeyOf(Item), Index) then
- Delete(Index);
- Add(Item);
- end;
- procedure TSortedCollection.Add(Item: Pointer);
- var
- I: Integer;
- begin
- Search(KeyOf(Item), I);
- Insert(I, Item);
- end;
- procedure TSortedCollection.AddList(Source: TList; FromIndex, ToIndex: Integer);
- var
- I: Integer;
- begin
- for I := FromIndex to ToIndex do
- Add(Source.Items[I]);
- end;
- function TSortedCollection.KeyOf(Item: Pointer): Pointer;
- begin
- Result := Item;
- end;
- function TSortedCollection.Search(Key: Pointer; var Index: Integer): Boolean;
- var
- L, H, I, C: Integer;
- begin
- Search := False;
- L := 0;
- H := Count - 1;
- while L <= H do
- begin
- I := (L + H) div 2;
- C := Compare(KeyOf(Items[I]), Key);
- if C < 0 then
- L := I + 1
- else
- begin
- H := I - 1;
- if C = 0 then
- Search := True;
- end;
- end;
- Index := L;
- end;
- { TStrCollection }
- function TStrCollection.Compare(Key1, Key2: Pointer): Integer;
- begin
- Compare := StrComp(Key1, Key2);
- end;
- procedure TStrCollection.FreeItem(Item: Pointer);
- begin
- StrDispose(Item);
- end;
- end.
|