// you’re reading...

Featured

Добавляем internationalization в проект (продолжение…)

Этот пост — продолжение предыдущего “Добавляем internationalization в проект“.

Итак, моя вавилонская башня завершена. Все строители успешно разговаривают на UTF-8 :-) . Поддержка i18n была сделана для следующих платформ:

  • Windows
  • Linux
  • Solaris
  • AIX

Хочется немного раскрыть особенности текстовой конвертации для каждой из платформ. Так как в результате пришлось написать что-то вроде мультиплатформенной компоненты, которая имела одинаковый интерфейс на любой из платформ. Пользоваться пришлось тем, что можно спокойно засунуть в поставку продукта, не заботясь о “проблемах” лицензирования. Т.е. абсолютно свободные библиотеки.

Итак, по-порядку:

  • Windows
  • Кодировка задается числом(!), а не текстовой строкой. Поэтому необходимо построить мэппинг из текстового представления кодировки (например “UTF-8“, “big5“, “IBM855“) в идентификатор кодовой страницы (UINT). Стандартными средствами (WINAPI) этого сделать невозможно. Поэтому пришлось решать эту задачу “в лоб”. Благо MSDN представляет полный список всех возможных кодировок с описаниями и числовыми значениями. Пару взмахов ViM‘ом и список можно превратить в однозначный мэппинг:

    “текстовое имя кодировки” = номер кодовой страницы;

    Для быстроты/удобства получения числового значения из текстового можно использовать HashSet с ключом — “текстовое имя кодировки” и значением — номер кодовой страницы. Для мэппинга из номера в текст проще всего использовать обычный массив. Благо его размер нам изначально известен.

    Выяснение кодировки текущей локали оказалось крайне простым занятием: GetACP() возвращает UINT идентификатор кодировки текущей локали.

    Схема конвертирования проста:

    1. получаем идентификатор входной строки и идентификатор выходной строки
    2. переводим входную строку с помошью функции MultiByteToWideChar() к UTF-16 строке wchar_t *
    3. затем обратно к нужной кодировке используя WideCharToMultiByte().
  • Linux, Solaris, AIX
  • Для этих платформ ядром конвертации является библиотека ICONV. Не смотря на ее простоту, существует один интересный момент (!) с которым придется столкнуться при ее использовании. Дело в том, что в природе существует как минимум 2 версии этой библиотеки. Более того, они как правило, неплохо уживаются на одной системе. Это системная реализация и реализация GNU. Лицензия GNU’шной реализации библиотеки ICONV не позволяет использовать ее в проектах с закрытым кодом, ну или как-то так :-) . Так что надо обязательным образом использовать системный вариант, так как он, являясь частью системной библиотеки, вообще не нуждается в том, чтобы его включали в поставку. Другими словами, системная реализация ICONV гарантированно всегда присутствует на любой из перечисленных платформ (что необязательно для GNU реализации), а потому включать ее еще в дистрибутив своего продукта смысла нет, а раз она не включается в дистрибутив продукта, то и нет никаких проблем с лицензией. Фув. В этом и есть основное различие использования библиотеки ICONV на перечисленных платформах.

    Выяснение текущей локали оказалось задачей решаемой. Ранее я писал, что функция nl_langinfo() не работает, как описано в man‘е. Оказалось, что достаточно добавить вызов: setlocale(LC_ALL, “”); перед вызовом  nl_langinfo() и все начинает отлично работать. Это известный подход, видимо в прошлый раз я просто не догадался его опробовать.

    Схема конвертации:

    1. используя текстовое название входной и выходной кодировок получаем дескриптор конвертора с помощью iconv_open()
    2. используя дескриптор конвертора переводим входную строку в выходную с помощью iconv()

    Особенности:

    • Linux
    • Библиотека ICONV входит в libc.so.

    • Solaris
    • Библиотека ICONV входит в libc.so.

      Чтобы заставить работать функции стандартной библиотеки необходимо объявить макрос:

      #define LIBICONV_PLUG

      перед подключением системных хедеров. Иначе, по умолчанию, будет использоваться реализация GNU.

    • AIX
    • Библиотека ICONV входит в iconv.so, которая является частью системы.


Discussion

Ads

Похожие статьи