lazutils: TranslateUTF8Chars: multibyte with different size replacements

git-svn-id: trunk@39799 -
This commit is contained in:
mattias 2013-01-07 16:49:16 +00:00
parent d594f5e36a
commit c47b6d72a2
2 changed files with 57 additions and 3 deletions

View File

@ -548,6 +548,55 @@ var
Result:=nil;
end;
procedure ReplaceMultiByteWithResize(List: PItem; ListLen: SizeInt; Src: PChar);
var
c: Char;
clen: Integer;
NewSIndex, i: SizeInt;
Item: PItem;
NewS: string;
NewSP: PChar;
NewCharLen: Integer;
NewCharP: PChar;
begin
SetLength(NewS,length(s));
NewSIndex:=Src-PChar(s)+1;
if NewSIndex>1 then
Move(s[1],NewS[1],NewSIndex-1);
while true do begin
c:=Src^;
if (c=#0) and (Src-PChar(s)=length(s)) then break;
clen:=UTF8CharacterLength(Src);
NewCharP:=Src;
NewCharLen:=clen;
// do a quick test via Pos
i:=Pos(c,SrcChars);
if i>0 then begin
// quick test positive, now search correctly
Item:=FindItem(List,ListLen,Src,clen);
if Item<>nil then begin
// replace
NewCharP:=@Item^.Dst[0];
NewCharLen:=Item^.DstLen;
end;
end;
inc(Src,clen);
if NewSIndex+NewCharLen-1>length(NewS) then begin
// need more space => grow
SetLength(NewS,NewSIndex+((length(NewS)-NewSIndex-NewCharLen)*3 div 2)+2);
end;
// copy character
NewSP:=@NewS[NewSIndex];
for i:=1 to NewCharLen do begin
NewSP^:=NewCharP^;
inc(NewCharP);
inc(NewSP);
end;
inc(NewSIndex,NewCharLen);
end;
s:=LeftStr(NewS,NewSIndex-1);
end;
procedure ReplaceMultiByte;
var
p: PChar;
@ -579,7 +628,10 @@ var
Move(Item^.Dst[0],p^,clen);
end else begin
// replace with different size
// ToDo
// all following characters are moved
// => use an optimized algorithm for this
ReplaceMultiByteWithResize(List,ListLen,p);
exit;
end;
end;
end;

View File

@ -79,9 +79,11 @@ begin
T('switch a,b','abaa','ab','ba','babb');
T('delete a','a','a','','');
T('delete a','aba','a','','b');
//T('replace ä with ö','bä','ä','ö','bö');
//T('replace ä with ö','äbä','ä','ö','öbö');
T('replace ä with ö','bä','ä','ö','bö');
T('replace ä with ö','äbä','ä','ö','öbö');
T('switch ä,ö','äbö','äö','öä','öbä');
T('delete ä','äbö','ä','','bö');
T('replace ä with a','äbö','ä','a','abö');
end;
initialization