(1) Apa yang dimaksud dengan urutan byte, sebuah array dari char di C? Apakah UTF-16 urutan byte, atau apakah itu? (2) Mengapa urutan byte tidak ada hubungannya dengan panjang variabel?
Anda tampaknya salah paham tentang masalah endian. Berikut ringkasan singkatnya.
Bilangan bulat 32-bit membutuhkan 4 byte. Sekarang, kita tahu urutan logis dari byte ini. Jika Anda memiliki integer 32-bit, Anda bisa mendapatkan byte tinggi ini dengan kode berikut:
uint32_t value = 0x8100FF32;
uint8_t highByte = (uint8_t)((value >> 24) & 0xFF); //Now contains 0x81
Semuanya baik dan bagus. Di mana masalahnya dimulai adalah bagaimana berbagai perangkat keras menyimpan dan mengambil bilangan bulat dari memori.
Dalam urutan Big Endian, sepotong memori 4 byte yang Anda baca sebagai integer 32-bit akan dibaca dengan byte pertama menjadi byte tinggi:
[0][1][2][3]
Dalam urutan Little Endian, sepotong memori 4 byte yang Anda baca sebagai integer 32-bit akan dibaca dengan byte pertama menjadi byte rendah :
[3][2][1][0]
Jika Anda memiliki pointer ke pointer ke nilai 32-bit, Anda bisa melakukan ini:
uint32_t value = 0x8100FF32;
uint32_t *pValue = &value;
uint8_t *pHighByte = (uint8_t*)pValue;
uint8_t highByte = pHighByte[0]; //Now contains... ?
Menurut C / C ++, hasil ini tidak terdefinisi. Itu bisa 0x81. Atau bisa juga 0x32. Secara teknis, itu bisa mengembalikan apa pun, tetapi untuk sistem nyata, itu akan mengembalikan satu atau yang lain.
Jika Anda memiliki pointer ke alamat memori, Anda dapat membaca alamat itu sebagai nilai 32-bit, nilai 16-bit, atau nilai 8-bit. Pada mesin big endian, pointer menunjuk ke byte tinggi; pada mesin endian kecil, pointer menunjuk ke byte rendah.
Perhatikan bahwa ini semua tentang membaca dan menulis ke / dari memori. Ini tidak ada hubungannya dengan kode C / C ++ internal. Versi pertama dari kode, yang tidak dinyatakan sebagai C / C ++ tidak terdefinisi, akan selalu berfungsi untuk mendapatkan byte tinggi.
Masalahnya adalah ketika Anda mulai membaca stream byte. Seperti dari suatu file.
Nilai 16-bit memiliki masalah yang sama dengan nilai 32-bit; mereka hanya memiliki 2 byte, bukan 4. Oleh karena itu, file dapat berisi nilai 16-bit yang disimpan dalam urutan endian besar atau kecil.
UTF-16 didefinisikan sebagai urutan nilai 16-bit . Secara efektif, itu adalah uint16_t[]
. Setiap unit kode individu memiliki nilai 16-bit. Oleh karena itu, untuk memuat UTF-16 dengan benar, Anda harus tahu apa kegunaan data itu.
UTF-8 didefinisikan sebagai urutan nilai 8-bit . Itu adalah uint8_t[]
. Setiap unit kode individu berukuran 8-bit: satu byte.
Sekarang, baik UTF-16 dan UTF-8 memungkinkan untuk beberapa unit kode (nilai 16-bit atau 8-bit) untuk bergabung bersama untuk membentuk titik kode Unicode ("karakter", tapi itu bukan istilah yang benar; itu adalah penyederhanaan ). The rangka unit kode ini yang membentuk codepoint sebuah ditentukan oleh UTF-16 dan UTF-8 encoding.
Saat memproses UTF-16, Anda membaca nilai 16-bit, melakukan konversi endian apa pun yang diperlukan. Kemudian, Anda mendeteksi apakah itu pasangan pengganti; jika ya, maka Anda membaca nilai 16-bit lain, menggabungkan keduanya, dan dari sana, Anda mendapatkan nilai titik kode Unicode.
Saat memproses UTF-8, Anda membaca nilai 8-bit. Konversi endian tidak dimungkinkan, karena hanya ada satu byte. Jika byte pertama menunjukkan urutan multi-byte, maka Anda membaca beberapa jumlah byte, seperti yang ditentukan oleh urutan multi-byte. Setiap byte individu adalah byte dan karenanya tidak memiliki konversi endian. para rangka ini byte dalam urutan, seperti urutan pasangan pengganti di UTF-16, didefinisikan oleh UTF-8.
Jadi tidak ada masalah endian dengan UTF-8.