Wie funktioniert RawByteString? (ab FPC 3.x)

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Wie funktioniert RawByteString? (ab FPC 3.x)

Beitrag von MmVisual »

Hallo,

Mit dem FPC 3.x werden ja sämtliche String-Konvertierungen umgebaut und wenn man in irgend welche andere Codierungen umstellen muss, so muss das auch wieder getestet werden. FPC 3.0 gibt es noch nicht, aber FPC 2.7.1 ist deren Vorgängerversion.

Ich habe nun dieses Problem, dass ich nich so recht verstehe wie, was in den Strings gespeichert werden kann:
- String
- UnicodeString
- AnsiString
- WideString
- UTF8String
- RawByteString
- noch weitere ?

Innerhalb meiner EXE möchte ich alles mit UTF8 codiert haben, auch die Datenbanken (über ZEOS) machen das auch mit UTF8 und klappt bisher gut mit dem Datentyp String und UTF8 (FPC 2.6.x). Ich muss aber einige Dateien beschreiben, die haben Unicode.
Jetzt hätte ich gerne gewusst welches dieser String Typen welche Text-Zeichen aufnehmen kann, bzw. welche Abhängigkeiten es gibt? Welcher String ist nur 8Bit breit und ist somit ab Char 128..255 Länderabhängig?

Ich habe jetzt keine vernünftige Doku (auf deutsch) gefunden.

Kann man ab FPC 2.7.1 (3.0) einen String einfach per Unicodestring() umcodieren oder muss immer noch UTF8Decode() (usw...) genutzt werden?

Und die wichtigste Frage: bleibt der Typ "String" so wie bisher mit FPC 3.0 auch UFT8String? Für alle Compiler Varianten (Win/Linux/Mac...)?

Eine Link zu einer ausführlichen Doku wäre toll und würde sicher vielen Helfen.

Grüße Markus
Zuletzt geändert von MmVisual am Sa 22. Jun 2013, 16:43, insgesamt 1-mal geändert.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Benutzeravatar
theo
Beiträge: 10899
Registriert: Mo 11. Sep 2006, 19:01

Re: Wie funktioniert RawByteString? (ab FPC 3.x)

Beitrag von theo »

Nur kurz und aus dem Ärmel geschüttelt, muss gleich weg.

String ist momentan ein Alias für AnsiString in mode H+
UnicodeString ist afaik ein referenzgezählter WideString (In Delphi afaik anders).
AnsiString: Referenzgezählter, längenunbegrenzter Byte (8bit) String
WideString: Längenunbegrenzter Word (16 bit) String.
RawByteString: Afaik ein AnsiString der keine automatischen Konversionen mitmacht. (Wide to Ansi etc.)

Ohne Gewähr

mschnell
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: Wie funktioniert RawByteString? (ab FPC 3.x)

Beitrag von mschnell »

Die fpc community ist dabei, fpc auf Delphi XE kompatible Strings umzustellen. Es steht aber noch nicht fest, wann das offiziell released wird und wie genau das arbeiten soll. Es soll jedenfalls definierbare "mode" Variablen geben, die bei einem bestimmten Wert ein Verhalten bewirken, dass möglichst gut Delphi XE kompatibel ist. Vermutlich wird dadurch auch festgelegt, was der Typ "String" (ohne weitere Spezifikation) ist. Vermutlich gibt es andere Werte, die an anderes oder besseres Verhalten bewirken.

Vermutlich wird Lazarus dieser Arbeitsweise erst folgen, wenn der offizielle FPC raus ist. Momentan sind für FPC anscheinend noch nicht einmal die genaue Specs festgezurrt (nur "irgendwie Delphi XE kompatibel").

Dieses Strings enthalten eine "dynamische" Kodierung, die zeigt, in welchem Code der String zu interpretieren ist und wie viele Bytes jede Teilcodierung umfasst (z.B. ANSIxyz -> 1, UTF-8 -> 1, UTF-16 -> 2, UTF32 -> 4).

Trotzdem ist die Arbeitsweise aus Performance-Gründen nicht (immer) voll dynamisch (d.h. einer String Variable kann bei der Deklaration ein fester Codierungstyp zugewiesen werden).

Ein RawByteString hat (vermutlich) die Codierunsnummer $FFFF und die Codelänge 1. Er wird nie automatisch in eine andere Codierung konvertiert (was bei den "echten" Codierungstypen bei jeder Operation passieren kann). Damit entspricht RawByteString vom verhalten her am ehesten den bisherigen Strings.

