mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-25 16:29:26 +02:00
* Merging revisions 41853 from trunk:
------------------------------------------------------------------------ r41853 | michael | 2019-04-09 13:35:56 +0200 (Tue, 09 Apr 2019) | 1 line * Patch from Serge Anvarov to improve TStrings.GetNextLine and TStrings.GetNextLineBreak (bug ID 35331) ------------------------------------------------------------------------ git-svn-id: branches/fixes_3_2@42420 -
This commit is contained in:
parent
e9ed572948
commit
364372f316
@ -610,57 +610,72 @@ end;
|
|||||||
|
|
||||||
Class Function TStrings.GetNextLine (Const Value : String; Var S : String; Var P : SizeInt) : Boolean;
|
Class Function TStrings.GetNextLine (Const Value : String; Var S : String; Var P : SizeInt) : Boolean;
|
||||||
|
|
||||||
Var
|
var
|
||||||
PS : PChar;
|
LengthOfValue: SizeInt;
|
||||||
IP,L : SizeInt;
|
StartPos, FuturePos: SizeInt;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
L:=Length(Value);
|
LengthOfValue := Length(Value);
|
||||||
S:='';
|
StartPos := P;
|
||||||
Result:=False;
|
if (StartPos <= 0) or (StartPos > LengthOfValue) then // True for LengthOfValue <= 0
|
||||||
If ((L-P)<0) then
|
|
||||||
exit;
|
|
||||||
if ((L-P)=0) and (not (value[P] in [#10,#13])) Then
|
|
||||||
Begin
|
|
||||||
s:=value[P];
|
|
||||||
inc(P);
|
|
||||||
Exit(True);
|
|
||||||
End;
|
|
||||||
PS:=PChar(Value)+P-1;
|
|
||||||
IP:=P;
|
|
||||||
While ((L-P)>=0) and (not (PS^ in [#10,#13])) do
|
|
||||||
begin
|
begin
|
||||||
P:=P+1;
|
S := '';
|
||||||
Inc(PS);
|
Exit(False);
|
||||||
end;
|
end;
|
||||||
SetLength (S,P-IP);
|
FuturePos := StartPos;
|
||||||
System.Move (Value[IP],Pointer(S)^,P-IP);
|
while (FuturePos <= LengthOfValue) and not (Value[FuturePos] in [#10, #13]) do
|
||||||
If (P<=L) and (Value[P]=#13) then
|
Inc(FuturePos);
|
||||||
Inc(P);
|
// If we use S := Copy(Value, StartPos, FuturePos - StartPos); then compiler
|
||||||
If (P<=L) and (Value[P]=#10) then
|
// generate TempS := Copy(...); S := TempS to eliminate side effects and
|
||||||
Inc(P); // Point to character after #10(#13)
|
// implicit "try finally" for TempS finalization
|
||||||
Result:=True;
|
// When we use SetString then no TempS, no try finally generated,
|
||||||
|
// but we must check case when Value and S is same (side effects)
|
||||||
|
if Pointer(S) = Pointer(Value) then
|
||||||
|
System.Delete(S, FuturePos, High(FuturePos))
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
SetString(S, @Value[StartPos], FuturePos - StartPos);
|
||||||
|
if (FuturePos <= LengthOfValue) and (Value[FuturePos] = #13) then
|
||||||
|
Inc(FuturePos);
|
||||||
|
if (FuturePos <= LengthOfValue) and (Value[FuturePos] = #10) then
|
||||||
|
Inc(FuturePos);
|
||||||
|
end;
|
||||||
|
P := FuturePos;
|
||||||
|
Result := True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Function TStrings.GetNextLineBreak (Const Value : String; Var S : String; Var P : SizeInt) : Boolean;
|
Function TStrings.GetNextLineBreak (Const Value : String; Var S : String; Var P : SizeInt) : Boolean;
|
||||||
|
|
||||||
Var
|
var
|
||||||
PS,PC,PP : PChar;
|
StartPos, FuturePos: SizeInt;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
S:='';
|
StartPos := P;
|
||||||
Result:=False;
|
if (StartPos <= 0) or (StartPos > Length(Value)) then // True for Length <= 0
|
||||||
If ((Length(Value)-P)<0) then
|
begin
|
||||||
exit;
|
S := '';
|
||||||
PS:=@Value[P];
|
Exit(False);
|
||||||
PC:=PS;
|
end;
|
||||||
PP:=AnsiStrPos(PS,PChar(FLineBreak));
|
FuturePos := Pos(FLineBreak, Value, StartPos); // Use PosEx in old RTL
|
||||||
// Stop on #0.
|
// Why we don't use Copy but use SetString read in GetNextLine
|
||||||
While (PC^<>#0) and (PC<>PP) do
|
if FuturePos = 0 then // No line breaks
|
||||||
Inc(PC);
|
begin
|
||||||
P:=P+(PC-PS)+Length(FLineBreak);
|
FuturePos := Length(Value) + 1;
|
||||||
SetString(S,PS,PC-PS);
|
if Pointer(S) = Pointer(Value) then
|
||||||
Result:=True;
|
// Nothing to do
|
||||||
|
else
|
||||||
|
SetString(S, @Value[StartPos], FuturePos - StartPos)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if Pointer(S) = Pointer(Value) then
|
||||||
|
System.Delete(S, FuturePos, High(FuturePos))
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
SetString(S, @Value[StartPos], FuturePos - StartPos);
|
||||||
|
Inc(FuturePos, Length(FLineBreak));
|
||||||
|
end;
|
||||||
|
P := FuturePos;
|
||||||
|
Result := True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{$IF (SizeOf(Integer) < SizeOf(SizeInt)) }
|
{$IF (SizeOf(Integer) < SizeOf(SizeInt)) }
|
||||||
|
Loading…
Reference in New Issue
Block a user