[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

XLC_LOCALE. Продолжение 2.




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

  Каждый блок выглядит как
cs<цифра> {.....}

  Внутри ...
Сначала - "отличительные признаки".

side
  Главный "отличительный признак".
В простейшем случае может быть GL или GR. Это означает, что -
  - к данному кодесету относятся все байты типа GL (в диапазоне 0-127)
  - или - все байты типа GR (коды 128-255)
После GL/GR может через двоеточие стоять слово Default.
Это имеет смысл если в данной кодировке может быть несколько кодесетов
с одинаковым "сайдом" (естественно, у них есть какие-то другие отличия).
Тогда один из таких кодесетов будет default, а другой - рассматривается
только при некоторых обстоятельствах (они описываются параметром mb_encoding).
  Для iso8859  всегда существут только два кодесета - один - GL:Default,
другой - GR:Default.

  Для CJK side может быть "none", тогда отличительным признаком будут
параметры вида - byte<цифра>.

length          <число>
  Длина "мультибайта".
  Для iso8859 всегда - 1.
А для CJK может быть несколько разных кодесетов с разной длиной.
Например, если бы мы так описывали UTF, то там был бы кодесет с длиной 1,
который описывал бы ascii, несколько кодесетов длиной - 2 (один из них
соответствовал бы кириллице), несколько - 3 и т.д.

byte*
  Еще один "отличительный признак" (встречается в sjis).
Если side = none, то этот параметр (byte*) просто задает диапазон кодов.
Этих byte должно быть столько, сколько указывает параметр length.
  Например, если
side	none
length	2
а дальше идет что-то типа
byte1	\x80,\xa0
byte2	\x20,\x40
то это означает - к данному кодесету относятся все mb коды, у которых
  - первый байт в дипазоне 0x80-0xa0
  - второй - в 0x20-0x40
  Кстати, дипазонов может быть и несколько, они указываются через ";".
  Для iso8859 этот параметр не требуется.

mb_encoding
  Еще один "отличительный признак" (встречается в некоторых CJK).
  Если есть несколько кодесетов с одинаковым side (или с одинаковыми byte*),
один из них должен быть default, а другой рассматривается, если в потоке
встретились "переключатели" (байт или последовательность байтов).
  Естествеено, и для перехода в default должен быть "переключатель".
  mb_encoding как-раз описывает - как выглядит "переключатель" на данный
кодесет.
  Возможны три переключателя
  <LSL> - locked shift left
  <LSR> - locked shift right
  <SS>  - single shift
locked - означает, что все дальнейшие байты интерпретируются "по-новому",
пока не появится новый "переключатель" (или пока конвертор не будет
принудительно "ресетнут" программой, тогда выбирается кодесет default).
single shift - означает, что отдельно интерпретируется только один символ
(не байт, а мультибайт), непосредственно за "переключателем".
  После "волшебных слов" <lsl>/<lsr>/<ss> идет последовательность кодов,
которая и является "переключателем".
  Для iso8859 - смысла не имеет.

  Ну и наконец - параметры, описавающие - как интерпретировать данный
кодесет.

wc_encoding
  Как я уже говорил - описывает преобразование в wc (и обратно).
  Если входной мультибайт относится к данному кодесету, он упаковывается
в соответствии с wc_shift_bits. А потом в этот w_char "вклеивается"
код, заданный wc_encoding.
  Если нужно выполнить обратное преобразование, то
 - в соответствии с wc_encoding_mask из w_char выделяется та часть, которая
различает кодесеты
 - среди кодесетов ищется тот, в котором указан подходящий wc_encoding
 - делается нужное преобразование в соответствии с параметрами выбраного
кодесета (side, length, mb_encoding и т.п.) и общего параметра wc_shift_bits
(он нужен для "раздергивания" wc на несколько байтов)

ct_encoding
  Преобразование в ctext (и обратно).
  В этом параметре указывается название чарсета. Считается, что Xlib
знает - какой "назначатель" (esc-sequence) соответствует данному чарсету
("назначатель" задан либо во внутренних таблицах Xlib, либо может быть
описан в XLC_LOCALE с помощью блока csd* - char set definition).
  "Секвенция" может быть указана и прямо в ct_encoding, например -
   ct_encoding     KOI8-1:GR:\x1b-K
(к сожалению, так можно указывать только "секвенции", которые "похожи на
стандартные" в смысле стандарта CTEXT. Последовательности типа
\033%/1/200/210koi8-r/002 будут восприняты неправильно.)
  Итак. Если нужно преобразовать mb или wc в ct, то конвертор должен найти
подоходящий кодесет и в соответствии с ct_encoding выбрать нужный
"назначатель".
  При обратном преобразовании, по "назначателю" находится нужное название
чарсета, а потом среди кодесетов ищется тот, где это название встречается
в ct_encoding. Ну и делается дальнейшее преобразование.
  Для iso8859 достаточно, чтобы в каждом кодесете был указан один чарсет.
Для GL - ISO8859-1:GL, а для GR - какой-нибудь "национальный", например -
KOI8-R:GR.
  Но обычно, в GL указывают и "национальный":GL. По-видимому, для того,
чтобы конверторы не вставляли лишних "назначателей", если в потоке
GR кодов встретится GL. Хотя при нормальной реализации, этого и так не должно
быть.
  А вот то, что в GR, кроме KOI8-R:GR добавлен и ISO8859-1:GR - "обход бага".
Вообще-то, это - нонсенс. Если GL для обоих чарсетов не отличется и можно
такие байты (0-128) интерпретировать как членов любого из этих чарсетов,
то в части GR эти чарсеты, как известно, не совпадают.
  А "трюк" этот понадобился из-за того, что конверторы из ct неправильно
находили (сейчас это вроде бы уже исправили) по нестандартному "назначателю"
нужное название чарсета и заменяли его на "дефолтовый" ISO8859-1:GR.
Естественно, чтобы они могли найти среди кодесетов нужный - приходилось
вписывать в него и этот "дефолтовый" чарсет.

  В некоторых CJK могут встретиться в описании кодесета некоторые другие
"слова". Но о них позже.

   Продолжение следует...

-- 
 Ivan U. Pascal         |   e-mail: pascal@tsu.ru
   Administrator of     |   Tomsk State University
     University Network |       Tomsk, Russia