summaryrefslogtreecommitdiff
path: root/rtl/objpas/strutils.pp
diff options
context:
space:
mode:
Diffstat (limited to 'rtl/objpas/strutils.pp')
-rw-r--r--rtl/objpas/strutils.pp1702
1 files changed, 1702 insertions, 0 deletions
diff --git a/rtl/objpas/strutils.pp b/rtl/objpas/strutils.pp
new file mode 100644
index 0000000000..4206c94d2a
--- /dev/null
+++ b/rtl/objpas/strutils.pp
@@ -0,0 +1,1702 @@
+{$mode objfpc}
+{$h+}
+{
+ $Id: strutils.pp,v 1.16 2005/04/14 17:43:35 michael Exp $
+ This file is part of the Free Pascal run time library.
+ Copyright (c) 1999-2000 by the Free Pascal development team
+
+ Delphi/Kylix compatibility unit: String handling routines.
+
+ 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.
+
+ **********************************************************************}
+unit strutils;
+
+interface
+
+uses
+ SysUtils{, Types};
+
+{ ---------------------------------------------------------------------
+ Case sensitive search/replace
+ ---------------------------------------------------------------------}
+
+Function AnsiResemblesText(const AText, AOther: string): Boolean;
+Function AnsiContainsText(const AText, ASubText: string): Boolean;
+Function AnsiStartsText(const ASubText, AText: string): Boolean;
+Function AnsiEndsText(const ASubText, AText: string): Boolean;
+Function AnsiReplaceText(const AText, AFromText, AToText: string): string;
+Function AnsiMatchText(const AText: string; const AValues: array of string): Boolean;
+Function AnsiIndexText(const AText: string; const AValues: array of string): Integer;
+
+{ ---------------------------------------------------------------------
+ Case insensitive search/replace
+ ---------------------------------------------------------------------}
+
+Function AnsiContainsStr(const AText, ASubText: string): Boolean;
+Function AnsiStartsStr(const ASubText, AText: string): Boolean;
+Function AnsiEndsStr(const ASubText, AText: string): Boolean;
+Function AnsiReplaceStr(const AText, AFromText, AToText: string): string;
+Function AnsiMatchStr(const AText: string; const AValues: array of string): Boolean;
+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;
+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;
+Function IfThen(AValue: Boolean; const ATrue: string): string; // ; AFalse: string = ''
+
+{ ---------------------------------------------------------------------
+ VB emulations.
+ ---------------------------------------------------------------------}
+
+Function LeftStr(const AText: AnsiString; const ACount: Integer): AnsiString;
+Function RightStr(const AText: AnsiString; const ACount: Integer): AnsiString;
+Function MidStr(const AText: AnsiString; const AStart, ACount: Integer): AnsiString;
+Function RightBStr(const AText: AnsiString; const AByteCount: Integer): AnsiString;
+Function MidBStr(const AText: AnsiString; const AByteStart, AByteCount: Integer): AnsiString;
+Function AnsiLeftStr(const AText: AnsiString; const ACount: Integer): AnsiString;
+Function AnsiRightStr(const AText: AnsiString; const ACount: Integer): AnsiString;
+Function AnsiMidStr(const AText: AnsiString; const AStart, ACount: Integer): AnsiString;
+{$ifndef ver1_0}
+Function LeftBStr(const AText: AnsiString; const AByteCount: Integer): AnsiString;
+Function LeftStr(const AText: WideString; const ACount: Integer): WideString;
+Function RightStr(const AText: WideString; const ACount: Integer): WideString;
+Function MidStr(const AText: WideString; const AStart, ACount: Integer): WideString;
+{$endif}
+
+{ ---------------------------------------------------------------------
+ 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; // ; Options: TStringSearchOptions = [soDown]
+Function PosEx(const SubStr, S: string; Offset: Cardinal): Integer;
+Function PosEx(const SubStr, S: string): Integer; // 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; // ; ALength: TSoundexLength = 4
+
+type
+ TSoundexIntLength = 1..8;
+
+Function SoundexInt(const AText: string; ALength: TSoundexIntLength): Integer;
+Function SoundexInt(const AText: string): Integer; //; 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;
+Function SoundexSimilar(const AText, AOther: string): Boolean; //; ALength: TSoundexLength = 4
+Function SoundexCompare(const AText, AOther: string; ALength: TSoundexLength): Integer;
+Function SoundexCompare(const AText, AOther: string): Integer; //; 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;
+function PadRight(const S: string; N: Integer): string;
+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;
+function Copy2SpaceDel(var S: string): string;
+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;
+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 = ['-','/'];
+
+implementation
+
+{ ---------------------------------------------------------------------
+ Auxiliary functions
+ ---------------------------------------------------------------------}
+
+Procedure NotYetImplemented (FN : String);
+
+begin
+ Raise Exception.CreateFmt('Function "%s" (strutils) is not yet implemented',[FN]);
+end;
+
+{ ---------------------------------------------------------------------
+ Case sensitive 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:=Pos(ASubText,AText)<>0;
+end;
+
+Function AnsiStartsText(const ASubText, AText: string): Boolean;
+begin
+ Result:=Copy(AText,1,Length(AsubText))=ASubText;
+end;
+
+Function AnsiEndsText(const ASubText, AText: string): Boolean;
+begin
+ result:=Copy(AText,Length(AText)-Length(ASubText)+1,Length(ASubText))=asubtext;
+end;
+
+Function AnsiReplaceText(const AText, AFromText, AToText: string): string;
+
+var iFrom, iTo: longint;
+
+begin
+ iTo:=Pos(AFromText,AText);
+ if iTo=0 then
+ result:=AText
+ else
+ begin
+ result:='';
+ iFrom:=1;
+ while (ito<>0) do
+ begin
+ result:=Result+Copy(AText,IFrom,Ito-IFrom+1)+AToText;
+ ifrom:=ITo+Length(afromtext);
+ ito:=Posex(Afromtext,atext,ifrom);
+ end;
+ if ifrom<=length(atext) then
+ result:=result+copy(AText,ifrom, length(atext));
+ end;
+end;
+
+Function AnsiMatchText(const AText: string; const AValues: array of string): Boolean;
+
+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 insensitive search/replace
+ ---------------------------------------------------------------------}
+
+Function AnsiContainsStr(const AText, ASubText: string): Boolean;
+
+begin
+ Result := Pos(ASubText,AText)<>0;
+end;
+
+
+
+Function AnsiStartsStr(const ASubText, AText: string): Boolean;
+
+begin
+ Result := Pos(ASubText,AText)=1;
+end;
+
+
+
+Function AnsiEndsStr(const ASubText, AText: string): Boolean;
+
+begin
+ Result := Pos(ASubText,AText)=(length(AText)-length(ASubText)+1);
+end;
+
+
+Function AnsiReplaceStr(const AText, AFromText, AToText: string): string;
+
+begin
+Result := StringReplace(AText,AFromText,AToText,[rfReplaceAll]);
+end;
+
+
+
+Function AnsiMatchStr(const AText: string; const AValues: array of string): Boolean;
+
+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;
+
+begin
+ Result:=ReverseString(AText);
+end;
+
+
+
+Function StuffString(const AText: string; AStart, ALength: Cardinal; const ASubText: string): string;
+
+var i,j : longint;
+
+begin
+ j:=length(ASubText);
+ i:=length(AText);
+ SetLength(Result,i-ALength+j);
+ move (AText[1],result[1],AStart-1);
+ move (ASubText[1],result[AStart],j);
+ move (AText[AStart+ALength], Result[AStart+j],i-AStart-ALength+1);
+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;
+
+begin
+ if avalue then
+ result:=atrue
+ else
+ result:=afalse;
+end;
+
+
+
+Function IfThen(AValue: Boolean; const ATrue: string): string; // ; AFalse: string = ''
+
+begin
+ if avalue then
+ result:=atrue
+ else
+ result:='';
+end;
+
+
+
+{ ---------------------------------------------------------------------
+ VB emulations.
+ ---------------------------------------------------------------------}
+
+Function LeftStr(const AText: AnsiString; const ACount: Integer): AnsiString;
+
+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;
+
+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;
+
+begin
+ Result:=LeftStr(AText,AByteCount);
+end;
+
+
+
+Function RightBStr(const AText: AnsiString; const AByteCount: Integer): AnsiString;
+
+begin
+ Result:=RightStr(Atext,AByteCount);
+end;
+
+
+
+Function MidBStr(const AText: AnsiString; const AByteStart, AByteCount: Integer): AnsiString;
+
+begin
+ Result:=MidStr(AText,AByteStart,AByteCount);
+end;
+
+
+
+Function AnsiLeftStr(const AText: AnsiString; const ACount: Integer): AnsiString;
+
+begin
+ Result := copy(AText,1,ACount);
+end;
+
+
+
+Function AnsiRightStr(const AText: AnsiString; const ACount: Integer): AnsiString;
+
+begin
+ Result := copy(AText,length(AText)-ACount+1,ACount);
+end;
+
+
+
+Function AnsiMidStr(const AText: AnsiString; const AStart, ACount: Integer): AnsiString;
+
+begin
+ Result:=Copy(AText,AStart,ACount);
+end;
+
+{$ifndef ver1_0}
+Function LeftStr(const AText: WideString; const ACount: Integer): WideString;
+
+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;
+
+begin
+ Result:=Copy(AText,AStart,ACount);
+end;
+{$endif}
+
+
+
+
+{ ---------------------------------------------------------------------
+ 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; // ; 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>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; // 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>length(s)) then exit(0);
+ l:=length(s);
+{$ifndef useindexbyte}
+ while (offset<=l) and (s[offset]<>c) do inc(offset);
+ if 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; // ; 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; //; 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;
+
+begin
+ Result:=Soundex(AText,ALength)=Soundex(AOther,ALength);
+end;
+
+
+
+Function SoundexSimilar(const AText, AOther: string): Boolean; //; ALength: TSoundexLength = 4
+
+begin
+ Result:=SoundexSimilar(AText,AOther,4);
+end;
+
+
+
+Function SoundexCompare(const AText, AOther: string; ALength: TSoundexLength): Integer;
+
+begin
+ Result:=AnsiCompareStr(Soundex(AText,ALength),Soundex(AOther,ALength));
+end;
+
+
+
+Function SoundexCompare(const AText, AOther: string): Integer; //; 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;
+begin
+ Result:=AddCharR(' ',S,N);
+end;
+
+function PadLeft(const S: string; N: Integer): string;
+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;
+
+begin
+ Result:=Copy2Symb(S,Symb);
+ S:=TrimRight(Copy(S,Length(Result)+1,Length(S)));
+end;
+
+function Copy2Space(const S: string): string;
+begin
+ Result:=Copy2Symb(S,' ');
+end;
+
+function Copy2SpaceDel(var S: string): string;
+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;
+
+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);
+ if (i<=l) and (S[i] in Delims) then
+ 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
+ Result:=ExtractWord(i,S,WordDelims)=W;
+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:=StrTointDef(HexStr,0);
+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
+ 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 : Integer;
+ 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 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;
+
+end.
+
+{
+ $Log: strutils.pp,v $
+ Revision 1.16 2005/04/14 17:43:35 michael
+ + Fix for BintoHex and hextobin by Uberto Barbini
+
+ Revision 1.15 2005/03/25 22:53:39 jonas
+ * fixed several warnings and notes about unused variables (mainly) or
+ uninitialised use of variables/function results (a few)
+
+ Revision 1.14 2005/02/14 17:13:31 peter
+ * truncate log
+
+ Revision 1.13 2005/02/03 21:38:17 marco
+ * committed bintohex and hextobin
+
+ Revision 1.12 2005/01/26 11:05:09 marco
+ * fix
+
+ Revision 1.11 2005/01/01 18:45:25 marco
+ * rpos and rposex, both two versions
+
+}