суббота, 18 декабря 2010 г.

Может ли кодовая страница меняться? Как насчёт кодовой страницы, на которую указывает локаль?

Это перевод Can a codepage be changed? How about which codepage a locale points to? Автор: Майкл Каплан.

Ранее сегодня я рассмотрел вопрос, можно ли добавлять символы в Unicode, но Иван Петров также спрашивал, можно ли изменить кодовую страницу 1251, поскольку в ней пропущено 20 кирилических символов.

К сожалению, с этим ничего нельзя сделать по нескольким причинам.

Во-первых, как пытался указать Mike Dimmick в комментариях к тому посту (пост был скрыт как спойлер - извини, Майк!), кодовая страница 1251 имеет только один свободный слот, поэтому не существует способа добавить к ней целых 20 символов. Это, конечно же, делает обновление кодовой страницы 1251 невозможным.

Во-вторых, Microsoft не обновляет кодовые страницы ANSI1 - согласно своей политике. Никогда. Мы не можем. Мы пробовали это дважды:
  • Когда-то между Windows NT 4.0 и 2000 (и также между Windows 98 и Me) некоторые, но не все кодовые точки для фарси были добавлены в кодовую страницу 1256 (для всех там не было места).
  • Во времена Windows 2000 почти все кодовые страницы ANSI были обновлены для добавления символа Euro2.
Даже сегодня нам всё ещё приходится иметь дело с последствиями этих изменений, и мы пообещали всем заинтересованным сторонам (как внутри, так и вне Microsoft), что мы никогда не сделаем эту же ошибку снова. Такое изменение вляет на форматы хранения, совместимость приложений, платформенную совместимость и т.д.

В любом случае кодовые страницы ANSI от Microsoft достаточно странны. Они не ANSI стандарта и большинство из них моделированы на базе ISO-8859. Главное отличие состоит в том, что область C1 (в ISO-8859 она зарезервирована для управляющих кодов, которые также можно увидеть в Unicode) используется для символов. Положительный момент - кодовая страница становится более полезной; отрицательная сторона - если данные принимают за ISO-8859, то в Microsoft летят все помидоры за "нарушение стандартов".

Простой факт: для большинства языков 8 бит - просто не достаточно.

Dr. International говорил об этом ещё в августе 2000-го, заходя так далеко, что указывал, что GetLocaleInfo/LOCALE_IDEFAULTANSICODEPAGE для локали больше похоже на "наилучшее проецирование", которое может не содержать всех букв в языке.

Есть четыре разных способа, которыми решаются такие проблемы:
  • "Метод Microsoft", который я описал чуть выше, когда мы добавляли новые кодовые точки. Мы забросили этот метод.
  • "Метод ISO", под которым я ссылаюсь на серию ISO-8859, в которой добавляемые символы образуют новую кодовую страницу. Очевидно, это приводит к изобилию проблем с совместимостью, так как только некоторые люди устанавливают обновление.
  • "Метод IBM", под которым я ссылаюсь на оригинальные кодовые страницы "OEM" в DOS, а также серию EBCDIC. Решение похоже на "метод ISO", но гораздо более свободно к выпуску новых кодовых страниц. Насколько мне известно, IBM больше этим не занимается, хотя я могу ошибаться (да, я знаю, что Microsoft не добавляет поддержку новых кодовых страниц OEM/EBCDIC).
  • "Метод Unicode", под которым я понимаю избегания этой ситуации использованием Unicode, а не не-Unicode кодовых страниц.
Этот четвёртый метод - то, что используется Microsoft сегодня (после того, как из собственного опыта и чужого, мы увидели, насколько плохо работают первые три метода).

Любой может "хромать" без Unicode настолько хорошо, насколько они это смогут (просто для некоторых языков, не так-то просто для других), или они могут перейти на Unicode и увидеть, что их язык поддерживается насколько хорошо, насколько это позволяют сделать текущие определения.

Кроме этого, был ещё дополнительный вопрос насчёт смены значения кодовой страницы, используемой локалью, т.е. изменения значения OEMCP, возвращаемого GetLocaleInfo/LOCALE_IDEFAULTCODEPAGE. Такой поступок привёл бы к тому, что любой файл, ранее сохранённый из консоли, был бы испорчен - разумеется, ни при каких условиях польза от поддержки нового языка не может перевесить порчу данных. Поэтому, определённо, ответ заключается в использовании Unicode.

Последний поднятый Иваном вопрос - насчёт кодовой страницы OEM для Bulgarian MIK. Это одна из страниц, которую мы не можем добавить в Windows. И даже если бы она была, она не помогла бы. Пришло время переходить на Unicode, особенно, если вы используете язык, для которого он нужен. Болгарский находится в той же нише, что и урду и 600+ языков, которые не влезают в 8 бит.

1 - Реймонд Чен рассказал, почему эта кодовая страница (неверно) называется "ANSI". Возможно, я тоже про это скажу, так как тут есть что добавить...

2 - Если вы знаете, что это за символ без подглядывания в кодовые страницы Windows, я буду удивлён. Но поскольку у меня нет возможности узнать, подсматривали ли вы, то я останусь спокойным.


This post sponsored by "?" (U+003f, a.k.a. QUESTION MARK)
Символ, который появляется почти во всех кодовых страницах, когда вы пытаетесь сконвертировать в них текст из Unicode, но нужный символ не существует...

Комментариев нет:

Отправить комментарий

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.