12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778 |
- {
- Delphi/Kylix compatibility unit: String handling routines.
- This file is part of the Free Pascal run time library.
- Copyright (c) 1999-2005 by the Free Pascal development team
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- {$mode objfpc}
- {$h+}
- {$inline on}
- unit strutils;
- interface
- uses
- SysUtils{, Types};
- { ---------------------------------------------------------------------
- Case insensitive search/replace
- ---------------------------------------------------------------------}
- Function AnsiResemblesText(const AText, AOther: string): Boolean;
- Function AnsiContainsText(const AText, ASubText: string): Boolean;
- Function AnsiStartsText(const ASubText, AText: string): Boolean;inline;
- Function AnsiEndsText(const ASubText, AText: string): Boolean;inline;
- Function AnsiReplaceText(const AText, AFromText, AToText: string): string;inline;
- Function AnsiMatchText(const AText: string; const AValues: array of string): Boolean;inline;
- Function AnsiIndexText(const AText: string; const AValues: array of string): Integer;
- { ---------------------------------------------------------------------
- Case sensitive search/replace
- ---------------------------------------------------------------------}
- Function AnsiContainsStr(const AText, ASubText: string): Boolean;inline;
- Function AnsiStartsStr(const ASubText, AText: string): Boolean;inline;
- Function AnsiEndsStr(const ASubText, AText: string): Boolean;inline;
- Function AnsiReplaceStr(const AText, AFromText, AToText: string): string;inline;
- Function AnsiMatchStr(const AText: string; const AValues: array of string): Boolean;inline;
- Function AnsiIndexStr(const AText: string; const AValues: array of string): Integer;
- { ---------------------------------------------------------------------
- Playthingies
- ---------------------------------------------------------------------}
- Function DupeString(const AText: string; ACount: Integer): string;
- Function ReverseString(const AText: string): string;
- Function AnsiReverseString(const AText: AnsiString): AnsiString;inline;
- Function StuffString(const AText: string; AStart, ALength: Cardinal; const ASubText: string): string;
- Function RandomFrom(const AValues: array of string): string; overload;
- Function IfThen(AValue: Boolean; const ATrue: string; AFalse: string): string;inline;
- Function IfThen(AValue: Boolean; const ATrue: string): string;inline; // ; AFalse: string = ''
- { ---------------------------------------------------------------------
- VB emulations.
- ---------------------------------------------------------------------}
- Function LeftStr(const AText: AnsiString; const ACount: Integer): AnsiString;inline;
- Function RightStr(const AText: AnsiString; const ACount: Integer): AnsiString;
- Function MidStr(const AText: AnsiString; const AStart, ACount: Integer): AnsiString;inline;
- Function RightBStr(const AText: AnsiString; const AByteCount: Integer): AnsiString;inline;
- Function MidBStr(const AText: AnsiString; const AByteStart, AByteCount: Integer): AnsiString;inline;
- Function AnsiLeftStr(const AText: AnsiString; const ACount: Integer): AnsiString;inline;
- Function AnsiRightStr(const AText: AnsiString; const ACount: Integer): AnsiString;inline;
- Function AnsiMidStr(const AText: AnsiString; const AStart, ACount: Integer): AnsiString;inline;
- Function LeftBStr(const AText: AnsiString; const AByteCount: Integer): AnsiString;inline;
- Function LeftStr(const AText: WideString; const ACount: Integer): WideString;inline;
- Function RightStr(const AText: WideString; const ACount: Integer): WideString;
- Function MidStr(const AText: WideString; const AStart, ACount: Integer): WideString;inline;
- { ---------------------------------------------------------------------
- Extended search and replace
- ---------------------------------------------------------------------}
- const
- { Default word delimiters are any character except the core alphanumerics. }
- WordDelimiters: set of Char = [#0..#255] - ['a'..'z','A'..'Z','1'..'9','0'];
- type
- TStringSearchOption = (soDown, soMatchCase, soWholeWord);
- TStringSearchOptions = set of TStringSearchOption;
- TStringSeachOption = TStringSearchOption;
- Function SearchBuf(Buf: PChar; BufLen: Integer; SelStart, SelLength: Integer; SearchString: String; Options: TStringSearchOptions): PChar;
- Function SearchBuf(Buf: PChar; BufLen: Integer; SelStart, SelLength: Integer; SearchString: String): PChar;inline; // ; Options: TStringSearchOptions = [soDown]
- Function PosEx(const SubStr, S: string; Offset: Cardinal): Integer;
- Function PosEx(const SubStr, S: string): Integer;inline; // Offset: Cardinal = 1
- Function PosEx(c:char; const S: string; Offset: Cardinal): Integer;
- { ---------------------------------------------------------------------
- Soundex Functions.
- ---------------------------------------------------------------------}
- type
- TSoundexLength = 1..MaxInt;
- Function Soundex(const AText: string; ALength: TSoundexLength): string;
- Function Soundex(const AText: string): string;inline; // ; ALength: TSoundexLength = 4
- type
- TSoundexIntLength = 1..8;
- Function SoundexInt(const AText: string; ALength: TSoundexIntLength): Integer;
- Function SoundexInt(const AText: string): Integer;inline; //; ALength: TSoundexIntLength = 4
- Function DecodeSoundexInt(AValue: Integer): string;
- Function SoundexWord(const AText: string): Word;
- Function DecodeSoundexWord(AValue: Word): string;
- Function SoundexSimilar(const AText, AOther: string; ALength: TSoundexLength): Boolean;inline;
- Function SoundexSimilar(const AText, AOther: string): Boolean;inline; //; ALength: TSoundexLength = 4
- Function SoundexCompare(const AText, AOther: string; ALength: TSoundexLength): Integer;inline;
- Function SoundexCompare(const AText, AOther: string): Integer;inline; //; ALength: TSoundexLength = 4
- Function SoundexProc(const AText, AOther: string): Boolean;
- type
- TCompareTextProc = Function(const AText, AOther: string): Boolean;
- Const
- AnsiResemblesProc: TCompareTextProc = @SoundexProc;
- { ---------------------------------------------------------------------
- Other functions, based on RxStrUtils.
- ---------------------------------------------------------------------}
- function IsEmptyStr(const S: string; const EmptyChars: TSysCharSet): Boolean;
- function DelSpace(const S: string): string;
- function DelChars(const S: string; Chr: Char): string;
- function DelSpace1(const S: string): string;
- function Tab2Space(const S: string; Numb: Byte): string;
- function NPos(const C: string; S: string; N: Integer): Integer;
- Function RPosEX(C:char;const S : AnsiString;offs:cardinal):Integer; overload;
- Function RPosex (Const Substr : AnsiString; Const Source : AnsiString;offs:cardinal) : Integer; overload;
- Function RPos(c:char;const S : AnsiString):Integer; overload;
- Function RPos (Const Substr : AnsiString; Const Source : AnsiString) : Integer; overload;
- function AddChar(C: Char; const S: string; N: Integer): string;
- function AddCharR(C: Char; const S: string; N: Integer): string;
- function PadLeft(const S: string; N: Integer): string;inline;
- function PadRight(const S: string; N: Integer): string;inline;
- function PadCenter(const S: string; Len: Integer): string;
- function Copy2Symb(const S: string; Symb: Char): string;
- function Copy2SymbDel(var S: string; Symb: Char): string;
- function Copy2Space(const S: string): string;inline;
- function Copy2SpaceDel(var S: string): string;inline;
- function AnsiProperCase(const S: string; const WordDelims: TSysCharSet): string;
- function WordCount(const S: string; const WordDelims: TSysCharSet): Integer;
- function WordPosition(const N: Integer; const S: string; const WordDelims: TSysCharSet): Integer;
- function ExtractWord(N: Integer; const S: string; const WordDelims: TSysCharSet): string;inline;
- function ExtractWordPos(N: Integer; const S: string; const WordDelims: TSysCharSet; var Pos: Integer): string;
- function ExtractDelimited(N: Integer; const S: string; const Delims: TSysCharSet): string;
- function ExtractSubstr(const S: string; var Pos: Integer; const Delims: TSysCharSet): string;
- function IsWordPresent(const W, S: string; const WordDelims: TSysCharSet): Boolean;
- function FindPart(const HelpWilds, InputStr: string): Integer;
- function IsWild(InputStr, Wilds: string; IgnoreCase: Boolean): Boolean;
- function XorString(const Key, Src: ShortString): ShortString;
- function XorEncode(const Key, Source: string): string;
- function XorDecode(const Key, Source: string): string;
- function GetCmdLineArg(const Switch: string; SwitchChars: TSysCharSet): string;
- function Numb2USA(const S: string): string;
- function Hex2Dec(const S: string): Longint;
- function Dec2Numb(N: Longint; Len, Base: Byte): string;
- function Numb2Dec(S: string; Base: Byte): Longint;
- function IntToBin(Value: Longint; Digits, Spaces: Integer): string;
- function IntToRoman(Value: Longint): string;
- function RomanToInt(const S: string): Longint;
- procedure BinToHex(BinValue, HexValue: PChar; BinBufSize: Integer);
- function HexToBin(HexValue, BinValue: PChar; BinBufSize: Integer): Integer;
- const
- DigitChars = ['0'..'9'];
- Brackets = ['(',')','[',']','{','}'];
- StdWordDelims = [#0..' ',',','.',';','/','\',':','''','"','`'] + Brackets;
- StdSwitchChars = ['-','/'];
- function PosSet (const c:TSysCharSet;const s : ansistring ):Integer;
- function PosSet (const c:string;const s : ansistring ):Integer;
- function PosSetEx (const c:TSysCharSet;const s : ansistring;count:Integer ):Integer;
- function PosSetEx (const c:string;const s : ansistring;count:Integer ):Integer;
- Procedure Removeleadingchars(VAR S : AnsiString; Const CSet:TSysCharset);
- Procedure RemoveTrailingChars(VAR S : AnsiString;Const CSet:TSysCharset);
- Procedure RemovePadChars(VAR S : AnsiString;Const CSet:TSysCharset);
- function TrimLeftSet(const S: String;const CSet:TSysCharSet): String;
- Function TrimRightSet(const S: String;const CSet:TSysCharSet): String;
- function TrimSet(const S: String;const CSet:TSysCharSet): String;
- implementation
- { ---------------------------------------------------------------------
- Auxiliary functions
- ---------------------------------------------------------------------}
- Procedure NotYetImplemented (FN : String);
- begin
- Raise Exception.CreateFmt('Function "%s" (strutils) is not yet implemented',[FN]);
- end;
- { ---------------------------------------------------------------------
- Case insensitive search/replace
- ---------------------------------------------------------------------}
- Function AnsiResemblesText(const AText, AOther: string): Boolean;
- begin
- if Assigned(AnsiResemblesProc) then
- Result:=AnsiResemblesProc(AText,AOther)
- else
- Result:=False;
- end;
- Function AnsiContainsText(const AText, ASubText: string): Boolean;
- begin
- AnsiContainsText:=AnsiPos(AnsiUppercase(ASubText),AnsiUppercase(AText))>0;
- end;
- Function AnsiStartsText(const ASubText, AText: string): Boolean;inline;
- begin
- Result:=AnsiCompareText(Copy(AText,1,Length(AsubText)),ASubText)=0;
- end;
- Function AnsiEndsText(const ASubText, AText: string): Boolean;inline;
- begin
- result:=AnsiCompareText(Copy(AText,Length(AText)-Length(ASubText)+1,Length(ASubText)),asubtext)=0;
- end;
- Function AnsiReplaceText(const AText, AFromText, AToText: string): string;inline;
- begin
- Result := StringReplace(AText,AFromText,AToText,[rfReplaceAll,rfIgnoreCase]);
- end;
- Function AnsiMatchText(const AText: string; const AValues: array of string): Boolean;inline;
- begin
- Result:=(AnsiIndexText(AText,AValues)<>-1)
- end;
- Function AnsiIndexText(const AText: string; const AValues: array of string): Integer;
- var i : longint;
- begin
- result:=-1;
- if high(AValues)=-1 Then
- Exit;
- for i:=low(AValues) to High(Avalues) do
- if CompareText(avalues[i],atext)=0 Then
- exit(i); // make sure it is the first val.
- end;
- { ---------------------------------------------------------------------
- Case sensitive search/replace
- ---------------------------------------------------------------------}
- Function AnsiContainsStr(const AText, ASubText: string): Boolean;inline;
- begin
- Result := AnsiPos(ASubText,AText)>0;
- end;
- Function AnsiStartsStr(const ASubText, AText: string): Boolean;inline;
- begin
- Result := AnsiPos(ASubText,AText)=1;
- end;
- Function AnsiEndsStr(const ASubText, AText: string): Boolean;inline;
- begin
- Result := AnsiCompareStr(Copy(AText,length(AText)-length(ASubText)+1,length(ASubText)),ASubText)=0;
- end;
- Function AnsiReplaceStr(const AText, AFromText, AToText: string): string;inline;
- begin
- Result := StringReplace(AText,AFromText,AToText,[rfReplaceAll]);
- end;
- Function AnsiMatchStr(const AText: string; const AValues: array of string): Boolean;inline;
- begin
- Result:=AnsiIndexStr(AText,Avalues)<>-1;
- end;
- Function AnsiIndexStr(const AText: string; const AValues: array of string): Integer;
- var
- i : longint;
- begin
- result:=-1;
- if high(AValues)=-1 Then
- Exit;
- for i:=low(AValues) to High(Avalues) do
- if (avalues[i]=AText) Then
- exit(i); // make sure it is the first val.
- end;
- { ---------------------------------------------------------------------
- Playthingies
- ---------------------------------------------------------------------}
- Function DupeString(const AText: string; ACount: Integer): string;
- var i,l : integer;
- begin
- result:='';
- if aCount>=0 then
- begin
- l:=length(atext);
- SetLength(result,aCount*l);
- for i:=0 to ACount-1 do
- move(atext[1],Result[l*i+1],l);
- end;
- end;
- Function ReverseString(const AText: string): string;
- var
- i,j:longint;
- begin
- setlength(result,length(atext));
- i:=1; j:=length(atext);
- while (i<=j) do
- begin
- result[i]:=atext[j-i+1];
- inc(i);
- end;
- end;
- Function AnsiReverseString(const AText: AnsiString): AnsiString;inline;
- begin
- Result:=ReverseString(AText);
- end;
- Function StuffString(const AText: string; AStart, ALength: Cardinal; const ASubText: string): string;
- var i,j : SizeUInt;
- begin
- j:=length(ASubText);
- i:=length(AText);
- SetLength(Result,i+j-ALength);
- move (AText[1],result[1],AStart-1);
- move (ASubText[1],result[AStart],j);
- move (AText[AStart+ALength], Result[AStart+j],i+1-AStart-ALength);
- end;
- Function RandomFrom(const AValues: array of string): string; overload;
- begin
- if high(AValues)=-1 then exit('');
- result:=Avalues[random(High(AValues)+1)];
- end;
- Function IfThen(AValue: Boolean; const ATrue: string; AFalse: string): string;inline;
- begin
- if avalue then
- result:=atrue
- else
- result:=afalse;
- end;
- Function IfThen(AValue: Boolean; const ATrue: string): string;inline; // ; AFalse: string = ''
- begin
- if avalue then
- result:=atrue
- else
- result:='';
- end;
- { ---------------------------------------------------------------------
- VB emulations.
- ---------------------------------------------------------------------}
- Function LeftStr(const AText: AnsiString; const ACount: Integer): AnsiString;inline;
- begin
- Result:=Copy(AText,1,ACount);
- end;
- Function RightStr(const AText: AnsiString; const ACount: Integer): AnsiString;
- var j,l:integer;
- begin
- l:=length(atext);
- j:=ACount;
- if j>l then j:=l;
- Result:=Copy(AText,l-j+1,j);
- end;
- Function MidStr(const AText: AnsiString; const AStart, ACount: Integer): AnsiString;inline;
- begin
- if (ACount=0) or (AStart>length(atext)) then
- exit('');
- Result:=Copy(AText,AStart,ACount);
- end;
- Function LeftBStr(const AText: AnsiString; const AByteCount: Integer): AnsiString;inline;
- begin
- Result:=LeftStr(AText,AByteCount);
- end;
- Function RightBStr(const AText: AnsiString; const AByteCount: Integer): AnsiString;inline;
- begin
- Result:=RightStr(Atext,AByteCount);
- end;
- Function MidBStr(const AText: AnsiString; const AByteStart, AByteCount: Integer): AnsiString;inline;
- begin
- Result:=MidStr(AText,AByteStart,AByteCount);
- end;
- Function AnsiLeftStr(const AText: AnsiString; const ACount: Integer): AnsiString;inline;
- begin
- Result := copy(AText,1,ACount);
- end;
- Function AnsiRightStr(const AText: AnsiString; const ACount: Integer): AnsiString;inline;
- begin
- Result := copy(AText,length(AText)-ACount+1,ACount);
- end;
- Function AnsiMidStr(const AText: AnsiString; const AStart, ACount: Integer): AnsiString;inline;
- begin
- Result:=Copy(AText,AStart,ACount);
- end;
- Function LeftStr(const AText: WideString; const ACount: Integer): WideString;inline;
- begin
- Result:=Copy(AText,1,ACount);
- end;
- Function RightStr(const AText: WideString; const ACount: Integer): WideString;
- var
- j,l:integer;
- begin
- l:=length(atext);
- j:=ACount;
- if j>l then j:=l;
- Result:=Copy(AText,l-j+1,j);
- end;
- Function MidStr(const AText: WideString; const AStart, ACount: Integer): WideString;inline;
- begin
- Result:=Copy(AText,AStart,ACount);
- end;
- { ---------------------------------------------------------------------
- Extended search and replace
- ---------------------------------------------------------------------}
- Function SearchBuf(Buf: PChar; BufLen: Integer; SelStart, SelLength: Integer; SearchString: String; Options: TStringSearchOptions): PChar;
- var
- Len,I,SLen: Integer;
- C: Char;
- Found : Boolean;
- Direction: Shortint;
- CharMap: array[Char] of Char;
- Function GotoNextWord(var P : PChar): Boolean;
- begin
- if (Direction=1) then
- begin
- // Skip characters
- While (Len>0) and not (P^ in WordDelimiters) do
- begin
- Inc(P);
- Dec(Len);
- end;
- // skip delimiters
- While (Len>0) and (P^ in WordDelimiters) do
- begin
- Inc(P);
- Dec(Len);
- end;
- Result:=Len>0;
- end
- else
- begin
- // Skip Delimiters
- While (Len>0) and (P^ in WordDelimiters) do
- begin
- Dec(P);
- Dec(Len);
- end;
- // skip characters
- While (Len>0) and not (P^ in WordDelimiters) do
- begin
- Dec(P);
- Dec(Len);
- end;
- Result:=Len>0;
- // We're on the first delimiter. Pos back on char.
- Inc(P);
- Inc(Len);
- end;
- end;
- begin
- Result:=nil;
- Slen:=Length(SearchString);
- if (BufLen<=0) or (Slen=0) then
- Exit;
- if soDown in Options then
- begin
- Direction:=1;
- Inc(SelStart,SelLength);
- Len:=BufLen-SelStart-SLen+1;
- if (Len<=0) then
- Exit;
- end
- else
- begin
- Direction:=-1;
- Dec(SelStart,Length(SearchString));
- Len:=SelStart+1;
- end;
- if (SelStart<0) or (SelStart>BufLen) then
- Exit;
- Result:=@Buf[SelStart];
- for C:=Low(Char) to High(Char) do
- if (soMatchCase in Options) then
- CharMap[C]:=C
- else
- CharMap[C]:=Upcase(C);
- if Not (soMatchCase in Options) then
- SearchString:=UpCase(SearchString);
- Found:=False;
- while (Result<>Nil) and (Not Found) do
- begin
- if ((soWholeWord in Options) and
- (Result<>@Buf[SelStart]) and
- not GotoNextWord(Result)) then
- Result:=Nil
- else
- begin
- // try to match whole searchstring
- I:=0;
- while (I<Slen) and (CharMap[Result[I]]=SearchString[I+1]) do
- Inc(I);
- // Whole searchstring matched ?
- if (I=SLen) then
- Found:=(Len=0) or
- (not (soWholeWord in Options)) or
- (Result[SLen] in WordDelimiters);
- if not Found then
- begin
- Inc(Result,Direction);
- Dec(Len);
- If (Len=0) then
- Result:=Nil;
- end;
- end;
- end;
- end;
- Function SearchBuf(Buf: PChar; BufLen: Integer; SelStart, SelLength: Integer; SearchString: String): PChar;inline; // ; Options: TStringSearchOptions = [soDown]
- begin
- Result:=SearchBuf(Buf,BufLen,SelStart,SelLength,SearchString,[soDown]);
- end;
- Function PosEx(const SubStr, S: string; Offset: Cardinal): Integer;
- var i : pchar;
- begin
- if (offset<1) or (offset>SizeUInt(length(s))) then exit(0);
- i:=strpos(@s[offset],@substr[1]);
- if i=nil then
- PosEx:=0
- else
- PosEx:=succ(i-pchar(s));
- end;
- Function PosEx(const SubStr, S: string): Integer;inline; // Offset: Cardinal = 1
- begin
- posex:=posex(substr,s,1);
- end;
- Function PosEx(c:char; const S: string; Offset: Cardinal): Integer;
- var l : longint;
- begin
- if (offset<1) or (offset>SizeUInt(length(s))) then exit(0);
- l:=length(s);
- {$ifndef useindexbyte}
- while (SizeInt(offset)<=l) and (s[offset]<>c) do inc(offset);
- if SizeInt(offset)>l then
- posex:=0
- else
- posex:=offset;
- {$else}
- posex:=offset+indexbyte(s[offset],l-offset+1);
- if posex=(offset-1) then
- posex:=0;
- {$endif}
- end;
- { ---------------------------------------------------------------------
- Soundex Functions.
- ---------------------------------------------------------------------}
- Const
- SScore : array[1..255] of Char =
- ('0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0', // 1..32
- '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0', // 33..64
- '0','1','2','3','0','1','2','i','0','2','2','4','5','5','0','1','2','6','2','3','0','1','i','2','i','2', // 64..90
- '0','0','0','0','0','0', // 91..95
- '0','1','2','3','0','1','2','i','0','2','2','4','5','5','0','1','2','6','2','3','0','1','i','2','i','2', // 96..122
- '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0', // 123..154
- '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0', // 155..186
- '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0', // 187..218
- '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0', // 219..250
- '0','0','0','0','0'); // 251..255
- Function Soundex(const AText: string; ALength: TSoundexLength): string;
- Var
- S,PS : Char;
- I,L : integer;
- begin
- Result:='';
- PS:=#0;
- If Length(AText)>0 then
- begin
- Result:=Upcase(AText[1]);
- I:=2;
- L:=Length(AText);
- While (I<=L) and (Length(Result)<ALength) do
- begin
- S:=SScore[Ord(AText[i])];
- If Not (S in ['0','i',PS]) then
- Result:=Result+S;
- If (S<>'i') then
- PS:=S;
- Inc(I);
- end;
- end;
- L:=Length(Result);
- If (L<ALength) then
- Result:=Result+StringOfChar('0',Alength-L);
- end;
- Function Soundex(const AText: string): string;inline; // ; ALength: TSoundexLength = 4
- begin
- Result:=Soundex(AText,4);
- end;
- Const
- Ord0 = Ord('0');
- OrdA = Ord('A');
- Function SoundexInt(const AText: string; ALength: TSoundexIntLength): Integer;
- var
- SE: string;
- I: Integer;
- begin
- Result:=-1;
- SE:=Soundex(AText,ALength);
- If Length(SE)>0 then
- begin
- Result:=Ord(SE[1])-OrdA;
- if ALength > 1 then
- begin
- Result:=Result*26+(Ord(SE[2])-Ord0);
- for I:=3 to ALength do
- Result:=(Ord(SE[I])-Ord0)+Result*7;
- end;
- Result:=ALength+Result*9;
- end;
- end;
- Function SoundexInt(const AText: string): Integer;inline; //; ALength: TSoundexIntLength = 4
- begin
- Result:=SoundexInt(AText,4);
- end;
- Function DecodeSoundexInt(AValue: Integer): string;
- var
- I, Len: Integer;
- begin
- Result := '';
- Len := AValue mod 9;
- AValue := AValue div 9;
- for I:=Len downto 3 do
- begin
- Result:=Chr(Ord0+(AValue mod 7))+Result;
- AValue:=AValue div 7;
- end;
- if Len>2 then
- Result:=IntToStr(AValue mod 26)+Result;
- AValue:=AValue div 26;
- Result:=Chr(OrdA+AValue)+Result;
- end;
- Function SoundexWord(const AText: string): Word;
- Var
- S : String;
- begin
- S:=SoundEx(Atext,4);
- Result:=Ord(S[1])-OrdA;
- Result:=Result*26+StrToInt(S[2]);
- Result:=Result*7+StrToInt(S[3]);
- Result:=Result*7+StrToInt(S[4]);
- end;
- Function DecodeSoundexWord(AValue: Word): string;
- begin
- Result := Chr(Ord0+ (AValue mod 7));
- AValue := AValue div 7;
- Result := Chr(Ord0+ (AValue mod 7)) + Result;
- AValue := AValue div 7;
- Result := IntToStr(AValue mod 26) + Result;
- AValue := AValue div 26;
- Result := Chr(OrdA+AValue) + Result;
- end;
- Function SoundexSimilar(const AText, AOther: string; ALength: TSoundexLength): Boolean;inline;
- begin
- Result:=Soundex(AText,ALength)=Soundex(AOther,ALength);
- end;
- Function SoundexSimilar(const AText, AOther: string): Boolean;inline; //; ALength: TSoundexLength = 4
- begin
- Result:=SoundexSimilar(AText,AOther,4);
- end;
- Function SoundexCompare(const AText, AOther: string; ALength: TSoundexLength): Integer;inline;
- begin
- Result:=AnsiCompareStr(Soundex(AText,ALength),Soundex(AOther,ALength));
- end;
- Function SoundexCompare(const AText, AOther: string): Integer;inline; //; ALength: TSoundexLength = 4
- begin
- Result:=SoundexCompare(AText,AOther,4);
- end;
- Function SoundexProc(const AText, AOther: string): Boolean;
- begin
- Result:=SoundexSimilar(AText,AOther);
- end;
- { ---------------------------------------------------------------------
- RxStrUtils-like functions.
- ---------------------------------------------------------------------}
- function IsEmptyStr(const S: string; const EmptyChars: TSysCharSet): Boolean;
- var
- i,l: Integer;
- begin
- l:=Length(S);
- i:=1;
- Result:=True;
- while Result and (i<=l) do
- begin
- Result:=Not (S[i] in EmptyChars);
- Inc(i);
- end;
- end;
- function DelSpace(const S: String): string;
- begin
- Result:=DelChars(S,' ');
- end;
- function DelChars(const S: string; Chr: Char): string;
- var
- I,J: Integer;
- begin
- Result:=S;
- I:=Length(Result);
- While I>0 do
- begin
- if Result[I]=Chr then
- begin
- J:=I-1;
- While (J>0) and (Result[J]=Chr) do
- Dec(j);
- Delete(Result,J+1,I-J);
- I:=J+1;
- end;
- dec(I);
- end;
- end;
- function DelSpace1(const S: string): string;
- var
- i: Integer;
- begin
- Result:=S;
- for i:=Length(Result) downto 2 do
- if (Result[i]=' ') and (Result[I-1]=' ') then
- Delete(Result,I,1);
- end;
- function Tab2Space(const S: string; Numb: Byte): string;
- var
- I: Integer;
- begin
- I:=1;
- Result:=S;
- while I <= Length(Result) do
- if Result[I]<>Chr(9) then
- inc(I)
- else
- begin
- Result[I]:=' ';
- If (Numb>1) then
- Insert(StringOfChar('0',Numb-1),Result,I);
- Inc(I,Numb);
- end;
- end;
- function NPos(const C: string; S: string; N: Integer): Integer;
- var
- i,p,k: Integer;
- begin
- Result:=0;
- if N<1 then
- Exit;
- k:=0;
- i:=1;
- Repeat
- p:=pos(C,S);
- Inc(k,p);
- if p>0 then
- delete(S,1,p);
- Inc(i);
- Until (i>n) or (p=0);
- If (P>0) then
- Result:=K;
- end;
- function AddChar(C: Char; const S: string; N: Integer): string;
- Var
- l : Integer;
- begin
- Result:=S;
- l:=Length(Result);
- if l<N then
- Result:=StringOfChar(C,N-l)+Result;
- end;
- function AddCharR(C: Char; const S: string; N: Integer): string;
- Var
- l : Integer;
- begin
- Result:=S;
- l:=Length(Result);
- if l<N then
- Result:=Result+StringOfChar(C,N-l);
- end;
- function PadRight(const S: string; N: Integer): string;inline;
- begin
- Result:=AddCharR(' ',S,N);
- end;
- function PadLeft(const S: string; N: Integer): string;inline;
- begin
- Result:=AddChar(' ',S,N);
- end;
- function Copy2Symb(const S: string; Symb: Char): string;
- var
- p: Integer;
- begin
- p:=Pos(Symb,S);
- if p=0 then
- p:=Length(S)+1;
- Result:=Copy(S,1,p-1);
- end;
- function Copy2SymbDel(var S: string; Symb: Char): string;
- var
- p: Integer;
- begin
- p:=Pos(Symb,S);
- if p=0 then
- begin
- result:=s;
- s:='';
- end
- else
- begin
- Result:=Copy(S,1,p-1);
- delete(s,1,p);
- end;
- end;
- function Copy2Space(const S: string): string;inline;
- begin
- Result:=Copy2Symb(S,' ');
- end;
- function Copy2SpaceDel(var S: string): string;inline;
- begin
- Result:=Copy2SymbDel(S,' ');
- end;
- function AnsiProperCase(const S: string; const WordDelims: TSysCharSet): string;
- var
- // l : Integer;
- P,PE : PChar;
- begin
- Result:=AnsiLowerCase(S);
- P:=PChar(Result);
- PE:=P+Length(Result);
- while (P<PE) do
- begin
- while (P<PE) and (P^ in WordDelims) do
- inc(P);
- if (P<PE) then
- P^:=UpCase(P^);
- while (P<PE) and not (P^ in WordDelims) do
- inc(P);
- end;
- end;
- function WordCount(const S: string; const WordDelims: TSysCharSet): Integer;
- var
- P,PE : PChar;
- begin
- Result:=0;
- P:=Pchar(S);
- PE:=P+Length(S);
- while (P<PE) do
- begin
- while (P<PE) and (P^ in WordDelims) do
- Inc(P);
- if (P<PE) then
- inc(Result);
- while (P<PE) and not (P^ in WordDelims) do
- inc(P);
- end;
- end;
- function WordPosition(const N: Integer; const S: string; const WordDelims: TSysCharSet): Integer;
- var
- PS,P,PE : PChar;
- Count: Integer;
- begin
- Result:=0;
- Count:=0;
- PS:=PChar(S);
- PE:=PS+Length(S);
- P:=PS;
- while (P<PE) and (Count<>N) do
- begin
- while (P<PE) and (P^ in WordDelims) do
- inc(P);
- if (P<PE) then
- inc(Count);
- if (Count<>N) then
- while (P<PE) and not (P^ in WordDelims) do
- inc(P)
- else
- Result:=(P-PS)+1;
- end;
- end;
- function ExtractWord(N: Integer; const S: string; const WordDelims: TSysCharSet): string;inline;
- var
- i: Integer;
- begin
- Result:=ExtractWordPos(N,S,WordDelims,i);
- end;
- function ExtractWordPos(N: Integer; const S: string; const WordDelims: TSysCharSet; var Pos: Integer): string;
- var
- i,j,l: Integer;
- begin
- j:=0;
- i:=WordPosition(N, S, WordDelims);
- Pos:=i;
- if (i<>0) then
- begin
- j:=i;
- l:=Length(S);
- while (j<=L) and not (S[j] in WordDelims) do
- inc(j);
- end;
- SetLength(Result,j-i);
- If ((j-i)>0) then
- Move(S[i],Result[1],j-i);
- end;
- function ExtractDelimited(N: Integer; const S: string; const Delims: TSysCharSet): string;
- var
- w,i,l,len: Integer;
- begin
- w:=0;
- i:=1;
- l:=0;
- len:=Length(S);
- SetLength(Result, 0);
- while (i<=len) and (w<>N) do
- begin
- if s[i] in Delims then
- inc(w)
- else
- begin
- if (N-1)=w then
- begin
- inc(l);
- SetLength(Result,l);
- Result[L]:=S[i];
- end;
- end;
- inc(i);
- end;
- end;
- function ExtractSubstr(const S: string; var Pos: Integer; const Delims: TSysCharSet): string;
- var
- i,l: Integer;
- begin
- i:=Pos;
- l:=Length(S);
- while (i<=l) and not (S[i] in Delims) do
- inc(i);
- Result:=Copy(S,Pos,i-Pos);
- while (i<=l) and (S[i] in Delims) do
- inc(i);
- Pos:=i;
- end;
- function isWordPresent(const W, S: string; const WordDelims: TSysCharSet): Boolean;
- var
- i,Count : Integer;
- begin
- Result:=False;
- Count:=WordCount(S, WordDelims);
- I:=1;
- While (Not Result) and (I<=Count) do
- begin
- Result:=ExtractWord(i,S,WordDelims)=W;
- Inc(i);
- end;
- end;
- function Numb2USA(const S: string): string;
- var
- i, NA: Integer;
- begin
- i:=Length(S);
- Result:=S;
- NA:=0;
- while (i > 0) do begin
- if ((Length(Result) - i + 1 - NA) mod 3 = 0) and (i <> 1) then
- begin
- insert(',', Result, i);
- inc(NA);
- end;
- Dec(i);
- end;
- end;
- function PadCenter(const S: string; Len: Integer): string;
- begin
- if Length(S)<Len then
- begin
- Result:=StringOfChar(' ',(Len div 2) -(Length(S) div 2))+S;
- Result:=Result+StringOfChar(' ',Len-Length(Result));
- end
- else
- Result:=S;
- end;
- function Hex2Dec(const S: string): Longint;
- var
- HexStr: string;
- begin
- if Pos('$',S)=0 then
- HexStr:='$'+ S
- else
- HexStr:=S;
- Result:=StrToInt(HexStr);
- end;
- function Dec2Numb(N: Longint; Len, Base: Byte): string;
- var
- C: Integer;
- Number: Longint;
- begin
- if N=0 then
- Result:='0'
- else
- begin
- Number:=N;
- Result:='';
- while Number>0 do
- begin
- C:=Number mod Base;
- if C>9 then
- C:=C+55
- else
- C:=C+48;
- Result:=Chr(C)+Result;
- Number:=Number div Base;
- end;
- end;
- if (Result<>'') then
- Result:=AddChar('0',Result,Len);
- end;
- function Numb2Dec(S: string; Base: Byte): Longint;
- var
- i, P: Longint;
- begin
- i:=Length(S);
- Result:=0;
- S:=UpperCase(S);
- P:=1;
- while (i>=1) do
- begin
- if (S[i]>'@') then
- Result:=Result+(Ord(S[i])-55)*P
- else
- Result:=Result+(Ord(S[i])-48)*P;
- Dec(i);
- P:=P*Base;
- end;
- end;
- function RomanToint(const S: string): Longint;
- const
- RomanChars = ['C','D','I','L','M','V','X'];
- RomanValues : array['C'..'X'] of Word
- = (100,500,0,0,0,0,1,0,0,50,1000,0,0,0,0,0,0,0,0,5,0,10);
- var
- index, Next: Char;
- i,l: Integer;
- Negative: Boolean;
- begin
- Result:=0;
- i:=0;
- Negative:=(Length(S)>0) and (S[1]='-');
- if Negative then
- inc(i);
- l:=Length(S);
- while (i<l) do
- begin
- inc(i);
- index:=UpCase(S[i]);
- if index in RomanChars then
- begin
- if Succ(i)<=l then
- Next:=UpCase(S[i+1])
- else
- Next:=#0;
- if (Next in RomanChars) and (RomanValues[index]<RomanValues[Next]) then
- begin
- inc(Result, RomanValues[Next]);
- Dec(Result, RomanValues[index]);
- inc(i);
- end
- else
- inc(Result, RomanValues[index]);
- end
- else
- begin
- Result:=0;
- Exit;
- end;
- end;
- if Negative then
- Result:=-Result;
- end;
- function intToRoman(Value: Longint): string;
- const
- Arabics : Array[1..13] of Integer
- = (1,4,5,9,10,40,50,90,100,400,500,900,1000);
- Romans : Array[1..13] of String
- = ('I','IV','V','IX','X','XL','L','XC','C','CD','D','CM','M');
- var
- i: Integer;
- begin
- Result:='';
- for i:=13 downto 1 do
- while (Value >= Arabics[i]) do
- begin
- Value:=Value-Arabics[i];
- Result:=Result+Romans[i];
- end;
- end;
- function intToBin(Value: Longint; Digits, Spaces: Integer): string;
- begin
- Result:='';
- if (Digits>32) then
- Digits:=32;
- while (Digits>0) do
- begin
- if (Digits mod Spaces)=0 then
- Result:=Result+' ';
- Dec(Digits);
- Result:=Result+intToStr((Value shr Digits) and 1);
- end;
- end;
- function FindPart(const HelpWilds, inputStr: string): Integer;
- var
- i, J: Integer;
- Diff: Integer;
- begin
- Result:=0;
- i:=Pos('?',HelpWilds);
- if (i=0) then
- Result:=Pos(HelpWilds, inputStr)
- else
- begin
- Diff:=Length(inputStr) - Length(HelpWilds);
- for i:=0 to Diff do
- begin
- for J:=1 to Length(HelpWilds) do
- if (inputStr[i + J] = HelpWilds[J]) or (HelpWilds[J] = '?') then
- begin
- if (J=Length(HelpWilds)) then
- begin
- Result:=i+1;
- Exit;
- end;
- end
- else
- Break;
- end;
- end;
- end;
- function isWild(inputStr, Wilds: string; ignoreCase: Boolean): Boolean;
- function SearchNext(var Wilds: string): Integer;
- begin
- Result:=Pos('*', Wilds);
- if Result>0 then
- Wilds:=Copy(Wilds,1,Result - 1);
- end;
- var
- CWild, CinputWord: Integer; { counter for positions }
- i, LenHelpWilds: Integer;
- MaxinputWord, MaxWilds: Integer; { Length of inputStr and Wilds }
- HelpWilds: string;
- begin
- if Wilds = inputStr then begin
- Result:=True;
- Exit;
- end;
- repeat { delete '**', because '**' = '*' }
- i:=Pos('**', Wilds);
- if i > 0 then
- Wilds:=Copy(Wilds, 1, i - 1) + '*' + Copy(Wilds, i + 2, Maxint);
- until i = 0;
- if Wilds = '*' then begin { for fast end, if Wilds only '*' }
- Result:=True;
- Exit;
- end;
- MaxinputWord:=Length(inputStr);
- MaxWilds:=Length(Wilds);
- if ignoreCase then begin { upcase all letters }
- inputStr:=AnsiUpperCase(inputStr);
- Wilds:=AnsiUpperCase(Wilds);
- end;
- if (MaxWilds = 0) or (MaxinputWord = 0) then begin
- Result:=False;
- Exit;
- end;
- CinputWord:=1;
- CWild:=1;
- Result:=True;
- repeat
- if inputStr[CinputWord] = Wilds[CWild] then begin { equal letters }
- { goto next letter }
- inc(CWild);
- inc(CinputWord);
- Continue;
- end;
- if Wilds[CWild] = '?' then begin { equal to '?' }
- { goto next letter }
- inc(CWild);
- inc(CinputWord);
- Continue;
- end;
- if Wilds[CWild] = '*' then begin { handling of '*' }
- HelpWilds:=Copy(Wilds, CWild + 1, MaxWilds);
- i:=SearchNext(HelpWilds);
- LenHelpWilds:=Length(HelpWilds);
- if i = 0 then begin
- { no '*' in the rest, compare the ends }
- if HelpWilds = '' then Exit; { '*' is the last letter }
- { check the rest for equal Length and no '?' }
- for i:=0 to LenHelpWilds - 1 do begin
- if (HelpWilds[LenHelpWilds - i] <> inputStr[MaxinputWord - i]) and
- (HelpWilds[LenHelpWilds - i]<> '?') then
- begin
- Result:=False;
- Exit;
- end;
- end;
- Exit;
- end;
- { handle all to the next '*' }
- inc(CWild, 1 + LenHelpWilds);
- i:=FindPart(HelpWilds, Copy(inputStr, CinputWord, Maxint));
- if i= 0 then begin
- Result:=False;
- Exit;
- end;
- CinputWord:=i + LenHelpWilds;
- Continue;
- end;
- Result:=False;
- Exit;
- until (CinputWord > MaxinputWord) or (CWild > MaxWilds);
- { no completed evaluation }
- if CinputWord <= MaxinputWord then Result:=False;
- if (CWild <= MaxWilds) and (Wilds[MaxWilds] <> '*') then Result:=False;
- end;
- function XorString(const Key, Src: ShortString): ShortString;
- var
- i: Integer;
- begin
- Result:=Src;
- if Length(Key) > 0 then
- for i:=1 to Length(Src) do
- Result[i]:=Chr(Byte(Key[1 + ((i - 1) mod Length(Key))]) xor Ord(Src[i]));
- end;
- function XorEncode(const Key, Source: string): string;
- var
- i: Integer;
- C: Byte;
- begin
- Result:='';
- for i:=1 to Length(Source) do
- begin
- if Length(Key) > 0 then
- C:=Byte(Key[1 + ((i - 1) mod Length(Key))]) xor Byte(Source[i])
- else
- C:=Byte(Source[i]);
- Result:=Result+AnsiLowerCase(intToHex(C, 2));
- end;
- end;
- function XorDecode(const Key, Source: string): string;
- var
- i: Integer;
- C: Char;
- begin
- Result:='';
- for i:=0 to Length(Source) div 2 - 1 do
- begin
- C:=Chr(StrTointDef('$' + Copy(Source, (i * 2) + 1, 2), Ord(' ')));
- if Length(Key) > 0 then
- C:=Chr(Byte(Key[1 + (i mod Length(Key))]) xor Byte(C));
- Result:=Result + C;
- end;
- end;
- function GetCmdLineArg(const Switch: string; SwitchChars: TSysCharSet): string;
- var
- i: Integer;
- S: string;
- begin
- i:=1;
- Result:='';
- while (Result='') and (i<=ParamCount) do
- begin
- S:=ParamStr(i);
- if (SwitchChars=[]) or ((S[1] in SwitchChars) and (Length(S) > 1)) and
- (AnsiCompareText(Copy(S,2,Length(S)-1),Switch)=0) then
- begin
- inc(i);
- if i<=ParamCount then
- Result:=ParamStr(i);
- end;
- inc(i);
- end;
- end;
- Function RPosEX(C:char;const S : AnsiString;offs:cardinal):Integer; overload;
- var I : SizeUInt;
- p,p2: pChar;
- Begin
- I:=Length(S);
- If (I<>0) and (offs<=i) Then
- begin
- p:=@s[offs];
- p2:=@s[1];
- while (p2<=p) and (p^<>c) do dec(p);
- RPosEx:=(p-p2)+1;
- end
- else
- RPosEX:=0;
- End;
- Function RPos(c:char;const S : AnsiString):Integer; overload;
- var I : Integer;
- p,p2: pChar;
- Begin
- I:=Length(S);
- If I<>0 Then
- begin
- p:=@s[i];
- p2:=@s[1];
- while (p2<=p) and (p^<>c) do dec(p);
- i:=p-p2+1;
- end;
- RPos:=i;
- End;
- Function RPos (Const Substr : AnsiString; Const Source : AnsiString) : Integer; overload;
- var
- MaxLen,llen : Integer;
- c : char;
- pc,pc2 : pchar;
- begin
- rPos:=0;
- llen:=Length(SubStr);
- maxlen:=length(source);
- if (llen>0) and (maxlen>0) and ( llen<=maxlen) then
- begin
- // i:=maxlen;
- pc:=@source[maxlen];
- pc2:=@source[llen-1];
- c:=substr[llen];
- while pc>=pc2 do
- begin
- if (c=pc^) and
- (CompareChar(Substr[1],pchar(pc-llen+1)^,Length(SubStr))=0) then
- begin
- rPos:=pchar(pc-llen+1)-pchar(@source[1])+1;
- exit;
- end;
- dec(pc);
- end;
- end;
- end;
- Function RPosex (Const Substr : AnsiString; Const Source : AnsiString;offs:cardinal) : Integer; overload;
- var
- MaxLen,llen : Integer;
- c : char;
- pc,pc2 : pchar;
- begin
- rPosex:=0;
- llen:=Length(SubStr);
- maxlen:=length(source);
- if SizeInt(offs)<maxlen then maxlen:=offs;
- if (llen>0) and (maxlen>0) and ( llen<=maxlen) then
- begin
- // i:=maxlen;
- pc:=@source[maxlen];
- pc2:=@source[llen-1];
- c:=substr[llen];
- while pc>=pc2 do
- begin
- if (c=pc^) and
- (CompareChar(Substr[1],pchar(pc-llen+1)^,Length(SubStr))=0) then
- begin
- rPosex:=pchar(pc-llen+1)-pchar(@source[1])+1;
- exit;
- end;
- dec(pc);
- end;
- end;
- end;
- // def from delphi.about.com:
- procedure BinToHex(BinValue, HexValue: PChar; BinBufSize: Integer);
- Const
- HexDigits='0123456789ABCDEF';
- var
- i : longint;
- begin
- for i:=0 to binbufsize-1 do
- begin
- HexValue[0]:=hexdigits[1+((ord(binvalue^) shr 4))];
- HexValue[1]:=hexdigits[1+((ord(binvalue^) and 15))];
- inc(hexvalue,2);
- inc(binvalue);
- end;
- end;
- function HexToBin(HexValue, BinValue: PChar; BinBufSize: Integer): Integer;
- // more complex, have to accept more than bintohex
- // A..F 1000001
- // a..f 1100001
- // 0..9 110000
- var i,j,h,l : integer;
- begin
- i:=binbufsize;
- while (i>0) do
- begin
- if hexvalue^ IN ['A'..'F','a'..'f'] then
- h:=((ord(hexvalue^)+9) and 15)
- else if hexvalue^ IN ['0'..'9'] then
- h:=((ord(hexvalue^)) and 15)
- else
- break;
- inc(hexvalue);
- if hexvalue^ IN ['A'..'F','a'..'f'] then
- l:=(ord(hexvalue^)+9) and 15
- else if hexvalue^ IN ['0'..'9'] then
- l:=(ord(hexvalue^)) and 15
- else
- break;
- j := l + (h shl 4);
- inc(hexvalue);
- binvalue^:=chr(j);
- inc(binvalue);
- dec(i);
- end;
- result:=binbufsize-i;
- end;
- function possetex (const c:TSysCharSet;const s : ansistring;count:Integer ):Integer;
- var i,j:Integer;
- begin
- if pchar(s)=nil then
- j:=0
- else
- begin
- i:=length(s);
- j:=count;
- if j>i then
- begin
- result:=0;
- exit;
- end;
- while (j<=i) and (not (s[j] in c)) do inc(j);
- if (j>i) then
- j:=0; // not found.
- end;
- result:=j;
- end;
- function posset (const c:TSysCharSet;const s : ansistring ):Integer;
- begin
- result:=possetex(c,s,1);
- end;
- function possetex (const c:string;const s : ansistring;count:Integer ):Integer;
- var cset : TSysCharSet;
- i : integer;
- begin
- cset:=[];
- if length(c)>0 then
- for i:=1 to length(c) do
- include(cset,c[i]);
- result:=possetex(cset,s,count);
- end;
- function posset (const c:string;const s : ansistring ):Integer;
- var cset : TSysCharSet;
- i : integer;
- begin
- cset:=[];
- if length(c)>0 then
- for i:=1 to length(c) do
- include(cset,c[i]);
- result:=possetex(cset,s,1);
- end;
- Procedure Removeleadingchars(VAR S : AnsiString; Const CSet:TSysCharset);
- VAR I,J : Longint;
- Begin
- I:=Length(S);
- IF (I>0) Then
- Begin
- J:=1;
- While (J<=I) And (S[J] IN CSet) DO
- INC(J);
- IF J>1 Then
- Delete(S,1,J-1);
- End;
- End;
- function TrimLeftSet(const S: String;const CSet:TSysCharSet): String;
- begin
- result:=s;
- removeleadingchars(result,cset);
- end;
- Procedure RemoveTrailingChars(VAR S : AnsiString;Const CSet:TSysCharset);
- VAR I,J: LONGINT;
- Begin
- I:=Length(S);
- IF (I>0) Then
- Begin
- J:=I;
- While (j>0) and (S[J] IN CSet) DO DEC(J);
- IF J<>I Then
- SetLength(S,J);
- End;
- End;
- Function TrimRightSet(const S: String;const CSet:TSysCharSet): String;
- begin
- result:=s;
- RemoveTrailingchars(result,cset);
- end;
- Procedure RemovePadChars(VAR S : AnsiString;Const CSet:TSysCharset);
- VAR I,J,K: LONGINT;
- Begin
- I:=Length(S);
- IF (I>0) Then
- Begin
- J:=I;
- While (j>0) and (S[J] IN CSet) DO DEC(J);
- if j=0 Then
- begin
- s:='';
- exit;
- end;
- k:=1;
- While (k<=I) And (S[k] IN CSet) DO
- INC(k);
- IF k>1 Then
- begin
- move(s[k],s[1],j-k+1);
- setlength(s,j-k+1);
- end
- else
- setlength(s,j);
- End;
- End;
- function TrimSet(const S: String;const CSet:TSysCharSet): String;
- begin
- result:=s;
- RemovePadChars(result,cset);
- end;
- end.
|