Total Commander Forum Index Total Commander
Форум поддержки пользователей Total Commander
Сайты: Все о Total Commander | Totalcmd.net | Ghisler.com | RU.TCKB
 
 RulesRules   SearchSearch   FAQFAQ   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

DLL для определения кодировки?

 
Post new topic   Reply to topic    Total Commander Forum Index -> Написание плагинов для Total Commander printer-friendly view
View previous topic :: View next topic  
Author Message
Alextp



Joined: 06 Feb 2005
Posts: 4957

Post (Separately) Posted: Mon Aug 16, 2010 23:32    Post subject: DLL для определения кодировки? Reply with quote

Ищется код(лучше- DLL!) для определния кодировки файла, если нету BOM. По первым NN Кб. Для плагина Syn2.

если код на С, я его использовать не могу.
_________________
UniViewer - CudaText - LogViewer
Back to top
View user's profile Send private message
Alextp



Joined: 06 Feb 2005
Posts: 4957

Post (Separately) Posted: Tue Aug 17, 2010 00:29    Post subject: Reply with quote

Посмотрел код akelpad- непонятно, какие-то watermarks-массивы, что они значат не понял (а тупо переводить код не хочется)
_________________
UniViewer - CudaText - LogViewer
Back to top
View user's profile Send private message
Loopback



Joined: 07 Sep 2009
Posts: 1274

Post (Separately) Posted: Tue Aug 17, 2010 09:45    Post subject: Reply with quote

Насколько я понимаю, нужно определить UTF-8 или нет, т.к. BOM к другого рода кодировкам (типа 1251, KOI-8 ) не имеет отношения. Я пользуюсь такой функцией (где-то когда-то нашел):

Code:

function IsUTF8Memory(AMem: PBYTE; ASize: Int64): boolean;
var
  i: Int64;
  c: Integer;

  function UTF8CharLength(const c: BYTE): Integer;
  begin
    // First Byte: 0xxxxxxx
    if ((c and $80) = $00) then
      Result:=1
    // First Byte: 110yyyyy
    else if ((c and $E0) = $C0) then
      Result:=2
    // First Byte: 1110zzzz
    else if ((c and $F0) = $E0) then
      Result:=3
    // First Byte: 11110uuu
    else if ((c and $F8) = $F0) then
      Result:=4
    // not valid, return the error value
    else
      Result:=-1;
  end;

  //After than you check all the trail bytes for that characters (if any)
  //for conformity with this:
  function UTF8IsTrailChar(const c: BYTE): BOOLEAN;
  begin
    // trail bytes have this form: 10xxxxxx
    Result:=((c and $C0) = $80);
  end;

begin
  Result := True;
  i := 0;
  while (i < ASize) do
  begin
    // get the length if the current UTF-8 character
    c:=UTF8CharLength(AMem^);
    // check if it is valid and fits into ASize
    if ((c>= 1) and (c <= 4) and ((i+c-1) < ASize)) then
    begin
      inc(i, c);
      inc(AMem);
      // if it is a multi-byte character, check the trail bytes
      while (c>1) do
      begin
        if (not UTF8IsTrailChar(AMem^)) then
        begin
          Result := False;
          break;
        end
        else
        begin
          dec(c);
          inc(AMem);
        end;
      end;
    end
    else
    begin
      Result:=False;
    end;
    if (not Result) then break;
  end;
end;
Back to top
View user's profile Send private message
Alextp



Joined: 06 Feb 2005
Posts: 4957

Post (Separately) Posted: Tue Aug 17, 2010 10:20    Post subject: Reply with quote

Не только UTF8: ANSI, OEM, KOI8, UTF8. Спасибо за ф-цию. осталось ANSI/OEM/KOI8
_________________
UniViewer - CudaText - LogViewer
Back to top
View user's profile Send private message
Loopback



Joined: 07 Sep 2009
Posts: 1274

Post (Separately) Posted: Tue Aug 17, 2010 10:35    Post subject: Reply with quote

Определение этих кодировок - уже по-любому статистические алгоритмы. Их вроде найти не проблема. Например, вот. Сначала определяем, UTF-8 ли текст, и если нет - смотрим кодировку.
Back to top
View user's profile Send private message
Alextp



Joined: 06 Feb 2005
Posts: 4957

Post (Separately) Posted: Tue Aug 17, 2010 11:50    Post subject: Reply with quote

тестирую код №2. Файл- atorg.net.ru/temp/beta/cp.rar
Показывает "Ansi" для OEM строки -плохо
_________________
UniViewer - CudaText - LogViewer
Back to top
View user's profile Send private message
MVV



Joined: 15 Oct 2009
Posts: 4811
Location: Ростов-Дон

Post (Separately) Posted: Tue Aug 17, 2010 12:53    Post subject: Reply with quote

Определение этих кодировок уже зависит от кодовой страницы. Для русской будет один результат, для каких-нибудь еще - другой. Наверное можно попробовать составить список букв, действительных для каждой кодировки, и подсчитывать число букв текста, совпадающих с ними - где будет больше, та кодировка скорее используется. Но опять же, до какой-то степени множества символов кодировок пересекаются - на поле в 128 символов особо не разгуляешься.
_________________
TCFS2 + TCFS2Tools: Полноэкранный режим и многое другое (обсуждение)
WINCMD.RU: AskParam, CopyTree, NTLinks, Sudo, VirtualPanel…
Back to top
View user's profile Send private message
Alextp



Joined: 06 Feb 2005
Posts: 4957

Post (Separately) Posted: Sat Jan 21, 2012 21:30    Post subject: Reply with quote

(Up)
Кто-нибудь может за небольшую плату сделать dll, для определения "'это - UTF8 без BOM", с настройкой "для русского/ немецкого/ ..... "? могу дать пример на C. из сорса Notepad++.

