uKeyInterface.pas 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. unit uKeyInterface;
  2. ////
  3. //// 添加Delete函数
  4. /// 2014年1月20日 14:07:30
  5. //// 添加remove函数
  6. //// 2014年1月17日 17:21:26
  7. interface
  8. uses
  9. Classes, SysUtils, Windows;
  10. type
  11. TKeyStr = string[255];
  12. TEntryBlock = record
  13. key: TKeyStr;
  14. intf: IInterface;
  15. end;
  16. PEntryBlock = ^TEntryBlock;
  17. TKeyInterface = class(TObject)
  18. private
  19. FList: TList;
  20. function findBlock(const key: TKeyStr): PEntryBlock;
  21. function findIndex(const key:String): Integer;
  22. function Getcount: Integer;
  23. function GetValues(Index: Integer): IInterface;
  24. public
  25. procedure clear;
  26. constructor Create;
  27. destructor Destroy; override;
  28. function exists(const key:string): Boolean;
  29. function find(const key:string): IInterface;
  30. procedure remove(const key:string);
  31. procedure Delete(pvIndex:Integer);
  32. procedure put(const key: string; const intf: IInterface);
  33. property count: Integer read Getcount;
  34. property Values[Index: Integer]: IInterface read GetValues; default;
  35. end;
  36. implementation
  37. procedure TKeyInterface.clear;
  38. var
  39. lvBlock:PEntryBlock;
  40. begin
  41. while FList.Count > 0 do
  42. begin
  43. lvBlock := PEntryBlock(FList[0]);
  44. try
  45. lvBlock.intf := nil;
  46. except
  47. //屏蔽掉释放错误
  48. end;
  49. FreeMem(lvBlock, SizeOf(TEntryBlock));
  50. FList.Delete(0);
  51. end;
  52. end;
  53. constructor TKeyInterface.Create;
  54. begin
  55. inherited Create;
  56. FList := TList.Create();
  57. end;
  58. procedure TKeyInterface.Delete(pvIndex: Integer);
  59. var
  60. lvBlock:PEntryBlock;
  61. begin
  62. if (pvIndex < 0) or (pvIndex >= FList.Count) then
  63. raise Exception.CreateFmt('keyInterface out of bound[%d]', [pvIndex]);
  64. lvBlock := PEntryBlock(FList[pvIndex]);
  65. try
  66. lvBlock.intf := nil;
  67. except
  68. end;
  69. FreeMem(lvBlock, SizeOf(TEntryBlock));
  70. FList.Delete(pvIndex);
  71. end;
  72. destructor TKeyInterface.Destroy;
  73. begin
  74. clear;
  75. FList.Free;
  76. inherited Destroy;
  77. end;
  78. function TKeyInterface.exists(const key:string): Boolean;
  79. begin
  80. Result := findBlock(TKeyStr(key)) <> nil;
  81. end;
  82. function TKeyInterface.find(const key:string): IInterface;
  83. var
  84. lvBlock:PEntryBlock;
  85. begin
  86. lvBlock := findBlock(TKeyStr(key));
  87. if lvBlock <> nil then
  88. begin
  89. Result := lvBlock.intf;
  90. end;
  91. end;
  92. function TKeyInterface.findBlock(const key: TKeyStr): PEntryBlock;
  93. var
  94. i:Integer;
  95. lvBlock:PEntryBlock;
  96. begin
  97. Result := nil;
  98. for i := 0 to FList.Count - 1 do
  99. begin
  100. lvBlock := PEntryBlock(FList[i]);
  101. if sameText(string(lvBlock.key), String(key)) then
  102. begin
  103. Result := lvBlock;
  104. Break;
  105. end;
  106. end;
  107. end;
  108. function TKeyInterface.findIndex(const key: String): Integer;
  109. var
  110. i:Integer;
  111. lvBlock:PEntryBlock;
  112. begin
  113. Result := -1;
  114. for i := 0 to FList.Count - 1 do
  115. begin
  116. lvBlock := PEntryBlock(FList[i]);
  117. if sameText(string(lvBlock.key), key) then
  118. begin
  119. Result := i;
  120. Break;
  121. end;
  122. end;
  123. end;
  124. function TKeyInterface.Getcount: Integer;
  125. begin
  126. Result := FList.Count;
  127. end;
  128. function TKeyInterface.GetValues(Index: Integer): IInterface;
  129. var
  130. lvBlock:PEntryBlock;
  131. begin
  132. Result := nil;
  133. lvBlock := PEntryBlock(FList[Index]);
  134. if lvBlock <> nil then
  135. begin
  136. Result := lvBlock.intf;
  137. end;
  138. end;
  139. procedure TKeyInterface.put(const key: string; const intf: IInterface);
  140. var
  141. lvBlock:PEntryBlock;
  142. lvkey:TKeyStr;
  143. begin
  144. lvkey := TKeyStr(key);
  145. lvBlock := findBlock(lvkey);
  146. if lvBlock <> nil then
  147. begin
  148. lvBlock.intf := intf;
  149. end else
  150. begin
  151. GetMem(lvBlock, SizeOf(TEntryBlock));
  152. ZeroMemory(lvBlock, SizeOf(TEntryBlock));
  153. lvBlock.key := lvkey;
  154. lvBlock.intf := intf;
  155. FList.Add(lvBlock);
  156. end;
  157. end;
  158. procedure TKeyInterface.remove(const key: string);
  159. var
  160. lvBlock:PEntryBlock;
  161. i:Integer;
  162. begin
  163. i := findIndex(key);
  164. if i <> -1 then
  165. begin
  166. lvBlock := PEntryBlock(FList[i]);
  167. lvBlock.intf := nil;
  168. FreeMem(lvBlock, SizeOf(TEntryBlock));
  169. FList.Delete(i);
  170. end;
  171. end;
  172. end.