IdStrings.pas 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. { $HDR$}
  2. {**********************************************************************}
  3. { Unit archived using Team Coherence }
  4. { Team Coherence is Copyright 2002 by Quality Software Components }
  5. { }
  6. { For further information / comments, visit our WEB site at }
  7. { http://www.TeamCoherence.com }
  8. {**********************************************************************}
  9. {}
  10. { $Log: 10353: IdStrings.pas
  11. {
  12. { Rev 1.0 2002.11.12 10:54:14 PM czhower
  13. }
  14. unit IdStrings;
  15. interface
  16. Uses
  17. Classes;
  18. {
  19. 2000-03-27 Pete Mee
  20. - Added FindFirstOf, FindFirstNotOf and TrimAllOf functions.
  21. 2002-01-03 Andrew P.Rybin
  22. - StrHTMLEnc/Dec,BinToHexStr,SplitColumns,IsWhiteString
  23. 2002-03-12 Andrew P.Rybin
  24. - SplitColumns[NoTrim]
  25. }
  26. function FindFirstOf(AFind, AText: String): Integer;
  27. function FindFirstNotOf(AFind, AText : String) : Integer;
  28. function TrimAllOf(ATrim, AText : String) : String;
  29. // Empty or contain only TAB and Space. Use it vs Length(Trim(AStr))>0
  30. function IsWhiteString(const AStr: String): Boolean;
  31. function BinToHexStr (AData: Pointer; ADataLen: Integer): String;
  32. // Encode reserved html chars: < > ' & " {Do not Localize}
  33. function StrHtmlEncode (const AStr: String): String;
  34. function StrHtmlDecode (const AStr: String): String;
  35. //in Integer(Strings.Objects[i]) - column position in AData
  36. procedure SplitColumnsNoTrim (const AData: String; AStrings: TStrings; const ADelim: String=' '); {Do not Localize}
  37. procedure SplitColumns (const AData: String; AStrings: TStrings; const ADelim: String=' '); {Do not Localize}
  38. procedure SplitLines (AData: PChar; ADataSize: Integer; AStrings: TStrings);
  39. // SplitString splits a string into left and right parts,
  40. // i.e. SplitString('Namespace:tag', ':'..) will return 'Namespace' and 'Tag'
  41. procedure SplitString(const AStr, AToken: String; var VLeft, VRight: String);
  42. // commaadd will append AStr2 to the right of AStr1 and return the result.
  43. // if there is any content in AStr1, a comma will be added
  44. function CommaAdd(Const AStr1, AStr2:String):string;
  45. implementation
  46. uses
  47. IdException,
  48. IdGlobal,
  49. SysUtils;
  50. function StrHtmlEncode (const AStr: String): String;
  51. begin
  52. Result := StringReplace(AStr, '&', '&amp;', [rfReplaceAll]); {Do not Localize}
  53. Result := StringReplace(Result, '<', '&lt;', [rfReplaceAll]); {Do not Localize}
  54. Result := StringReplace(Result, '>', '&gt;', [rfReplaceAll]); {Do not Localize}
  55. Result := StringReplace(Result, '"', '&quot;', [rfReplaceAll]); {Do not Localize}
  56. Result := StringReplace(Result, '''', '&apos;', [rfReplaceAll]); {Do not Localize}
  57. end;
  58. function StrHtmlDecode (const AStr: String): String;
  59. begin
  60. Result := StringReplace(AStr, '&apos;', '''', [rfReplaceAll]); {Do not Localize}
  61. Result := StringReplace(Result, '&quot;', '"', [rfReplaceAll]); {Do not Localize}
  62. Result := StringReplace(Result, '&gt;', '>', [rfReplaceAll]); {Do not Localize}
  63. Result := StringReplace(Result, '&lt;', '<', [rfReplaceAll]); {Do not Localize}
  64. Result := StringReplace(Result, '&amp;', '&', [rfReplaceAll]); {Do not Localize}
  65. end;
  66. {Function ReadTimeStampCounter: Int64;
  67. Asm
  68. db $0F,$31 //RDTSC
  69. End;//Read CPU TimeStamp}
  70. function FindFirstOf(AFind, AText: string): Integer;
  71. var
  72. nCount, nPos: Integer;
  73. begin
  74. Result := 0;
  75. for nCount := 1 to Length(AFind) do begin
  76. nPos := IndyPos(AFind[nCount], AText);
  77. if nPos > 0 then begin
  78. if Result = 0 then begin
  79. Result := nPos;
  80. end else if Result > nPos then begin
  81. Result := nPos;
  82. end;
  83. end;
  84. end;
  85. end;
  86. function FindFirstNotOf(AFind, AText : String) : Integer;
  87. var
  88. i : Integer;
  89. begin
  90. result := 0;
  91. if length(AFind) = 0 then
  92. begin
  93. result := 1;
  94. exit;
  95. end;
  96. if length(AText) = 0 then
  97. begin
  98. exit;
  99. end;
  100. for i := 1 to length(AText) do
  101. begin
  102. if IndyPos(AText[i], AFind) = 0 then
  103. begin
  104. result := i;
  105. exit;
  106. end;
  107. end;
  108. end;
  109. function TrimAllOf(ATrim, AText : String) : String;
  110. begin
  111. while Length(AText) > 0 do
  112. begin
  113. if Pos(AText[1], ATrim) > 0 then
  114. begin
  115. System.Delete(AText, 1, 1);
  116. end else break;
  117. end;
  118. while Length(AText) > 0 do begin
  119. if Pos(AText[length(AText)], ATrim) > 0 then
  120. begin
  121. System.Delete(AText, Length(AText), 1);
  122. end else break;
  123. end;
  124. result := AText;
  125. End;
  126. function BinToHexStr (AData: Pointer; ADataLen: Integer): String;
  127. var
  128. LSrc: PChar;
  129. i: Integer;
  130. Begin
  131. LSrc:=AData;
  132. SetString(Result,NIL,ADataLen*2);
  133. for i:=0 to ADataLen-1 do begin
  134. Result[i*2+1]:=IdHexDigits[ord(LSrc^) shr 4];
  135. Result[i*2+2]:=IdHexDigits[ord(LSrc^) and $F];
  136. inc(LSrc);
  137. end;//for
  138. End;
  139. procedure SplitColumnsNoTrim(const AData: String; AStrings: TStrings; const ADelim: String=' '); {Do not Localize}
  140. var
  141. i: Integer;
  142. LDelim: Integer; //delim len
  143. LLeft: String;
  144. LLastPos: Integer;
  145. Begin
  146. Assert(Assigned(AStrings));
  147. AStrings.Clear;
  148. LDelim := Length(ADelim);
  149. LLastPos := 1;
  150. i := Pos(ADelim, AData);
  151. while I > 0 do begin
  152. LLeft:= Copy(AData, LLastPos, I-LLastPos); //'abc d' len:=i(=4)-1 {Do not Localize}
  153. if LLeft > '' then begin {Do not Localize}
  154. AStrings.AddObject(LLeft,Pointer(LLastPos));
  155. end;
  156. LLastPos := I + LDelim; //first char after Delim
  157. i := PosIdx (ADelim, AData, LLastPos);
  158. end;//while found
  159. if LLastPos <= Length(AData) then begin
  160. AStrings.AddObject(Copy(AData,LLastPos,MaxInt), Pointer(LLastPos));
  161. end;
  162. End;//TIdFTPListItems.ParseColumns
  163. procedure SplitColumns(const AData: String; AStrings: TStrings; const ADelim: String=' '); {Do not Localize}
  164. var
  165. i: Integer;
  166. LData: String;
  167. LDelim: Integer; //delim len
  168. LLeft: String;
  169. LLastPos: Integer;
  170. LLeadingSpaceCnt: Integer;
  171. Begin
  172. Assert(Assigned(AStrings));
  173. AStrings.Clear;
  174. LDelim := Length(ADelim);
  175. LLastPos := 1;
  176. LData := Trim(AData);
  177. LLeadingSpaceCnt := 0;
  178. if Length(LData)>0 then begin //if Not WhiteStr
  179. while AData[LLeadingSpaceCnt+1]<=' ' do inc(LLeadingSpaceCnt);
  180. end
  181. else begin
  182. EXIT;
  183. end;
  184. i := Pos(ADelim, LData);
  185. while I > 0 do begin
  186. LLeft:= Copy(LData, LLastPos, I-LLastPos); //'abc d' len:=i(=4)-1 {Do not Localize}
  187. if LLeft > '' then begin {Do not Localize}
  188. AStrings.AddObject(Trim(LLeft),Pointer(LLastPos+LLeadingSpaceCnt));
  189. end;
  190. LLastPos := I + LDelim; //first char after Delim
  191. i := PosIdx (ADelim, LData, LLastPos);
  192. end;//while found
  193. if LLastPos <= Length(LData) then begin
  194. AStrings.AddObject(Trim( Copy(LData,LLastPos,MaxInt) ), Pointer(LLastPos+LLeadingSpaceCnt));
  195. end;
  196. End;//TIdFTPListItems.ParseColumns
  197. function IsWhiteString(const AStr: String): Boolean;
  198. const
  199. WhiteSet = [TAB,' ']; {Do not Localize}
  200. var
  201. i: Integer;
  202. LLen: Integer;
  203. Begin
  204. LLen := Length(AStr);
  205. if LLen > 0 then begin
  206. Result:=TRUE; //only white
  207. for i:=1 to LLen do begin
  208. if NOT (AStr[i] in WhiteSet) then begin
  209. Result:=FALSE;
  210. EXIT;
  211. end;
  212. end;
  213. end
  214. else begin
  215. Result:=TRUE; //empty
  216. end;
  217. End;//IsWhiteString
  218. procedure SplitString(const AStr, AToken: String; var VLeft, VRight: String);
  219. var
  220. i: Integer;
  221. LLocalStr: String;
  222. begin
  223. { It is possible that VLeft or VRight may be the same variable as AStr. So we copy it first }
  224. LLocalStr := AStr;
  225. i := Pos(AToken, LLocalStr);
  226. if i = 0 then
  227. begin
  228. VLeft := LLocalStr;
  229. VRight := '';
  230. end
  231. else
  232. begin
  233. VLeft := Copy(LLocalStr, 1, i - 1);
  234. VRight := Copy(LLocalStr, i + Length(AToken), Length(LLocalStr));
  235. end;
  236. end;
  237. function CommaAdd(Const AStr1, AStr2:String):string;
  238. begin
  239. if AStr1 = '' then
  240. result := AStr2
  241. else
  242. result := AStr1 + ',' + AStr2;
  243. end;
  244. procedure SplitLines (AData: PChar; ADataSize: Integer; AStrings: TStrings);
  245. var
  246. P, LLast, Start: PChar;
  247. S: string;
  248. begin
  249. AStrings.BeginUpdate;
  250. try
  251. AStrings.Clear;
  252. P := AData;
  253. if P <> NIL then begin
  254. LLast := P+ADataSize;
  255. while P < LLast do begin
  256. Start := P;
  257. while (P < LLast) and NOT (P^ in [CR, LF]) do Inc(P);
  258. SetString(S, Start, P - Start);
  259. AStrings.AddObject(S, Pointer(Start - AData +1));
  260. if P^ = #13 then Inc(P);
  261. if P^ = #10 then Inc(P);
  262. end;//while
  263. end;//if
  264. finally
  265. AStrings.EndUpdate;
  266. end;
  267. End;//SplitLines
  268. END.