Добавлено спустя 40 секунд:

точнее Akelpad
_________________
UniViewer - CudaText - LogViewer
Back to top
View user's profile Send private message
ApceH



Joined: 08 Apr 2011
Posts: 316
Location: Димитровград

Post (Separately) Posted: Sat Jan 21, 2012 23:19    Post subject: Reply with quote

Alextp
Вот мой код чуть более общий:
Code:
type
  TEncodingType = (ANSI, UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE);

function DetectEncodingType(hOpenedFile: Cardinal): TEncodingType;
//вялое определние кодировки
//файл должен быть уже открыт на чтение
var
  buf: array[0..3] of AnsiChar;
begin
  Result := ANSI;
  FileRead(hOpenedFile, buf, 4);
  case buf[0] of
    #$EF:
      begin
        if (buf[1] = #$BB) and (buf[2] = #$BF) then
        begin
          FileSeek(hOpenedFile, 3, spBegin);
          Result := UTF8;
        end;
      end;
    #$FE:
      begin
        if (buf[1] = #$FF) then
          FileSeek(hOpenedFile, 2, spBegin);
        Result := UTF16BE;
      end;
    #$FF:
      begin
        if (buf[1] = #$FE) then
          if (buf[2] = #$00) and (buf[3] = #$00) then
          begin
            FileSeek(hOpenedFile, 4, spBegin);
            Result := UTF32LE;
          end
          else
          begin
            FileSeek(hOpenedFile, 2, spBegin);
            Result := UTF16LE;
          end;
      end;
    #$00:
      begin
        if (buf[1] = #$00) and (buf[2] = #$FE) and (buf[3] = #$FF) then
        begin
          FileSeek(hOpenedFile, 4, spBegin);
          Result := UTF32BE;
        end;
      end;
  else
    FileSeek(hOpenedFile, 0, spBegin);
  end;
end;

А среди 8-битных делал только на C#. Определяло практически всё правильно. Если надо скину.
_________________
kIT Programs PowerPack, kIT Universal Presets | Есть только одна истинная вера: чёрная магия...
Back to top
View user's profile Send private message
Alextp



Joined: 06 Feb 2005
Posts: 4957

Post (Separately) Posted: Sat Jan 21, 2012 23:23    Post subject: Reply with quote

Мне же детектить текст UTF8 без BOM. А у вас по сигнатуре. Не то. А на С# оно детектит UTF8?
_________________
UniViewer - CudaText - LogViewer
Back to top
View user's profile Send private message
CaptainFlint



Joined: 14 Dec 2004
Posts: 6151
Location: Москва

Post (Separately) Posted: Sun Jan 22, 2012 14:33    Post subject: Reply with quote

Alextp
В общем случае задача неразрешима, потому что если текст целиком на английском, то в ANSI и UTF-8 он будет выглядеть идентично. Да и сам по себе UTF-8 принципиально от ANSI не отличается. Так что как минимум возникает вопрос о приоритетах списка кодировок.

Тому, кто захочет этим заниматься, могу подкинуть лишь идею для реализации, основанную на поведении Тотала (CompareUtf8Detect): пробежаться по файлу, оценивая его с точки зрения допустимости в UTF-8. Если встретилась хотя бы одна недопустимая последовательность байтов, значит, это ANSI. Если встретилась хотя бы одна допустимая мультибайтовая последовательность — с определённым риском можно считать, что это UTF-8 (хотя реально это может быть и ANSI, гарантий нет). Если нет ни того, ни другого, то выбор между ANSI и UTF-8 придётся делать волевым решением (или опцией). Дополнительно (опять-таки, по мотивам Тотала) можно для HTML/XML/CSS-файлов поискать сигнатуры кодировок и встроить их в описанный алгоритм предпочтений.

Следующий уровень для наворотов — учёт языковых особенностей (что если файл русскоязычный, то большинство символов там будет не просто UTF-8, а из конкретного диапазона), но это очень опасный шаг, если методика планируется для повсеместного применения: каждый язык придётся изучать на предмет алфавита и используемых символов, для каждого хардкодить списки последовательностей… Плюс есть вероятность, что из-за этих наворотов точность определения кодировки для неизвестных языков уменьшится, и придётся либо активно дорабатывать списки символов для большого количества языков (возможно, тем самым ещё сильнее ухудшая работу с оставшимися неподдерживающимися языками), либо предусматривать конфигурируемость алгоритма.
_________________
Почему же, ё-моё, ты нигде не пишешь "ё"?
Back to top
View user's profile Send private message
Alextp



Joined: 06 Feb 2005
Posts: 4957

Post (Separately) Posted: Sun Jan 22, 2012 15:55    Post subject: Reply with quote

Нужно не "общий случай", а хотя бы как. Как сделано в Akelpad. хотя бы
А навороты не нужны пока

Добавлено спустя 3 минуты:

PS. спасибо, что расписал.
_________________
UniViewer - CudaText - LogViewer
Back to top
View user's profile Send private message
Alextp



Joined: 06 Feb 2005
Posts: 4957

Post (Separately) Posted: Wed Jan 25, 2012 23:59    Post subject: Reply with quote

http://ghisler.ch/board/viewtopic.php?p=240222#240222
_________________
UniViewer - CudaText - LogViewer
Back to top
View user's profile Send private message
Chusik



Joined: 26 May 2007
Posts: 11
Location: Волгоград

Post (Separately) Posted: Fri Jan 27, 2012 17:50    Post subject: Reply with quote

Вот неплохая библиотека (исходники на delphi), может быть использована как напрямую из кода, так и в виде dll.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Total Commander Forum Index -> Написание плагинов для Total Commander All times are GMT + 4 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group