Это вопрос, который был открыт какое-то время.
Тогда в феврале (боже, я действительно писал в блог целый год?) я объяснил разницу между Big Endian и Little Endian Unicode. В январе я также говорил про Byte Order Mark.
Но этот пост не про это.
Этот пост - про Preferred Charset Label для web-страниц, которые кодируются в Big Endian Unicode (или 'Unicode (Big Endian)', как любит называть его Блокнот).
Это на самом деле unicodeFFFE.
"Но, Майкл, это не является допустимой кодовой точкой Unicode!" - плачут одни.
"Но, Майкл, это не то, как выглядит в памяти big endian BOM, если посмотреть на байты!" - плачут другие.
"Но, Майкл, это не то, как big endian BOM выглядит на Big Endian системах!" - плачет часть оставшихся людей.
"Майкл, Microsoft сошла с ума?" - вопрошают оставшиеся (они употребляют намного менее вежливый язык, но я нашёл письмо с самой вежливой формой и поэтому использую именно её).
И, верите вы или нет, вот некоторые баги, которые были сообщены нам людьми из разных команд за эти годы, которые не были счастливы из-за одной или нескольких вещей:
- Результаты MLang
- Encoding.BigEndianUnicode.WebName
- Preferred Charset Label в Internet Explorer
- Документация MSDN, которая говорит про unicodeFFFE
"Byte-order mark для big-endian unicode - это FEFF, так что это должно называться UnicodeFEFF. Это выглядит разумно, но я боюсь что-то сломать, если буду это менять" - объясняет Shawn Steele, разработчик и владелец кодировок в Windows и .NET Framework.
"Я думаю, что это была ошибка в изначальных данных MLang, но нам приходится сохранять это по соображениям обратной совместимости" - объясняет разработчик, кто раньше работал над и владел MLang, а теперь глава разработки MUI.
"Да, это неправильное употребление термина, которое мы унаследовали от MLang. Слишком поздно менять это сейчас" - объясняет глава разработки NLS.
"Да, это было неверно в первой реализации. Но сейчас код приложений содержит эту константу, так что мы не можем её изменить" - объясняет архитектор Chris Lovett из команды SQL Server team.
Но правда в том, что оригинальное название из MLang вовсе не такое уж безумное. Вообще, Windows (да и Microsoft) живут в мире преимущественно Little Endian (даже когда Windows запускается на BE платформах вроде Alpha, всё равно при этом используется LE). И когда кто-то на little endian системе читает два байта как если бы они были одним WideChar (думая, что это кодовая точка UTF-16 LE), то они видят #$FFFE, что, конечно же, не является допустимой кодовой точкой Unicode. Вот почему так легко увидеть, что это big endian.
UTF-16 BOM - это всегда U+FEFF. Всегда. ВСЕГДА. Но это означает, что в памяти это будет (в байтах):
$ff $fe
- little endian BOM на любой системе.$fe $ff
- big endian BOM на любой системе.
$feff
- little endian BOM на little endian системах.$fffe
- big endian BOM на little endian системах.$fffe
- little endian BOM на big endian системах.$feff
- big endian BOM на big endian системах.
Семантика достаточно прозрачна и очевидна, просто плохо документирована, и, возможно, кто-то посчитает её глупым способом думать так про эти вещи. Название unicodeFFFE действует как несколько разумная (хотя и несколько платформенно-провинциальная) маркировка того, что все видят на почти 100% всех платформ Windows.
Как уже сказали другие люди, сейчас в любом случае поздно это менять...
This post brought to you by U+fffe, навечно зарезервированной кодовой точкой в Unicode, так что вся эта BOM идентификация сможет оставаться простым делом...
Такое поведение исправлено в новых версиях Windows/MLang:
ОтветитьУдалитьВ Windows XP MLang сообщает unicodeFFFE
В Windows 7 MLang сообщает unicodeFEFF