Es wird jedenfalls lustig :evil:

-Michael
Zuletzt geändert von mschnell am So 23. Jun 2013, 13:14, insgesamt 2-mal geändert.

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: Wie funktioniert RawByteString? (ab FPC 3.x)

Beitrag von MmVisual »

Wenn man den Typ für String festlegen kann, dann hoffe ich doch schwer dass man dies in den Projektoptionen macht und nicht in jeder Datei mit einer Kompilerdirektive angeben muss.

Schade, dass sie die FPC Developer nicht einigen können.

Ich würde das ganze UTF8String, AnsiString, WideString und das alles komplett eliminieren, es ist einfach zu unübersichtlich und wird schussendlich niemand wirklich verstehen.

Stattdessen würde es es so machen: (bitte keine Prügel...)

Ein String ist automatisch eine Klasse, die aber nicht mit Create/Free erzeugt/gelöscht werden muss, sondern automatisch geschieht so wie bisher auch bei Strings.

Code: Alles auswählen

Type TStringType = (stUTF8, stUTF16, stUnicode, stAnsiCP1233, ...];
Type String
  FType: TStringType;
  FBuffer: String;
  Procedure ConvertTo(Type: TStringType);
  Function GetAs(Type: TSTringType): String;
  Function Length: Integer;
  Function SizeOf: Integer;
  : :
End;
So ungefähr.

Wenn man nun eine Zuweisung auf einen String macht, so wir der einfach zugewiesen, wie bisher auch.
Str1 := Str2 + 'hhhh'; // Geht auch
Nur hat man zum String noch Zusatzfunktionen wie z.B. Str1.Length() (siehe oben).

Ich meine, damit hätte man endlich wirklich dieses Kuddelmuddel beseitigt.

Um abwärtskompatibel zu sein, ist einfach ein String = Ansistring = Unicodestring = SontwasString und alles ist ein Typ String.
Zuletzt geändert von MmVisual am So 23. Jun 2013, 09:37, insgesamt 1-mal geändert.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Benutzeravatar
theo
Beiträge: 10899
Registriert: Mo 11. Sep 2006, 19:01

Re: Wie funktioniert RawByteString? (ab FPC 3.x)

Beitrag von theo »

So etwas ähnliches hatte ich hier mit dem TUniString mal gepostet:

http://www.lazarusforum.de/viewtopic.ph ... 94&p=54025

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: Wie funktioniert RawByteString? (ab FPC 3.x)

Beitrag von MmVisual »

Ja, genau ... Jetzt sollte das nur nicht TUniString heißen, sonder einfach String.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Benutzeravatar
theo
Beiträge: 10899
Registriert: Mo 11. Sep 2006, 19:01

Re: Wie funktioniert RawByteString? (ab FPC 3.x)

Beitrag von theo »

MmVisual hat geschrieben:Ja, genau ... Jetzt sollte das nur nicht TUniString heißen, sonder einfach String.
Da kannste lange warten.. :wink:

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: Wie funktioniert RawByteString? (ab FPC 3.x)

Beitrag von MmVisual »

Vielleicht ein FPC Bugreport schreiben (und Deine Unit unistring anhängen)?
EleLa - Elektronik Lagerverwaltung - www.elela.de

Benutzeravatar
theo
Beiträge: 10899
Registriert: Mo 11. Sep 2006, 19:01

Re: Wie funktioniert RawByteString? (ab FPC 3.x)

Beitrag von theo »

MmVisual hat geschrieben:Vielleicht ein FPC Bugreport schreiben (und Deine Unit unistring anhängen)?
Das ist komplett illusorisch. Niemals würde das FPC Team den String Typ durch solch ein Konstrukt ersetzen, das ist inkompatibel und UTF-8 zentriert.
Du kennst offenbar die Entscheidungsprozesse nicht.

Du kannst TUniString aber gerne nutzen, funktionieren tut's schon. :wink:

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: Wie funktioniert RawByteString? (ab FPC 3.x)

Beitrag von MmVisual »

Ja, es klingt illusorisch.

Aber

Der ganze Käse hat schon vor meinem Leben bekommen, als alle Text-Zeichen nur 8 Bit breit waren. Und dann kamen auf ein mal die Russen mit ihren Zeichen, also wurden die 8 Bit anders benutzt und dann kamen die Chinesen, da haben die 8 Bit nicht mehr gereicht und dann gab es noch solche Leute die wollten alle Zeichen aller Länder und dann gab es UTF8, UTF16, Unicode und den ganzen Quatsch.
Schlussendlich hat das ganze damals angefangen, als es nur begrenzen RAM für einen Computer gab (8 Bit Zeichen).
Irgendwann einmal muss man sich doch endlich von dieser "Altlast" trennen und endlich den String als einen einzigen Typ universell gestalten. Ein Typ, der automatisch oder per Befehl in andere konvertiert.

