dbf_prssupp.pas 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. unit dbf_prssupp;
  2. // parse support
  3. {$i Dbf_Common.inc}
  4. interface
  5. uses
  6. Classes;
  7. type
  8. {TOCollection interfaces between OWL TCollection and VCL TList}
  9. TOCollection = class(TList)
  10. public
  11. procedure AtFree(Index: Integer);
  12. procedure FreeAll;
  13. procedure DoFree(Item: Pointer);
  14. procedure FreeItem(Item: Pointer); virtual;
  15. destructor Destroy; override;
  16. end;
  17. TNoOwnerCollection = class(TOCollection)
  18. public
  19. procedure FreeItem(Item: Pointer); override;
  20. end;
  21. { TSortedCollection object }
  22. TSortedCollection = class(TOCollection)
  23. public
  24. function Compare(Key1, Key2: Pointer): Integer; virtual; abstract;
  25. function IndexOf(Item: Pointer): Integer; virtual;
  26. procedure Add(Item: Pointer); virtual;
  27. procedure AddReplace(Item: Pointer); virtual;
  28. procedure AddList(Source: TList; FromIndex, ToIndex: Integer);
  29. {if duplicate then replace the duplicate else add}
  30. function KeyOf(Item: Pointer): Pointer; virtual;
  31. function Search(Key: Pointer; var Index: Integer): Boolean; virtual;
  32. end;
  33. { TStrCollection object }
  34. TStrCollection = class(TSortedCollection)
  35. public
  36. function Compare(Key1, Key2: Pointer): Integer; override;
  37. procedure FreeItem(Item: Pointer); override;
  38. end;
  39. implementation
  40. uses SysUtils;
  41. destructor TOCollection.Destroy;
  42. begin
  43. FreeAll;
  44. inherited Destroy;
  45. end;
  46. procedure TOCollection.AtFree(Index: Integer);
  47. var
  48. Item: Pointer;
  49. begin
  50. Item := Items[Index];
  51. Delete(Index);
  52. FreeItem(Item);
  53. end;
  54. procedure TOCollection.FreeAll;
  55. var
  56. I: Integer;
  57. begin
  58. try
  59. for I := 0 to Count - 1 do
  60. FreeItem(Items[I]);
  61. finally
  62. Count := 0;
  63. end;
  64. end;
  65. procedure TOCollection.DoFree(Item: Pointer);
  66. begin
  67. AtFree(IndexOf(Item));
  68. end;
  69. procedure TOCollection.FreeItem(Item: Pointer);
  70. begin
  71. if (Item <> nil) then
  72. with TObject(Item) as TObject do
  73. Free;
  74. end;
  75. {----------------------------------------------------------------virtual;
  76. Implementing TNoOwnerCollection
  77. -----------------------------------------------------------------}
  78. procedure TNoOwnerCollection.FreeItem(Item: Pointer);
  79. begin
  80. end;
  81. { TSortedCollection }
  82. function TSortedCollection.IndexOf(Item: Pointer): Integer;
  83. var
  84. I: Integer;
  85. begin
  86. IndexOf := -1;
  87. if Search(KeyOf(Item), I) then
  88. begin
  89. while (I < Count) and (Item <> Items[I]) do
  90. Inc(I);
  91. if I < Count then IndexOf := I;
  92. end;
  93. end;
  94. procedure TSortedCollection.AddReplace(Item: Pointer);
  95. var
  96. Index: Integer;
  97. begin
  98. if Search(KeyOf(Item), Index) then
  99. Delete(Index);
  100. Add(Item);
  101. end;
  102. procedure TSortedCollection.Add(Item: Pointer);
  103. var
  104. I: Integer;
  105. begin
  106. Search(KeyOf(Item), I);
  107. Insert(I, Item);
  108. end;
  109. procedure TSortedCollection.AddList(Source: TList; FromIndex, ToIndex: Integer);
  110. var
  111. I: Integer;
  112. begin
  113. for I := FromIndex to ToIndex do
  114. Add(Source.Items[I]);
  115. end;
  116. function TSortedCollection.KeyOf(Item: Pointer): Pointer;
  117. begin
  118. Result := Item;
  119. end;
  120. function TSortedCollection.Search(Key: Pointer; var Index: Integer): Boolean;
  121. var
  122. L, H, I, C: Integer;
  123. begin
  124. Search := False;
  125. L := 0;
  126. H := Count - 1;
  127. while L <= H do
  128. begin
  129. I := (L + H) div 2;
  130. C := Compare(KeyOf(Items[I]), Key);
  131. if C < 0 then
  132. L := I + 1
  133. else
  134. begin
  135. H := I - 1;
  136. if C = 0 then
  137. Search := True;
  138. end;
  139. end;
  140. Index := L;
  141. end;
  142. { TStrCollection }
  143. function TStrCollection.Compare(Key1, Key2: Pointer): Integer;
  144. begin
  145. Compare := StrComp(Key1, Key2);
  146. end;
  147. procedure TStrCollection.FreeItem(Item: Pointer);
  148. begin
  149. StrDispose(Item);
  150. end;
  151. end.