uMapObject.pas 4.2 KB

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