Hallo zusammen,
MMVisual hatte mir geschrieben...
Nun scheint mir hier große Verwirrung zu herschen?!
Nochmal zitiert:
const
CP_ACP = 0; // default to ANSI code page
CP_UTF16 = 1200; // utf-16
CP_UTF16BE = 1201; // unicodeFFFE
CP_UTF7 = 65000; // utf-7
CP_UTF8 = 65001; // utf-8
CP_ASCII = 20127; // us-ascii
CP_NONE = $FFFF; // rawbytestring encoding
das ist vollkomment richtig.
Um eines vorn weg zu nehmen der Typ RawByteString ist unabdingbar!
Eigentlich ist hier nur folgendes Problem zu sehen:
FPC und LCL gehen zwei verschiedene Wege. LCL hat alles auf UTF8 encodierung umgestellt welches der FPC jedoch nicht weiter verfolgt, sonst würden sie den Delphi-Compilern nicht hinterher kommen.
Um die Compiler-Magig vom FPC2.7.x & D2009+ etwas aufzuklären
String(GetACP) := AnsiString(GET_ACP, AnsiDaten)+UTFString(CP_UTF8, UTF8-Daten) sollte vollgendes durchführen:
String_Daten := AnsiDaten + WideToAnsiMove(UTF8ToWideMove(UTF8Daten)); somit ist Data-Loss möglich
AUTF8String_Daten := AnsiString(GET_ACP, AnsiDaten)+UTFString(CP_UTF8, UTF8-Daten) sollte vollgendes durchführen:
AUTF8String_Daten := WideToUTF8(AnsiToWide(AnsiDaten)) + UTFDaten; //Data-loss ist nicht möglich, da UTF8 Encodierung.
RawByteString_Daten := AnsiDaten + UTF8Daten; ohne konvertierung. Sicheres konvertien zu Unicode/Ansi/UTF8 ist nicht mehr möglich, da ein CP-"Mischmasch" vom Progger veranlaßt wurde!
Weiterhin gilt zu sagen, das Delphi ein begrenztes Tracking für den Ursprung der Daten vornimmt:
RawByteString := AnsiString/UTF8String; //bei direkter zuweisung weiß der compiler die (Get_ACP) codepage und kann danch den Rawbyte string sicher zu UTF8 oder Unicode oder Ansi konvertieren.
Das Tracking endet bei Delphi mit PAnsiChar Zuweisungen, move-mem, oder CodePage-Mischungen (RawByteString_Daten := AnsiDaten + UTF8Daten;)
Beim FPC derzeit noch nicht(mein Stand ist hier ein halbes Jahr alt, also nich hauen, wenn ich mich irre). Aber ihr könnt doch die String-CodePage selber setzen: DefaultSystemCodpe := CP_UTF8; Tata! (Sollte LCL eigentlich selber tun)
Das ganze Konstruckt dient aber eher dem UnicodeString(Compiler -> schnell)/WideString(COM-based, Global heap und langsam) und deren Casts wie folgt:
AnsiString(UnicodeString) = AAnsiString := WideToAnsiMove(UnicodeString) mit Ansi-codePage
UTF8String(UnicodeString) = AUtf8String := WideToAnsiMove(UnicodeString) mit UTF8-CodePage
Ein RBS cast nutzet die DefaultSystemCodePage..
Zusammenfassend:
Der RawByteString ist ein single-byte Allesfresser, welcher den Compiler automatisierten Convertierungen aus dem weg geht. Unabdingbar und hilfreich, wenn man z.B. Datenbank Anwendung schreibt, der Encodierung wechseln kann. Der Developer sollte hier aber wirklich sorgfälltig arbeiten und wissen, was er tut! Die Zeos Interna ist deher vollständig auf RBS umgesetzt, sonst könnten wir automatisierte convertieungen für MSSQL + LCL z.B. nicht lösen und würden in die Automatisierten compiler Konvertierungen, je nach DefaultSystemCodePage, rennen.
In custring.inc findet ihr die AnsiToWide/AnsiToUnicode und WideToAnsi/UnicodeToAnsi Routinen, welche !immer! (auch bei Delphi) benützt werden, wenn ihr Wide/Unicode casts oder Ansi-CodePages mischt (je nach Ergebnis-Typ). Wie sonst sollte der Compiler die 2Byte Chars auf Single-Byte umstellen können? Oder Ansi Codierungen auf UTF8 automatisch umstellen?
Michael
P.S.
Nun ist die Topic (ab FPC3.x) markiert. Davon weis ich auch. Ich kann mir vorstellen, daß bei einem neuen Major-Realease, der FPC auch auf Unicode ausetzt. Leider gibt es da noch keine eindeutigen Aussagen von FPC-core. Mich würde das jedoch nicht wundern. Nur was ist dann mit LCL? Im Prinzip ist der Nabel der Probleme, das LCL IMMER von String(cp_utf8) ausgeht(was eigentlich total daneben ist, aber alles universal macht), der FPC dem jedoch nicht Folge leistet und seine eigenen Wege geht. All das schafft Verwirrung, wenn euer Code nicht eindeutig ist, das sollten die oben genannten Bsp. zeigen können.