(1) What does byte sequence mean, an arrary of char in C? Is UTF-16 a byte sequence, or what is it then? (2) Why does a byte sequence have nothing to do with variable length?
Sembra che tu stia fraintendendo i problemi di endian. Ecco un breve riassunto.
Un numero intero a 32 bit occupa 4 byte. Ora conosciamo l'ordine logico di questi byte. Se hai un intero a 32 bit, puoi ottenere il byte più alto con il seguente codice:
uint32_t value = 0x8100FF32;
uint8_t highByte = (uint8_t)((value >> 24) & 0xFF); //Now contains 0x81
Va tutto bene. Il punto in cui inizia il problema è il modo in cui vari hardware memorizzano e recuperano gli interi dalla memoria.
Nell'ordine Big Endian, una parte di memoria di 4 byte che leggerai come numero intero a 32 bit verrà letta con il primo byte come byte alto:
[0][1][2][3]
Nell'ordine Little Endian, un pezzo di memoria di 4 byte che tu leggi come un intero a 32 bit verrà letto con il primo byte che è il basso byte:
[3][2][1][0]
Se hai un puntatore a un puntatore a un valore a 32 bit, puoi fare ciò:
uint32_t value = 0x8100FF32;
uint32_t *pValue = &value;
uint8_t *pHighByte = (uint8_t*)pValue;
uint8_t highByte = pHighByte[0]; //Now contains... ?
Secondo C / C ++, il risultato di questo non è definito. Potrebbe essere 0x81. O potrebbe essere 0x32. Tecnicamente, potrebbe restituire qualsiasi cosa, ma per i sistemi reali, restituirà uno o l'altro.
Se si dispone di un puntatore a un indirizzo di memoria, è possibile leggere quell'indirizzo come valore a 32 bit, a 16 bit o a 8 bit. Su una macchina big endian, il puntatore punta al byte alto; su una piccola macchina endian, il puntatore punta al byte basso.
Si noti che si tratta di leggere e scrivere su / dalla memoria. Ha niente da fare con il codice C / C ++ interno. La prima versione del codice, quella che C / C ++ non dichiara come indefinita, lavorerà always per ottenere il byte più alto.
Il problema si verifica quando inizi a leggere i flussi di byte. Ad esempio da un file.
I valori a 16 bit hanno gli stessi problemi di quelli a 32 bit; hanno solo 2 byte invece di 4. Pertanto, un file può contenere valori a 16 bit memorizzati in big endian o little endian.
UTF-16 è definito come una sequenza di valori a 16 bit . In effetti, è un uint16_t[]
. Ogni singola unità di codice è un valore a 16 bit. Pertanto, per caricare correttamente UTF-16, è necessario sapere qual è la endianità dei dati.
UTF-8 è definito come una sequenza di valori a 8 bit . È un uint8_t[]
. Ogni singola unità di codice ha una dimensione di 8 bit: un singolo byte.
Ora, sia UTF-16 che UTF-8 consentono più unità di codice (valori a 16 bit o 8 bit) da combinare insieme per formare un punto di codice Unicode (un "carattere", ma questo è non il termine corretto, è una semplificazione). L' ordine di queste unità di codice che formano un punto di codice è dettato dalle codifiche UTF-16 e UTF-8.
Durante l'elaborazione di UTF-16, si legge un valore a 16 bit, facendo qualsiasi conversione endian è necessaria. Quindi, si rileva se si tratta di una coppia surrogata; se lo è, allora leggi un altro valore a 16 bit, combina i due e, da quello, ottieni il valore di codice Unicode.
Durante l'elaborazione di UTF-8, si legge un valore a 8 bit. Non è possibile alcuna conversione endian, poiché esiste un solo byte. Se il primo byte indica una sequenza multi-byte, allora si legge un certo numero di byte, come dettato dalla sequenza multi-byte. Ogni singolo byte è un byte e quindi non ha alcuna conversione endian. L'ordine di questi byte nella sequenza, proprio come l'ordine delle coppie surrogate in UTF-16, è definito da UTF-8.
Quindi non ci possono essere problemi con Endian UTF-8.