mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 15:47:53 +02:00
* Faster DupeString by Rika. Fixes issue #39949
This commit is contained in:
parent
d5777174d8
commit
0b3c608d79
@ -1154,24 +1154,34 @@ end;
|
||||
function DupeString(const AText: string; ACount: Integer): string;
|
||||
|
||||
var
|
||||
Len: SizeInt;
|
||||
Source, Target: PByte;
|
||||
|
||||
Len, BitIndex, Rp: SizeInt;
|
||||
|
||||
begin
|
||||
Len := Length(AText);
|
||||
if (Len = 0) or (ACount <= 0) then
|
||||
Exit('');
|
||||
if ACount = 1 then
|
||||
Exit(AText);
|
||||
|
||||
SetLength(Result, ACount * Len);
|
||||
// Use PByte to skip implicit UniqueString, because SetLength always unique
|
||||
Target := PByte(Result);
|
||||
if Target = nil then // ACount = 0 or AText = ''
|
||||
Exit;
|
||||
// Now ACount > 0 and Len > 0
|
||||
Source := PByte(AText);
|
||||
repeat
|
||||
Move(Source[0], Target[0], Len * SizeOf(Char));
|
||||
Inc(Target, Len * SizeOf(Char));
|
||||
Dec(ACount);
|
||||
until ACount = 0;
|
||||
end;
|
||||
Rp := 0;
|
||||
|
||||
// Build up ACount repeats by duplicating the string built so far and adding another AText if corresponding ACount binary digit is 1.
|
||||
// For example, ACount = 5 = %101 will, starting from the empty string:
|
||||
// (1) duplicate (count = 0), add AText (count = 1)
|
||||
// (0) duplicate (count = 2)
|
||||
// (1) duplicate (count = 4), add AText (count = 5)
|
||||
for BitIndex := BsrDWord(ACount) downto 0 do
|
||||
begin
|
||||
Move(Pointer(Result)^, PChar(Pointer(Result))[Rp], Rp * SizeOf(Char));
|
||||
Inc(Rp, Rp);
|
||||
if ACount shr BitIndex and 1 <> 0 then
|
||||
begin
|
||||
Move(Pointer(AText)^, PChar(Pointer(Result))[Rp], Len * SizeOf(Char));
|
||||
Inc(Rp, Len);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ReverseString(const AText: string): string;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user