syshelps.inc 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511
  1. {%MainUnit sysutils.pp}
  2. { ---------------------------------------------------------------------
  3. TStringHelper
  4. ---------------------------------------------------------------------}
  5. {$ifdef IS_ANSISTRINGHELPER}
  6. type
  7. TTrimMode = {$push} {$scopedenums on} (Left, Right, Both) {$pop};
  8. {$endif}
  9. {$IF not defined(IS_SHORTSTRINGHELPER) and not defined(IS_UNICODESTRINGHELPER)}
  10. // Doubles with (wide/ansi)string...
  11. Function HaveChar(AChar : TStringChar; const AList: array of TStringChar) : Boolean;
  12. Var
  13. I : SizeInt;
  14. begin
  15. I:=0;
  16. while (I<=High(AList)) and (AList[I]<>AChar) do
  17. Inc(I);
  18. Result:=I<=High(AList);
  19. end;
  20. {$ENDIF}
  21. function Trim(const S: TStringType; const ATrimChars: array of TStringChar; mode: TTrimMode): TStringType;
  22. var
  23. start, ed, ns: SizeInt;
  24. begin
  25. start := 1;
  26. ns := System.Length(S);
  27. ed := ns;
  28. if mode <> TTrimMode.Right then
  29. while (start <= ed) and HaveChar(S[start], ATrimChars) do
  30. inc(start);
  31. if mode <> TTrimMode.Left then
  32. while (start <= ed) and HaveChar(S[ed], ATrimChars) do
  33. dec(ed);
  34. if (start = 1) and (ed = ns) then
  35. Result := S
  36. else
  37. Result := Copy(S, start, ed - start + 1);
  38. end;
  39. function TStringHelper.GetChar(AIndex: SizeInt): TStringChar;
  40. begin
  41. Result:=Self[AIndex+1];
  42. end;
  43. function TStringHelper.GetLength: SizeInt;
  44. begin
  45. Result:=System.Length(Self);
  46. end;
  47. class function TStringHelper.Compare(const A: TStringType; const B: TStringType): Integer;
  48. begin
  49. Result:=Compare(A,0,B,0,System.Length(B),[]);
  50. end;
  51. class function TStringHelper.Compare(const A: TStringType; const B: TStringType;
  52. IgnoreCase: Boolean): Integer; //deprecated 'Use same with TCompareOptions';
  53. begin
  54. if IgnoreCase then
  55. Result:=Compare(A,B,[coIgnoreCase])
  56. else
  57. Result:=Compare(A,B,[]);
  58. end;
  59. class function TStringHelper.Compare(const A: TStringType; const B: TStringType;
  60. Options: TCompareOptions): Integer;
  61. var
  62. LenA,LenB : integer;
  63. begin
  64. LenB:=System.Length(B);
  65. LenA:=System.Length(A);
  66. if LenB=LenA then
  67. Result:=Compare(A,0,B,0,LenB,Options)
  68. else if (LenB>LenA) then
  69. begin
  70. Result:=Compare(A,0,B,0,LenA,Options);
  71. if Result=0 then // over the length of A, both are equal.
  72. Result:=-1;
  73. end
  74. else // lenB<LenA
  75. begin
  76. Result:=Compare(A,0,B,0,LenB,Options);
  77. if Result=0 then // Over the length of B, both are equal
  78. Result:=1;
  79. end;
  80. end;
  81. class function TStringHelper.Compare(const A: TStringType; IndexA: SizeInt;
  82. const B: TStringType; IndexB: SizeInt; ALen: SizeInt): Integer;
  83. begin
  84. Result:=Compare(A,IndexA,B,IndexB,ALen,[]);
  85. end;
  86. class function TStringHelper.Compare(const A: TStringType; IndexA: SizeInt;
  87. const B: TStringType; IndexB: SizeInt; ALen: SizeInt; IgnoreCase: Boolean
  88. ): Integer; //deprecated 'Use same with TCompareOptions';
  89. begin
  90. if IgnoreCase then
  91. Result:=Compare(A,IndexA,B,IndexB,ALen,[coIgnoreCase])
  92. else
  93. Result:=Compare(A,IndexA,B,IndexB,ALen,[])
  94. end;
  95. class function TStringHelper.Compare(const A: TStringType; IndexA: SizeInt;
  96. const B: TStringType; IndexB: SizeInt; ALen: SizeInt; Options: TCompareOptions
  97. ): Integer;
  98. Var
  99. L : SizeInt;
  100. begin
  101. L:=ALen;
  102. If (L>system.Length(A)-IndexA) then
  103. L:=system.Length(A)-IndexA;
  104. If (L>system.Length(B)-IndexB) then
  105. L:=system.Length(B)-IndexB;
  106. if (coIgnoreCase in Options) then
  107. begin
  108. Result:=strlicomp(PTStringChar(@A[IndexA+1]),PTStringChar(@B[IndexB+1]),L)
  109. end
  110. else
  111. Result:=strlcomp(PTStringChar(@A[IndexA+1]),PTStringChar(@B[IndexB+1]),L);
  112. end;
  113. class function TStringHelper.CompareOrdinal(const A: TStringType; const B: TStringType
  114. ): Integer;
  115. Var
  116. L : SizeInt;
  117. begin
  118. L:=System.Length(B);
  119. if L>System.Length(A) then
  120. L:=System.Length(A);
  121. Result:=CompareOrdinal(A,0,B,0,L);
  122. end;
  123. class function TStringHelper.CompareOrdinal(const A: TStringType; IndexA: SizeInt;
  124. const B: TStringType; IndexB: SizeInt; ALen: SizeInt): Integer;
  125. begin
  126. Result:=StrLComp(PTStringChar(@A[IndexA+1]), PTStringChar(@B[IndexB+1]), ALen);
  127. end;
  128. class function TStringHelper.CompareText(const A: TStringType; const B: TStringType
  129. ): Integer;
  130. begin
  131. Result:=SUT.CompareText(A,B);
  132. end;
  133. class function TStringHelper.Copy(const Str: TStringType): TStringType;
  134. begin
  135. Result:=Str;
  136. {$IFNDEF IS_SHORTSTRINGHELPER}
  137. UniqueString(Result);
  138. {$ENDIF}
  139. end;
  140. class function TStringHelper.Create(AChar: TStringChar; ACount: SizeInt): TStringType;
  141. begin
  142. Result:=StringOfChar(AChar,ACount);
  143. end;
  144. class function TStringHelper.Create(const AValue: array of TStringChar): TStringType;
  145. begin
  146. Result:=Create(AValue,0,System.Length(AValue));
  147. end;
  148. class function TStringHelper.Create(const AValue: array of TStringChar;
  149. StartIndex: SizeInt; ALen: SizeInt): TStringType;
  150. begin
  151. SetLength(Result,ALen);
  152. if ALen>0 then
  153. Move(AValue[StartIndex],Result[1],ALen);
  154. end;
  155. class function TStringHelper.EndsText(const ASubText, AText: TStringType): Boolean;
  156. begin
  157. Result:=(ASubText<>'') and (SUT.CompareText(System.Copy(AText,System.Length(AText)-System.Length(ASubText)+1,System.Length(ASubText)),ASubText)=0);
  158. end;
  159. class function TStringHelper.Equals(const a: TStringType; const b: TStringType): Boolean;
  160. begin
  161. Result:=A=B;
  162. end;
  163. class function TStringHelper.Format(const AFormat: TStringType;
  164. const args: array of const): TStringType;
  165. begin
  166. Result:=SUT.Format(AFormat,Args);
  167. end;
  168. class function TStringHelper.IsNullOrEmpty(const AValue: TStringType): Boolean;
  169. begin
  170. Result:=system.Length(AValue)=0;
  171. end;
  172. class function TStringHelper.IsNullOrWhiteSpace(const AValue: TStringType): Boolean;
  173. const
  174. LWhiteSpace = [#0..' '];
  175. var
  176. I: SizeInt;
  177. begin
  178. for I:=1 to System.Length(AValue) do
  179. if not (AValue[I] in LWhiteSpace) then
  180. exit(False);
  181. Result:=True;
  182. end;
  183. class function TStringHelper.Join(const Separator: TStringType;
  184. const Values: array of const): TStringType;
  185. Var
  186. SValues : Array of TStringType;
  187. I,L : SizeInt;
  188. S : TStringType;
  189. P : ^TVarRec;
  190. begin
  191. L:=System.Length(Values);
  192. SetLength(SValues,L);
  193. Dec(L);
  194. for I:=0 to L do
  195. begin
  196. S:='';
  197. P:=@Values[I];
  198. Case P^.VType of
  199. vtInteger : S:=IntToStr(P^.VInteger);
  200. vtBoolean : S:=BoolToStr(P^.VBoolean, True);
  201. vtChar : S:=P^.VChar;
  202. vtPChar : S:= TStringType(P^.VPChar);
  203. {$ifndef FPUNONE}
  204. vtExtended : S:=FloatToStr(P^.VExtended^);
  205. {$endif}
  206. vtObject : S:=TObject(P^.VObject).Classname;
  207. vtClass : S:=P^.VClass.Classname;
  208. vtCurrency : S:=CurrToStr(P^.VCurrency^);
  209. vtVariant : S:=(P^.VVariant^);
  210. vtInt64 : S:=IntToStr(PInt64(P^.VInt64)^);
  211. vtQword : S:=IntToStr(PQWord(P^.VQword)^);
  212. vtWideChar : S:=WideString(P^.VWideChar);
  213. vtPWideChar : S:=WideString(P^.VPWideChar);
  214. vtUnicodeString : S:=UnicodeString(P^.VUnicodeString);
  215. vtAnsiString : S:=Ansistring(P^.VAnsiString);
  216. else
  217. S:=Format('Unknown type: %d',[P^.VType]);
  218. end;
  219. SValues[I]:=S;
  220. end;
  221. Result:=Join(Separator,SValues);
  222. end;
  223. class function TStringHelper.Join(const Separator: TStringType;
  224. const Values: array of TStringType): TStringType;
  225. begin
  226. Result:=Join(Separator,Values,0,System.Length(Values));
  227. end;
  228. class function TStringHelper.Join(const Separator: TStringType;
  229. const Values: array of TStringType; StartIndex: SizeInt; ACount: SizeInt): TStringType;
  230. Var
  231. VLen,I,CountLim,NR,NSep,N : SizeInt;
  232. Rp: PTStringChar;
  233. begin
  234. VLen:=System.Length(Values);
  235. If (ACount=0) then
  236. Exit('');
  237. CountLim:=VLen-StartIndex;
  238. if ACount>CountLim then
  239. ACount:=CountLim;
  240. If (ACount<0) or (StartIndex>VLen) or (StartIndex<0) then
  241. raise ERangeError.Create(SRangeError);
  242. if ACount=1 then
  243. exit(Values[StartIndex]);
  244. NSep:=System.Length(Separator);
  245. NR:=(ACount-1)*NSep;
  246. for I:=StartIndex to StartIndex+ACount-1 do
  247. NR:=NR+System.Length(Values[I]);
  248. SetLength(Result,NR);
  249. Rp:=@Result[1];
  250. for I:=StartIndex to StartIndex+ACount-1 do
  251. begin
  252. if I>StartIndex then
  253. begin
  254. Move(separator[1],Rp^,NSep*sizeof(TStringChar));
  255. Rp:=Rp+NSep;
  256. end;
  257. N:=System.Length(Values[I]);
  258. Move(Values[I][1],Rp^,N*sizeof(TStringChar));
  259. Rp:=Rp+N;
  260. end;
  261. end;
  262. class function TStringHelper.LowerCase(const S: TStringType): TStringType;
  263. begin
  264. Result:=SUT.Lowercase(S);
  265. end;
  266. class function TStringHelper.Parse(const AValue: Boolean): TStringType;
  267. begin
  268. Result:=BoolToStr(AValue);
  269. end;
  270. class function TStringHelper.Parse(const AValue: Extended): TStringType;
  271. begin
  272. Result:=FloatToStr(AValue);
  273. end;
  274. class function TStringHelper.Parse(const AValue: Int64): TStringType;
  275. begin
  276. Result:=IntToStr(AValue);
  277. end;
  278. class function TStringHelper.Parse(const AValue: Integer): TStringType;
  279. begin
  280. Result:=IntToStr(AValue);
  281. end;
  282. class function TStringHelper.ToBoolean(const S: TStringType): Boolean;
  283. begin
  284. Result:=StrToBool(S);
  285. end;
  286. class function TStringHelper.ToDouble(const S: TStringType): Double;
  287. begin
  288. Result:=StrToFloat(S);
  289. end;
  290. class function TStringHelper.ToExtended(const S: TStringType): Extended;
  291. begin
  292. Result:=StrToFloat(S);
  293. end;
  294. class function TStringHelper.ToInt64(const S: TStringType): Int64;
  295. begin
  296. Result:=StrToInt64(S);
  297. end;
  298. class function TStringHelper.ToInteger(const S: TStringType): Integer;
  299. begin
  300. Result:=StrToInt(S);
  301. end;
  302. class function TStringHelper.ToSingle(const S: TStringType): Single;
  303. begin
  304. Result:=StrToFloat(S);
  305. end;
  306. class function TStringHelper.UpperCase(const S: TStringType): TStringType;
  307. begin
  308. Result:=SUT.Uppercase(S);
  309. end;
  310. function TStringHelper.CompareTo(const B: TStringType): Integer;
  311. begin
  312. // Order is important
  313. {$IFDEF IS_SHORTSTRINGHELPER}
  314. Result:=SUT.StrComp(PTStringChar(@Self[1]),PTStringChar(@B[1]));
  315. {$ELSE}
  316. Result:=SUT.StrComp(PTStringChar(Self),PTStringChar(B));
  317. {$ENDIF}
  318. end;
  319. procedure TStringHelper.CopyTo(SourceIndex: SizeInt; var destination: array of TStringChar; DestinationIndex: SizeInt; ACount: SizeInt);
  320. Var
  321. P1,P2 : PTStringChar;
  322. begin
  323. // Writeln('((',DestinationIndex,'+',ACount,')<',System.Length(Destination),') : ', ((DestinationIndex+ACount)<System.Length(Destination)));
  324. if ((DestinationIndex+ACount)<=System.Length(Destination)) then
  325. begin
  326. // Writeln('AHA');
  327. P1:=@Self[SourceIndex+1];
  328. P2:=@Destination[DestinationIndex];
  329. Move(P1^,P2^,ACount*SizeOf(TStringChar));
  330. end;
  331. end;
  332. function TStringHelper.Contains(const AValue: TStringType; IgnoreCase: Boolean): Boolean;
  333. begin
  334. if IgnoreCase then
  335. Result:=Pos(LowerCase(AValue),LowerCase(Self))>0
  336. else
  337. Result:=Pos(AValue,Self)>0;
  338. end;
  339. function TStringHelper.CountChar(const C: TStringChar): SizeInt;
  340. Var
  341. S : TStringChar;
  342. begin
  343. Result:=0;
  344. For S in Self do
  345. if (S=C) then
  346. Inc(Result);
  347. end;
  348. function TStringHelper.DeQuotedString: TStringType;
  349. begin
  350. Result:=DeQuotedString('''');
  351. end;
  352. function TStringHelper.DeQuotedString(const AQuoteChar: TStringChar): TStringType;
  353. var
  354. L,I : SizeInt;
  355. Res : Array of TStringChar;
  356. PS,PD : PTStringChar;
  357. IsQuote : Boolean;
  358. begin
  359. L:=System.Length(Self);
  360. if (L<2) or Not ((Self[1]=AQuoteChar) and (Self[L]=AQuoteChar)) then
  361. Exit(Self);
  362. SetLength(Res,L);
  363. IsQuote:=False;
  364. PS:=@Self[2];
  365. PD:=@Res[0];
  366. For I:=2 to L-1 do
  367. begin
  368. if (PS^=AQuoteChar) then
  369. begin
  370. IsQuote:=Not IsQuote;
  371. if Not IsQuote then
  372. begin
  373. PD^:=PS^;
  374. Inc(PD);
  375. end;
  376. end
  377. else
  378. begin
  379. if IsQuote then
  380. IsQuote:=false;
  381. PD^:=PS^;
  382. Inc(PD);
  383. end;
  384. Inc(PS);
  385. end;
  386. SetString(Result,@Res[0],PD-@Res[0]);
  387. end;
  388. function TStringHelper.EndsWith(const AValue: TStringType): Boolean;
  389. begin
  390. Result:=EndsWith(AValue,False);
  391. end;
  392. function TStringHelper.EndsWith(const AValue: TStringType; IgnoreCase: Boolean): Boolean;
  393. Var
  394. L,NS : SizeInt;
  395. begin
  396. L:=system.Length(AVAlue);
  397. NS:=System.Length(Self);
  398. Result:=L<=NS;
  399. if Result then
  400. if IgnoreCase then
  401. Result:=SameText(System.Copy(Self,NS-L+1,L),AValue)
  402. else
  403. {$IFDEF IS_SHORTSTRINGHELPER}
  404. Result:=CompareByte(PTStringChar(@Self[1])[NS-L],PTStringChar(@AValue[1])^,L*sizeof(TStringChar))=0;
  405. {$ELSE}
  406. Result:=CompareByte(PTStringChar(Pointer(Self))[NS-L],PTStringChar(Pointer(AValue))^,L*sizeof(TStringChar))=0;
  407. {$ENDIF}
  408. end;
  409. function TStringHelper.Equals(const AValue: TStringType; IgnoreCase: Boolean = False): Boolean;
  410. begin
  411. if IgnoreCase then
  412. Result:=SameText(Self,aValue)
  413. else
  414. Result:=(Self=AValue);
  415. end;
  416. function TStringHelper.Format(const args: array of const): TStringType;
  417. begin
  418. Result:=Format(Self,Args);
  419. end;
  420. function TStringHelper.GetHashCode: Integer;
  421. // Taken from contnrs, fphash
  422. var
  423. P,pmax : PTStringChar;
  424. begin
  425. {$push}
  426. {$Q-}
  427. Result:=0;
  428. {$IFDEF IS_SHORTSTRINGHELPER}
  429. P:=PTStringChar(@Self[1]);
  430. {$ELSE}
  431. P:=PTStringChar(Self);
  432. {$ENDIF}
  433. pmax:=p+length;
  434. while (p<pmax) do
  435. begin
  436. Result:=LongWord(LongInt(Result shl 5) - LongInt(Result)) xor LongWord(P^);
  437. Inc(p);
  438. end;
  439. {$pop}
  440. end;
  441. function TStringHelper.IndexOf(AValue: TStringChar): SizeInt;
  442. begin
  443. Result:=IndexOf(AValue,0,Length);
  444. end;
  445. function TStringHelper.IndexOf(const AValue: TStringType): SizeInt;
  446. begin
  447. Result:=IndexOf(AValue,0,Length);
  448. end;
  449. function TStringHelper.IndexOf(AValue: TStringChar; StartIndex: SizeInt): SizeInt;
  450. begin
  451. Result:=IndexOf(AValue,StartIndex,Length);
  452. end;
  453. function TStringHelper.IndexOf(const AValue: TStringType; StartIndex: SizeInt
  454. ): SizeInt;
  455. begin
  456. Result:=IndexOf(AValue,StartIndex,Length);
  457. end;
  458. function TStringHelper.IndexOf(AValue: TStringChar; StartIndex: SizeInt;
  459. ACount: SizeInt): SizeInt;
  460. Var
  461. CountLim : SizeInt;
  462. begin
  463. if StartIndex<0 then
  464. StartIndex:=0;
  465. CountLim:=System.Length(Self)-StartIndex;
  466. if ACount>CountLim then
  467. ACount:=CountLim;
  468. if ACount<=0 then
  469. Exit(-1);
  470. // pointer casts are to access self as 0 based index!
  471. {$IFDEF IS_SHORTSTRINGHELPER}
  472. Result:=IndexChar(PTStringChar(@self[1])[StartIndex],ACount,AValue);
  473. {$ELSE}
  474. Result:=IndexChar(PTStringChar(Pointer(self))[StartIndex],ACount,AValue);
  475. {$ENDIF}
  476. if Result>=0 then
  477. Result:=Result+StartIndex;
  478. end;
  479. function TStringHelper.IndexOf(const AValue: TStringType; StartIndex: SizeInt;
  480. ACount: SizeInt): SizeInt;
  481. Var
  482. CountLim,NV,Ofs : SizeInt;
  483. SP,SE : PTStringChar;
  484. begin
  485. if StartIndex<0 then
  486. StartIndex:=0;
  487. CountLim:=System.Length(Self)-StartIndex;
  488. if ACount>CountLim then
  489. ACount:=CountLim;
  490. NV:=System.Length(AValue);
  491. if (NV>0) and (ACount>=NV) then
  492. begin
  493. {$IFDEF IS_SHORTSTRINGHELPER}
  494. SP:=PTStringChar(@Self[1])+StartIndex;
  495. {$ELSE}
  496. SP:=PTStringChar(Pointer(Self))+StartIndex;
  497. {$ENDIF}
  498. SE:=SP+ACount-NV+1;
  499. repeat
  500. {$IFDEF IS_SHORTSTRINGHELPER}
  501. Ofs:=IndexChar(SP^,SE-SP,PTStringChar(@AValue[1])[0]);
  502. {$ELSE}
  503. Ofs:=IndexChar(SP^,SE-SP,PTStringChar(Pointer(AValue))[0]);
  504. {$ENDIF}
  505. if Ofs<0 then
  506. Break;
  507. SP:=SP+Ofs+1;
  508. {$IFDEF IS_SHORTSTRINGHELPER}
  509. if CompareByte(SP^,PTStringChar(@AValue[1])[1],(NV-1)*sizeof(TStringChar))=0 then
  510. Exit(SP-PTStringChar(@Self[1])-1);
  511. {$ELSE}
  512. if CompareByte(SP^,PTStringChar(Pointer(AValue))[1],(NV-1)*sizeof(TStringChar))=0 then
  513. Exit(SP-PTStringChar(Pointer(Self))-1);
  514. {$ENDIF}
  515. until false;
  516. end;
  517. Result:=-1;
  518. end;
  519. function TStringHelper.IndexOfUnQuoted(const AValue: TStringType; StartQuote,
  520. EndQuote: TStringChar; StartIndex: SizeInt = 0): SizeInt;
  521. Var
  522. LV : SizeInt;
  523. Function MatchAt(I : SizeInt) : Boolean ; Inline;
  524. Var
  525. J : SizeInt;
  526. begin
  527. J:=1;
  528. Repeat
  529. Result:=(Self[I+J-1]=AValue[j]);
  530. Inc(J);
  531. Until (Not Result) or (J>LV);
  532. end;
  533. Var
  534. I,L,Q: SizeInt;
  535. begin
  536. Result:=-1;
  537. LV:=system.Length(AValue);
  538. L:=Length-LV+1;
  539. if L<0 then
  540. L:=0;
  541. I:=StartIndex+1;
  542. Q:=0;
  543. if StartQuote=EndQuote then
  544. begin
  545. While (Result=-1) and (I<=L) do
  546. begin
  547. if (Self[I]=StartQuote) then
  548. Q:=1-Q;
  549. if (Q=0) and MatchAt(i) then
  550. Result:=I-1;
  551. Inc(I);
  552. end;
  553. end
  554. else
  555. begin
  556. While (Result=-1) and (I<=L) do
  557. begin
  558. if Self[I]=StartQuote then
  559. Inc(Q)
  560. else if (Self[I]=EndQuote) and (Q>0) then
  561. Dec(Q);
  562. if (Q=0) and MatchAt(i) then
  563. Result:=I-1;
  564. Inc(I);
  565. end;
  566. end;
  567. end;
  568. function TStringHelper.IndexOfAny(const AnyOf: array of TStringChar): SizeInt;
  569. begin
  570. Result:=IndexOfAny(AnyOf,0,Length);
  571. end;
  572. function TStringHelper.IndexOfAny(const AnyOf: array of TStringChar;
  573. StartIndex: SizeInt): SizeInt;
  574. begin
  575. Result:=IndexOfAny(AnyOf,StartIndex,Length);
  576. end;
  577. function TStringHelper.IndexOfAny(const AnyOf: array of TStringChar;
  578. StartIndex: SizeInt; ACount: SizeInt): SizeInt;
  579. Var
  580. i,L : SizeInt;
  581. begin
  582. I:=StartIndex+1;
  583. L:=I+ACount-1;
  584. If L>Length then
  585. L:=Length;
  586. Result:=-1;
  587. While (Result=-1) and (I<=L) do
  588. begin
  589. if HaveChar(Self[i],AnyOf) then
  590. Result:=I-1;
  591. Inc(I);
  592. end;
  593. end;
  594. function TStringHelper.IndexOfAny(const AnyOf: array of TStringType): SizeInt;
  595. begin
  596. Result:=IndexOfAny(AnyOf,0,Length);
  597. end;
  598. function TStringHelper.IndexOfAny(const AnyOf: array of TStringType;
  599. StartIndex: SizeInt): SizeInt;
  600. begin
  601. Result:=IndexOfAny(AnyOf,StartIndex,Length-StartIndex);
  602. end;
  603. function TStringHelper.IndexOfAny(const AnyOf: array of TStringType;
  604. StartIndex: SizeInt; ACount: SizeInt): SizeInt;
  605. Var
  606. M : SizeInt;
  607. begin
  608. Result:=IndexOfAny(AnyOf,StartIndex,ACount,M);
  609. end;
  610. function TStringHelper.IndexOfAny(const AnyOf: array of TStringType;
  611. StartIndex: SizeInt; ACount: SizeInt; out AMatch: SizeInt): SizeInt;
  612. Var
  613. L,I : SizeInt;
  614. begin
  615. Result:=-1;
  616. For I:=0 to System.Length(AnyOf)-1 do
  617. begin
  618. L:=IndexOf(AnyOf[i],StartIndex,ACount);
  619. If (L>=0) and ((Result=-1) or (L<Result)) then
  620. begin
  621. Result:=L;
  622. AMatch:=I;
  623. end;
  624. end;
  625. end;
  626. function TStringHelper.IndexOfAnyUnquoted(const AnyOf: array of TStringChar;
  627. StartQuote, EndQuote: TStringChar): SizeInt;
  628. begin
  629. Result:=IndexOfAnyUnquoted(AnyOf,StartQuote,EndQuote,0,Length);
  630. end;
  631. function TStringHelper.IndexOfAnyUnquoted(const AnyOf: array of TStringChar;
  632. StartQuote, EndQuote: TStringChar; StartIndex: SizeInt): SizeInt;
  633. begin
  634. Result:=IndexOfAnyUnquoted(AnyOf,StartQuote,EndQuote,StartIndex,Length);
  635. end;
  636. function TStringHelper.IndexOfAnyUnquoted(const AnyOf: array of TStringChar;
  637. StartQuote, EndQuote: TStringChar; StartIndex: SizeInt; ACount: SizeInt): SizeInt;
  638. Var
  639. I,L : SizeInt;
  640. Q : SizeInt;
  641. begin
  642. Result:=-1;
  643. L:=StartIndex+ACount-1;
  644. if L>Length then
  645. L:=Length;
  646. I:=StartIndex+1;
  647. Q:=0;
  648. if StartQuote=EndQuote then
  649. begin
  650. While (Result=-1) and (I<=L) do
  651. begin
  652. if (Self[I]=StartQuote) then
  653. Q:=1-Q;
  654. if (Q=0) and HaveChar(Self[i],AnyOf) then
  655. Result:=I-1;
  656. Inc(I);
  657. end;
  658. end
  659. else
  660. begin
  661. While (Result=-1) and (I<=L) do
  662. begin
  663. if Self[I]=StartQuote then
  664. Inc(Q)
  665. else if (Self[I]=EndQuote) and (Q>0) then
  666. Dec(Q);
  667. if (Q=0) and HaveChar(Self[i],AnyOf) then
  668. Result:=I-1;
  669. Inc(I);
  670. end;
  671. end;
  672. end;
  673. function TStringHelper.IndexOfAnyUnquoted(const AnyOf: array of TStringType;
  674. StartQuote, EndQuote: TStringChar; StartIndex: SizeInt; out Matched: SizeInt
  675. ): SizeInt;
  676. Var
  677. L,I : SizeInt;
  678. begin
  679. Result:=-1;
  680. For I:=0 to System.Length(AnyOf)-1 do
  681. begin
  682. L:=IndexOfUnquoted(AnyOf[i],StartQuote,EndQuote,StartIndex);
  683. If (L>=0) and ((Result=-1) or (L<Result)) then
  684. begin
  685. Result:=L;
  686. Matched:=I;
  687. end;
  688. end;
  689. end;
  690. function TStringHelper.Insert(StartIndex: SizeInt; const AValue: TStringType
  691. ): TStringType;
  692. begin
  693. system.Insert(AValue,Self,StartIndex+1);
  694. Result:=Self;
  695. end;
  696. function TStringHelper.IsDelimiter(const Delimiters: TStringType; Index: SizeInt
  697. ): Boolean;
  698. begin
  699. Result:=SUT.IsDelimiter(Delimiters,Self,Index+1);
  700. end;
  701. function TStringHelper.IsEmpty: Boolean;
  702. begin
  703. Result:=(Length=0)
  704. end;
  705. function TStringHelper.LastDelimiter(const Delims: TStringType): SizeInt;
  706. begin
  707. Result:=SUT.LastDelimiter(Delims,Self)-1;
  708. end;
  709. function TStringHelper.LastIndexOf(AValue: TStringChar): SizeInt;
  710. begin
  711. Result:=LastIndexOf(AValue,Length-1,Length);
  712. end;
  713. function TStringHelper.LastIndexOf(const AValue: TStringType): SizeInt;
  714. begin
  715. Result:=LastIndexOf(AValue,Length-1,Length);
  716. end;
  717. function TStringHelper.LastIndexOf(AValue: TStringChar; AStartIndex: SizeInt): SizeInt;
  718. begin
  719. Result:=LastIndexOf(AValue,AStartIndex,Length);
  720. end;
  721. function TStringHelper.LastIndexOf(const AValue: TStringType; AStartIndex: SizeInt
  722. ): SizeInt;
  723. begin
  724. Result:=LastIndexOf(AValue,AStartIndex,Length);
  725. end;
  726. function TStringHelper.LastIndexOf(AValue: TStringChar; AStartIndex: SizeInt;
  727. ACount: SizeInt): SizeInt;
  728. Var
  729. Min : SizeInt;
  730. begin
  731. Result:=AStartIndex+1;
  732. Min:=Result-ACount+1;
  733. If Min<1 then
  734. Min:=1;
  735. While (Result>=Min) and (Self[Result]<>AValue) do
  736. Dec(Result);
  737. if Result<Min then
  738. Result:=-1
  739. else
  740. Result:=Result-1;
  741. end;
  742. function TStringHelper.LastIndexOf(const AValue: TStringType; AStartIndex: SizeInt; ACount: SizeInt): SizeInt;
  743. var
  744. I,L,LS,M : SizeInt;
  745. S : TStringType;
  746. P : PTStringChar;
  747. begin
  748. Result:=-1;
  749. LS:=system.Length(Self);
  750. L:=system.Length(AValue);
  751. if (L=0) or (L>LS) then
  752. Exit;
  753. {$IFDEF IS_SHORTSTRINGHELPER}
  754. P:=PTStringChar(@AValue[1]);
  755. {$ELSE}
  756. P:=PTStringChar(AValue);
  757. {$ENDIF}
  758. S:=Self;
  759. I:=AStartIndex+1; // 1 based
  760. if (I>LS) then
  761. I:=LS;
  762. I:=I-L+1;
  763. M:=AStartIndex-ACount+2; // 1 based
  764. if M<1 then
  765. M:=1;
  766. while (Result=-1) and (I>=M) do
  767. begin
  768. if (0=StrLComp(PTStringChar(@S[I]),P,L)) then
  769. Result:=I-1;
  770. Dec(I);
  771. end;
  772. end;
  773. function TStringHelper.LastIndexOfAny(const AnyOf: array of TStringChar): SizeInt;
  774. begin
  775. Result:=LastIndexOfAny(AnyOf,Length-1,Length);
  776. end;
  777. function TStringHelper.LastIndexOfAny(const AnyOf: array of TStringChar;
  778. AStartIndex: SizeInt): SizeInt;
  779. begin
  780. Result:=LastIndexOfAny(AnyOf,AStartIndex,Length);
  781. end;
  782. function TStringHelper.LastIndexOfAny(const AnyOf: array of TStringChar;
  783. AStartIndex: SizeInt; ACount: SizeInt): SizeInt;
  784. Var
  785. Min : SizeInt;
  786. begin
  787. Result:=AStartIndex+1;
  788. Min:=Result-ACount+1;
  789. If Min<1 then
  790. Min:=1;
  791. While (Result>=Min) and Not HaveChar(Self[Result],AnyOf) do
  792. Dec(Result);
  793. if Result<Min then
  794. Result:=-1
  795. else
  796. Result:=Result-1;
  797. end;
  798. function TStringHelper.PadLeft(ATotalWidth: SizeInt): TStringType;
  799. begin
  800. Result:=PadLeft(ATotalWidth,' ');
  801. end;
  802. function TStringHelper.PadLeft(ATotalWidth: SizeInt; PaddingChar: TStringChar): TStringType;
  803. Var
  804. L : SizeInt;
  805. begin
  806. Result:=Self;
  807. L:=ATotalWidth-Length;
  808. If L>0 then
  809. Result:=StringOfChar(PaddingChar,L)+Result;
  810. end;
  811. function TStringHelper.PadRight(ATotalWidth: SizeInt): TStringType;
  812. begin
  813. Result:=PadRight(ATotalWidth,' ');
  814. end;
  815. function TStringHelper.PadRight(ATotalWidth: SizeInt; PaddingChar: TStringChar
  816. ): TStringType;
  817. Var
  818. L : SizeInt;
  819. begin
  820. Result:=Self;
  821. L:=ATotalWidth-Length;
  822. If L>0 then
  823. Result:=Result+StringOfChar(PaddingChar,L);
  824. end;
  825. function TStringHelper.QuotedString: TStringType;
  826. begin
  827. Result:=QuotedStr(Self);
  828. end;
  829. function TStringHelper.QuotedString(const AQuoteChar: TStringChar): TStringType;
  830. begin
  831. Result:=AnsiQuotedStr(Self,AQuoteChar);
  832. end;
  833. function TStringHelper.Remove(StartIndex: SizeInt): TStringType;
  834. begin
  835. Result:=Remove(StartIndex,Self.Length-StartIndex);
  836. end;
  837. function TStringHelper.Remove(StartIndex: SizeInt; ACount: SizeInt): TStringType;
  838. begin
  839. Result:=Self;
  840. System.Delete(Result,StartIndex+1,ACount);
  841. end;
  842. function TStringHelper.Replace(OldChar: TStringChar; NewChar: TStringChar): TStringType;
  843. begin
  844. Result:=Replace(OldChar,NewChar,[rfReplaceAll]);
  845. end;
  846. function TStringHelper.Replace(OldChar: TStringChar; NewChar: TStringChar;
  847. ReplaceFlags: TReplaceFlags): TStringType;
  848. var
  849. Sp,Se,Rp : PTStringChar;
  850. Ofs : SizeInt;
  851. begin
  852. if rfIgnoreCase in ReplaceFlags then
  853. exit(StringReplace(Self,OldChar,NewChar,ReplaceFlags));
  854. {$IFDEF IS_SHORTSTRINGHELPER}
  855. Sp:=PTStringChar(@Self[1]);
  856. {$ELSE}
  857. Sp:=PTStringChar(Pointer(Self));
  858. {$ENDIF}
  859. Se:=Sp+System.Length(Self);
  860. Ofs:=IndexChar(Sp^,Se-Sp,OldChar);
  861. if Ofs<0 then
  862. exit(Self);
  863. SetLength(Result,Se-Sp);
  864. {$IFDEF IS_SHORTSTRINGHELPER}
  865. Rp:=PTStringChar(@Result[1]);
  866. {$ELSE}
  867. Rp:=PTStringChar(Pointer(Result));
  868. {$ENDIF}
  869. repeat
  870. Move(Sp^,Rp^,Ofs*sizeof(TStringChar));
  871. Sp:=Sp+Ofs+1;
  872. Rp[Ofs]:=NewChar;
  873. Rp:=Rp+Ofs+1;
  874. if not (rfReplaceAll in ReplaceFlags) then
  875. break;
  876. { This loop can be removed entirely, but greatly speeds up replacing streaks of characters. }
  877. while (Sp<Se) and (Sp^=OldChar) do
  878. begin
  879. Rp^:=NewChar;
  880. Sp:=Sp+1;
  881. Rp:=Rp+1;
  882. end;
  883. Ofs:=IndexChar(Sp^,Se-Sp,OldChar);
  884. until Ofs<0;
  885. Move(Sp^,Rp^,(Se-Sp)*sizeof(TStringChar));
  886. end;
  887. function TStringHelper.Replace(const OldValue: TStringType; const NewValue: TStringType
  888. ): TStringType;
  889. begin
  890. Result:=Replace(OldValue,NewValue,[rfReplaceAll]);
  891. end;
  892. function TStringHelper.Replace(const OldValue: TStringType; const NewValue: TStringType;
  893. ReplaceFlags: TReplaceFlags): TStringType;
  894. begin
  895. Result:=StringReplace(Self,OldValue,NewValue,ReplaceFlags);
  896. end;
  897. function TStringHelper.Split(const Separators: array of TStringChar): TSHStringArray;
  898. begin
  899. Result:=Split(Separators,#0,#0,Length+1,TStringSplitOptions.None);
  900. end;
  901. function TStringHelper.Split(const Separators: array of TStringChar; ACount: SizeInt
  902. ): TSHStringArray;
  903. begin
  904. Result:=Split(Separators,#0,#0,ACount,TStringSplitOptions.None);
  905. end;
  906. function TStringHelper.Split(const Separators: array of TStringChar;
  907. Options: TStringSplitOptions): TSHStringArray;
  908. begin
  909. Result:=Split(Separators,Length+1,Options);
  910. end;
  911. function TStringHelper.Split(const Separators: array of TStringChar; ACount: SizeInt;
  912. Options: TStringSplitOptions): TSHStringArray;
  913. begin
  914. Result:=Split(Separators,#0,#0,ACount,Options);
  915. end;
  916. function TStringHelper.Split(const Separators: array of TStringType): TSHStringArray;
  917. begin
  918. Result:=Split(Separators,Length+1);
  919. end;
  920. function TStringHelper.Split(const Separators: array of TStringType; ACount: SizeInt
  921. ): TSHStringArray;
  922. begin
  923. Result:=Split(Separators,ACount,TStringSplitOptions.None);
  924. end;
  925. function TStringHelper.Split(const Separators: array of TStringType;
  926. Options: TStringSplitOptions): TSHStringArray;
  927. begin
  928. Result:=Split(Separators,Length+1,Options);
  929. end;
  930. function TStringHelper.Split(const Separators: array of TStringType;
  931. ACount: SizeInt; Options: TStringSplitOptions): TSHStringArray;
  932. begin
  933. Result:=Split(Separators,#0,#0,ACount,Options);
  934. end;
  935. function TStringHelper.Split(const Separators: array of TStringChar; AQuote: TStringChar
  936. ): TSHStringArray;
  937. begin
  938. Result:=Split(Separators,AQuote,AQuote);
  939. end;
  940. function TStringHelper.Split(const Separators: array of TStringChar; AQuoteStart,
  941. AQuoteEnd: TStringChar): TSHStringArray;
  942. begin
  943. Result:=Split(Separators,AQuoteStart,AQuoteEnd,TStringSplitOptions.None);
  944. end;
  945. function TStringHelper.Split(const Separators: array of TStringChar; AQuoteStart,
  946. AQuoteEnd: TStringChar; Options: TStringSplitOptions): TSHStringArray;
  947. begin
  948. Result:=Split(Separators,AQuoteStart,AQuoteEnd,Length+1,Options);
  949. end;
  950. function TStringHelper.Split(const Separators: array of TStringChar; AQuoteStart,
  951. AQuoteEnd: TStringChar; ACount: SizeInt): TSHStringArray;
  952. begin
  953. Result:=Split(Separators,AQuoteStart,AQuoteEnd,ACount,TStringSplitOptions.None);
  954. end;
  955. function TStringHelper.Split(const Separators: array of TStringChar; AQuoteStart,
  956. AQuoteEnd: TStringChar; ACount: SizeInt; Options: TStringSplitOptions): TSHStringArray;
  957. Function NextSep(StartIndex : SizeInt) : SizeInt;
  958. begin
  959. if (AQuoteStart<>#0) then
  960. Result:=Self.IndexOfAnyUnQuoted(Separators,AQuoteStart,AQuoteEnd,StartIndex)
  961. else
  962. Result:=Self.IndexOfAny(Separators,StartIndex);
  963. end;
  964. Procedure MaybeGrow(Curlen : SizeInt);
  965. begin
  966. if System.Length(Result)<=CurLen then
  967. SetLength(Result,System.Length(Result)+4+SizeInt(SizeUint(System.Length(Result)) div 4));
  968. end;
  969. Var
  970. Sep,LastSep,Len : SizeInt;
  971. begin
  972. Result:=nil;
  973. Len:=0;
  974. LastSep:=0;
  975. While ((ACount=0) or (Len<ACount)) and (LastSep<=System.Length(Self)) do
  976. begin
  977. Sep:=NextSep(LastSep);
  978. if Sep<0 then
  979. Sep:=System.Length(Self);
  980. // Writeln('Examining >',T,'< at pos ',LastSep,', till pos ',Sep);
  981. If (Sep>LastSep) or (not (TStringSplitOptions.ExcludeEmpty=Options)) then
  982. begin
  983. MaybeGrow(Len);
  984. Result[Len]:=SubString(LastSep,Sep-LastSep);
  985. Inc(Len);
  986. end;
  987. LastSep:=Sep+1;
  988. end;
  989. if (TStringSplitOptions.ExcludeLastEmpty=Options) then
  990. if (Len > 0) and (Result[Len-1] = '') then
  991. dec(Len);
  992. SetLength(Result,Len);
  993. end;
  994. function TStringHelper.Split(const Separators: array of TStringType; AQuote: TStringChar
  995. ): TSHStringArray;
  996. begin
  997. Result:=SPlit(Separators,AQuote,AQuote);
  998. end;
  999. function TStringHelper.Split(const Separators: array of TStringType; AQuoteStart,
  1000. AQuoteEnd: TStringChar): TSHStringArray;
  1001. begin
  1002. Result:=SPlit(Separators,AQuoteStart,AQuoteEnd,Length+1,TStringSplitOptions.None);
  1003. end;
  1004. function TStringHelper.Split(const Separators: array of TStringType; AQuoteStart,
  1005. AQuoteEnd: TStringChar; Options: TStringSplitOptions): TSHStringArray;
  1006. begin
  1007. Result:=SPlit(Separators,AQuoteStart,AQuoteEnd,Length+1,Options);
  1008. end;
  1009. function TStringHelper.Split(const Separators: array of TStringType; AQuoteStart,
  1010. AQuoteEnd: TStringChar; ACount: SizeInt): TSHStringArray;
  1011. begin
  1012. Result:=SPlit(Separators,AQuoteStart,AQuoteEnd,ACount,TStringSplitOptions.None);
  1013. end;
  1014. function TStringHelper.Split(const Separators: array of TStringType; AQuoteStart,
  1015. AQuoteEnd: TStringChar; ACount: SizeInt; Options: TStringSplitOptions): TSHStringArray;
  1016. Const
  1017. BlockSize = 10;
  1018. Function NextSep(StartIndex : SizeInt; out Match : SizeInt) : SizeInt;
  1019. begin
  1020. if (AQuoteStart<>#0) then
  1021. Result:=Self.IndexOfAnyUnQuoted(Separators,AQuoteStart,AQuoteEnd,StartIndex,Match)
  1022. else
  1023. Result:=Self.IndexOfAny(Separators,StartIndex,Length,Match);
  1024. if Result<>-1 then
  1025. end;
  1026. Procedure MaybeGrow(Curlen : SizeInt);
  1027. begin
  1028. if System.Length(Result)<=CurLen then
  1029. SetLength(Result,System.Length(Result)+BlockSize);
  1030. end;
  1031. Var
  1032. Sep,LastSep,Len,Match : SizeInt;
  1033. T : TStringType;
  1034. begin
  1035. SetLength(Result,BlockSize);
  1036. Len:=0;
  1037. LastSep:=0;
  1038. Sep:=NextSep(0,Match);
  1039. While (Sep<>-1) and ((ACount=0) or (Len<ACount)) do
  1040. begin
  1041. T:=SubString(LastSep,Sep-LastSep);
  1042. If (T<>'') or (not (TStringSplitOptions.ExcludeEmpty=Options)) then
  1043. begin
  1044. MaybeGrow(Len);
  1045. Result[Len]:=T;
  1046. Inc(Len);
  1047. end;
  1048. LastSep:=Sep+System.Length(Separators[Match]);
  1049. Sep:=NextSep(LastSep,Match);
  1050. end;
  1051. if (LastSep<=Length) and ((ACount=0) or (Len<ACount)) then
  1052. begin
  1053. T:=SubString(LastSep);
  1054. // Writeln('Examining >',T,'< at pos,',LastSep,' till pos ',Sep);
  1055. If (T<>'') or (not (TStringSplitOptions.ExcludeEmpty=Options)) then
  1056. begin
  1057. MaybeGrow(Len);
  1058. Result[Len]:=T;
  1059. Inc(Len);
  1060. end;
  1061. end;
  1062. If (TStringSplitOptions.ExcludeLastEmpty=Options) then
  1063. if (Len > 0) and (Result[Len-1] = '') then
  1064. dec(Len);
  1065. SetLength(Result,Len);
  1066. end;
  1067. function TStringHelper.StartsWith(const AValue: TStringType): Boolean;
  1068. begin
  1069. Result:=StartsWith(AValue,False);
  1070. end;
  1071. function TStringHelper.StartsWith(const AValue: TStringType; IgnoreCase: Boolean
  1072. ): Boolean;
  1073. Var
  1074. L : SizeInt;
  1075. begin
  1076. L:=System.Length(AValue);
  1077. Result:=L<=System.Length(Self);
  1078. if Result then
  1079. if IgnoreCase then
  1080. Result:=SameText(System.Copy(Self,1,L),AValue)
  1081. else
  1082. {$IFDEF IS_SHORTSTRINGHELPER}
  1083. Result:=CompareByte(PTStringChar(@Self[1])^,PTStringChar(@AValue[1])^,L*sizeof(TStringChar))=0;
  1084. {$ELSE}
  1085. Result:=CompareByte(PTStringChar(Pointer(Self))^,PTStringChar(Pointer(AValue))^,L*sizeof(TStringChar))=0;
  1086. {$ENDIF}
  1087. end;
  1088. function TStringHelper.Substring(AStartIndex: SizeInt): TStringType;
  1089. begin
  1090. Result:=Self.SubString(AStartIndex,Self.Length-AStartIndex);
  1091. end;
  1092. function TStringHelper.Substring(AStartIndex: SizeInt; ALen: SizeInt): TStringType;
  1093. begin
  1094. if (AStartIndex<=0) and (ALen>=System.Length(Self)) then
  1095. Result:=Self
  1096. else
  1097. Result:=system.Copy(Self,AStartIndex+1,ALen);
  1098. end;
  1099. function TStringHelper.ToBoolean: Boolean;
  1100. begin
  1101. Result:=StrToBool(Self);
  1102. end;
  1103. function TStringHelper.ToInteger: Integer;
  1104. begin
  1105. Result:=StrToInt(Self);
  1106. end;
  1107. function TStringHelper.ToInt64: Int64;
  1108. begin
  1109. Result:=StrToInt64(Self);
  1110. end;
  1111. function TStringHelper.ToSingle: Single;
  1112. begin
  1113. Result:=StrToFLoat(Self);
  1114. end;
  1115. function TStringHelper.ToDouble: Double;
  1116. begin
  1117. Result:=StrToFLoat(Self);
  1118. end;
  1119. function TStringHelper.ToExtended: Extended;
  1120. begin
  1121. Result:=StrToFLoat(Self);
  1122. end;
  1123. function TStringHelper.ToCharArray: TCharArray;
  1124. begin
  1125. Result:=ToCharArray(0,Self.Length);
  1126. end;
  1127. function TStringHelper.ToCharArray(AStartIndex: SizeInt; ALen: SizeInt
  1128. ): TCharArray;
  1129. Var
  1130. I : SizeInt;
  1131. begin
  1132. SetLength(Result,ALen);
  1133. For I:=0 to ALen-1 do
  1134. Result[I]:=Self[AStartIndex+I+1];
  1135. end;
  1136. function TStringHelper.ToLower: TStringType;
  1137. begin
  1138. Result:=LowerCase(Self);
  1139. end;
  1140. function TStringHelper.ToLowerInvariant: TStringType;
  1141. begin
  1142. Result:=LowerCase(Self);
  1143. end;
  1144. function TStringHelper.ToUpper: TStringType;
  1145. begin
  1146. Result:=UpperCase(Self);
  1147. end;
  1148. function TStringHelper.ToUpperInvariant: TStringType;
  1149. begin
  1150. Result:=UpperCase(Self);
  1151. end;
  1152. function TStringHelper.Trim: TStringType;
  1153. begin
  1154. Result:=SUT.Trim(Self);
  1155. end;
  1156. function TStringHelper.TrimLeft: TStringType;
  1157. begin
  1158. Result:=SUT.TrimLeft(Self);
  1159. end;
  1160. function TStringHelper.TrimRight: TStringType;
  1161. begin
  1162. Result:=SUT.TrimRight(Self);
  1163. end;
  1164. function TStringHelper.Trim(const ATrimChars: array of TStringChar): TStringType;
  1165. begin
  1166. Result:=SUT.Trim(Self, ATrimChars, TTrimMode.Both);
  1167. end;
  1168. function TStringHelper.TrimLeft(const ATrimChars: array of TStringChar): TStringType;
  1169. begin
  1170. Result:=SUT.Trim(Self, ATrimChars, TTrimMode.Left);
  1171. end;
  1172. function TStringHelper.TrimRight(const ATrimChars: array of TStringChar): TStringType;
  1173. begin
  1174. Result:=SUT.Trim(Self, ATrimChars, TTrimMode.Right);
  1175. end;
  1176. function TStringHelper.TrimEnd(const ATrimChars: array of TStringChar): TStringType;
  1177. begin
  1178. Result:=TrimRight(ATrimChars);
  1179. end;
  1180. function TStringHelper.TrimStart(const ATrimChars: array of TStringChar): TStringType;
  1181. begin
  1182. Result:=TrimLeft(ATrimChars);
  1183. end;