уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

В прошлой статье про кодировки я рассматривал вопросы того как можно представить веб-страницу в правильной кодировке. При этом в качестве источника информации о кодовой странице я предлагал использовать либо информацию из заголовков сервера, либо информацию из мета-тегов страницы.
Сегодня рассмотрим ещё один способ получения кодовой страницы для заданной строки с использованием MLang.

Сразу следует отметить, что любой автоматический способ определения кодовой страницы для текста не имеет 100% точности. Думаю, что вы не раз сталкивались с такой ситуацией, когда загружаемая Вами веб-страница в IE имела совершенно нечитабельный текст? Это как раз и следствие того, что браузер ошибся в определении кодировки. Но, как говориться, всегда приходится чем-то жертвовать.
Сегодня воспользуемся интерфейсом MLang под названием IMultiLanguage2. Этот интерфейс содержит все методы, которые имеет его родитель IMultiLanguage, а также ряд новых методов в числе которых необходимый нам DetectInputCodepage — определение кодовой страницы для заданной строки.
Параметры метода DetectInputCodepage следующие:
dwFlag [in] битовый флаг, определяющий специфику входной строки. Допустимые значения флага:
MLDETECTCP_NONE=0;
MLDETECTCP_7BIT=1;
MLDETECTCP_8BIT=2;
MLDETECTCP_DBCS=4;
MLDETECTCP_HTML=8;
dwPrefWinCodePage [in] вспомогательный параметр. Если он равен нулю, то MLang проверяет все возможные кодовые страницы
pSrcStr [in] входная строка для которой определяется кодовая страница.
pcSrcSize [in, out] размер строки. Если функция выполнена успешно, то pcSrcSize содержит количество проанализированный байтов строки.
lpEncoding [in, out] структура DetectEncodingInfo в которой содержится информация по кодовой странице для строки.
pnScores [in, out] Содержит количество элементов массива структур DetectEncodingInfo (для интерфейса IMultiLanguage2 равен 1).
Структура DetectEncodingInfo содержит следующие данные:

tagDetectEncodingInfo = packed record
    nLangID: SYSUINT; //ID языка
    nCodePage: SYSUINT;//номер кодовой страницы
    nDocPercent: SYSINT;//процент текста документа занятого текстом на языке nLangID
    nConfidence: SYSINT;//относительный параметр, по которому можно судить о точности определения кодовой страницы. Т.к. параметр относительный, то его значение может превысить 100. 
  end;

Соответственно, судя по параметру nConfidence можно делать вывод о том, стоит ли доверять «чутью» MLang или применить другой метод определения кодовой страницы. Давайте проведем небольшой эксперимент: составим небольшую программку, которая будет определять кодировку текста на странице и будем задавать адреса страниц с заведомо известными кодировками и посмотрим сколько раз MLang ошибется.
Итак, открываем Delphi, и создаем приложение примерно следующего вида:

В uses подключаем модуль MLang и, если Вы как и я используете для работы в Сети библиотеку Synapse, то ещё один модуль — httpsend.
Теперь в обработчике onClick кнопки «Detect» пишем:

procedure TForm5.Button1Click(Sender: TObject);
var count:integer;
    i:integer;
    Data:TStringStream;
    MultiLang: IMultiLanguage2;
    DE: tagDetectEncodingInfo;
    s:PAnsiChar;
begin
with THTTPSend.Create do
  begin
    if HTTPMethod('GET',Edit1.Text) then
      begin
        Data:=TStringStream.Create('');
        Data.LoadFromStream(Document);
      end;
  end; 
  MultiLang:=CoCMultiLanguage.Create as IMultiLanguage2;
  s:=PAnsiChar(Data.Bytes);
  i:=Data.Size;
  FillChar(DE, SizeOf(DE), 0); 
  count:=1;
 OleCheck(MultiLang.DetectInputCodepage(8,0,s,i,DE,count));
  label5.Caption:=IntToStr(DE.nCodePage);
  label10.Caption:=IntToStr(DE.nConfidence);
end;

Обратите внимание на то, каким образом получается значение переменной s:

 s:=PAnsiChar(Data.Bytes);

Используются байты строки (нововведение из Delphi 2009). Если написать так:

 s:=PAnsiChar(Data.DataString);

то DetectInputCodepage вернет кодовую страницу 1252 для любой страницы.
Теперь начнем проверку. Для начала проверим кодировку страниц моего блога. Результат:
Кодовая страница 65001 — это ни что иное, как utf-8. Теперь проверим главную страницу Гугла:

Тут уже есть неточность. На самом деле www.google.ru имеет кодироку utf-8, но и параметр «уверенности» тоже вернулся менее 100.
Аналогичным образом можно проверить ещё сколь угодно много страниц и получить результат. Могу сказать, что пока писал пост попутно проверил ряд страниц в кодировке koi8-r и результат был верным для всех проверенных страниц.
На сегодня, пожалуй все. Надеюсь, что приведенный выше способ определения кодовой страницы для строки найдет применение в Ваших программах.

0 0 голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
0 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии