219 lines
7.9 KiB
ObjectPascal
219 lines
7.9 KiB
ObjectPascal
////////////////////////////////////////////////////////////////////////////////
|
||
//
|
||
// ****************************************************************************
|
||
// * Project : FWZip
|
||
// * Unit Name : UseExDataBlob
|
||
// * Purpose : Демонстрация работы с блоками ExData
|
||
// * Author : Александр (Rouse_) Багель
|
||
// * Copyright : © Fangorn Wizards Lab 1998 - 2013.
|
||
// * Version : 1.0.10
|
||
// * Home Page : http://rouse.drkb.ru
|
||
// * Home Blog : http://alexander-bagel.blogspot.ru
|
||
// ****************************************************************************
|
||
// * Stable Release : http://rouse.drkb.ru/components.php#fwzip
|
||
// * Latest Source : https://github.com/AlexanderBagel/FWZip
|
||
// ****************************************************************************
|
||
//
|
||
// Используемые источники:
|
||
// ftp://ftp.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip
|
||
// http://zlib.net/zlib-1.2.5.tar.gz
|
||
// http://www.base2ti.com/
|
||
//
|
||
|
||
// Данный пример показывает работу с блоками ExData.
|
||
// Их добавление при создании архива и извлечение.
|
||
// Данные блоки могут содержать любые дополнительные параметры связанные
|
||
// с элементом архива. Список зарезервированных блоков см. в коментарии
|
||
// обработчика OnSaveExData.
|
||
|
||
program UseExDataBlob;
|
||
|
||
{$APPTYPE CONSOLE}
|
||
|
||
uses
|
||
SysUtils,
|
||
Classes,
|
||
FWZipWriter,
|
||
FWZipReader,
|
||
FWZipConsts;
|
||
|
||
const
|
||
TestExDataBlob: Cardinal = $DEADBEEF;
|
||
|
||
var
|
||
Writer: TFWZipWriter;
|
||
Reader: TFWZipReader;
|
||
Method: TMethod;
|
||
|
||
//
|
||
// Обработчик при помощи которого мы добавляем блок расширенных данных ExData
|
||
// к каждому элементу массива
|
||
// =============================================================================
|
||
procedure OnSaveExData(Self, Sender: TObject; ItemIndex: Integer;
|
||
UserExDataBlockCount: Integer; var Tag: Word; Data: TStream);
|
||
var
|
||
RandomValue: Cardinal;
|
||
begin
|
||
|
||
// При добавлении блока расширенных данных следует указать его Тэг и
|
||
// записать сами данные в стрим Data, при этом размер Data не может
|
||
// превысить значение MAXWORD а значение Тэг должно быть отлично от нуля.
|
||
|
||
// Данный обработчик будет вызываться до тех пор, пока вы не укажете
|
||
// что более блоков данных нет. Для этого нужно не заполнять стрим Data.
|
||
|
||
// Количество вызовов обработчика для текущего элемента можно узнать по
|
||
// переменной UserExDataBlockCount
|
||
|
||
// Обратите внимание, следующие значения тэгов зарезервированы:
|
||
|
||
{
|
||
The current Header ID mappings defined by PKWARE are:
|
||
|
||
0x0001 ZIP64 extended information extra field
|
||
0x0007 AV Info
|
||
0x0008 Reserved for future Unicode file name data (PFS)
|
||
0x0009 OS/2 extended attributes (also Info-ZIP)
|
||
0x000a NTFS (Win9x/WinNT FileTimes)
|
||
0x000c OpenVMS (also Info-ZIP)
|
||
0x000d Unix
|
||
0x000e Reserved for file stream and fork descriptors
|
||
0x000f Patch Descriptor
|
||
0x0014 PKCS#7 Store for X.509 Certificates
|
||
0x0015 X.509 Certificate ID and Signature for
|
||
individual file
|
||
0x0016 X.509 Certificate ID for Central Directory
|
||
0x0017 Strong Encryption Header
|
||
0x0018 Record Management Controls
|
||
0x0019 PKCS#7 Encryption Recipient Certificate List
|
||
0x0065 IBM S/390 (Z390), AS/400 (I400) attributes
|
||
- uncompressed
|
||
0x0066 Reserved for IBM S/390 (Z390), AS/400 (I400)
|
||
attributes - compressed
|
||
|
||
The Header ID mappings defined by Info-ZIP and third parties are:
|
||
|
||
0x07c8 Info-ZIP Macintosh (old, J. Lee)
|
||
0x2605 ZipIt Macintosh (first version)
|
||
0x2705 ZipIt Macintosh v 1.3.5 and newer (w/o full filename)
|
||
0x2805 ZipIt Macintosh 1.3.5+
|
||
0x334d Info-ZIP Macintosh (new, D. Haase's 'Mac3' field)
|
||
0x4154 Tandem NSK
|
||
0x4341 Acorn/SparkFS (David Pilling)
|
||
0x4453 Windows NT security descriptor (binary ACL)
|
||
0x4704 VM/CMS
|
||
0x470f MVS
|
||
0x4854 Theos, old inofficial port
|
||
0x4b46 FWKCS MD5 (see below)
|
||
0x4c41 OS/2 access control list (text ACL)
|
||
0x4d49 Info-ZIP OpenVMS (obsolete)
|
||
0x4d63 Macintosh SmartZIP, by Macro Bambini
|
||
0x4f4c Xceed original location extra field
|
||
0x5356 AOS/VS (binary ACL)
|
||
0x5455 extended timestamp
|
||
0x554e Xceed unicode extra field
|
||
0x5855 Info-ZIP Unix (original; also OS/2, NT, etc.)
|
||
0x6542 BeOS (BeBox, PowerMac, etc.)
|
||
0x6854 Theos
|
||
0x7441 AtheOS (AtheOS/Syllable attributes)
|
||
0x756e ASi Unix
|
||
0x7855 Info-ZIP Unix (new)
|
||
0xfb4a SMS/QDOS
|
||
}
|
||
|
||
// Для примера мы заполним три блока данных:
|
||
case UserExDataBlockCount of
|
||
0:
|
||
begin
|
||
// Выбираем незарезервированное значение тэга (например $FFFA)
|
||
Tag := $FFFA;
|
||
// и пишем сами данные
|
||
Data.WriteBuffer(TestExDataBlob, 4);
|
||
end;
|
||
1..2:
|
||
begin
|
||
// Выбираем другое незарезервированное значение тэга
|
||
Tag := $FFFB + UserExDataBlockCount;
|
||
// данные рандомные - просто для демонстрации записи двух и более полей
|
||
Randomize;
|
||
RandomValue := Random(MaxInt);
|
||
Data.WriteBuffer(RandomValue, 4);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
//
|
||
// Обработчик при помощи которого мы получаем блок расширенных данных ExData
|
||
// который не смог обработать TFWZipReader.
|
||
// Обработчик вызывается для каждого нераспознанного элемента ExData,
|
||
// количество которых не ограничено.
|
||
// Данный обработчик вызывается при вызове метода TFWZipReader.LoadFromFile
|
||
// Sender в данном обработчике является TFWZipReaderItem,
|
||
// т.е. элементом при чтении которого не распознался тэг ExData.
|
||
// =============================================================================
|
||
procedure OnLoadExData(Self, Sender: TObject; ItemIndex: Integer;
|
||
Tag: Word; Data: TStream);
|
||
var
|
||
Value: Cardinal;
|
||
begin
|
||
// так как мы знаем как нужно обрабатывать только блок данных с тэгом $FFFA
|
||
// то остальные необходимо пропустить
|
||
if Tag = $FFFA then
|
||
begin
|
||
// Для демонстрации просто проверяем совпадает ли значение в блоке с нашим
|
||
if Data.Size <> 4 then
|
||
raise Exception.Create('Неверный размер блока ExData');
|
||
Data.ReadBuffer(Value, Data.Size);
|
||
if Value <> TestExDataBlob then
|
||
raise Exception.Create('Неверное значение блока ExData');
|
||
|
||
// связать данные с элементом массива можно например используя поле Tag
|
||
TFWZipReaderItem(Sender).Tag := Integer(Value);
|
||
|
||
// вот такой вызов делать нельзя, т.к. в данный момент Sender
|
||
// находится в конструкторе и не добавлен в список элементов
|
||
// главного класса
|
||
// Reader[ItemIndex].Tag := Integer(Value); - ошибочный код
|
||
end;
|
||
end;
|
||
|
||
begin
|
||
SetCurrentDir(ExtractFilePath(ParamStr(0)));
|
||
try
|
||
Writer := TFWZipWriter.Create;
|
||
try
|
||
// Для начала добавим в корень архива файлы из корневой директории
|
||
Writer.AddFolder('', '..\..\', '*.*', False);
|
||
|
||
// Назначаем обработчик через который мы будем добавлять блок расширенных данных
|
||
Method.Code := @OnSaveExData;
|
||
Method.Data := Writer;
|
||
Writer.OnSaveExData := TZipSaveExDataEvent(Method);
|
||
|
||
// Сохраняем результат
|
||
ForceDirectories('..\DemoResults\');
|
||
Writer.BuildZip('..\DemoResults\UseExDataBlob.zip');
|
||
finally
|
||
Writer.Free;
|
||
end;
|
||
|
||
Reader := TFWZipReader.Create;
|
||
try
|
||
|
||
// Теперь наша задача получить расширенные блоки данных.
|
||
// Для этого необходимо назначить обработчик OnLoadExData
|
||
// и открыть сам архив.
|
||
Method.Code := @OnLoadExData;
|
||
Method.Data := Reader;
|
||
Reader.OnLoadExData := TZipLoadExDataEvent(Method);
|
||
Reader.LoadFromFile('..\DemoResults\UseExDataBlob.zip');
|
||
finally
|
||
Reader.Free;
|
||
end;
|
||
except
|
||
on E: Exception do
|
||
Writeln(E.ClassName, ': ', E.Message);
|
||
end;
|
||
Readln;
|
||
end.
|