Wie '\x9d' zu u'\x9d' transcodieren?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Obwohl in der Unicode-Spezifikation vorhanden, verweigert unicode() bei 8Bit-Steuerzeichen den Dienst. Ein Mapping von CHAR->WCHAR wollte ich eigentlich vermeiden.

Meine derzeitige Lösung ist unvorteilhaft, da ich auf ucs2 vs. ucs4 und die Bytereihenfolge der Pythoninstallation prüfen müsste. Und überhaupt riecht mir das zu sehr nach C:

Code: Alles auswählen

import codecs
from ctypes import c_wchar, memset, byref

def term_replace(exc):
    if isinstance(exc, UnicodeDecodeError):
        c = exc.object[exc.start]
        wc = c_wchar()
        memset(byref(wc), ord(c), 1)
        return wc.value, exc.end # exc.start+1 ?
codecs.register_error('term_replace', term_replace)

if __name__ == '__main__':
    s = 'Hallo\x9dWelt'
    print repr(s.decode('utf8', 'term_replace')) # --> u'Hallo\x9dWelt'
Weiss jmd. einem pythonischeren Weg?
lunar

@jerch: Täusche ich mich, oder suchst Du wirklich nur "s.decode('unicode-escape')"?
BlackJack

@lunar: Das `repr()` steht da nur damit man sieht was tatsächlich enthalten ist. Es geht nicht um das Ergebnis vom `repr()` sondern um das Argument. Das Beispiel ist vielleicht etwas schlecht gewählt weil zum Beispiel kein Umlaut enthalten ist. Aus 'H\xc3\xa4llo\x9dWelt' sollte beispielsweise u'H\xe4llo\x9dWelt' werden. UTF-8 Bytes/Bytefolgen sollen zu Unicode-Codepoints werden, ausser bei Bytes und Bytefolgen die nicht gültig wären, da sollen einfach die Bytewerte als Codepoints übernommen werden.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Ja das Bsp. ist schlecht gewählt, danke für die Klarstellung BlackJack.

Hintergrund des Ganzen ist der Versuch, dem ANSI-Parser C1 Steuerzeichen (8Bit) beizubringen und durch Einsatz von Unicode den Aufwand für die print-Transition zu minimieren/vereinheitlichen.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Das Problem mit den C1-Steuerzeichen gestaltet sich schwieriger als erwartet. Vllt. sollte ich die Unterstützung hierfür ganz rausnehmen, was den Parser praktisch auf das Niveau des VT102 zurückwirft. Hauptproblem sind diverse Copepages/Encodings, die den C1-Bereich mit eigenen Zeichen belegen (vorallem Windows-Encodings, zB. cp1252) bzw. undefiniert lassen (UTF8). Die C1-Befehle waren softwareseitig nie weit verbreitet, zumal alle C1-Befehle in C0 emuliert werden können und alle C1-fähigen Terminals diesen Modus im Sinne der Abwärtskompatibilität verstanden.
UTF8 zB. geht einen sehr eigenen Weg. Hier werden die C1-Befehle auf 2-Byte Sequenzen gemappt und die oberen Bits als Indikator für die Länge des eingeleiteten Multibytezeichens genutzt, wobei die folgenden Bytes nur 0x80-0xbf sein dürfen. Das hat sich der Herr Thompson ziemlich clever ausgedacht, häufigste Zeichen werden weiterhin als 1Byte ausgedrückt und die Multibytezeichen besitzen zusätzlich eine Längecodierung. Damit dürfte das Encoding ziemlich robust gegen fehlerhafte/verloren gegangene Bytes sein.
Alle anderen üblichen Encodings (die ISO-Reihe) reservieren den C1-Block normal.

Für einen unixoiden Terminalparser sind Windows-Codepages irrelevant (oder nutzt jmd. ernsthaft Windows-Encodings unter Unix?). Für UTF8 und das "erweiterte" ASCII (also das, was die C1-fähigen Terminals seinerzeit oberhalb von 127 getrieben haben) werd ich die Ausgabe der Steuerzeichen nochmal mit den üblichen Verdächtigen (shell, vi, emacs, mutt, mc usw.) genauer testen müssen. Sollte keines der Programme oder wichtiger Libs wie curses C1 nutzen und immer auf C0 setzen (was aus Gründen der Abwärtskompatibilität sinnvoll erscheint), würde ich die C1-Unterstützung nicht weiter verfolgen. (Für xterm hatte ich das schonmal getestet, da kamen trotz C1-Unterstützung nur C0-Sequenzen). Sollten für ein echtes 8Bit-Terminal/-emulator tatsächlich C1-Sequenzen generiert werden, muss ich das Problem neu überdenken. Für ASCII müsste ich dann den oberen Bereich, wie im Ausgangspost geschildert, fixen und bei UFT8 zunächst schauen, ob die Steuersequenzen korrekt codiert (2Byte) oder als Encoding-Müll von den Programmen abgesetzt werden.

Bin für Tipps und Anregungen offen, insbesondere was Encodings, Softwareunterstützung und Pro/Kontra C1 angeht.
Antworten