AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Delphi und Linux - Encoding-Salat?

Ein Thema von knaeuel · begonnen am 8. Aug 2019 · letzter Beitrag vom 9. Aug 2019
Antwort Antwort
knaeuel

Registriert seit: 2. Jul 2007
110 Beiträge
 
Delphi 10.3 Rio
 
#1

AW: Delphi und Linux - Encoding-Salat?

  Alt 9. Aug 2019, 13:06
kleiner Nachtrag:

tatsächlich würde ich inzwischen von einem Bug in der System.SysUtils.pas sprechen - nur für Linux.

ANSI-Dateien werden fälschlicherweise als UTF-8 deklariert und können dann nicht z.B. in eine Stringlist geladen werden (Fehlermeldung "No mapping for the Unicode character exists in the target multi-byte code page"). Der Default-Wert beim Feststellen der Kodierung sollte nicht UTF-8 sein, wenn UTF-8 vorher explizit ausgeschlossen wurde.

Macht man sich die Mühe und surft mit dem Debugger durch die Bibliotheken, wenn man unter Linux eine ANSI-Datei in eine Stringlist laden will (was überigens auch beim Öffnen einer Datei mit der XMLDocument-Komponente passiert), dann kann man im richtigen Moment eingreifen und die Kodierung von UTF-8 auf ANSI korrigieren. Dann wird die Datei fehlerfrei geladen. Macht man das während des Ladens der Datei in die XMLDoc-Komponente, dann kann die XML-Datei anschließend fehlerfrei ausgewertet und angezeigt werden - inklusive Sonderzeichen!

Der Fehler hat seinen Ursprung (wie gesagt) beim Feststellen der Kodierung, für Stringlisten in System.Classes.pas in Zeile 6894. Dort wird TEncoding.GetBufferEncoding (System.SysUtils.pas Zeile 32708) aufgerufen, was dann unter Linux den falschen default-Wert "UTF-8" zurückliefert.

Liefert diese function das korrekte Ergebnis "ANSI" (durch manuellen Eingriff) zurück, läuft anschließend alles fehlerfrei.
Liefert sie für eine ANSI-Datei den Standardwert UTF-8 zurück, klappt die Umwandlung der ANSI-Sonderzeichen nicht, weil die Kodierung nicht zu UTF-8 passt.

Aktuell habe ich nur eine geerbte Klasse TMyEncoding = class(TEncoding) in der ich dann ein paar Dinge überschrieben habe. Dadurch kann ich wenigstens schonmal selber die richtigen Codierungen angeben.
Allerdings wird aus den Systembibliotheken natürlich nach wie vor auf die Hauptklasse TEncoding zugegriffen.

Gibt es eine Möglichkeit, die Original-Function irgendwie zu überschreiben?

Es geht um die "class function TEncoding.GetDefault: TEncoding;" bzw. "class property Default: TEncoding read GetDefault;" aus der Klasse TEncoding, System.SysUtils.pas
Wolfgang
  Mit Zitat antworten Zitat
Schokohase
(Gast)

n/a Beiträge
 
#2

AW: Delphi und Linux - Encoding-Salat?

  Alt 9. Aug 2019, 14:16
Deine Schlußfolgerungen sind leider falsch.

Unter Linux ist das Default Encoding UTF-8 weil das Betriebs-System so eingestellt ist.

Das ist also kein Fehler von Delphi (insofern es nicht hart kodiert ist sondern den Wert vom OS ausliest).

Ich weiß, du glaubst mir nicht, also hier der Beweis:

Führe auf der Konsole folgendes aus:
Code:
locales
Was steht da?

Bei mir kommt z.B.
Code:
LANG=de_DE.UTF-8
Würde ich mich da wundern, wenn als Default Encoding auf diesem System UTF-8 kommt? NEIN!
  Mit Zitat antworten Zitat
knaeuel

Registriert seit: 2. Jul 2007
110 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Delphi und Linux - Encoding-Salat?

  Alt 9. Aug 2019, 14:34
naja, Default meint hier nicht (oder sagen wir "sollte nicht meinen") das Betriebssystem-Default, sondern einfach einen Notfallwert, wenn kein BOM vorhanden ist. (BOMs sind bei UTF8 ja Standard)

ich schätze, mit genau der Überlegung kam es zu der Entscheidung, UTF-8 als Fallback zu setzen. Aber sinnvoll ist es eher nicht, würde ich sagen.

1. es ist hart kodiert. (siehe class function TEncoding.GetDefault: TEncoding; in System.SysUtils.pas)