Ich finde, das ist schon ein Bugreport wert.

Ich progge schon fast 30 Jahre und diese (scheiß) Strings sind mir schon immer ein Dorn im Auge.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Wie funktioniert RawByteString? (ab FPC 3.x)

Beitrag von Socke »

MmVisual hat geschrieben:Ich progge schon fast 30 Jahre und diese (scheiß) Strings sind mir schon immer ein Dorn im Auge.
Vielleicht liegt es ja genau daran ;-) Bei mir sind es noch nicht ganz so viele Jahre und daher bin ich mit Unicode praktisch aufgewachsen. Für das was ich mache, definiere ich immer: Alles ist UTF-8 damit hat man so lange keine Probleme, wie man Einfluss auf die Programme hat oder weiß, was da hinaus kommt. Die meisten Probleme habe ich mit Altlasten wie Microsoft Access (Dank geringem Umfang der Laufzeitbibliothek) und ABAP (UTF-8 geht auch, muss aber extra angegeben werden) oder anderen Programmierern, die sich darum keine Gedanken machen.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Achtzig
Beiträge: 90
Registriert: Mo 15. Okt 2007, 13:09
OS, Lazarus, FPC: Debian
CPU-Target: xxBit

Re: Wie funktioniert RawByteString? (ab FPC 3.x)

Beitrag von Achtzig »

MmVisual hat geschrieben:Ich progge schon fast 30 Jahre und diese (scheiß) Strings sind mir schon immer ein Dorn im Auge.
Ich programmiere auch schon fast 30 Jahre (seit 1984 und ab TP3 mit Pascal) und die Strings haben mich noch nie gestört :)

mschnell
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: Wie funktioniert RawByteString? (ab FPC 3.x)

Beitrag von mschnell »

MmVisual hat geschrieben:Stattdessen würde es es so machen: (bitte keine Prügel...)
Es wurde natürlich diskutiert, ob man für String einfach ein Objekt und Operator Oveload nehmen könnte. Das würde aber die Performance bei "normalen" Operationen drastisch herabsetzten.

-Michael

mschnell
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: Wie funktioniert RawByteString? (ab FPC 3.x)

Beitrag von mschnell »

MmVisual hat geschrieben:Der ganze Käse hat schon vor meinem Leben bekommen, als alle Text-Zeichen nur 8 Bit breit waren.
Es fing sogar schon früher an. Zuerst reichten für die Amerikaner 7 Bit ASCII - Zeichen. Dann kamen die Europäer und 7 Bit waren nicht mehr genug: der 8 Bit ANSI-Code musste erfunden werden. Igitt !!!!
MmVisual hat geschrieben:Und dann kamen auf ein mal die Russen mit ihren Zeichen, also wurden die 8 Bit anders benutzt und dann kamen die Chinesen, da haben die 8 Bit nicht mehr gereicht und dann gab es noch solche Leute die wollten alle Zeichen aller Länder und dann gab es UTF8, UTF16, Unicode und den ganzen Quatsch....

Genau. Russen, Chinesen Araber und alle diese Leute sollten nicht programmieren und eigentlich Computern gar nicht anfassen dürfen ! Bei Zuwiderhandlung ab nach Guantanamo !!!

-Michael

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: Wie funktioniert RawByteString? (ab FPC 3.x)

Beitrag von MmVisual »

mschnell hat geschrieben: Das würde aber die Performance bei "normalen" Operationen drastisch herabsetzten.
Meine ich nicht. Wenn per Default intern mit UTF8 - so wie bisher - gearbeitet wird, und so wie oben es einen "TStringType" gibt und das UTF8 immer zu Anfang mit einem IF abgefragt wird, dann braucht auch nichts extra herum gerechnet/konvertiert werden und das ganze ist nach wie vor gleich schnell. Auch wenn ein String vom gleichen Stringtyp addiert wird:
TStringType := TStringType + TStringType;
dann braucht auch nichts extra gerechnet werden. Ist nur eine einzige IF Abfrage.
Erst wenn ein Typ UTF8 und Unicode addiert wird, dann käme als Ergebnis der FPC Standard UTF8 raus und der müsste den Unicode Teil auf UTF8 konvertieren. Aber das Ergebnis ist schon mal korrekt, nicht wie bisher.

