Einzelnen Beitrag anzeigen

Benutzerbild von sECuRE
sECuRE

Registriert seit: 10. Apr 2003
Ort: Heidelberg
360 Beiträge
 
Delphi 7 Professional
 
#1

UTF8ToAnsi (gemodded) und ANSI/UTF8 gemischt

  Alt 5. Apr 2005, 15:14
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
  Mit Zitat antworten Zitat