WideString, AnsiString, UTF8String, UCS4String Verwirrung
-
- Beiträge: 462
- Registriert: Mi 30. Jul 2008, 13:11
- OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
- CPU-Target: 32Bit
- Kontaktdaten:
Re: WideString, AnsiString, UTF8String, UCS4String Verwirrung
Wie ist das mit dem Dateizugriff/ der Übergabe von Pfaden? Ich (Laz 0.9.26 auf WinXP) bekomme offenbar vom OpenDlg UTF8. FindFirst benötigt offenbar Ansi. Kann ich davon ausgehen, dass alle Schnittstellen zum System (zumindest im Fall von WinXP) Ansi verlangen bzw. liefern? Bis jetzt ist das so (TOpenDialog ist ja nicht Systemeigen), habe schon mehrere Stellen probiert (z.b. application.exename und findfirst). Ich hoffe das ist wenigstens eingheitlich so. Speziell bin ich jetzt mal auf readXMLFile und WriteXMLFile gespannt, die arbeiten intern mit TFileStream hab ich schon gesehen. 2.: Wie verhält sich das dann auf anderen Systemen, wie z.B. Linux? Sind da beim Crosscompiling Compilerweichen nötig?
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!
Re: WideString, AnsiString, UTF8String, UCS4String Verwirrung
http://wiki.lazarus.freepascal.org/LCL_ ... _filenames" onclick="window.open(this.href);return false;
-
- Beiträge: 462
- Registriert: Mi 30. Jul 2008, 13:11
- OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
- CPU-Target: 32Bit
- Kontaktdaten:
Re: WideString, AnsiString, UTF8String, UCS4String Verwirrung
Ups, danke für den Link, sehr interessant. Ist aber sicherlich gut, dass dieser Link in diesem Thread mit erscheint 

Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!
-
- Beiträge: 2013
- Registriert: Do 16. Okt 2008, 10:22
- OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
- CPU-Target: x86,x64,ARM
Re: WideString, AnsiString, UTF8String, UCS4String Verwirrung
Bei MSEide+MSEgui ist das so gelöst, dass alle File Dialoge und dergleichen mit widestrings arbeiten. Für das Öffnen von Dateien und Erstellen von streams gibt es MSEgui eigene, widestring basierte Funktionen und Klassen, die Umsetzung in die vom Betriebssystem benötigte Codierung wird von MSEgui vorgenommen. Es gibt auch eine Plattform unabhängige Form der Pfadnamen, "c:\aaa\bbb\ccc.ddd" wird zu "/c:/aaa/bbb/ccc.ddd".RSE hat geschrieben:Wie ist das mit dem Dateizugriff/ der Übergabe von Pfaden??
Die MSEgui Datenbank Komponenten konvertieren Text beim Lesen von utf-8 oder der Systemcodierung (einstellbar) zu widestring. In den MSEgui Datenpuffern werden Texte als widestrings variabler Länge gehalten. Beim Schreiben der Texte zur Datenbank wird wieder zu utf-8 oder der Systemcodierung gewandelt.
-
- Beiträge: 3444
- Registriert: Mo 11. Sep 2006, 10:24
- OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
- CPU-Target: X32 / X64 / ARMv5
- Wohnort: Krefeld
Re: WideString, AnsiString, UTF8String, UCS4String Verwirrung
Woher soll denn das system wissen ob da gerade kein Chinese vor dem Bildschirm sitzt ? Wenn Surrogate Pairs erlaubt sind, muss _immer_ durchsucht werden, statt einen Index zu benutzen. Schau Dir doch 'mal den ASM code an der bei a:widechar; s: widestring; a := s; erzeugt wird (bei MSEIDE geht das ja, bei Lazarus leider nicht).mse hat geschrieben:Der Unterschied ist halt, dass bei utf-8 durch die Begrenzung auf ASCII lediglich Amerikaner die effiziente Adressierung mittels Index benutzen können, bei utf-16 durch UCS2 praktisch alle Erdenbürger, die Europäer auf jeden Fall.
das ist wohl wahr. Trotzdem ist ein Widechar nur 16 bit und da passt kein surrogate pair rein.mse hat geschrieben:Ebenfalls zu bedenken ist, dass Surrogate*pair* handling wesentlich einfacher und effizienter zu implementieren ist als die Behandlung der 1 bis 4 Bytes von utf-8.
-Michael
Zuletzt geändert von mschnell am So 19. Okt 2008, 22:36, insgesamt 1-mal geändert.
-
- Beiträge: 3444
- Registriert: Mo 11. Sep 2006, 10:24
- OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
- CPU-Target: X32 / X64 / ARMv5
- Wohnort: Krefeld
Re: WideString, AnsiString, UTF8String, UCS4String Verwirrung
Das ist sicher wahr. Wenn die Widestrings aber nicht richtig mit surrogats funktionieren weil z.B. Widechar (16 Bit) keine surrogates aufnehmen kann und wenn man mit "x[3]:=irgendwas;" auch x[4] verändert, weil ein surrogate da hingeschrieben wird, das sowohl x[3] als auch x[4] belegt, gibt dann aber keinen vernünftigen Grund die Widestring/WideChar -Kodierung als utf16 zu bezeichnen und nicht als ucs2.theo hat geschrieben:Du kannst dich einfach auf den Standpunkt stellen, dass bei dir keine Zeichen über $FFFF vorkommen, dann hast du damit auch nix zu tun und kannst deine WideString als UCS-2 betrachten.
-Michael
Re: WideString, AnsiString, UTF8String, UCS4String Verwirrung
Ich kann dir nicht ganz folgen. Ein Widechar kann nat. nicht ein Surrogat-Paar speichern.mschnell hat geschrieben: Das ist sicher wahr. Wenn die Widestrings aber nicht richtig mit surrogats funktionieren weil z.B. Widechar (16 Bit) keine surrogates aufnehmen kann und wenn man mit "x[3]:=irgendwas;" auch x[4] verändert, weil ein surrogate da hingeschrieben wird, das sowohl x[3] als auch x[4] belegt, gibt dann aber keinen vernünftigen Grund die Widestring/WideChar -Kodierung als utf16 zu bezeichnen und nicht als ucs2.
Aber was willst du damit sagen?
-
- Beiträge: 462
- Registriert: Mi 30. Jul 2008, 13:11
- OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
- CPU-Target: 32Bit
- Kontaktdaten:
Re: WideString, AnsiString, UTF8String, UCS4String Verwirrung
Wenn du string[4] einen 2 WideChar breites Surrogat Paar zuweist, wird das an Position 4 und 5 geschrieben. Damit hast du Zeichen 5 u.U. ungewollt überschrieben. Ist halt nur alles nicht mehr so einfach wie zu ANSI-Zeiten 

Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!
Re: WideString, AnsiString, UTF8String, UCS4String Verwirrung
Ich hab mal einen Versuch gemacht (GTK2) mit Zeichen über $FFFF:
Was ist hier falsch? Ich bekomme eine 0 Länge für den WideString und UTF8String;
Was ist hier falsch? Ich bekomme eine 0 Länge für den WideString und UTF8String;
Code: Alles auswählen
procedure TForm1.Button1Click(Sender: TObject);
var
UCS4S:UCS4String;
WS:WideString;
UTF8S:UTF8String;
begin
SetLength(UCS4S,1);
UCS4S[1]:=UCS4Char($100E4); //LINEAR B IDEOGRAM VESSEL B205. UTF8 Sequenz: f0 90 83 a4
writeln(Length(UCS4S)); //-> 1
WS:=UCS4StringToWideString(UCS4S);
writeln(Length(WS)); //-> 0
UTF8S:=UTF8Encode(WS);
writeln(Length(UTF8S)); //-> 0
Caption:=UTF8S; // -> ''
end;
-
- Beiträge: 2013
- Registriert: Do 16. Okt 2008, 10:22
- OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
- CPU-Target: x86,x64,ARM
Re: WideString, AnsiString, UTF8String, UCS4String Verwirrung
UCS4String ist null basierend:theo hat geschrieben: Was ist hier falsch?
Code: Alles auswählen
UCS4Char = type 0..$10ffff;
PUCS4Char = ^UCS4Char;
TUCS4CharArray = array[0..$effffff] of UCS4Char;
PUCS4CharArray = ^TUCS4CharArray;
UCS4String = array of UCS4Char;
Code: Alles auswählen
function UCS4StringToWideString(const s : UCS4String) : WideString;
var
i : SizeInt;
resindex : SizeInt;
begin
{ skip terminating #0 }
SetLength(result,length(s)-1);
resindex:=1;
for i:=0 to high(s)-1 do
ConcatUTF32ToWideStr(s[i],result,resindex);
{ adjust result length (may be too big due to growing }
{ for surrogate pairs) }
setlength(result,resindex-1);
end;
Code: Alles auswählen
SetLength(UCS4S,1+1); //one char + terminating 0
UCS4S[0]:=UCS4Char($100E4); //LINEAR B IDEOGRAM VESSEL B205. UTF8 Sequenz: f0 90 83 a4
//UCS4String is 0 based
writeln(Length(UCS4S)); //-> 2
WS:=UCS4StringToWideString(UCS4S);
writeln(Length(WS)); //-> 2
UTF8S:=UTF8Encode(WS);
writeln(Length(UTF8S)); //-> 6 ????
Vermutlich hat tatsächlich noch kein FPC Anwender Codepoints ausserhalb UCS2 verwendet.
Re: WideString, AnsiString, UTF8String, UCS4String Verwirrung
Autsch, hätte ich sehen müssen. Merci!mse hat geschrieben: UCS4String ist null basierend:
So geht's: Siehe UTF16ToUTF8(WS) statt UTF8Encode
Code: Alles auswählen
procedure TForm1.Button3Click(Sender: TObject);
var
UCS4S:UCS4String;
WS:WideString;
UTF8S:UTF8String;
i:integer;
begin
SetLength(UCS4S,1+1);
UCS4S[0]:=UCS4Char($100E4); //LINEAR B IDEOGRAM VESSEL B205. UTF8 Sequenz: f0 90 83 a4
writeln(Length(UCS4S));
WS:=UCS4StringToWideString(UCS4S);
writeln(Length(WS));
UTF8S:=UTF16ToUTF8(WS);
writeln(Length(UTF8S));
Caption:=UTF8S;
for i:=1 to Length(UTF8S) do Write(' $'+IntToHex(Byte(UTF8S[i]),2)); //-> $F0 $90 $83 $A4
end;
-
- Beiträge: 2013
- Registriert: Do 16. Okt 2008, 10:22
- OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
- CPU-Target: x86,x64,ARM
Re: WideString, AnsiString, UTF8String, UCS4String Verwirrung
Schon, aber für viele Aufgaben hat utf-16 trotzdem Vorteile gegenüber utf-8.mschnell hat geschrieben: das ist wohl wahr. Trotzdem ist ein Widechar nur 16 bit und da passt kein surrogate pair rein.
Nimm mal an, du willst das erste Vorkommen des Zeichen 'Ä' oder jedes andern UCS2 Zeichens in einem String herausfinden. Mit widestrings geht das zum Beispiel so:
Code: Alles auswählen
var
wstr1: widestring;
wch1: widechar;
po1,po2,po3: pwidechar;
result: ptruint;
begin
//#nnn notation because of encoding independent example
wstr1:= '12345'#196'7890';
wch1:= #196;
po1:= pwidechar(wstr1);
po2:= po1;
po3:= po1; //base pointer backup
while po1^ <> #0 do begin
if po1^ = wch1 then begin
po2:= po1+1;
break;
end;
inc(po1);
end;
result:= po2-po3; //found char pointer - basepointer + 1 -> stringindex
writeln(result); // 6
//zero in case of not found
end.
-
- Beiträge: 3444
- Registriert: Mo 11. Sep 2006, 10:24
- OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
- CPU-Target: X32 / X64 / ARMv5
- Wohnort: Krefeld
Re: WideString, AnsiString, UTF8String, UCS4String Verwirrung
Wie soll es denn überhaupt gehen, s[4] ein Surrogat Paar zuzuweisen ?RSE hat geschrieben:Wenn du string[4] einen 2 WideChar breites Surrogat Paar zuweist, wird das an Position 4 und 5 geschrieben. Damit hast du Zeichen 5 u.U. ungewollt überschrieben. Ist halt nur alles nicht mehr so einfach wie zu ANSI-Zeiten
-Michael
-
- Beiträge: 3444
- Registriert: Mo 11. Sep 2006, 10:24
- OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
- CPU-Target: X32 / X64 / ARMv5
- Wohnort: Krefeld
Re: WideString, AnsiString, UTF8String, UCS4String Verwirrung
Damit will ich sagen, dass WideChar nicht utf16 kodiert sein kann, weil ein utf16 Character aus einem Surrogat-Paar (also 32 Bit) bestehen kann.RSE hat geschrieben:Ich kann dir nicht ganz folgen. Ein Widechar kann nat. nicht ein Surrogat-Paar speichern. Aber was willst du damit sagen?
Widechar ist also offensichtlich UCS2 kodiert. Für mich repräsentiert ein Widestring eine Kette von Widechars und ist deshalb auch UCS2-kodiert und nicht utf16.
-Michael
Re: WideString, AnsiString, UTF8String, UCS4String Verwirrung
Naja, kann man so sehen. Aber das Problem ist genau das gleiche wie bei ANSI und UTF8. Gewisse Chars in UTF8 sind vollständige Zeichen, andere nur Teil eines Codes / einer Sequenz.mschnell hat geschrieben: Damit will ich sagen, dass WideChar nicht utf16 kodiert sein kann, weil ein utf16 Character aus einem Surrogat-Paar (also 32 Bit) bestehen kann.
Widechar ist also offensichtlich UCS2 kodiert. Für mich repräsentiert ein Widestring eine Kette von Widechars und ist deshalb auch UCS2-kodiert und nicht utf16.
Das was du "haben willst" ist UCS-4. Da geht alles, frisst aber Speicher.