Glibmm und UTF-8
-
Tach,
Ich stehe irgend wie etwas auf der Leitung, wenn
es darum geht mit UTF-8 richtig umzugehen.
Zum Beispiel: wann muss ich was wohin encoden bzw. wandeln (charset) auf
welcher plattform.Ich mache das nun so:
Alles was der Benutzer/System eingibt, wird mal in UTF-8 konvertiert, da
ich im Programm inneren nur (falls nicht anders bekannt) UTF-8 Strings
(ustrings) benutze.
Wenn ich nun etwas ausgebe wandle ich es wieder zurück in die locale charset.
Ist das so Sinn voll?Nun kommt mir aber ein Problem entgegen...
Windows hat ja ein Unicode Filesystem (oder naja fast).
Das heisst für mich, wenn ich nun eine Datei öffnen will,
muss ich das under windows ja anders machen, da er ja ein unicode string
erwartet. In pseudo code ausgedrückt etwa so:Glib::ustring filename; #ifdef OS_WINDOWS write(filename.c_str(), data); #else write((Glib::filename_from_utf8(filename)).c_str(), data); #endif
Oder sehe ich das falsch?
Was muss man eigentlich sonst noch so beachten bei einem
Unicode fähigem programm?Gruss,
Ghost
-
Bei der glib(mm)-Programmierung gibt es in der Regel drei interessante Charsets: Das Filename Encoding, die Encoding der Locale und UTF-8. Wenn man, wie du, intern alles als UTF-8 represäntiert, hat man nachher keine Probleme, wenn man seine Strings in einer Gtk-GUI anzeigen will.
Der << und >>-Operator ist für die ustring-Klasse so überladen, dass er schon ohne weiteres die richtige Konvertierung nach UTF-8 vornimmt. Hier ist also keine weitere Arbeit nötig.
Interessant wird es bei Dateinamen. Wenn man folgendes beachtet ist man meistens auf der sicheren Seite: Alle glib-Funktionen, die Dateinamen erwarten oder zurückgeben, tun dies im glib Filename encoding (welches im übrigen mit der Environment-Variablen G_FILENAME_ENCODING gesetzt werden kann). Unter Windows ist das immer UTF-8, unter anderen Betriebssystemen nicht notwendigerweise. Konvertierung geht mit Glib::filename_from/to_utf8. Zum Arbeiten mit Dateien sollte man also immer glib-Funktionen verwenden (Bekannte C-Funktionen sind in glib mit g_-gepräfixt enthalten (so zum Beispiel g_open oder g_rename), die auf die Filename-Encoding-Geschichte achten). Zum Lesen/Schreiben von Dateien ist besonders die Glib::IOChannel-Klasse geeignet, zum Lesen von Verzeichnissen Glib::Dir. Spezielle #ifdefs um auf Betriebssysteme zu prüfen sollten nicht erforderlich sein. In deinem Beispiel würde ich einfach immer die Glib::filename_from_utf8-Konvertierung machen und statt write (was wohl nicht das posix-write ist/sein soll?) einen Glib::IOChannel oder g_file_set_contents verwenden.
Ansonsten ist es natürlich immer hilfreich, geeignete Tests mit Unicode-Strings auf verschiedenen Systemen durchzuführen, damit man merkt, wenn irgendwo ein Problem ist.
-
Danke für dein Beschrieb.
Ich habe in der Glib Ref. auch die Lösung gefunden welche
sich mit deinem beschrieb deckt.write ist hier nur eine Pseudo Funktion.
Kann man eigentlich mit den Glib::IOChannel auch
socket Verbindungen mit callback Funktionen machen?
Somit könnte man sich einen Thread sparen.Gg
-
Bemerkung:
Ein weiterer Vorteil wenn alle strings UTF-8 sind, ist dass
man dann auch mit hex vergleichen kann.Somit konnte ich mir eine boost::format für utf8 ustrings machen
welche eine Laufzeit von O(n) hat.