(1) Was bedeutet Bytesequenz, ein arrary of char in C? Ist UTF-16 eine Bytesequenz oder was ist es dann? (2) Warum hat eine Bytefolge nichts mit variabler Länge zu tun?
Sie scheinen zu missverstehen, was Endian-Themen sind. Hier ist eine kurze Zusammenfassung.
Eine 32-Bit-Ganzzahl belegt 4 Bytes. Nun kennen wir die logische Reihenfolge dieser Bytes. Wenn Sie eine 32-Bit-Ganzzahl haben, können Sie das High-Byte mit dem folgenden Code abrufen:
uint32_t value = 0x8100FF32;
uint8_t highByte = (uint8_t)((value >> 24) & 0xFF); //Now contains 0x81
Das ist alles schön und gut. Wo das Problem beginnt, ist, wie verschiedene Hardware ganze Zahlen aus dem Speicher speichert und abruft.
In der Big-Endian-Reihenfolge wird ein 4-Byte-Speicher, den Sie als 32-Bit-Ganzzahl lesen, gelesen, wobei das erste Byte das High-Byte ist:
[0][1][2][3]
In Little Endian-Reihenfolge wird ein 4-Byte-Speicher, den Sie als 32-Bit-Ganzzahl lesen, gelesen, wobei das erste Byte das untere Byte ist:
[3][2][1][0]
Wenn Sie einen Zeiger auf einen Zeiger auf einen 32-Bit-Wert haben, können Sie dies tun:
uint32_t value = 0x8100FF32;
uint32_t *pValue = &value;
uint8_t *pHighByte = (uint8_t*)pValue;
uint8_t highByte = pHighByte[0]; //Now contains... ?
Das Ergebnis ist laut C / C ++ undefiniert. Es könnte 0x81 sein. Oder es könnte 0x32 sein. Technisch könnte es alles zurückgeben, aber für echte Systeme wird es das eine oder andere zurückgeben.
Wenn Sie einen Zeiger auf eine Speicheradresse haben, können Sie diese Adresse als 32-Bit-Wert, 16-Bit-Wert oder 8-Bit-Wert lesen. Auf einer Big-Endian-Maschine zeigt der Zeiger auf das High-Byte. Auf einer kleinen Endian-Maschine zeigt der Zeiger auf das niedrige Byte.
Beachten Sie, dass es hier nur um das Lesen und Schreiben in den / aus dem Speicher geht. Es hat nichts mit dem internen C / C ++ - Code zu tun. Die erste Version des Codes, die C / C ++ nicht als undefiniert deklariert, funktioniert immer , um das High-Byte zu erhalten.
Das Problem ist, wenn Sie mit dem Lesen von Byte-Streams beginnen. Wie aus einer Datei.
16-Bit-Werte haben dieselben Probleme wie 32-Bit-Werte. Sie haben nur 2 Bytes anstelle von 4. Daher kann eine Datei 16-Bit-Werte enthalten, die in Big-Endian- oder Little-Endian-Reihenfolge gespeichert sind.
UTF-16 ist als Folge von 16-Bit-Werten definiert . Tatsächlich ist es ein uint16_t[]
. Jede einzelne Codeeinheit ist ein 16-Bit-Wert. Um UTF-16 korrekt laden zu können, müssen Sie daher die Endianität der Daten kennen.
UTF-8 ist als Folge von 8-Bit-Werten definiert . Es ist ein uint8_t[]
. Jede einzelne Codeeinheit hat eine Größe von 8 Bit: ein einzelnes Byte.
Sowohl in UTF-16 als auch in UTF-8 können mehrere Codeeinheiten (16-Bit- oder 8-Bit-Werte) zu einem Unicode-Codepunkt (einem "Zeichen") kombiniert werden, dies ist jedoch nicht der richtige Begriff, sondern eine Vereinfachung ). Die Reihenfolge dieser Codeeinheiten, die einen Codepunkt bilden, wird durch die UTF-16- und UTF-8-Codierungen bestimmt.
Bei der Verarbeitung von UTF-16 lesen Sie einen 16-Bit-Wert und führen die erforderliche Endian-Konvertierung durch. Dann stellen Sie fest, ob es sich um ein Ersatzpaar handelt. Wenn dies der Fall ist, lesen Sie einen weiteren 16-Bit-Wert, kombinieren die beiden und erhalten daraus den Unicode-Codepunktwert.
Bei der Verarbeitung von UTF-8 lesen Sie einen 8-Bit-Wert. Eine Endian-Konvertierung ist nicht möglich, da nur ein Byte vorhanden ist. Wenn das erste Byte eine Multibyte-Sequenz angibt, lesen Sie eine bestimmte Anzahl von Bytes, die von der Multibyte-Sequenz vorgegeben wird. Jedes einzelne Byte ist ein Byte und hat daher keine Endian-Konvertierung. Die Reihenfolge dieser Bytes in der Sequenz wird ebenso wie die Reihenfolge der Ersatzpaare in UTF-16 durch UTF-8 definiert.
Es kann also keine Endian-Probleme mit UTF-8 geben.