Автоматическое определение кодировки

привожу вариант объекта Delphi для автоопределения DOS/WIN кодировки, который используется в редакторе swe


unit UCode;

{*******************************************************}
{ модуль для автоопределения DOS/WINDOWS кодировки      }
{ (C) 2003 (SW) http://uafo.ru/msg/homepage/            }
{*******************************************************}

interface


type

(*========================================================*)
(* массив для подсчёта частот встречаемости символов      *)
TFreqArr = array[0..255] of integer;

(*========================================================*)
(* инструмент для анализа кодировки                       *)
TCodeAnalizer = class(TObject)
  A : TFreqArr;
  N : integer;   (* объём просканиорванных данных *)
  N_80_AF : integer;
  N_C0_FF : integer;

procedure Init; (* обнуление данных *)
procedure Run(var B;N0:integer); (* пробежать по буферу текста *)
function IsDOS:boolean;
function IsBIN:boolean;
end;



implementation

procedure TCodeAnalizer.Init; (* обнуление данных *)
var I : integer;
begin
  for I := 0 to 255 do A[I] := 0;
  N := 0;
end;

procedure TCodeAnalizer.Run(var B;N0:integer);
var I : integer;
  P : pointer;
  PB : ^byte absolute P;
begin
(* сканируем буфер *)
  P := @B;
  for I := 1 to N0 do begin
    inc(A[PB^]);
    inc(PB);
  end;

(* суммируем число встреченных символов в характерных диапазонах *)
  N_80_AF := 0; (* в этом диапазоне нет Win_Cyr - символов и 75% DOS_Cyr симв.*)
  N_C0_FF := 0; (* Wyn_Cyr диапазон (100%) и часть (C0-DF) DOS-псевдографики  *)
  for I := $80 to $AF do N_80_AF := N_80_AF + A[I];
  for I := $C0 to $FF do N_C0_FF := N_C0_FF + A[I];
end;

function TCodeAnalizer.IsDOS:boolean;
begin
(* проверяем как альтернативу друг другу DOS и Windows кодировку *)
  IsDOS := false;
  if N_80_AF = 0 then Exit; (* совсем нет символов в DOS-Cyrilic диапазоне *)
  if N_C0_FF div N_80_AF >= 5 then Exit;(*DOS-"псевдографики" слишком много *)
  IsDOS := True;
end;

function TCodeAnalizer.IsBIN:boolean;
begin
  (* в текстовых файлах не бывает символа с кодом 0 *)
  (* и более одного символа с кодом 26 (^Z)         *)
  IsBIN := (A[0] + A[26] >= 3)
end;


end.
Вернуться
(с) Можаровский С.Г. // mailto:mozharovskys@mail.ru // swHome page