Hallo hoika,
ich hatte vor einer Zeit das gleiche Problem und hatte zur Lösung eine kleine Routine geschrieben.
Es hat etwas gedauert aber ich hab sie jetzt wiedergefunden.
Die zweite Funktion ist "pure Pascal" und ist entsprechend langsamer.
Um die Performance zu testen habe ich einen String mit der Länge 100 Mio komplett mit 'A's gefüllt,
dann an 2 Mio zufälligen Positionen #10 bzw #13#10 eingestreut.
Ergebnis : 175 ms bzw. 375 ms (zweite Funktion).
Für einen Vergleich mit StringReplace(s,#10,#13#10,[rfReplaceAll]) habe ich einen String mit der Länge 1 Mio genommen und an 20000 Positionen #10 eigestreut.
StringReplace braucht 39 s, die beiden anderen < 15 ms.
Naja, kein ganz fairer Vergleich, weil StringReplace universell einsetzbar ist aber ich denke, daß die, die StringReplace geschrieben haben, sich die Sache etwas leicht gemacht haben.
Delphi-Quellcode:
FUNCTION EnsureCRLF(s:
string):
string;
FUNCTION Replace(dest,source:
string):integer;
asm
push eax
push ebx
mov bx,$0A0D
// BL=CR, BH=LF
jmp @Entry
@Char: mov [eax],cl
add eax,1
@1: add edx,1
@Entry: mov cx,[edx]
// 2 Chars aus Source
cmp cx,bx
je @CRLF
cmp cl,bh
je @LF
test cl,cl
jne @Char
jmp @
End
@LF: mov [eax],bx
add eax,2
jmp @1
@CRLF: mov [eax],bx
add edx,2
add eax,2
jmp @Entry
@
End: pop ebx
pop ecx
sub eax,ecx
end;
//------------------------------------------------------------------------------
var len:integer; dest:
string;
begin
if s='
'
then exit;
SetLength(result,Length(s)*2);
SetLength(result,Replace(result,s));
end;
Delphi-Quellcode:
FUNCTION xEnsureCRLF(var s:string):string;
FUNCTION Replace(var dest:string; const source:string):integer;
var ps,pd,pdsave:PChar;
begin
ps:=@source[1];
pd:=@dest[1];
pdsave:=pd;
repeat
case ps^ of
#10 : begin
PWord(pd)^:=$0A0D;
inc(PWord(pd));
inc(ps);
end;
#13 : if (ps+1)^=#10 then begin
PWord(pd)^:=$0A0D;
inc(PWord(pd));
inc(PWord(ps));
end else begin
pd^:=#13;
inc(pd);
inc(ps);
end;
#0 : break;
else begin
pd^:=ps^;
inc(pd);
inc(ps);
end;
end;
until false;
result:=Integer(pd)-Integer(pdsave);
end;
//------------------------------------------------------------------------------
var len:integer; dest:string;
begin
if s='' then exit;
SetLength(result,Length(s)*2);
SetLength(result,Replace(result,s));
end;