Die Sourcen von Theo sind schon mal eine sehr gute Grundlage, nun noch den TStringType rein nehmen und wenn nötig automatisch konvertieren anhand dem TStringType. Die vielen Operatoren braucht es dann auch nicht mehr.

Ganz wichtig natürlich: Dieser neue String Typ muss natürlich im FPC richtig verankert sein und schon klappt das auch mit der vollen Geschwindigkeit.

Dann sähe das für den normalen User aus:

Code: Alles auswählen

 
Var s, s2, s3: String; // String mit ".StringTyp = stUTF8"
Begin
  s := 'Hallo'; // Wie früher, UTF8
  s2 := ' Welt';
  s3 := s + s2; // Kein extra Aufwand da TStringTyp beides mal UTF8 ist
  If s.StringTyp = stUTF8 Then // Das ist neu
    ...;
  s.StringTyp := stUnicode; // Macht eine Konvertierung (und braucht Rechenzeit)
  s3 := s + s2; // Extra Rechenaufwand, da s nun stUnicode ist, Ergebnis ist jedoch UTF8 damit weitere Rechenoperationen in Lazarus nicht nochmal extra Rechnen müssen und UTF8 alle Zeichen kann.
 
  s2.StringTyp := stUnicode; // Macht eine Konvertierung (und braucht Rechenzeit)
  s3.StringTyp := stUnicode; // kein Rechenaufwand, da String in der nächsten Zeile ohnehin neu überschrieben wird (Compiler optimiert)
  s3 := s + s2; // Kein extra Aufwand da TStringTyp beides mal Unicode ist, auch das Ergebnis
 
  s3 := ''; // String auf NIL setzen, kein Rechenaufwand
  s3.StringTyp := stUTF8; // Kein Rechenaufwand, da s3 = '' ist
 
  s3 := UTF8String(s); // Macht eine Zuweisung von s nach s3, aber ohne Konvertierung, also der s.StringTyp stUnicode wird ignoriert, Ergebnis in s3 ist UTF8, aber eben korrupt (User selbst schuld, keine Rechenzeit)
End;
Oder habe ich jetzt irgendwo einen Denkfehler?

Wenn man nun einen UnicodeString definiert, dann würde das so aussehen:
Var s: UnicodeString;
Damit würde der FPC automatisch s.StringTyp = stUnicode vor belegen. aber schlussendlich ist es dennoch ein String.

Dann gibt es noch das:
s.InterpretiereAs(stUnicode); // Macht keine Konvertierung vom String, sondern setzt einfach nur StringTyp auf stUnicode, also die Daten in dem String-Buffer wird ab jetzt mit einer anderen Codierung interpretiert, also ein Typecast wird aufgezwungen. (oder wie das auch immer heißen mag) und kostet auch keine Rechenzeit (wie bisher):

Code: Alles auswählen

UTF8String(s);
UnicodeString(s);
Ich hoffe mal, ich konnte euch FPC'ler etwas animieren weiter in die Zukunft zu denken :D
FPC 3.0 wäre eine gute Möglichkeit diese blöde Stringkonvertiererei endgültig ab zu schaffen, so dass der User tatsächlich sich damit nicht mehr so sehr ärgern muss (bis auf wenige Experten, die das wissen).

Außerdem: Der Vorteil dieser Struktur wäre vor allem auch bei der Debuger-Anzeige in Lazarus, der zeigt dann den Inhalt immer korrekt an, egal was drin steht, anhand vom StringTyp.

Beispiel: ich lese MP3 Tg ID's ein und schreibe die auch wieder in die Datei zurück und damit habe ich Probleme bei den osteuropäischen Zeichen. Mit FPC 2.6.x sieht das anders aus als mit dem FPC 2.7.1, also wenn ich den FPC wechsle, dann muss ich alles mit anderer (Standard FPC) Codierung als UTF8 ohnehin anfassen.

Grüße Markus

PS:

Code: Alles auswählen

type TStringType = (stUTF8, stUTF16, stUnicode, stAnsiCP1233, ...);
const stWinAPIWideCharCall = stUnicode;
An DelphiXE würde ich mich jetzt auch nicht zu sehr anlehnen wollen, denn die sind mit ihrer jetzigen Struktur auch nicht zu glücklich und wissen selbst nicht wie die das gescheit lösen sollen. Also sollen die doch mal beim FPC abgucken :mrgreen:
EleLa - Elektronik Lagerverwaltung - www.elela.de

Antworten