(1)バイトシーケンスとはどういう意味ですか?UTF-16はバイトシーケンスですか、それとも何ですか?(2)なぜバイトシーケンスが可変長とは関係ないのですか?
エンディアンの問題を誤解しているようです。ここに簡単な要約があります。
32ビット整数は4バイトを占有します。これで、これらのバイトの論理的な順序がわかりました。32ビット整数がある場合、次のコードでこれの上位バイトを取得できます。
uint32_t value = 0x8100FF32;
uint8_t highByte = (uint8_t)((value >> 24) & 0xFF); //Now contains 0x81
それはすべてうまくいっています。問題が始まるのは、さまざまなハードウェアがどのように整数をメモリから保存および取得するかです。
ビッグエンディアン順では、32ビット整数として読み取る4バイトのメモリは、最初のバイトが上位バイトで読み取られます。
[0][1][2][3]
リトルエンディアンの順序では、32ビット整数として読み取る4バイトのメモリは、最初のバイトが下位バイトで読み取られます。
[3][2][1][0]
32ビット値へのポインターへのポインターがある場合、これを行うことができます。
uint32_t value = 0x8100FF32;
uint32_t *pValue = &value;
uint8_t *pHighByte = (uint8_t*)pValue;
uint8_t highByte = pHighByte[0]; //Now contains... ?
C / C ++によると、この結果は未定義です。0x81の可能性があります。または、0x32である可能性があります。技術的には、何でも返すことができますが、実際のシステムでは、どちらか一方を返します。
メモリアドレスへのポインタがある場合、そのアドレスを32ビット値、16ビット値、または8ビット値として読み取ることができます。ビッグエンディアンマシンでは、ポインターは上位バイトを指します。リトルエンディアンのマシンでは、ポインターは下位バイトを指します。
これは、メモリの読み取りと書き込みに関するものであることに注意してください。内部C / C ++コードとは関係ありません。C / C ++が未定義として宣言しないコードの最初のバージョンは、常に上位バイトを取得するために機能します。
問題は、バイトストリームの読み取りを開始するときです。ファイルからなど。
16ビット値には、32ビット値と同じ問題があります。4バイトではなく2バイトだけです。したがって、ファイルにはビッグエンディアンまたはリトルエンディアンの順序で格納された16ビット値を含めることができます。
UTF-16は16ビット値のシーケンスとして定義されます。事実上、それはuint16_t[]
です。各コード単位は16ビット値です。したがって、UTF-16を適切にロードするには、データのエンディアンが何であるかを知る必要があります。
UTF-8は、8ビット値のシーケンスとして定義されます。それはuint8_t[]
です。個々のコード単位は、サイズが8ビット(1バイト)です。
現在、UTF-16とUTF-8の両方で、複数のコードユニット(16ビットまたは8ビット値)を組み合わせてUnicodeコードポイント(「文字」ですが、これは正しい用語ではありません。これは簡略化です) )。コードポイントを形成するこれらのコードユニットの順序は、UTF-16およびUTF-8エンコーディングによって決まります。
UTF-16を処理する場合、16ビット値を読み取り、必要なエンディアン変換を実行します。次に、サロゲートペアかどうかを検出します。そうである場合は、別の16ビット値を読み取り、2つを組み合わせて、そこからUnicodeコードポイント値を取得します。
UTF-8を処理するとき、8ビット値を読み取ります。1バイトしかないため、エンディアン変換はできません。最初のバイトがマルチバイトシーケンスを示す場合、マルチバイトシーケンスの指示に従って、いくつかのバイトを読み取ります。個々のバイトは1バイトであるため、エンディアン変換は行われません。オーダーだけUTF-16サロゲートペアの順序と配列中のこれらのバイトは、UTF-8で定義されています。
したがって、UTF-8にはエンディアンの問題はありません。