uses
SysUtils, StrUtils;
type
TIncStringFormatRec =
record
Mode: TSysCharSet;
Chars:
String;
CaseSensitive: Boolean;
end;
TIncStringFormat =
array of TIncStringFormatRec;
TIncStringFormat1 =
array[0..0]
of TIncStringFormatRec;
TIncStringFormat8 =
array[0..7]
of TIncStringFormatRec;
const
NoneIncFormat: TIncStringFormat1 = (
(Mode: ['
-', '
_']; Chars: '
'; CaseSensitive: True));
DecIncFormat: TIncStringFormat1 = (
(Mode: ['
D', '
0']; Chars: '
0123456789'; CaseSensitive: True));
HexIncFormat: TIncStringFormat1 = (
(Mode: ['
X', '
H']; Chars: '
0123456789ABCDEF'; CaseSensitive: False));
AlphaIncFormat: TIncStringFormat1 = (
(Mode: ['
A']; Chars: '
ABCDEFGHIJKLMNOPQRSTUVWXYZ'; CaseSensitive: False));
AlphaNumIncFormat: TIncStringFormat1 = (
(Mode: ['
N']; Chars: '
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; CaseSensitive: False));
BinIncFormat: TIncStringFormat1 = (
(Mode: ['
B']; Chars: '
01'; CaseSensitive: True));
OctIncFormat: TIncStringFormat1 = (
(Mode: ['
C']; Chars: '
01234567'; CaseSensitive: True));
Base64IncFormat: TIncStringFormat1 = (
(Mode: ['
Z']; Chars: '
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; CaseSensitive: True));
AllIncFormats: TIncStringFormat8 = (
(Mode: ['
-', '
_']; Chars: '
'; CaseSensitive: True),
(Mode: ['
D', '
0']; Chars: '
0123456789'; CaseSensitive: True),
(Mode: ['
X', '
H']; Chars: '
0123456789ABCDEF'; CaseSensitive: False),
(Mode: ['
A']; Chars: '
ABCDEFGHIJKLMNOPQRSTUVWXYZ'; CaseSensitive: False),
(Mode: ['
N']; Chars: '
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; CaseSensitive: False),
(Mode: ['
B']; Chars: '
01'; CaseSensitive: True),
(Mode: ['
C']; Chars: '
01234567'; CaseSensitive: True),
(Mode: ['
Z']; Chars: '
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; CaseSensitive: True));
procedure IncStr(
var Number:
String; Format:
String; Increment: UInt64; IncFormat:
array of TIncStringFormatRec; RightAligned: Boolean = True);
overload;
var
N, F, M, D, i: Integer;
NCNum:
String;
B: Boolean;
begin
NCNum := UpperCase(Number);
Format := UpperCase(Format);
for F := Length(Format)
downto 1
do begin
B := Format[F]
in ['
', '
~', '
*'];
for i := High(IncFormat)
downto 0
do
if Format[F]
in IncFormat[i].Mode
then begin
B := True;
Break;
end;
if not B
then
raise Exception.CreateFmt('
Ungültiger Format-Befehl "%s".', [Format[F]]);
end;
if not RightAligned
then begin
N := Length(Format);
if ContainsStr(Format, '
*')
then
raise Exception.Create('
Format-Befehl "*" darf nicht verwendet werden.');
end else
N := Length(Number);
F := Length(Format);
while Increment > 0
do begin
while (F > 0)
and (Format[F] = '
')
do begin
Dec(F);
Dec(N);
end;
if F <= 0
then
raise Exception.Create('
Format-String zu kurz.');
if Format[F] = '
~'
then // Überlauf ignorieren
break;
M := -1;
for i := High(IncFormat)
downto 0
do
if (Format[F]
in IncFormat[i].Mode)
or ((Format[F] = '
*')
and (Format[F + 1]
in IncFormat[i].Mode))
then begin
M := i;
Break;
end;
if M < 0
then
raise Exception.CreateFmt('
Ungültiger Format-Befehl "%s".', [Copy(Format, F, 2)]);
if N = 0
then begin
Insert(IncFormat[M].Chars[1], Number, 1);
Insert('
', NCNum, 1);
end else if N < 0
then
raise Exception.Create('
Number-String konnte nicht erweitert werden.');
D := Length(IncFormat[M].Chars);
if D <> 0
then begin
if IncFormat[M].CaseSensitive
then
i := Pos(Number[N], IncFormat[M].Chars) - 1
else
i := Pos(NCNum[N], IncFormat[M].Chars) - 1;
if i < 0
then
raise Exception.CreateFmt('
Ungültiger Wert "%s" in Number-String.', [Number[N]]);
Inc(i, Increment
mod D);
Number[N] := IncFormat[M].Chars[i
mod D + 1];
Increment := Increment
div D + i
div D;
end;
if Format[F] <> '
*'
then
Dec(F);
Dec(N);
end;
end;
procedure IncStr(
var Number:
String;
const Format:
String; Increment: UInt64 = 1; RightAligned: Boolean = True);
overload;
begin
IncStr(Number, Format, Increment, AllIncFormats, RightAligned);
end;
function GetIncStr(
const Number, Format:
String; Increment: UInt64; IncFormat:
array of TIncStringFormatRec; RightAligned: Boolean = True):
String;
overload;
begin
Result := Number;
IncStr(Result, Format, Increment, IncFormat, RightAligned);
end;
function GetIncStr(
const Number, Format:
String; Increment: UInt64 = 1; RightAligned: Boolean = True):
String;
overload;
begin
Result := Number;
IncStr(Result, Format, Increment, AllIncFormats, RightAligned);
end;
function IncStrPos(
const Str:
String; Start, Length: Integer; Format:
String; Increment: UInt64; IncFormat:
array of TIncStringFormatRec; RightAligned: Boolean = True):
String;
overload;
begin
Result := Copy(Str, 1, Start - 1) + GetIncStr(Copy(Str, Start, Length), Format, Increment, IncFormat, RightAligned) + Copy(Str, Start + Length);
end;
function IncStrPos(
const Str:
String; Start, Length: Integer;
const Format:
String; Increment: UInt64 = 1; RightAligned: Boolean = True):
String;
overload;
begin
Result := Copy(Str, 1, Start - 1) + GetIncStr(Copy(Str, Start, Length), Format, Increment, RightAligned) + Copy(Str, Start + Length);
end;