IdContainers.pas 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. {
  2. $Project$
  3. $Workfile$
  4. $Revision$
  5. $DateUTC$
  6. $Id$
  7. This file is part of the Indy (Internet Direct) project, and is offered
  8. under the dual-licensing agreement described on the Indy website.
  9. (http://www.indyproject.org/)
  10. Copyright:
  11. (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
  12. }
  13. {
  14. $Log$
  15. }
  16. {
  17. Rev 1.7 10/26/2004 11:08:10 PM JPMugaas
  18. Updated refs.
  19. Rev 1.6 28.09.2004 21:35:28 Andreas Hausladen
  20. Added TIdObjectList.Assign method for missing Delphi 5 TList.Assign
  21. Rev 1.5 1/4/2004 12:09:00 AM BGooijen
  22. Commented out Notify, this doesn't exist in DotNet, and doesn't do anything
  23. anyways
  24. Rev 1.4 3/13/2003 11:10:52 AM JPMugaas
  25. Fixed warning message.
  26. Rev 1.3 2/8/2003 04:33:34 AM JPMugaas
  27. Commented out a free statement in the TIdObjectList.Notify method because it
  28. was causing instability in some new IdFTPList code I was working on.
  29. Added a TStringList descendent object that implements a buble sort. That
  30. should require less memory than a QuickSort. This also replaces the
  31. TStrings.CustomSort because that is not supported in D4.
  32. Rev 1.2 2/7/2003 10:33:48 AM JPMugaas
  33. Added BoubleSort to TIdObjectList to facilitate some work.
  34. Rev 1.1 12/2/2002 04:32:30 AM JPMugaas
  35. Fixed minor compile errors.
  36. Rev 1.0 11/14/2002 02:16:14 PM JPMugaas
  37. Revision 1.0 2001-02-20 02:02:09-05 dsiders
  38. Initial revision
  39. }
  40. {********************************************************************}
  41. {* IdContainers.pas *}
  42. {* *}
  43. {* Provides compatibility with the Contnr.pas unit from *}
  44. {* Delphi 5 not found in Delphi 4. *}
  45. {* *}
  46. {* Based on ideas from the Borland VCL Contnr.pas interface. *}
  47. {* *}
  48. {********************************************************************}
  49. unit IdContainers;
  50. interface
  51. {$i IdCompilerDefines.inc}
  52. uses
  53. Classes
  54. {$IFDEF HAS_UNIT_Generics_Collections}
  55. , System.Generics.Collections
  56. {$ELSE}
  57. {$IFDEF HAS_TObjectList}
  58. , Contnrs
  59. {$ENDIF}
  60. {$ENDIF}
  61. ;
  62. type
  63. {$IFDEF HAS_GENERICS_TObjectList}
  64. TIdSortCompare<T: class> = function(AItem1, AItem2 : T): Integer;
  65. {$ELSE}
  66. TIdSortCompare = function(AItem1, AItem2 : TObject): Integer;
  67. {$ENDIF}
  68. {TIdObjectList}
  69. {$IFDEF HAS_GENERICS_TObjectList}
  70. TIdObjectList<T: class> = class(TObjectList<T>)
  71. public
  72. procedure BubbleSort(ACompare : TIdSortCompare<T>);
  73. procedure Assign(Source: TIdObjectList<T>);
  74. end;
  75. {$ELSE}
  76. {$IFDEF HAS_TObjectList}
  77. TIdObjectList = class(TObjectList)
  78. public
  79. procedure BubbleSort(ACompare : TIdSortCompare);
  80. // Delphi 5 does not have TList.Assign.
  81. // This is a simplyfied Assign method that does only support the copy operation.
  82. procedure Assign(Source: TIdObjectList); {$IFDEF VCL_6_OR_ABOVE}reintroduce;{$ENDIF}
  83. end;
  84. {$ELSE}
  85. TIdObjectList = class(TList)
  86. private
  87. FOwnsObjects: Boolean;
  88. protected
  89. function GetItem(AIndex: Integer): TObject;
  90. procedure SetItem(AIndex: Integer; AObject: TObject);
  91. {$IFNDEF DOTNET}
  92. procedure Notify(AItemPtr: Pointer; AAction: TListNotification); override;
  93. {$ENDIF}
  94. public
  95. constructor Create; overload;
  96. constructor Create(AOwnsObjects: Boolean); overload;
  97. procedure BubbleSort(ACompare : TIdSortCompare);
  98. function Add(AObject: TObject): Integer;
  99. function FindInstanceOf(AClassRef: TClass; AMatchExact: Boolean = True; AStartPos: Integer = 0): Integer;
  100. function IndexOf(AObject: TObject): Integer;
  101. function Remove(AObject: TObject): Integer;
  102. procedure Insert(AIndex: Integer; AObject: TObject);
  103. procedure Assign(Source: TIdObjectList);
  104. property Items[AIndex: Integer]: TObject read GetItem write SetItem; default;
  105. property OwnsObjects: Boolean read FOwnsObjects write FOwnsObjects;
  106. end;
  107. {$ENDIF}
  108. {$ENDIF}
  109. TIdStringListSortCompare = function(List: TStringList; Index1, Index2: Integer): Integer;
  110. TIdBubbleSortStringList = class(TStringList)
  111. public
  112. procedure BubbleSort(ACompare: TIdStringListSortCompare); virtual;
  113. end;
  114. implementation
  115. {$IFDEF VCL_XE3_OR_ABOVE}
  116. uses
  117. System.Types;
  118. {$ENDIF}
  119. { TIdObjectList }
  120. {$IFNDEF HAS_GENERICS_TObjectList}
  121. {$IFNDEF HAS_TObjectList}
  122. constructor TIdObjectList.Create;
  123. begin
  124. inherited Create;
  125. FOwnsObjects := True;
  126. end;
  127. constructor TIdObjectList.Create(AOwnsObjects: Boolean);
  128. begin
  129. inherited Create;
  130. FOwnsObjects := AOwnsObjects;
  131. end;
  132. function TIdObjectList.Add(AObject: TObject): Integer;
  133. begin
  134. Result := inherited Add(AObject);
  135. end;
  136. function TIdObjectList.FindInstanceOf(AClassRef: TClass;
  137. AMatchExact: Boolean = True; AStartPos: Integer = 0): Integer;
  138. var
  139. iPos: Integer;
  140. bIsAMatch: Boolean;
  141. begin
  142. Result := -1; // indicates item is not in object list
  143. for iPos := AStartPos to Count - 1 do
  144. begin
  145. bIsAMatch :=
  146. ((not AMatchExact) and Items[iPos].InheritsFrom(AClassRef)) or
  147. (AMatchExact and (Items[iPos].ClassType = AClassRef));
  148. if bIsAMatch then
  149. begin
  150. Result := iPos;
  151. Break;
  152. end;
  153. end;
  154. end;
  155. function TIdObjectList.GetItem(AIndex: Integer): TObject;
  156. begin
  157. Result := inherited Items[AIndex];
  158. end;
  159. function TIdObjectList.IndexOf(AObject: TObject): Integer;
  160. begin
  161. Result := inherited IndexOf(AObject);
  162. end;
  163. procedure TIdObjectList.Insert(AIndex: Integer; AObject: TObject);
  164. begin
  165. inherited Insert(AIndex, AObject);
  166. end;
  167. {$IFNDEF DOTNET}
  168. procedure TIdObjectList.Notify(AItemPtr: Pointer; AAction: TListNotification);
  169. begin
  170. if OwnsObjects and (AAction = lnDeleted) then begin
  171. TObject(AItemPtr).Free;
  172. end;
  173. inherited Notify(AItemPtr, AAction);
  174. end;
  175. {$ENDIF}
  176. function TIdObjectList.Remove(AObject: TObject): Integer;
  177. begin
  178. Result := inherited Remove(AObject);
  179. end;
  180. procedure TIdObjectList.SetItem(AIndex: Integer; AObject: TObject);
  181. begin
  182. inherited Items[AIndex] := AObject;
  183. end;
  184. {$ENDIF}
  185. {$ENDIF}
  186. {$IFDEF HAS_GENERICS_TObjectList}
  187. procedure TIdObjectList<T>.BubbleSort(ACompare: TIdSortCompare<T>);
  188. {$ELSE}
  189. procedure TIdObjectList.BubbleSort(ACompare: TIdSortCompare);
  190. {$ENDIF}
  191. var
  192. i, n, newn : Integer;
  193. begin
  194. n := Count;
  195. repeat
  196. newn := 0;
  197. for i := 1 to n-1 do begin
  198. if ACompare(Items[i-1], Items[i]) > 0 then begin
  199. Exchange(i-1, i);
  200. newn := i;
  201. end;
  202. end;
  203. n := newn;
  204. until n = 0;
  205. end;
  206. {$IFDEF HAS_GENERICS_TObjectList}
  207. procedure TIdObjectList<T>.Assign(Source: TIdObjectList<T>);
  208. {$ELSE}
  209. procedure TIdObjectList.Assign(Source: TIdObjectList);
  210. {$ENDIF}
  211. var
  212. I: Integer;
  213. begin
  214. // Delphi 5 does not have TList.Assign.
  215. // This is a simplyfied Assign method that does only support the copy operation.
  216. Clear;
  217. Capacity := Source.Capacity;
  218. for I := 0 to Source.Count - 1 do begin
  219. Add(Source[I]);
  220. end;
  221. end;
  222. { TIdBubbleSortStringList }
  223. procedure TIdBubbleSortStringList.BubbleSort(ACompare: TIdStringListSortCompare);
  224. var
  225. i, n, newn : Integer;
  226. begin
  227. n := Count;
  228. repeat
  229. newn := 0;
  230. for i := 1 to n-1 do begin
  231. if ACompare(Self, i-1, i) > 0 then begin
  232. Exchange(i-1, i);
  233. newn := i;
  234. end;
  235. end;
  236. n := newn;
  237. until n = 0;
  238. end;
  239. end.