системе }
function GetCodeClassName(Index: Integer): String;
{ Возвращает имя класса кода по индексу. Например,
класс кода Рида-Маллера имеет имя TRMCode }
function GetCodeName(Index: Integer): String;
{ Возвращает название кода по индексу. Т.е. результат
вызова метода GetName для соответствующего кода. }
function GetIndexOfCodeName(CodeName: String): Integer;
{ Возвращает индекс первого найденного кода название
которого совпало с заданным. Если совпадений не найдено,
то возвращается -1 }
function GetIndexOfCodeClassName(CodeClassName:
String): Integer;
{ Возвращает индекс первого найденного кода, имя класса
которого совпало с заданным. Если совпадений не
найдено, то возвращается -1 }
public
{ Свойства }
property Count: Integer read GetCount;
property CodeNames[Index: Integer]: String read GetCodeName;
property CodeClassNames[Index: Integer]: String read
GetCodeClassName;
property IndexOfCodeName[CodeName: String]: Integer read
GetIndexOfCodeName;
property IndexOfCodeClassName[CodeClassName: String]:
Integer read GetIndexOfCodeClassName;
end;
{ Функции общего назначения }
{ Вес слова (количество ненулевых бит) }
function WordWeight(const Word; Len: Integer): Integer;
{ Регистрация кода в потоковой системе.
Незарегистрированный код не может быть использован при
декодировании из потока }
procedure RegisterCode(C: TPersistentCode);
{ Удаление кода из потоковой системы }
procedure UnRegisterCode(C: TPersistentCode);
{ Проверка параметров при кодировании и декодировании }
procedure CheckEncoderParams(InStream, OutStream:
TStream; Code: TCode);
procedure CheckDecoderParams(InStream, OutStream:
TStream; Code: TCode = TCode($1));
{ Кодирование и декодирование потоков
При кодировании в выходной поток записывается
заголовок следующего содержания:
Версия - версия кодового потока
Размер входного потока в байтах
Информация о коде (сериализованный TCode)
Далее, до конца потока, следуют упакованные
кодовые слова
При декодировании, сначала анализируется заголовок.
Если в нем указана неизвестная версия то, генерируется
Исключение EDecoder. Затем происходит попытка создать
код, используя записанную в потоке информацию о нем. После
чего, начинается само декодирование }
procedure DecodeStream(InStream, OutStream: TStream);
procedure EncodeStream(InStream, OutStream: TStream;
Code: TCode);
{ Кодирование и декодирование файлов
Эти процедуры являются надстройками над DecodeStream и
EncodeStream }
procedure DecodeFile(InputFileName, OutputFileName: String);
procedure EncodeFile(InputFileName, OutputFileName: String; Code: TCode);
{ Кодирование и декодирование без заголовка
При кодировании в поток не записывается дополнительная
информация (заголовок).
Поэтому при декодировании нужно явно указывать код,
которым нужно его производить }
procedure RawDecodeStream(InStream, OutStream: TStream;
Code: TCode);
procedure RawEncodeStream(InStream, OutStream: TStream;
Code: TCode);
{ Запись заголовка в поток }
procedure WriteHeader(InStream, OutStream: TStream;
Code: TCode);
implementation
type
{ TCodeList
Этот класс хранит информацию о кодах зарегистрированных в
Потоковой системе системе }
TCodeList = class(TObject)
private
FCodeList: TClassList;
{ Список классов }
function GetCount: Integer;
{ Число элементов в списке классов }
function GetCodeClassName(Index: Integer): String;
{ Имя класса кода по индексу, например TRMCode }
function GetCodeName(Index: Integer): String;
{ Название кода по индексу, например Код Рида-Маллера }
public
constructor Create;
destructor Destroy; override;
function Add(Code: TPersistentCode): Integer;
{ Добавляет класс в список, если его там нет,
и возвращает его индекс.
Если класс уже есть, то просто возвращается его индекс }
procedure Delete(Code: TPersistentCode);
{ Удаляет класс из списка }
{ Свойства }
property Count: Integer read GetCount;
property CodeClassNames[Index: Integer]: String read
GetCodeClassName;
property CodeNames[Index: Integer]: String read GetCodeName;
end; { TCodeList }
var
CodeList: TCodeList;
{ Экземпляр класса TCodeList. Создается в секции
инициализации данного модуля. Уничтожается в секции
финализации }
Модуль содержит классы, реализующие кодирование и декодирование в отдельном потоке (thread). Эти классы используются тестовой программой для того, чтобы визуализировать результаты работы в реальном времени, а также для предоставления возможности пользователю отменить операции кодирования и декодирования.
unit CodeThreads;
interface
uses
SysUtils, Code, Forms, Classes, Windows;
const
DEF_ONPROGRESS_INTERVAL = 500;
{ интервал в миллисекундах между событиями OnProgress. Потоки (thread)
генерируют события OnProgress для того чтобы основная программа
смогла показать пользователю текущее состояние работы потока }
type
TProgressEvent = procedure(Sender: TObject;
BitsProcessed: Int64) of object;
{ Описание обработчика события OnProgress.
Sender – объект, который сгенерировал событие OnProgress
BitsProcessed - число обработанных бит }
TDecodeCodeCreateEvent = procedure(Sender: TObject;
ACode: TCode) of object;
{ Описание обработчика события OnDecodeCodeCreate.
Данное событие генерируется после того, как поток (thread) создаст
код при декодировании. Это позволяет программе получить сведения о
коде, которым были кодированы исходные данные }
{ TCustomCodecThread
Класс для кодирования и декодирования потоков с возможностью
обработки прогресса и отмены операции }
TCustomCodecThread = class(TThread)
private
FCode: TCode;
{ код, которым производится кодирование }
FDecodeCode: TCode;
{ код использующийся для декодирования, создается автоматически на
основе информации во входном потоке }
FOutStream: TStream;
{ поток вывода}
FInStream: TStream;
{ поток ввода}
FWorking: Boolean;
{ Признак того, что поток (thread) в данный момент работает }
FInterval: Cardinal;
{ Интервал в миллисекундах, через который генерируются события
OnProgress }
FBitsProcessed: Int64;
{ Число обработанных бит (при кодировании и декодировании) }
FException: Exception;
{ Хранит объект исключительной ситуации на время работы
обработчика события OnException }
FEncodeMode: Boolean;
{ Задает режим работы потока (thread).
Если истина, то кодирование. Если ложь - декодирование }
FOnException: TExceptionEvent;
{ Указатель на обработчик события OnException.
Данное событие генерируется при возникновении исключительной
ситуации во время процесса кодирования и декодирования }
FOnProgress: TProgressEvent;
{ Указатель на обработчик события OnProgress.
Событие периодически генерируется во время процессов
кодирования и декодирования }
FOnDecodeCodeCreate: TDecodeCodeCreateEvent;
{ Указатель на обработчик события OnDecodeCodeCreate }
{ Set методы для свойств класса. Большинство из
них игнорируют новые значения для свойств класса
если FWorking = True }
procedure SetCode(const Value: TCode);
procedure SetInterval(const Value: Cardinal);
procedure SetInStream(const Value: TStream);
procedure SetOutStream(const Value: TStream);
procedure SetEncodeMode(const Value: Boolean);
{ Методы вызова обработчиков событий }
procedure CallOnDecodeCodeCreate;
procedure CallOnProgress;
procedure ExceptionHandler;
protected
{ Проверка параметров перед началом кодирования
В случае обнаружения ошибки - исключение }
procedure EncodeCheck; virtual;
{ Проверка параметров перед декодированием
В случае ошибки - исключение }
procedure DecodeCheck; virtual;
{ Запись заголовочных данных (THeader и информация о коде) в
выходной поток }
procedure WriteHeaders; virtual;
{ Чтение заголовочных данных из входного потока }
procedure ReadHeaders; virtual;
{ Кодирование входного потока и его запись в выходной поток.
Наследники могут перекрывать этот метод, если хотят изменить
процесс кодирования }
procedure EncodeProc; virtual;
{ Декодирование входного потока и его запись в выходной поток.
Наследники могут перекрывать этот метод, если хотят изменить
процесс декодирования }
procedure DecodeProc; virtual;
{ Свойства класса }
property Code: TCode read FCode write SetCode;
property DecodeCode: TCode read FDecodeCode;
{ Код использующийся при декодировании.
DecodeCode <> nil только во время процесса декодирования.
После окончания декодирования снова становится равным nil }
property EncodeMode: Boolean read FEncodeMode write SetEncodeMode;
property InStream: TStream read FInStream write SetInStream;
property OutStream: TStream read FOutStream write SetOutStream;
property Working: Boolean read FWorking;
{ События }
property OnDecodeCodeCreate: TDecodeCodeCreateEvent
read FOnDecodeCodeCreate write FOnDecodeCodeCreate;
property OnProgress: TProgressEvent read FOnProgress write FOnProgress;
property Interval: Cardinal read FInterval write SetInterval;
property OnException: TExceptionEvent read FOnException
write FOnException;
public
constructor Create(AEncodeMode: Boolean = True);
procedure Execute; override;
{ Метод реализует работу потока (thread) }
end; { TCustomCodecThread }
{ TCodecThread
Наследник TCustomCodecThread. Просто публикует свойства
класса TCustomCodecThread }
TCodecThread = class(TCustomCodecThread)
public
property Code;
property EncodeMode;
property InStream;
property Interval;
property OutStream;
property OnDecodeCodeCreate;
property OnProgress;
property OnException;
end; { TEncodeThread }
{ TFileEncodeThread
Наследник TCustomCodecThread, надстройка. Позволяет сделать
кодирование и декодирование файлов проще.
Нужно указать имена исходного и целевого файлов, автоматически