2. die Procedure TEncoding.GetBufferEncoding (System.SysUtils.pas Zeile 32708) prüft zunächst, ob die Kodierung UTF-8, Unicode LE oder Unicode BE ist. Trifft alles NICHT zu, wird der FEST KODIERTE Wert UTF-8 zurückgegeben, OBWOHL direkt vorher festgestellt wurde, dass es UTF-8 NICHT sein kann.

3. Das führt dazu, dass unter Linux keine ANSI-Dateien in Strings geladen werden können. Sobald du das versuchst, versucht Delphi einen UTF8-String einzulesen, obwohl ein ANSI-String kommt. Das führt bei Umlauten und vielen anderen Sonderzeichen zum Abbruch mit der Meldung "No mapping for the Unicode character exists in the target multi-byte code page". Kein Wunder -> es ist ja auch kein Unicode-Character sondern ein ANSI-Character, der zu verarbeiten wäre.

Also für mich ist das ein Bug. Ich habe inzwischen einen funktionierenden Workaround und kann jetzt einfach meine ANSI-kodierten XML-Dateien unter Linux öffnen. Fehlerfrei. Alle Sonderzeichen werden korrekt dargestellt.
Wolfgang

Geändert von knaeuel ( 9. Aug 2019 um 14:58 Uhr)
  Mit Zitat antworten Zitat
Schokohase
(Gast)

n/a Beiträge
 
#4

AW: Delphi und Linux - Encoding-Salat?

  Alt 9. Aug 2019, 15:16
Irgendwie verstehe ich dich glaube ich nicht.

Wenn du egal wo immer den gleichen Standard-Wert für das Encoding haben möchtest, falls es keinen BOM gibt, dann verwende die overload Variante der Methode und gib das gewünschte Encoding mit
Delphi-Quellcode:
LEncoding := nil;
LOffset := TEncoding.GetBufferEncoding( LBuffer, LEncoding, TEncoding.ANSI { dieses Default-Encoding verwenden } );
und das Kas is gerollt.

Oder etwa nicht?
  Mit Zitat antworten Zitat
knaeuel

Registriert seit: 2. Jul 2007
110 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: Delphi und Linux - Encoding-Salat?

  Alt 9. Aug 2019, 15:42
ja, solange ich den Aufruf selber mache, passts. Problematisch wirds, wenn innerhalb der Delphi-Bibliotheken "GetBufferEncoding" aufgerufen wird. Dann kann ich nicht verhindern, dass (unter Linux) ANSI-Dateien fälschlicherweise als UTF-8 betrachtet werden.

Ich habe ja jetzt auch einen funktionierenden Workaround, seit ich gesehen habe, dass ich eine XML-Datei auch per LoadFromStream in die TXMLDocument-komponente bekomme. Da kann ich nämlich die Kodierung auch mitangeben.

Zum Feststellen der Kodierung einer Datei musste ich die Klasse TEncoding erben und die Methoden "GetBufferEncoding" und "GetDefault" überschreiben.

Durch diese neue Klasse TMyEncoding kann ich jetzt auch unter Linux ANSI-Dateien konvertieren und als z.B. UTF-8 oder UTF-16 LE/BE speichern. Das war vorher nicht möglich, weil eben auch wieder von einem falschen Quellformat ausgegangen wurde.
Wolfgang
  Mit Zitat antworten Zitat
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
3.050 Beiträge
 
Delphi 12 Athens
 
#6

AW: Delphi und Linux - Encoding-Salat?

  Alt 9. Aug 2019, 16:29
ja, solange ich den Aufruf selber mache, passts. Problematisch wirds, wenn innerhalb der Delphi-Bibliotheken "GetBufferEncoding" aufgerufen wird. Dann kann ich nicht verhindern, dass (unter Linux) ANSI-Dateien fälschlicherweise als UTF-8 betrachtet werden.

Ich habe ja jetzt auch einen funktionierenden Workaround, seit ich gesehen habe, dass ich eine XML-Datei auch per LoadFromStream in die TXMLDocument-komponente bekomme. Da kann ich nämlich die Kodierung auch mitangeben.

Zum Feststellen der Kodierung einer Datei musste ich die Klasse TEncoding erben und die Methoden "GetBufferEncoding" und "GetDefault" überschreiben.

Durch diese neue Klasse TMyEncoding kann ich jetzt auch unter Linux ANSI-Dateien konvertieren und als z.B. UTF-8 oder UTF-16 LE/BE speichern. Das war vorher nicht möglich, weil eben auch wieder von einem falschen Quellformat ausgegangen wurde.
Ok, dann erstelle dopch mal einen QP Report. Dan sehen wir ja auch bald wie EMBT darauf reagiert.
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:00 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz