TStringUnit.pas 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. {
  2. Copyright 2005-2006 Log4Delphi Project
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. }
  13. {*----------------------------------------------------------------------------
  14. Contains the TString class.
  15. @version 0.5
  16. @author <a href="mailto:tcmiller@users.sourceforge.net">Trevor Miller</a>
  17. ----------------------------------------------------------------------------}
  18. unit TStringUnit;
  19. {$ifdef fpc}
  20. {$mode objfpc}
  21. {$h+}
  22. {$endif}
  23. interface
  24. uses
  25. SysUtils, Classes;
  26. type
  27. {*----------------------------------------------------------------------------
  28. This class is meant to mimic the java.lang.String class and is provided
  29. purely for utility in that it extends TObject it may be used as an
  30. object in a TStrings list.
  31. ----------------------------------------------------------------------------}
  32. TString = class (TObject)
  33. private
  34. FValue : String;
  35. FCount : Integer;
  36. FOffset : Integer;
  37. public
  38. constructor Create; Overload;
  39. constructor Create(const AValue : array of char); Overload;
  40. constructor Create(const AValue : String); Overload;
  41. constructor Create(const AValue : TString); Overload;
  42. procedure SetString(const AString : String);
  43. procedure ToUppercase();
  44. procedure ToLowerCase();
  45. procedure Trim();
  46. function CharAt(const AIndex : Integer) : Char;
  47. function CompareTo(const AString : String) : Integer;
  48. function CompareToIgnoreCase(const AString : String) : Integer;
  49. function Concat(const str : String) : TString;
  50. function EndsWith(const ASuffix : String) : Boolean; Overload;
  51. function EndsWith(const ASuffix : String; AOffset : Integer) :
  52. Boolean; Overload;
  53. function Equals(const AString : String) : Boolean;
  54. function EqualsIgnoreCase(const AString : String) : Boolean;
  55. function IndexOf(const AChar : Char) : Integer; Overload;
  56. function IndexOf(const ACHar : Char; const AIndex : Integer) :
  57. Integer; Overload;
  58. function IndexOf(const Astring : String) : Integer; Overload;
  59. function IndexOf(const AString : String; const AIndex : Integer) :
  60. Integer; Overload;
  61. function LastIndexOf(const AChar : Char) : Integer; Overload;
  62. function LastIndexOf(const AChar : Char; const AIndex : Integer) :
  63. Integer; Overload;
  64. function LastIndexOf(const AString : String) : Integer; Overload;
  65. function LastIndexOf(const AString : String; const AIndex : Integer) :
  66. Integer; Overload;
  67. function Length() : Integer;
  68. function Replace(const AOldChar : Char; const ANewChar : Char) : TString;
  69. function StartsWith(const AString : String) : Boolean; Overload;
  70. function StartsWith(const AString : String; const AIndex : Integer) :
  71. Boolean; Overload;
  72. function Substring(const AStartIndex : Integer) : TString; Overload;
  73. function Substring(const AStartIndex : Integer; const AEndIndex : Integer) :
  74. TString; Overload;
  75. function ToString() : String;
  76. end;
  77. TStringTokenizer = class (TObject)
  78. private
  79. FCurrentPosition : Integer;
  80. FTokens : TStringList;
  81. protected
  82. public
  83. constructor Create(const AStr : String); Overload;
  84. constructor Create(const AStr : String; ADelim : String); Overload;
  85. constructor Create(const AStr : String; ADelim : String;
  86. returnDelims : Boolean); Overload;
  87. destructor Destroy; Override;
  88. function HasMoreTokens() : Boolean;
  89. function NextToken() : String;
  90. function CountTokens() : Integer;
  91. end;
  92. function EndsWith(const S : String; const ASuffix : String; AOffset : Integer) : Boolean;
  93. function IndexOf(const S : String; const AString : String; const AIndex : Integer) : Integer;
  94. function LastIndexOf(const S : String; const AString : String; const AIndex : Integer) : Integer;
  95. function StartsWith(const S : String; const AString : String; const AIndex : Integer) : Boolean;
  96. implementation
  97. Function ReverseString(S : String): String;
  98. Var
  99. i : Integer;
  100. Begin
  101. Result := '';
  102. For i := Length(S) DownTo 1 Do
  103. Begin
  104. Result := Result + Copy(S,i,1) ;
  105. End;
  106. End;
  107. constructor TString.Create;
  108. begin
  109. FValue := '';
  110. FCount := 0;
  111. FOffset := 1;
  112. end;
  113. constructor TString.Create(const AValue : array of char);
  114. begin
  115. FValue := AValue;
  116. FCount := System.length(FValue);
  117. FOffset := 1;
  118. end;
  119. constructor TString.Create(const AValue : String);
  120. begin
  121. FValue := AValue;
  122. FCount := System.length(FValue);
  123. FOffset := 1;
  124. end;
  125. constructor TString.Create(const AValue : TString);
  126. begin
  127. FValue := AValue.FValue;
  128. FCount := System.length(FValue);
  129. FOffset := 1;
  130. end;
  131. procedure TString.SetString(const AString : String);
  132. begin
  133. FValue := AString;
  134. FCount := System.length(FValue);
  135. FOffset := 1;
  136. end;
  137. procedure TString.ToUppercase();
  138. begin
  139. FValue := Uppercase(FValue);
  140. end;
  141. procedure TString.ToLowerCase();
  142. begin
  143. FValue := LowerCase(FValue);
  144. end;
  145. procedure TString.Trim();
  146. begin
  147. FValue := SysUtils.Trim(FValue);
  148. FCount := System.Length(FValue);
  149. end;
  150. function TString.CharAt(const AIndex : Integer) : Char;
  151. begin
  152. CharAt := FValue[AIndex + FOffset];
  153. end;
  154. function TString.CompareTo(const AString : String) : Integer;
  155. begin
  156. CompareTo := CompareStr(FValue, AString);
  157. end;
  158. function TString.CompareToIgnoreCase(const AString : String) : Integer;
  159. begin
  160. CompareToIgnoreCase := CompareText(FValue, AString);
  161. end;
  162. function TString.Concat(const str : String) : TString;
  163. begin
  164. Concat := TString.Create(FValue + str);
  165. end;
  166. function TString.EndsWith(const ASuffix : String) : Boolean;
  167. begin
  168. EndsWith := EndsWith(ASuffix, 0);
  169. end;
  170. function TString.EndsWith(const ASuffix : String; AOffset : Integer) : Boolean;
  171. var
  172. tmp : String;
  173. begin
  174. if (System.Length(ASuffix) > FCount) then
  175. result := false
  176. else if (AOffset > (FCount - System.Length(ASuffix)+1)) then
  177. result := false
  178. else begin
  179. tmp := Copy(FValue,AOffset, System.Length(ASuffix));
  180. result := (CompareStr(ASuffix, tmp) = 0);
  181. end;
  182. end;
  183. function TString.Equals(const AString : String) : Boolean;
  184. begin
  185. Equals := (CompareStr(FValue, AString) = 0);
  186. end;
  187. function TString.EqualsIgnoreCase(const AString : String) : Boolean;
  188. begin
  189. EqualsIgnoreCase := (CompareText(FValue, AString) = 0);
  190. end;
  191. function TString.IndexOf(const AChar : Char) : Integer;
  192. begin
  193. IndexOf := IndexOf(AChar, 0);
  194. end;
  195. function TString.IndexOf(const AChar : Char; const AIndex : Integer) : Integer;
  196. var
  197. fromIndex, res, i : Integer;
  198. begin
  199. fromIndex := AIndex;
  200. if (fromIndex < 0) then
  201. fromIndex := 1;
  202. if (fromIndex > FCount) then begin
  203. IndexOf := -1;
  204. exit;
  205. end;
  206. res := -1;
  207. for i := AIndex to FCount do
  208. if (FValue[i] = AChar) then
  209. res := i;
  210. IndexOf := res;
  211. end;
  212. function TString.indexOf(const AString : String) : Integer;
  213. begin
  214. IndexOf := IndexOf(Astring ,0);
  215. end;
  216. function TString.IndexOf(const AString : String; const AIndex : Integer) : Integer;
  217. var
  218. tmp : String;
  219. begin
  220. tmp := Copy(AString, AIndex, System.Length(AString) - AIndex);
  221. result := Pos(AString, FValue);
  222. if (result >= 0) then
  223. result := result + AIndex;
  224. end;
  225. function TString.LastIndexOf(const AChar : Char) : Integer;
  226. begin
  227. LastIndexOf := LastIndexOf(AChar, FCount);
  228. end;
  229. function TString.LastIndexOf(const AChar : Char; const AIndex : Integer) : Integer;
  230. var
  231. fromIndex, i : Integer;
  232. res : Integer;
  233. begin
  234. res := -1;
  235. fromIndex := AIndex;
  236. if (fromINdex > FCount) then
  237. fromIndex := FCount;
  238. for i := fromIndex downto 1 do
  239. if (FValue[i] = AChar) then
  240. res := i;
  241. lastIndexOf := res;
  242. end;
  243. function TString.LastIndexOf(const AString : String) : Integer;
  244. begin
  245. LastIndexOf := LastIndexOf(AString, FCount);
  246. end;
  247. function TString.LastIndexOf(const AString : String; const AIndex : Integer) : Integer;
  248. var
  249. tmp : String;
  250. res, index : Integer;
  251. begin
  252. tmp := Copy(AString, AIndex, System.Length(AString) - AIndex);
  253. index := Pos(AString, tmp);
  254. res := 0;
  255. while (index >= 0) do begin
  256. res := res + index;
  257. tmp := Copy(tmp, index+1, System.length(tmp)-index+1);
  258. index := Pos(AString, tmp);
  259. end;
  260. result := res;
  261. end;
  262. function TString.Length() : Integer;
  263. begin
  264. Length := FCount;
  265. end;
  266. function TString.Replace(const AOldChar : Char; const ANewChar : Char) : TString;
  267. begin
  268. Replace := TString.Create(StringReplace(FValue, AOldChar, ANewChar, [rfReplaceAll]));
  269. end;
  270. function TString.StartsWith(const AString : String) : Boolean;
  271. begin
  272. StartsWith := StartsWith(AString, 0);
  273. end;
  274. function TString.StartsWith(const AString : String; const AIndex : Integer) : Boolean;
  275. var
  276. tmp : String;
  277. begin
  278. if (System.Length(AString) > FCount) then
  279. result := false
  280. else if (AIndex > (FCount - System.Length(AString))) then
  281. result := false
  282. else begin
  283. tmp := Copy(FValue,AIndex+1, System.Length(AString));
  284. result := (CompareStr(AString, tmp) = 0);
  285. end;
  286. end;
  287. function TString.Substring(const AStartIndex : Integer) : TString;
  288. begin
  289. Substring := TString.Create(Copy(FValue, AStartIndex, System.Length(FValue)));
  290. end;
  291. function TString.Substring(const AStartIndex : Integer; const AEndIndex : Integer) : TString;
  292. begin
  293. substring := TString.Create(Copy(FValue, AStartIndex, (AStartIndex + AEndIndex)));
  294. end;
  295. function TString.ToString() : String;
  296. begin
  297. ToString := FValue;
  298. end;
  299. constructor TStringTokenizer.Create(const AStr : String);
  300. begin
  301. Self.Create(Astr, ' '+#9#10#13, false);
  302. end;
  303. constructor TStringTokenizer.Create(const AStr : String; ADelim : String);
  304. begin
  305. Self.Create(Astr, ADelim, false);
  306. end;
  307. constructor TStringTokenizer.Create(const AStr : String; ADelim : String;
  308. returnDelims : Boolean);
  309. var
  310. count : Integer;
  311. prev : Integer;
  312. begin
  313. FCurrentPosition := 0;
  314. FTokens := TStringList.Create;
  315. prev := 1;
  316. for count := 0 to Length(Astr) do begin
  317. if (IsDelimiter(ADelim, AStr, count)) then begin
  318. if (Copy(AStr,prev,count-prev) <> '') then
  319. FTokens.Add(Copy(AStr,prev,count-prev));
  320. prev := count;
  321. if (returnDelims) then
  322. FTokens.add(Copy(AStr,prev,1));
  323. prev := prev + 1;
  324. end;
  325. end;
  326. if (prev < Length(AStr)) then begin
  327. FTokens.Add(Copy(AStr,prev,Length(AStr)-prev+1));
  328. end;
  329. end;
  330. destructor TStringTokenizer.Destroy;
  331. begin
  332. FTokens.Free;
  333. end;
  334. function TStringTokenizer.HasMoreTokens() : Boolean;
  335. begin
  336. result := (FCurrentPosition < FTokens.Count);
  337. end;
  338. function TStringTokenizer.NextToken() : String;
  339. begin
  340. result := FTokens[FCurrentPosition];
  341. FCurrentPosition := FCurrentPosition + 1;
  342. end;
  343. function TStringTokenizer.CountTokens() : Integer;
  344. begin
  345. result := FTokens.Count-FCurrentPosition;
  346. end;
  347. function EndsWith(const S : String; const ASuffix : String; AOffset : Integer) : Boolean;
  348. var
  349. tmp : String;
  350. begin
  351. if (System.Length(ASuffix) > System.length(S)) then begin
  352. result := false
  353. end else if (AOffset > (System.length(S) - System.Length(ASuffix)+1)) then begin
  354. result := false
  355. end else begin
  356. tmp := Copy(S,AOffset, System.Length(S));
  357. tmp := Copy(S, (System.Length(S) - System.Length(ASuffix) + 1), System.length(ASuffix));
  358. result := (CompareStr(ASuffix, tmp) = 0);
  359. end;
  360. end;
  361. function IndexOf(const S : String; const AString : String; const AIndex : Integer) : Integer;
  362. var
  363. tmp : String;
  364. begin
  365. tmp := Copy(S, AIndex+1, (System.Length(S) - AIndex + 1));
  366. result := Pos(AString, tmp);
  367. if (result > 0) then
  368. result := result + AIndex - 1
  369. else
  370. Result := -1;
  371. end;
  372. function LastIndexOf(const S : String; const AString : String; const AIndex : Integer) : Integer;
  373. var
  374. tmp : String;
  375. i : Integer;
  376. begin
  377. tmp := Copy(S, AIndex+1, (System.Length(S) - AIndex + 1));
  378. tmp := reverseString(tmp);
  379. i := IndexOf(tmp, AString, 0);
  380. i := System.Length(S) - i - 1;
  381. if (i < System.Length(S)) then
  382. Result := i
  383. else
  384. Result := -1;
  385. end;
  386. function StartsWith(const S : String; const AString : String; const AIndex : Integer) : Boolean;
  387. var
  388. tmp : String;
  389. begin
  390. if (System.Length(AString) > System.length(S)) then begin
  391. result := false
  392. end else if (AIndex > (System.length(S) - System.Length(AString))) then begin
  393. result := false
  394. end else begin
  395. tmp := Copy(S,AIndex+1, System.Length(AString));
  396. result := (CompareStr(AString, tmp) = 0);
  397. end;
  398. end;
  399. end.