Hi,
ich hab kürzlich die Funktion UTF8ToAnsi gefunden und wenn in dem String nur UTF8-Zeichen oder "standard" vorkommen, funktioniert alles. Kommen allerdings "normale" Sonderzeichen (ISO-Irgendwas-Zeichensatz), also äöüß vor, bricht die Funktion ab und hinterlässt einen leeren String - nicht grade schön. Ich hab deshalb die Funktion etwas umgeschrieben:
Delphi-Quellcode:
// Das Copyright dieser Funktion liegt bei Borland, ich hab lediglich 4 Zeilen an verschiedenen Stellen ergänzt. Die Funktion findet man in der System.pas wenn man eine Delphi-Version mit Sourcecode der VCL hat.
function _Utf8ToUnicode(Dest: PWideChar; MaxDestChars: Cardinal; Source: PChar; SourceBytes: Cardinal): Cardinal;
overload;
var
i, count: Cardinal;
c: Byte;
wc: Cardinal;
begin
if Source =
nil then
begin
Result := 0;
Exit;
end;
Result := Cardinal(-1);
count := 0;
i := 0;
if Dest <>
nil then
begin
while (i < SourceBytes)
and (count < MaxDestChars)
do
begin
wc := Cardinal(Source[i]);
Inc(i);
if (wc
and $80) <> 0
then
begin
if i >= SourceBytes
then begin
dest[count]:=widechar(source[i-1]);
// von mir eingefügt, normal stand hier "exit;"
Inc(count);
continue;
end;
// incomplete multibyte char
wc := wc
and $3F;
if (wc
and $20) <> 0
then
begin
c := Byte(Source[i]);
Inc(i);
if (c
and $C0) <> $80
then begin
dest[count]:=WideChar(source[i-2]);
// von mir eingefügt, normal stand hier "exit;"
Inc(count);
Dec(i);
continue;
end;
// malformed trail byte or out of range char
if i >= SourceBytes
then begin
dest[count]:=WideChar(source[i-2]);
// von mir eingefügt, normal stand hier "exit;"
Inc(count);
continue;
end;
// incomplete multibyte char
wc := (wc
shl 6)
or (c
and $3F);
end;
c := Byte(Source[i]);
Inc(i);
if (c
and $C0) <> $80
then begin
dest[count]:=widechar(source[i-2]);
// von mir eingefügt, normal stand hier "exit;"
Inc(count);
Dec(i); continue;
end;
// malformed trail byte
Dest[count] := WideChar((wc
shl 6)
or (c
and $3F));
end
else
Dest[count] := WideChar(wc);
Inc(count);
end;
if count >= MaxDestChars
then count := MaxDestChars-1;
Dest[count] := #0;
end
else
begin
while (i < SourceBytes)
do
begin
c := Byte(Source[i]);
Inc(i);
if (c
and $80) <> 0
then
begin
if i >= SourceBytes
then exit;
// incomplete multibyte char
c := c
and $3F;
if (c
and $20) <> 0
then
begin
c := Byte(Source[i]);
Inc(i);
if (c
and $C0) <> $80
then exit;
// malformed trail byte or out of range char
if i >= SourceBytes
then exit;
// incomplete multibyte char
end;
c := Byte(Source[i]);
Inc(i);
if (c
and $C0) <> $80
then exit;
// malformed trail byte
end;
Inc(count);
end;
end;
Result := count+1;
end;
Nach verschiedenen AND/OR-Verknüpfungen wird also abgebrochen, diese Abbrüche hab ich einfach blind ersetzt und es funktioniert. Dass die Lösung nicht sehr schön ist, ist mir klar. Mit anderen Umlauten außer öäüß hab ich die Funktion bisher nicht getestet.
Meine Frage nun: Wozu sind die ganzen AND/OR-Verknüpfungen da, was wird da überprüft? Und: Wie kann man meine Lösung verbessern? Gibt es da schon Funktionen, mit denen man "gemischte" Strings vereinheitlichen kann?
BTW: (Zum testen) UTF8-"ö": ö
Vielen Dank & cu