lasarus_compotents/fwzip/FWZipTests.pas

2881 lines
80 KiB
ObjectPascal
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : FWZipTests
// * Purpose : Набор классов для юниттестирования FWZip
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2023.
// * Version : 2.0.2
// * 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
// https://zlib.net/zlib-1.2.13.tar.gz
// http://www.base2ti.com/
//
unit FWZipTests;
{$IFDEF FPC}
{$MODE Delphi}
{$H+}
{$ENDIF}
interface
uses
{$IFDEF FPC}
LCLIntf, LCLType, fpcunit, testregistry, FileUtil, DateUtils,
{$ELSE}
TestFramework, Windows,
{$ENDIF}
Classes, SysUtils,
FWZipStream,
FWZipWriter,
FWZipConsts,
FWZipCrc32,
FWZipZLib,
FWZipReader,
FWZipModifier,
FWZipUtils;
type
EFWZipUnitTestException = class(Exception);
{ TFWZipUnitTest }
TFWZipUnitTest = class(TTestCase)
strict private
FZipWriter: TFWZipWriter;
FZipReader: TFWZipReader;
function Reader: TFWZipReader;
function Writer: TFWZipWriter;
procedure CheckResult(Value: Integer);
procedure CheckCount(ACount, Expected: Integer);
procedure CheckSize(const FilePath: string; Expected: Int64); overload;
procedure CheckSize(ASize, Expected: Int64); overload;
procedure CheckBuildResult(Value: TBuildZipResult; Expected: TBuildZipResult = brDone);
procedure Clear;
procedure CheckReaderWidthExcept;
procedure CheckLoadReaderWidthExcept(const Path: string);
protected
procedure TearDown; override;
// Тесты преобразования времени
procedure TestDateTimeConvertion;
published
// Легкие тесты обычного архива
procedure TestBuildWithStream;
procedure TestBuildWithExistingFile;
procedure TestBuildWithExistingFile2;
procedure TestBuildWithPassword;
procedure TestBuildWithPassword1;
procedure TestMerge2Zip;
procedure TestChangeZip;
procedure TestDeleteFromZip;
procedure TestSplitZip;
procedure TestBuildWithException;
procedure TestExtractZeroSizeItem;
procedure TestFind;
{$IFNDEF WINE}
procedure TestExtractOverride;
{$ENDIF}
procedure TestExData;
// тесты стрима для мультипарт архива
procedure TestMultiStream1;
procedure TestMultiStream2;
procedure TestMultiStream3;
procedure TestMultiStream4;
procedure TestMultiStream5;
procedure TestMultiStream6;
procedure TestMultiStream7;
procedure TestMultiStream8;
procedure TestMultiStream9;
procedure TestMultiStream10;
procedure TestMultiStream11;
// Тесты для MultyPart архива
procedure TestMultyPartBuildWithStream;
procedure TestMultyPartBuildWithExistingFile;
procedure TestMultyPartBuildWithExistingFile2;
procedure TestMultyPartBuildWithPassword;
procedure TestMultyPartBuildWithPassword1;
procedure TestMultyPartMerge2Zip;
procedure TestMultyPartChangeZip;
procedure TestMultyPartDeleteFromZip;
procedure TestMultyPartSplitZip;
procedure TestMultyPartBuildWithException;
{$IFNDEF WINE}
procedure TestMultyPartExtractOverride;
{$ENDIF}
procedure TestMultyPartExData;
procedure TestMultyPartBuildSingleZip;
// Тяжелые тесты для обычного архива
procedure TestZip64_BigFiles;
procedure TestZip64_BigFilesCount;
// Тяжелые тесты для MultyPart архива
procedure TestMultyPartZip64_BigFiles;
procedure TestMultyPartZip64_BigFilesCount;
end;
implementation
uses
TypInfo;
type
TDataCount = record
Files, Folders: Integer;
end;
const
ZipName = 'test.zip';
ZipName1 = 'test1.zip';
ZipName2 = 'test2.zip';
RenamedZipName: string = 'renamed_file.txt';
TestStringBlock: array [0..2] of string = (
'Тестовый текстовый файл №1',
'Тестовый текстовый файл №2',
'Тестовый текстовый файл №3'
);
ReadLock = fmOpenRead or fmShareDenyNone;
{$IFDEF LINUX}
WriteLock = fmOpenWrite or fmShareExclusive;
{$ELSE}
WriteLock = fmOpenWrite or fmShareDenyNone;
{$ENDIF}
var
RootFolder: string
{$IFDEF CUSTOM_TEMP_FOLDER_PATH}
{$IFDEF LINUX}
//= '~/Documents/ZIP/Demos/DemoResults/'
= '/mnt/'
{$ELSE}
= 'W:\FWZip_UnitTest\'
{$ENDIF}
{$ENDIF};
_SorceFolder, _DestinationFolder: string;
TestFolderData: TStringList;
function _L(const Value: string): string; inline;
begin
Result := StringReplace(Value, '\', PathDelim, [rfReplaceAll]);
end;
function SourceFolder: string;
begin
Result := _SorceFolder;
end;
function DestinationFolder: string;
begin
Result := _DestinationFolder;
end;
procedure InitFolders;
begin
{$IFNDEF CUSTOM_TEMP_FOLDER_PATH}
{$IFDEF FPC}
RootFolder := GetTempDir;
{$ELSE}
SetLength(RootFolder, MAX_PATH);
if GetTempPath(MAX_PATH, @RootFolder[1]) = 0 then Exit;
{$ENDIF}
RootFolder := IncludeTrailingPathDelimiter(PChar(RootFolder));
{$ENDIF}
_SorceFolder := PathCanonicalize(RootFolder + _L('fwziptest\src\'));
ForceDirectories(_SorceFolder);
_DestinationFolder := PathCanonicalize(RootFolder + _L('fwziptest\dst\'));
ForceDirectoriesEx(_DestinationFolder);
TestFolderData := TStringList.Create;
TestFolderData.Add('1.txt');
TestFolderData.Add('2.txt');
TestFolderData.Add('3.txt');
TestFolderData.Add(_L('1\1.txt'));
TestFolderData.Add(_L('1\2.no_txt'));
TestFolderData.Add(_L('1\3.txt'));
TestFolderData.Add(_L('2\1.txt'));
TestFolderData.Add(_L('2\2.txt'));
TestFolderData.Add(_L('2\3.txt'));
TestFolderData.Add(_L('3\'));
TestFolderData.Add(_L('4\5\2.txt'));
TestFolderData.Add(_L('4\5\3.txt'));
TestFolderData.Add(_L('7\8\9\10\1.bin'));
TestFolderData.Add(_L('7\8\9\10\2.bin'));
end;
procedure DeleteFolder(const Path: string);
{$IFDEF FPC}
begin
DeleteDirectory(Path, False);
end;
{$ELSE}
var
SR: TSearchRec;
begin
if FindFirst(Path + '*.*', faAnyFile, SR) = 0 then
try
repeat
if SR.Name = '.' then Continue;
if SR.Name = '..' then Continue;
if DirectoryExists(Path + SR.Name) then
begin
DeleteFolder(Path + SR.Name + '\');
RemoveDirectory(PChar(Path + SR.Name));
Continue;
end;
DeleteFile(PChar(Path + SR.Name))
until FindNext(SR) <> 0;
finally
FindClose(SR);
end;
RemoveDirectory(PChar(Path));
end;
{$ENDIF}
procedure CreateFile(const Path: string);
var
I, Index: Integer;
S: TStringStream;
F: TFileStream;
begin
Index := -1;
if ExtractFileName(Path) = '1.txt' then
Index := 0;
if ExtractFileName(Path) = '2.txt' then
Index := 1;
if ExtractFileName(Path) = '3.txt' then
Index := 2;
if Index >= 0 then
begin
S := TStringStream.Create(TestStringBlock[Index]);
try
for I := 0 to 255 do
begin
S.WriteString(sLineBreak);
S.WriteString(TestStringBlock[Index]);
end;
S.SaveToFile(Path);
finally
S.Free;
end;
Exit;
end;
F := TFileStream.Create(Path, fmCreate);
try
for I := 0 to 255 do
F.Write(I, 1);
finally
F.Free;
end;
end;
function CreateTestDataInSrcFolder(const Root: string): TDataCount;
var
I: Integer;
Path: string;
begin
ZeroMemory(@Result, SizeOf(TDataCount));
for I := 0 to TestFolderData.Count - 1 do
begin
Path := Root + TestFolderData[I];
ForceDirectoriesEx(ExtractFilePath(Path));
if DirectoryExists(Path) then
begin
Inc(Result.Folders);
Continue;
end;
CreateFile(Path);
Inc(Result.Files);
end;
end;
procedure CheckFiles(const Src, Dst: string);
begin
if FileCRC32(Src) <> FileCRC32(Dst) then
raise Exception.Create('Контрольная сумма распакованного файла не сошлась');
end;
procedure CheckStream(StreamIndex: Integer; const Dst: string);
var
S: AnsiString;
begin
S := AnsiString(TestStringBlock[StreamIndex]);
if CRC32Calc(@S[1], Length(S)) <> FileCRC32(Dst) then
raise Exception.Create('Контрольная сумма распакованного файла не сошлась');
end;
procedure ClearFolder(const Path: string);
begin
DeleteFolder(Path);
ForceDirectoriesEx(Path);
end;
function GetTestFolderPath(TestIndex: Integer; SrcFolder: Boolean;
Clear: Boolean = False): string;
begin
if SrcFolder then
Result := SourceFolder
else
Result := DestinationFolder;
Result := IncludeTrailingPathDelimiter(Result + 'test_' + IntToStr(TestIndex));
if Clear then
ClearFolder(Result)
else
ForceDirectoriesEx(Result);
end;
procedure CreateLargeFile(const Path: string);
var
Buff: array of Byte;
F: TFileStream;
I, L: Integer;
MaxSize: Int64;
begin
L := MAXWORD;
SetLength(Buff{%H-}, $FFFF);
for I := 0 to L - 1 do
Buff[I] := Byte(I);
F := TFileStream.Create(Path, fmCreate);
try
MaxSize := $FFFFFFFF;
MaxSize := MaxSize + 150;
while F.Size < MaxSize do
F.WriteBuffer(Buff[0], L);
finally
F.Free;
end;
end;
procedure CreateBigFilesInFolder(const Root: string; One: Boolean = False);
begin
CreateLargeFile(Root + '1.bin');
if One then Exit;
CreateLargeFile(Root + '2.bin');
end;
procedure CreateBinFile(const Path: string);
const
D: AnsiString = 'TEST';
var
F: TFileStream;
begin
F := TFileStream.Create(Path, fmCreate);
try
F.WriteBuffer(D[1], 4);
finally
F.Free;
end;
end;
procedure CreateManyFilesInFolder(const Root: string);
var
I: Integer;
begin
for I := 0 to MAXWORD + 20 do
CreateBinFile(Root + IntToStr(I) + '.txt');
end;
procedure DeleteManyFilesInFolder(const Root: string);
var
I: Integer;
begin
for I := 0 to MAXWORD + 20 do
DeleteFile(Root + IntToStr(I) + '.txt');
end;
function GetFileSize(const Path: string): Int64;
var
F: TFileStream;
begin
F := TFileStream.Create(Path, fmShareDenyWrite);
try
Result := F.Size;
finally
F.Free;
end;
end;
function AddItem(AWriter: TFWZipWriter; const AName, AData: string): Integer;
var
S: TStringStream;
begin
S := TStringStream.Create(AData);
try
S.Position := 0;
Result := AWriter.AddStream(AName, S);
finally
S.Free;
end;
end;
{ Test_CreateZip }
procedure TFWZipUnitTest.CheckBuildResult(Value: TBuildZipResult;
Expected: TBuildZipResult);
begin
if Expected <> brDone then
begin
if Value <> Expected then
raise EFWZipUnitTestException.Create(string('Ошибка создания архива. Ожидалось ') +
GetEnumName(TypeInfo(TBuildZipResult), Integer(Expected)) +
string(', но вернулся результат ') +
GetEnumName(TypeInfo(TBuildZipResult), Integer(Value)));
end
else
if Value <> Expected then
raise EFWZipUnitTestException.Create(string('Ошибка создания архива. Result = ') +
GetEnumName(TypeInfo(TBuildZipResult), Integer(Value)));
end;
procedure TFWZipUnitTest.CheckCount(ACount, Expected: Integer);
begin
if ACount <> Expected then
raise EFWZipUnitTestException.CreateFmt(
'Неверное количество данных в архиве. Ожидалось %d по факту %d', [Expected, ACount]);
end;
procedure TFWZipUnitTest.CheckLoadReaderWidthExcept(const Path: string);
var
HasException: Boolean;
begin
HasException := False;
try
Reader.LoadFromFile(Path);
except
HasException := True;
end;
if not HasException then
raise EFWZipUnitTestException.Create('Reader.LoadFromFile не поднял ожидаемое исключения');
end;
procedure TFWZipUnitTest.CheckReaderWidthExcept;
var
HasException: Boolean;
begin
HasException := False;
try
Reader.Check;
except
HasException := True;
end;
if not HasException then
raise EFWZipUnitTestException.Create('Reader.Check не поднял ожидаемое исключения');
end;
procedure TFWZipUnitTest.CheckResult(Value: Integer);
begin
if Value < 0 then
raise EFWZipUnitTestException.Create('Ошибка добавления данных');
end;
procedure TFWZipUnitTest.CheckSize(ASize, Expected: Int64);
begin
if ASize <> Expected then
raise EFWZipUnitTestException.CreateFmt(
'Неверное количество размер архива. Ожидалось %d по факту %d',
[Expected, ASize]);
end;
procedure TFWZipUnitTest.CheckSize(const FilePath: string; Expected: Int64);
var
ASize: Int64;
begin
ASize := GetFileSize(FilePath);
if ASize <> Expected then
raise EFWZipUnitTestException.CreateFmt(
'Неверное количество размер тома архива "%s". Ожидалось %d по факту %d',
[FilePath, Expected, ASize]);
end;
procedure TFWZipUnitTest.Clear;
begin
FZipWriter.Free;
FZipWriter := TFWZipWriter.Create;
FZipReader.Free;
FZipReader := TFWZipReader.Create;
end;
function TFWZipUnitTest.Reader: TFWZipReader;
begin
Result := FZipReader;
end;
var
Method: TMethod;
hLockedFile: THandle;
procedure DropLock;
begin
FileClose(hLockedFile);
hLockedFile := 0;
end;
procedure OnException1(Self, Sender: TObject; E: Exception;
const ItemIndex: Integer; var Action: TExceptionAction;
var NewFilePath: string; NewFileData: TMemoryStream);
var
CurrentFilePath: string;
Src: THandleStream;
Dst: TFileStream;
hFile: THandle;
begin
{$IFDEF LINUX}
// с блокировкой под юниксом проблемы, поэтому пусть будет так
DropLock;
{$ENDIF}
CurrentFilePath := string(TFWZipWriter(Sender)[ItemIndex].FilePath);
NewFilePath := ChangeFileExt(CurrentFilePath, '.tmp');
hFile := FileOpen(CurrentFilePath, ReadLock);
try
Src := THandleStream.Create(hFile);
try
Dst := TFileStream.Create(NewFilePath, fmCreate);
try
Dst.CopyFrom(Src, 0);
finally
Dst.Free;
end;
finally
Src.Free;
end;
finally
FileClose(hFile);
end;
Action := eaUseNewFilePathAndDel;
end;
procedure OnException2(Self, Sender: TObject; E: Exception;
const ItemIndex: Integer; var Action: TExceptionAction;
var NewFilePath: string; NewFileData: TMemoryStream);
begin
DropLock;
Action := eaRetry;
end;
procedure OnException3(Self, Sender: TObject; E: Exception;
const ItemIndex: Integer; var Action: TExceptionAction;
var NewFilePath: string; NewFileData: TMemoryStream);
var
Src: THandleStream;
hFile: THandle;
begin
{$IFDEF LINUX}
// с блокировкой под юниксом проблемы, поэтому пусть будет так
DropLock;
{$ENDIF}
hFile := FileOpen(TFWZipWriter(Sender)[ItemIndex].FilePath, ReadLock);
try
Src := THandleStream.Create(hFile);
try
NewFileData.CopyFrom(Src, 0);
finally
Src.Free;
end;
finally
FileClose(hFile);
end;
Action := eaUseNewFileData;
end;
procedure TFWZipUnitTest.TearDown;
begin
inherited;
FreeAndNil(FZipWriter);
FreeAndNil(FZipReader);
end;
procedure TFWZipUnitTest.TestDateTimeConvertion;
var
ConstDateTime, CheckDateTimeValue: TDateTime;
F: TFileTime;
FileDate: Cardinal;
begin
{$MESSAGE 'Этот тест завязан на UTC и пока что отключен'}
// нужно в цикле менять локальный часовой пояс и проверять уже по локальным значениям
// сейчас цифры актуальны только для Бишкека UTC +6
PUInt64(@ConstDateTime)^ := 4675509705865876384; // '11.02.2005 10:40:12'
F := DateTimeToFileTime(ConstDateTime);
CheckEquals(F.dwLowDateTime, 3318603264, 'DateTimeToFileTime failed');
CheckEquals(F.dwHighDateTime, 29691891, 'DateTimeToFileTime failed');
CheckDateTimeValue := FileTimeToLocalDateTime(F);
CheckEquals(PUInt64(@ConstDateTime)^, PUInt64(@CheckDateTimeValue)^, 'FileTimeToLocalDateTime failed');
FileDate := FileTimeToLocalFileDate(F);
CheckEquals(FileDate, 843797766, 'FileTimeToLocalFileDate failed');
end;
procedure TFWZipUnitTest.TestBuildWithException;
var
SrcFolder, DstFolder, DstFile: string;
begin
Clear;
SrcFolder := GetTestFolderPath(9, True, True);
DstFolder := GetTestFolderPath(9, False, True);
DstFile := DstFolder + ZipName;
CreateTestDataInSrcFolder(SrcFolder);
// лочим один из файлов для демонстрации
Writer.AddFile(SrcFolder + TestFolderData[0]);
hLockedFile := FileOpen(SrcFolder + TestFolderData[0], WriteLock);
try
CheckBuildResult(Writer.BuildZip(DstFile), brFailed);
// теперь добавляем еще один не залоченый
DeleteFile(DstFile);
Writer.AddFile(SrcFolder + TestFolderData[1]);
CheckBuildResult(Writer.BuildZip(DstFile), brPartialBuild);
finally
FileClose(hLockedFile);
end;
// а теперь должно быть нормально
DeleteFile(DstFile);
CheckCount(Writer.Count, 2);
CheckBuildResult(Writer.BuildZip(DstFile));
Reader.LoadFromFile(DstFile);
Reader.Check;
Clear;
Writer.AddFile(SrcFolder + TestFolderData[0]);
hLockedFile := FileOpen(SrcFolder + TestFolderData[0], WriteLock);
try
// Назначаем обработчик через который мы будем обрабатывать ошибку
// В обработчике OnException1 будет создаваться копия файла
Method.Code := @OnException1;
Method.Data := Writer;
Writer.OnException := TZipBuildExceptionEvent(Method);
CheckBuildResult(Writer.BuildZip(DstFile));
finally
FileClose(hLockedFile);
end;
Clear;
Writer.AddFile(SrcFolder + TestFolderData[0]);
hLockedFile := FileOpen(SrcFolder + TestFolderData[0], WriteLock);
try
// снимаем исскуственную блокировку файла и выставляем
// свойство Action в eaRetry
Method.Code := @OnException2;
Method.Data := Writer;
Writer.OnException := TZipBuildExceptionEvent(Method);
CheckBuildResult(Writer.BuildZip(DstFile));
finally
FileClose(hLockedFile);
end;
Clear;
Writer.AddFile(SrcFolder + TestFolderData[0]);
hLockedFile := FileOpen(SrcFolder + TestFolderData[0], WriteLock);
try
// загружаем данные через стрим
Method.Code := @OnException3;
Method.Data := Writer;
Writer.OnException := TZipBuildExceptionEvent(Method);
CheckBuildResult(Writer.BuildZip(DstFile));
finally
FileClose(hLockedFile);
end;
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestBuildWithExistingFile;
var
Count: TDataCount;
SrcFolder, DstFolder, SrcFile, DstFile: string;
I: Integer;
begin
Clear;
SrcFolder := GetTestFolderPath(2, True, True);
Count := CreateTestDataInSrcFolder(SrcFolder);
if Writer.AddFolder(SrcFolder, True) <> Count.Files then
raise EFWZipUnitTestException.Create('Ошибка инициализации архива. Неверное количество добавленных файлов');
CheckBuildResult(Writer.BuildZip(SrcFolder + ZipName));
DstFolder := GetTestFolderPath(2, False, True);
Reader.LoadFromFile(SrcFolder + ZipName);
Reader.Check;
Reader.ExtractAll(DstFolder);
for I := 0 to TestFolderData.Count - 1 do
begin
SrcFile := _L(SrcFolder + TestFolderData[I]);
DstFile := _L(DstFolder + 'test_2\' + TestFolderData[I]);
if DirectoryExists(SrcFile) then Continue;
CheckFiles(SrcFile, DstFile);
end;
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestBuildWithExistingFile2;
var
SrcFolder, DstFolder: string;
SrcFile, DstFile, Ext: string;
I: Integer;
begin
Clear;
SrcFolder := GetTestFolderPath(3, True, True);
CreateTestDataInSrcFolder(SrcFolder);
if Writer.AddFolder('AddFolderDemo', SrcFolder, '*.bin;*.no_txt', True) <> 3 then
raise EFWZipUnitTestException.Create('Ошибка инициализации архива. Неверное количество добавленных файлов');
CheckBuildResult(Writer.BuildZip(SrcFolder + ZipName));
DstFolder := GetTestFolderPath(3, False, True);
Reader.LoadFromFile(SrcFolder + ZipName);
Reader.Check;
Reader.ExtractAll(DstFolder);
for I := 0 to TestFolderData.Count - 1 do
begin
SrcFile := _L(SrcFolder + TestFolderData[I]);
DstFile := _L(DstFolder + 'AddFolderDemo\' + TestFolderData[I]);
Ext := ExtractFileExt(DstFile);
if (Ext <> '.no_txt') and ((Ext <> '.bin')) then Continue;
CheckFiles(SrcFile, DstFile);
end;
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
procedure OnPassword(Self, Sender: TObject; const FileName: string;
var Password: string; var CancelExtract: Boolean);
begin
Password := 'password2';
end;
procedure TFWZipUnitTest.TestBuildWithPassword;
var
Count: TDataCount;
SrcFolder, DstFolder, SrcFile, DstFile: string;
I: Integer;
Item: TFWZipWriterItem;
begin
Clear;
SrcFolder := GetTestFolderPath(4, True, True);
Count := CreateTestDataInSrcFolder(SrcFolder);
Writer.AlwaysAddEmptyFolder := True;
if Writer.AddFolder(SrcFolder, True) <> Count.Files then
raise EFWZipUnitTestException.Create('Ошибка инициализации архива. Неверное количество добавленных файлов/папок');
// Сначала ставим пароли всем элементам включая папки (что делать нельзя)
for I := 0 to Writer.Count - 1 do
begin
Item := Writer[I];
// Изменим коментарий
Item.Comment := string('Тестовый коментарий к файлу ') + Item.FileName;
// Установим пароль
Item.Password := 'password' + IntToStr(Byte(I mod 3));
// Изменим тип сжатия
Item.CompressionLevel := TCompressionLevel(Byte(I mod 3));
end;
CheckBuildResult(Writer.BuildZip(SrcFolder + ZipName));
// архив должен открыться корретно
Reader.LoadFromFile(SrcFolder + ZipName);
CheckCount(Reader.Count, 23);
Reader.Clear;
DeleteFile(SrcFolder + ZipName);
// теперь скинем пароли с папок
for I := 0 to Writer.Count - 1 do
begin
Item := Writer[I];
if Item.IsFolder then
begin
Item.Password := '';
Item.CompressionLevel := clNone;
end;
end;
// теперь сбилдится должно успешно
CheckBuildResult(Writer.BuildZip(SrcFolder + ZipName));
Reader.LoadFromFile(SrcFolder + ZipName);
CheckCount(Reader.Count, 23);
CheckReaderWidthExcept; // без пароля обязано зарайзиться
Reader.PasswordList.Add('password0');
Reader.PasswordList.Add('password1');
CheckReaderWidthExcept; // без отстутсвующего пароля обязано зарайзиться
Method.Code := @OnPassword;
Method.Data := Reader;
Reader.OnPassword := TZipNeedPasswordEvent(Method);
Reader.Check; // повторная проверка, теперь все пароли должны быть на месте
DstFolder := GetTestFolderPath(4, False, True);
Reader.ExtractAll(DstFolder);
for I := 0 to TestFolderData.Count - 1 do
begin
SrcFile := _L(SrcFolder + TestFolderData[I]);
DstFile := _L(DstFolder + 'test_4\' + TestFolderData[I]);
if DirectoryExists(SrcFile) then Continue;
CheckFiles(SrcFile, DstFile);
end;
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestBuildWithPassword1;
var
Count: TDataCount;
SrcFolder, DstFolder, SrcFile, DstFile: string;
I: Integer;
Item: TFWZipWriterItem;
begin
Clear;
SrcFolder := GetTestFolderPath(41, True, True);
Count := CreateTestDataInSrcFolder(SrcFolder);
Writer.AlwaysAddEmptyFolder := True;
if Writer.AddFolder(SrcFolder, True) <> Count.Files then
raise EFWZipUnitTestException.Create('Ошибка инициализации архива. Неверное количество добавленных файлов/папок');
// Сначала ставим пароли всем элементам включая папки
for I := 0 to Writer.Count - 1 do
begin
Item := Writer[I];
// Изменим коментарий
Item.Comment := string('Тестовый коментарий к файлу ') + Item.FileName;
// Установим пароль
Item.Password := 'password' + IntToStr(Byte(I mod 3));
// Вместе с дескриптором
Item.NeedDescriptor := True;
// Изменим тип сжатия
Item.CompressionLevel := TCompressionLevel(Byte(I mod 3));
end;
CheckBuildResult(Writer.BuildZip(SrcFolder + ZipName));
// архив должен открыться корретно
Reader.LoadFromFile(SrcFolder + ZipName);
CheckCount(Reader.Count, 23);
Reader.Clear;
DeleteFile(SrcFolder + ZipName);
// теперь скинем пароли с папок
for I := 0 to Writer.Count - 1 do
begin
Item := Writer[I];
if Item.IsFolder then
begin
Item.Password := '';
Item.NeedDescriptor := False;
Item.CompressionLevel := clNone;
end;
end;
CheckBuildResult(Writer.BuildZip(SrcFolder + ZipName));
Reader.LoadFromFile(SrcFolder + ZipName);
CheckCount(Reader.Count, 23);
CheckReaderWidthExcept; // без пароля обязано зарайзиться
Reader.PasswordList.Add('password0');
Reader.PasswordList.Add('password1');
CheckReaderWidthExcept; // без отстутсвующего пароля обязано зарайзиться
Method.Code := @OnPassword;
Method.Data := Reader;
Reader.OnPassword := TZipNeedPasswordEvent(Method);
Reader.Check; // повторная проверка, теперь все пароли должны быть на месте
DstFolder := GetTestFolderPath(41, False, True);
Reader.ExtractAll(DstFolder);
for I := 0 to TestFolderData.Count - 1 do
begin
SrcFile := _L(SrcFolder + TestFolderData[I]);
DstFile := _L(DstFolder + 'test_41\' + TestFolderData[I]);
if DirectoryExists(SrcFile) then Continue;
CheckFiles(SrcFile, DstFile);
end;
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestBuildWithStream;
var
S: TStringStream;
ItemIndex: Integer;
SrcFolder, DstFolder: string;
begin
Clear;
ItemIndex := AddItem(Writer, 'test.txt', TestStringBlock[0]);
CheckResult(ItemIndex);
Writer.Item[ItemIndex].Comment := TestStringBlock[2];
S := TStringStream.Create(TestStringBlock[1]);
S.Position := 0;
ItemIndex := Writer.AddStream('test2.txt', S, soOwned);
CheckResult(ItemIndex);
S := TStringStream.Create(TestStringBlock[0]);
S.Position := 0;
ItemIndex := Writer.InsertStream('test0.txt', 0, S, soOwned);
CheckResult(ItemIndex);
CheckResult(AddItem(Writer,
_L('AddStreamData\SubFolder1\Subfolder2\Test.txt'), TestStringBlock[2]));
SrcFolder := GetTestFolderPath(1, True, True);
CheckBuildResult(Writer.BuildZip(SrcFolder + ZipName));
Reader.LoadFromFile(SrcFolder + ZipName);
Reader.Check;
DstFolder := GetTestFolderPath(1, False, True);
Reader.ExtractAll(DstFolder);
CheckStream(0, DstFolder + 'test.txt');
CheckStream(0, DstFolder + 'test0.txt');
CheckStream(1, DstFolder + 'test2.txt');
CheckStream(2, _L(DstFolder + 'AddStreamData\SubFolder1\Subfolder2\Test.txt'));
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestChangeZip;
var
SrcFolder, DstFolder: string;
Modifier: TFWZipModifier;
Index: TReaderIndex;
begin
Clear;
SrcFolder := GetTestFolderPath(6, True, True);
CreateTestDataInSrcFolder(SrcFolder);
Writer.AddFile(SrcFolder + TestFolderData[0]);
Writer.AddFile(SrcFolder + TestFolderData[1]);
Writer.AddFile(SrcFolder + TestFolderData[2]);
CheckBuildResult(Writer.BuildZip(SrcFolder + ZipName));
DstFolder := GetTestFolderPath(6, False, True);
Modifier := TFWZipModifier.Create;
try
Index := Modifier.AddZipFile(SrcFolder + ZipName);
Modifier.AddFromZip(Index, TestFolderData[0]);
Modifier.AddFromZip(Index, TestFolderData[1], RenamedZipName);
Modifier.AddFile(SrcFolder + TestFolderData[12]);
Modifier.AddFromZip(Index, TestFolderData[2]);
CheckCount(Modifier.Count, 4);
CheckBuildResult(Modifier.BuildZip(DstFolder + ZipName));
finally
Modifier.Free;
end;
Reader.LoadFromFile(DstFolder + ZipName);
Reader.Check;
Reader.ExtractAll(DstFolder);
CheckFiles(SrcFolder + TestFolderData[0], DstFolder + TestFolderData[0]);
CheckFiles(SrcFolder + TestFolderData[1], DstFolder + RenamedZipName);
CheckFiles(SrcFolder + TestFolderData[2], DstFolder + TestFolderData[2]);
CheckFiles(SrcFolder + TestFolderData[12],
DstFolder + ExtractFileName(TestFolderData[12]));
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestDeleteFromZip;
var
SrcFolder, DstFolder: string;
Modifier: TFWZipModifier;
Index: TReaderIndex;
begin
Clear;
SrcFolder := GetTestFolderPath(7, True, True);
CreateTestDataInSrcFolder(SrcFolder);
Writer.AddFile(SrcFolder + TestFolderData[0]);
Writer.AddFile(SrcFolder + TestFolderData[1]);
Writer.AddFile(SrcFolder + TestFolderData[2]);
CheckBuildResult(Writer.BuildZip(SrcFolder + ZipName));
DstFolder := GetTestFolderPath(7, False, True);
Modifier := TFWZipModifier.Create;
try
Index := Modifier.AddZipFile(SrcFolder + ZipName);
Modifier.AddFromZip(Index);
Modifier.DeleteItem(0);
CheckCount(Modifier.Count, 2);
CheckBuildResult(Modifier.BuildZip(DstFolder + ZipName));
finally
Modifier.Free;
end;
Reader.LoadFromFile(DstFolder + ZipName);
Reader.Check;
Reader.ExtractAll(DstFolder);
CheckFiles(SrcFolder + TestFolderData[1], DstFolder + TestFolderData[1]);
CheckFiles(SrcFolder + TestFolderData[2], DstFolder + TestFolderData[2]);
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
var
NewFilePath: TStringList;
procedure OnDuplicate(Self, Sender: TObject;
var Path: string; var Action: TDuplicateAction);
var
OldPath: string;
begin
OldPath := Path;
Path := MakeUniqueName(Path);
NewFilePath.Add(OldPath + '=' + Path);
Action := daUseNewFilePath;
end;
const
TestExDataBlob: Cardinal = $DEADBEEF;
procedure OnSaveExData(Self, Sender: TObject; ItemIndex: Integer;
UserExDataBlockCount: Integer; var Tag: Word; Data: TStream);
var
{%H-}RandomValue: Cardinal;
begin
case UserExDataBlockCount of
0:
begin
Tag := $FFFA;
Data.WriteBuffer(TestExDataBlob, 4);
end;
1..2:
begin
Tag := $FFFB + UserExDataBlockCount;
Randomize;
RandomValue := Random(MaxInt);
Data.WriteBuffer(RandomValue, 4);
end;
end;
end;
procedure OnLoadExData(Self, Sender: TObject; ItemIndex: Integer;
Tag: Word; Data: TStream);
var
Value: Cardinal;
begin
if Tag = $FFFA then
begin
if Data.Size <> 4 then
raise Exception.Create('Неверный размер блока ExData');
Value := 0;
Data.ReadBuffer(Value, Data.Size);
if Value <> TestExDataBlob then
raise Exception.Create('Неверное значение блока ExData');
TFWZipReaderItem(Sender).Tag := Integer(Value);
end;
end;
procedure TFWZipUnitTest.TestExData;
var
SrcFolder, DstFolder, SrcFile, DstFile: string;
I: Integer;
begin
Clear;
SrcFolder := GetTestFolderPath(12, True, True);
CreateTestDataInSrcFolder(SrcFolder);
Writer.AddFolder('', SrcFolder, '*.*', True);
Method.Code := @OnSaveExData;
Method.Data := Writer;
Writer.OnSaveExData := TZipSaveExDataEvent(Method);
CheckBuildResult(Writer.BuildZip(SrcFolder + ZipName));
DstFolder := GetTestFolderPath(12, False, True);
Method.Code := @OnLoadExData;
Method.Data := Reader;
Reader.OnLoadExData := TZipLoadExDataEvent(Method);
Reader.LoadFromFile(SrcFolder + ZipName);
Reader.Check;
Reader.ExtractAll(DstFolder);
for I := 0 to TestFolderData.Count - 1 do
begin
SrcFile := SrcFolder + TestFolderData[I];
DstFile := DstFolder + TestFolderData[I];
if DirectoryExists(SrcFile) then Continue;
CheckFiles(SrcFile, DstFile);
end;
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
{$IFNDEF WINE}
procedure TFWZipUnitTest.TestExtractOverride;
var
SrcFolder, DstFolder, SrcFile, DstFile: string;
I, A: Integer;
begin
Clear;
SrcFolder := GetTestFolderPath(10, True, True);
CreateTestDataInSrcFolder(SrcFolder);
Writer.AddFolder(SrcFolder);
CheckBuildResult(Writer.BuildZip(SrcFolder + ZipName));
DstFolder := GetTestFolderPath(10, False, True);
Reader.LoadFromFile(SrcFolder + ZipName);
Reader.Check;
Reader.ExtractAll(DstFolder);
Method.Code := @OnDuplicate;
Method.Data := Reader;
Reader.OnDuplicate := TZipDuplicateEvent(Method);
NewFilePath := TStringList.Create;
try
Reader.ExtractAll(DstFolder);
for I := 0 to TestFolderData.Count - 1 do
begin
SrcFile := _L(SrcFolder + TestFolderData[I]);
DstFile := _L(DstFolder + 'test_10\' + TestFolderData[I]);
if DirectoryExists(SrcFile) then Continue;
CheckFiles(SrcFile, DstFile);
A := NewFilePath.IndexOfName(_L(DstFolder + 'test_10\' + TestFolderData[I]));
CheckFiles(SrcFile, NewFilePath.ValueFromIndex[A]);
end;
finally
NewFilePath.Free;
end;
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
{$ENDIF}
procedure TFWZipUnitTest.TestExtractZeroSizeItem;
var
M: TMemoryStream;
ItemIndex: Integer;
SrcFolder: string;
begin
Clear;
SrcFolder := GetTestFolderPath(10, True, True) + 'test.txt';
M := TMemoryStream.Create;
try
M.SaveToFile(SrcFolder);
ItemIndex := Writer.AddFile(SrcFolder);
CheckResult(ItemIndex);
ItemIndex := Writer.AddFile(SrcFolder);
CheckResult(ItemIndex);
Writer.Item[ItemIndex].CompressionLevel := clNone;
CheckBuildResult(Writer.BuildZip(M));
M.Position := 0;
Reader.LoadFromStream(M);
Reader.Check;
finally
M.Free;
end;
Clear;
DeleteFolder(SrcFolder);
end;
procedure TFWZipUnitTest.TestFind;
const
FileName = 'test.txt';
procedure Check(Value: Boolean; const Caption: string);
begin
if not Value then
raise Exception.Create(string('Ошибка при поиске: ') + Caption);
end;
var
wi: TFWZipWriterItem;
ri: TFWZipReaderItem;
Modifier: TFWZipModifier;
M: TMemoryStream;
ReaderIndex: Integer;
begin
Clear;
AddItem(Writer, FileName, TestStringBlock[0]);
Check(Writer.Find(FileName, wi), 'Writer.Find ignore case');
Check(Assigned(wi), 'Writer.Find ignore case, item is nil');
Check(Writer.Find(FileName, wi, False), 'Writer.Find NO ignore case');
Check(Assigned(wi), 'Writer.Find NO ignore case, item is nil');
Check(Writer.Find(UpperCase(FileName), wi), 'Writer.Find UP CASE ignore case');
Check(Assigned(wi), 'Writer.Find UP CASE ignore case, item is nil');
Check(not Writer.Find(UpperCase(FileName), wi, False), 'Writer.Find UP CASE NO ignore case');
Check(wi = nil, 'Writer.Find UP CASE NO ignore case, item is nil');
M := TMemoryStream.Create;
try
Writer.BuildZip(M);
M.Position := 0;
Reader.LoadFromStream(M);
Check(Reader.Find(FileName, ri), 'Reader.Find ignore case');
Check(Assigned(ri), 'Reader.Find ignore case, item is nil');
Check(Reader.Find(FileName, ri, False), 'Reader.Find NO ignore case');
Check(Assigned(ri), 'Reader.Find NO ignore case, item is nil');
Check(Reader.Find(UpperCase(FileName), ri), 'Reader.Find UP CASE ignore case');
Check(Assigned(ri), 'Reader.Find UP CASE ignore case, item is nil');
Check(not Reader.Find(UpperCase(FileName), ri, False), 'Reader.Find UP CASE NO ignore case');
Check(not Assigned(ri), 'Reader.Find UP CASE NO ignore case, item is nil');
Modifier := TFWZipModifier.Create;
try
M.Position := 0;
ReaderIndex := Modifier.AddZipFile(M);
Modifier.AddFromZip(ReaderIndex);
Check(Modifier.Find(FileName, wi), 'Modifier.Find ignore case');
Check(Assigned(wi), 'Modifier.Find ignore case, item is nil');
Check(Modifier.Find(FileName, wi, False), 'Modifier.Find NO ignore case');
Check(Assigned(wi), 'Modifier.Find NO ignore case, item is nil');
Check(Modifier.Find(UpperCase(FileName), wi), 'Modifier.Find UP CASE ignore case');
Check(Assigned(wi), 'Modifier.Find UP CASE ignore case, item is nil');
Check(not Modifier.Find(UpperCase(FileName), wi, False), 'Modifier.Find UP CASE NO ignore case');
Check(wi = nil, 'Modifier.Find UP CASE NO ignore case, item is nil');
finally
Modifier.Free;
end;
finally
M.Free;
end;
Clear;
end;
procedure TFWZipUnitTest.TestMerge2Zip;
var
SrcFolder, DstFolder: string;
Modifier: TFWZipModifier;
Index1, Index2: TReaderIndex;
begin
Clear;
SrcFolder := GetTestFolderPath(5, True, True);
CreateTestDataInSrcFolder(SrcFolder);
Writer.AddFile(SrcFolder + TestFolderData[1]);
CheckBuildResult(Writer.BuildZip(SrcFolder + ZipName1));
Clear;
Writer.AddFile(SrcFolder + TestFolderData[2]);
CheckBuildResult(Writer.BuildZip(SrcFolder + ZipName2));
DstFolder := GetTestFolderPath(5, False, True);
Modifier := TFWZipModifier.Create;
try
Index1 := Modifier.AddZipFile(SrcFolder + ZipName1);
Index2 := Modifier.AddZipFile(SrcFolder + ZipName2);
Modifier.AddFromZip(Index1);
Modifier.AddFromZip(Index2);
CheckCount(Modifier.Count, 2);
CheckBuildResult(Modifier.BuildZip(DstFolder + ZipName));
finally
Modifier.Free;
end;
Reader.LoadFromFile(DstFolder + ZipName);
Reader.Check;
Reader.ExtractAll(DstFolder);
CheckFiles(SrcFolder + TestFolderData[1], DstFolder + TestFolderData[1]);
CheckFiles(SrcFolder + TestFolderData[2], DstFolder + TestFolderData[2]);
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultiStream1;
var
DstFolder: string;
F: TFWFileMultiStream;
begin
DstFolder := GetTestFolderPath(13, False, True);
F := TFWFileMultiStream.CreateWrite(DstFolder + ZipName, 100);
try
F.Size := 250;
finally
F.Free;
end;
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z01'), 100);
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z02'), 100);
CheckSize(DstFolder + ZipName, 50);
Clear;
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultiStream10;
var
DstFolder: string;
F: TFWFileMultiStream;
I: Integer;
Buff: array of Byte;
begin
DstFolder := GetTestFolderPath(22, False, True);
SetLength(Buff{%H-}, 400);
for I := 0 to 399 do
Buff[I] := Byte(I);
F := TFWFileMultiStream.CreateWrite(DstFolder + ZipName, 100);
try
F.WriteBuffer(Buff[0], 250);
CheckCount(F.Size, 250);
F.StartNewVolume;
F.WriteBuffer(Buff[300], 4);
F.Position := 240;
F.WriteBuffer(Buff[240], 95);
CheckCount(F.Size, 335);
finally
F.Free;
end;
Clear;
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultiStream11;
var
DstFolder: string;
F: TFWFileMultiStream;
I: Integer;
Buff, CheckBuff: array of Byte;
begin
DstFolder := GetTestFolderPath(22, False, True);
SetLength(Buff{%H-}, 400);
for I := 0 to 399 do
Buff[I] := Byte(I);
F := TFWFileMultiStream.CreateWrite(DstFolder + ZipName, 100);
try
F.WriteBuffer(Buff[0], 250);
CheckCount(F.Size, 250);
F.StartNewVolume;
F.WriteBuffer(Buff[300], 4); // новый том
F.Position := 240;
F.WriteBuffer(Buff[240], 95); // запись с накладкой на новый том
CheckCount(F.Size, 335);
F.StartNewVolume;
F.Position := 250;
F.WriteBuffer(Buff[250], 60);
CheckCount(F.Size, 335);
F.Position := 332;
F.WriteBuffer(Buff[332], 50);
CheckCount(F.Size, 382);
F.StartNewVolume;
F.StartNewVolume;
F.WriteBuffer(Buff[300], 4);
F.StartNewVolume;
F.StartNewVolume;
F.Position := 300;
F.WriteBuffer(Buff[300], 100);
CheckCount(F.Size, 404);
finally
F.Free;
end;
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z01'), 100);
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z02'), 100);
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z03'), 100);
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z04'), 100);
CheckSize(DstFolder + ZipName, 4);
F := TFWFileMultiStream.CreateRead(DstFolder + ZipName, rsmFull);
try
SetLength(CheckBuff{%H-}, F.Size);
F.Position := 0;
F.ReadBuffer(CheckBuff[0], F.Size);
finally
F.Free;
end;
if not CompareMem(@Buff[0], @CheckBuff[0], 400) then
raise EFWZipUnitTestException.Create('Прочитаны неверные данные');
Clear;
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultiStream2;
var
DstFolder: string;
F: TFWFileMultiStream;
begin
DstFolder := GetTestFolderPath(14, False, True);
F := TFWFileMultiStream.CreateWrite(DstFolder + ZipName);
try
F.Size := 250;
F.Size := 10;
if F.Size <> 10 then
raise EFWZipUnitTestException.Create('Размер архива должен быть равен 10');
finally
F.Free;
end;
CheckSize(DstFolder + ZipName, 10);
if FileExists(DstFolder + ChangeFileExt(ZipName, '.z01')) then
raise EFWZipUnitTestException.Create('Остался лишний том архива z01');
if FileExists(DstFolder + ChangeFileExt(ZipName, '.z02')) then
raise EFWZipUnitTestException.Create('Остался лишний том архива z02');
Clear;
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultiStream3;
var
DstFolder: string;
F: TFWFileMultiStream;
begin
DstFolder := GetTestFolderPath(15, False, True);
F := TFWFileMultiStream.CreateWrite(DstFolder + ZipName, 100);
try
F.Size := 250;
F.Position := 250;
F.StartNewVolume;
F.Size := 310;
F.Size := 315;
F.Position := 315;
F.StartNewVolume;
F.Size := 400;
finally
F.Free;
end;
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z01'), 100);
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z02'), 100);
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z03'), 50);
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z04'), 65);
CheckSize(DstFolder + ZipName, 85);
Clear;
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultiStream4;
var
DstFolder: string;
F: TFWFileMultiStream;
Buff, CheckBuff: array of Byte;
I: Integer;
begin
DstFolder := GetTestFolderPath(16, False, True);
SetLength(Buff{%H-}, 400);
for I := 0 to 399 do
Buff[I] := Byte(I);
F := TFWFileMultiStream.CreateWrite(DstFolder + ZipName, 100);
try
F.WriteBuffer(Buff[0], 250);
F.StartNewVolume;
F.WriteBuffer(Buff[250], 60);
F.StartNewVolume;
F.WriteBuffer(Buff[310], 90);
finally
F.Free;
end;
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z01'), 100);
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z02'), 100);
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z03'), 50);
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z04'), 60);
CheckSize(DstFolder + ZipName, 90);
F := TFWFileMultiStream.CreateRead(DstFolder + ZipName, rsmFull);
try
SetLength(CheckBuff{%H-}, F.Size);
F.Position := 0;
F.ReadBuffer(CheckBuff[0], F.Size);
finally
F.Free;
end;
if not CompareMem(@Buff[0], @CheckBuff[0], 400) then
raise EFWZipUnitTestException.Create('Прочитаны неверные данные');
Clear;
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultiStream5;
var
DstFolder: string;
F: TFWFileMultiStream;
Buff, CheckBuff: array of Byte;
I: Integer;
begin
DstFolder := GetTestFolderPath(17, False, True);
SetLength(Buff{%H-}, 400);
for I := 0 to 399 do
Buff[I] := Byte(I);
F := TFWFileMultiStream.CreateWrite(DstFolder + ZipName, 100);
try
F.WriteBuffer(Buff[0], 250);
F.WriteBuffer(Buff[250], 60);
F.WriteBuffer(Buff[310], 90);
finally
F.Free;
end;
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z01'), 100);
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z02'), 100);
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z03'), 100);
CheckSize(DstFolder + ZipName, 100);
F := TFWFileMultiStream.CreateRead(DstFolder + ZipName, rsmFull);
try
SetLength(CheckBuff{%H-}, F.Size);
F.Position := 0;
F.ReadBuffer(CheckBuff[0], F.Size);
finally
F.Free;
end;
if not CompareMem(@Buff[0], @CheckBuff[0], 400) then
raise EFWZipUnitTestException.Create('Прочитаны неверные данные');
Clear;
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultiStream6;
var
DstFolder: string;
F: TFWFileMultiStream;
Buff, CheckBuff: array of Byte;
I: Integer;
begin
DstFolder := GetTestFolderPath(18, False, True);
SetLength(Buff{%H-}, 400);
for I := 0 to 399 do
Buff[I] := Byte(I);
F := TFWFileMultiStream.CreateWrite(DstFolder + ZipName, 100);
try
F.WriteBuffer(Buff[0], 250);
F.Position := 240;
F.WriteBuffer(Buff[240], 95);
F.Position := 250;
F.WriteBuffer(Buff[250], 60);
F.Position := 300;
F.WriteBuffer(Buff[300], 100);
finally
F.Free;
end;
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z01'), 100);
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z02'), 100);
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z03'), 100);
CheckSize(DstFolder + ZipName, 100);
F := TFWFileMultiStream.CreateRead(DstFolder + ZipName, rsmFull);
try
SetLength(CheckBuff{%H-}, F.Size);
F.Position := 0;
F.ReadBuffer(CheckBuff[0], F.Size);
finally
F.Free;
end;
if not CompareMem(@Buff[0], @CheckBuff[0], 400) then
raise EFWZipUnitTestException.Create('Прочитаны неверные данные');
Clear;
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultiStream7;
var
DstFolder: string;
F: TFWFileMultiStream;
Buff, CheckBuff: array of Byte;
I: Integer;
begin
DstFolder := GetTestFolderPath(19, False, True);
SetLength(Buff{%H-}, 400);
for I := 0 to 399 do
Buff[I] := Byte(I);
F := TFWFileMultiStream.CreateWrite(DstFolder + ZipName, 100);
try
F.WriteBuffer(Buff[0], 250);
CheckSize(F.Size, 250);
F.Position := 240;
F.WriteBuffer(Buff[240], 95);
CheckSize(F.Size, 335);
F.Position := 250;
F.WriteBuffer(Buff[250], 60);
CheckSize(F.Size, 335);
F.Position := 332;
F.WriteBuffer(Buff[332], 60);
CheckSize(F.Size, 392);
F.Position := 300;
F.WriteBuffer(Buff[300], 100);
CheckSize(F.Size, 400);
finally
F.Free;
end;
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z01'), 100);
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z02'), 100);
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z03'), 100);
CheckSize(DstFolder + ZipName, 100);
F := TFWFileMultiStream.CreateRead(DstFolder + ZipName, rsmFull);
try
SetLength(CheckBuff{%H-}, F.Size);
F.Position := 0;
F.ReadBuffer(CheckBuff[0], F.Size);
finally
F.Free;
end;
if not CompareMem(@Buff[0], @CheckBuff[0], 400) then
raise EFWZipUnitTestException.Create('Прочитаны неверные данные');
Clear;
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultiStream8;
var
DstFolder: string;
F: TFWFileMultiStream;
I: Integer;
Buff, CheckBuff: array of Byte;
begin
DstFolder := GetTestFolderPath(20, False, True);
SetLength(Buff{%H-}, 400);
for I := 0 to 399 do
Buff[I] := Byte(I);
F := TFWFileMultiStream.CreateWrite(DstFolder + ZipName, 100);
try
F.WriteBuffer(Buff[0], 250);
CheckCount(F.Size, 250);
F.StartNewVolume;
F.Position := 240;
F.WriteBuffer(Buff[240], 95);
CheckCount(F.Size, 335);
F.Position := 250;
F.WriteBuffer(Buff[250], 60);
CheckCount(F.Size, 335);
F.Position := 332;
F.WriteBuffer(Buff[332], 60);
CheckCount(F.Size, 392);
F.Position := 300;
F.WriteBuffer(Buff[300], 100);
CheckCount(F.Size, 400);
finally
F.Free;
end;
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z01'), 100);
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z02'), 100);
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z03'), 100);
CheckSize(DstFolder + ZipName, 100);
F := TFWFileMultiStream.CreateRead(DstFolder + ZipName, rsmFull);
try
SetLength(CheckBuff{%H-}, F.Size);
F.Position := 0;
F.ReadBuffer(CheckBuff[0], F.Size);
finally
F.Free;
end;
if not CompareMem(@Buff[0], @CheckBuff[0], 400) then
raise EFWZipUnitTestException.Create('Прочитаны неверные данные');
Clear;
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultiStream9;
var
DstFolder: string;
F: TFWFileMultiStream;
I: Integer;
Buff, CheckBuff: array of Byte;
begin
DstFolder := GetTestFolderPath(21, False, True);
SetLength(Buff{%H-}, 400);
for I := 0 to 399 do
Buff[I] := Byte(I);
F := TFWFileMultiStream.CreateWrite(DstFolder + ZipName, 100);
try
F.WriteBuffer(Buff[0], 250);
CheckCount(F.Size, 250);
F.StartNewVolume;
F.Position := 240;
F.WriteBuffer(Buff[240], 95);
CheckCount(F.Size, 335);
F.StartNewVolume;
F.Position := 250;
F.WriteBuffer(Buff[250], 60);
CheckCount(F.Size, 335);
F.Position := 332;
F.WriteBuffer(Buff[332], 60);
CheckCount(F.Size, 392);
F.StartNewVolume;
F.Position := 300;
F.WriteBuffer(Buff[300], 100);
CheckCount(F.Size, 400);
finally
F.Free;
end;
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z01'), 100);
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z02'), 100);
CheckSize(DstFolder + ChangeFileExt(ZipName, '.z03'), 100);
CheckSize(DstFolder + ZipName, 100);
F := TFWFileMultiStream.CreateRead(DstFolder + ZipName, rsmFull);
try
SetLength(CheckBuff{%H-}, F.Size);
F.Position := 0;
F.ReadBuffer(CheckBuff[0], F.Size);
finally
F.Free;
end;
if not CompareMem(@Buff[0], @CheckBuff[0], 400) then
raise EFWZipUnitTestException.Create('Прочитаны неверные данные');
Clear;
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultyPartBuildSingleZip;
var
SrcFolder, DstFolder: string;
M: TFWFileMultiStream;
begin
// проверка, если размер тома указан больше чем финальный размер архива
// должен создасться обычный немноготомный архив
Clear;
SrcFolder := GetTestFolderPath(215, True, True);
DstFolder := GetTestFolderPath(215, False, True);
CreateTestDataInSrcFolder(SrcFolder);
M := TFWFileMultiStream.CreateWrite(DstFolder + ZipName, 1024 * 1024 * 8);
try
Writer.AddFolder('', SrcFolder, '');
Writer.BuildZip(M);
finally
M.Free;
end;
if FileExists(DstFolder + ChangeFileExt(ZipName, '.z01')) then
raise EFWZipUnitTestException.Create('Создан многотомный архив!!!');
Reader.LoadFromFile(DstFolder + ZipName);
Reader.Check;
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultyPartBuildWithException;
var
SrcFolder, DstFolder, DstFile: string;
M: TFWFileMultiStream;
begin
Clear;
SrcFolder := GetTestFolderPath(209, True, True);
DstFolder := GetTestFolderPath(209, False, True);
DstFile := DstFolder + ZipName;
CreateTestDataInSrcFolder(SrcFolder);
// лочим один из файлов для демонстрации
Writer.AddFile(SrcFolder + TestFolderData[0]);
hLockedFile := FileOpen(SrcFolder + TestFolderData[0], WriteLock);
try
M := TFWFileMultiStream.CreateWrite(DstFile);
try
CheckBuildResult(Writer.BuildZip(M), brFailed);
finally
M.Free;
end;
// теперь добавляем еще один не залоченый
ClearFolder(DstFolder);
Writer.AddFile(SrcFolder + TestFolderData[1]);
M := TFWFileMultiStream.CreateWrite(DstFile);
try
CheckBuildResult(Writer.BuildZip(M), brPartialBuild);
finally
M.Free;
end;
finally
FileClose(hLockedFile);
end;
// а теперь должно быть нормально
ClearFolder(DstFolder);
CheckCount(Writer.Count, 2);
M := TFWFileMultiStream.CreateWrite(DstFile);
try
CheckBuildResult(Writer.BuildZip(M));
finally
M.Free;
end;
M := TFWFileMultiStream.CreateRead(DstFile);
try
Reader.LoadFromStream(M);
Reader.Check;
finally
M.Free;
end;
ClearFolder(DstFolder);
Clear;
Writer.AddFile(SrcFolder + TestFolderData[0]);
hLockedFile := FileOpen(SrcFolder + TestFolderData[0], WriteLock);
try
// Назначаем обработчик через который мы будем обрабатывать ошибку
// В обработчике OnException1 будет создаваться копия файла
Method.Code := @OnException1;
Method.Data := Writer;
Writer.OnException := TZipBuildExceptionEvent(Method);
M := TFWFileMultiStream.CreateWrite(DstFile);
try
CheckBuildResult(Writer.BuildZip(M));
finally
M.Free;
end;
finally
FileClose(hLockedFile);
end;
ClearFolder(DstFolder);
Clear;
Writer.AddFile(SrcFolder + TestFolderData[0]);
hLockedFile := FileOpen(SrcFolder + TestFolderData[0], WriteLock);
try
// снимаем исскуственную блокировку файла и выставляем
// свойство Action в eaRetry
Method.Code := @OnException2;
Method.Data := Writer;
Writer.OnException := TZipBuildExceptionEvent(Method);
M := TFWFileMultiStream.CreateWrite(DstFile);
try
CheckBuildResult(Writer.BuildZip(M));
finally
M.Free;
end;
finally
FileClose(hLockedFile);
end;
ClearFolder(DstFolder);
Clear;
Writer.AddFile(SrcFolder + TestFolderData[0]);
hLockedFile := FileOpen(SrcFolder + TestFolderData[0], WriteLock);
try
// загружаем данные через стрим
Method.Code := @OnException3;
Method.Data := Writer;
Writer.OnException := TZipBuildExceptionEvent(Method);
M := TFWFileMultiStream.CreateWrite(DstFile);
try
CheckBuildResult(Writer.BuildZip(M));
finally
M.Free;
end;
finally
FileClose(hLockedFile);
end;
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultyPartBuildWithExistingFile;
var
Count: TDataCount;
SrcFolder, DstFolder, SrcFile, DstFile: string;
I: Integer;
M: TFWFileMultiStream;
begin
Clear;
SrcFolder := GetTestFolderPath(202, True, True);
Count := CreateTestDataInSrcFolder(SrcFolder);
if Writer.AddFolder('', SrcFolder, '*.*', True) <> Count.Files then
raise EFWZipUnitTestException.Create('Ошибка инициализации архива. Неверное количество добавленных файлов');
M := TFWFileMultiStream.CreateWrite(SrcFolder + ZipName, 100);
try
CheckBuildResult(Writer.BuildZip(M));
finally
M.Free;
end;
M := TFWFileMultiStream.CreateRead(SrcFolder + ZipName);
try
DstFolder := GetTestFolderPath(202, False, True);
CheckLoadReaderWidthExcept(SrcFolder + ZipName);
Reader.LoadFromStream(M);
Reader.Check;
Reader.ExtractAll(DstFolder);
finally
M.Free;
end;
for I := 0 to TestFolderData.Count - 1 do
begin
SrcFile := SrcFolder + TestFolderData[I];
DstFile := DstFolder + TestFolderData[I];
if DirectoryExists(SrcFile) then Continue;
CheckFiles(SrcFile, DstFile);
end;
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultyPartBuildWithExistingFile2;
var
SrcFolder, DstFolder: string;
SrcFile, DstFile, Ext: string;
I: Integer;
M: TFWFileMultiStream;
begin
Clear;
SrcFolder := GetTestFolderPath(203, True, True);
CreateTestDataInSrcFolder(SrcFolder);
if Writer.AddFolder('', SrcFolder, '*.bin;*.no_txt', True) <> 3 then
raise EFWZipUnitTestException.Create('Ошибка инициализации архива. Неверное количество добавленных файлов');
M := TFWFileMultiStream.CreateWrite(SrcFolder + ZipName);
try
CheckBuildResult(Writer.BuildZip(M));
finally
M.Free;
end;
DstFolder := GetTestFolderPath(203, False, True);
M := TFWFileMultiStream.CreateRead(SrcFolder + ZipName);
try
Reader.LoadFromStream(M);
Reader.Check;
Reader.ExtractAll(DstFolder);
finally
M.Free;
end;
for I := 0 to TestFolderData.Count - 1 do
begin
SrcFile := SrcFolder + TestFolderData[I];
DstFile := DstFolder + TestFolderData[I];
Ext := ExtractFileExt(DstFile);
if (Ext <> '.no_txt') and ((Ext <> '.bin')) then Continue;
CheckFiles(SrcFile, DstFile);
end;
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultyPartBuildWithPassword;
var
Count: TDataCount;
SrcFolder, DstFolder, SrcFile, DstFile: string;
I: Integer;
Item: TFWZipWriterItem;
M: TFWFileMultiStream;
begin
Clear;
SrcFolder := GetTestFolderPath(204, True, True);
DstFolder := GetTestFolderPath(204, False, True);
Count := CreateTestDataInSrcFolder(SrcFolder);
Writer.AlwaysAddEmptyFolder := True;
if Writer.AddFolder('', SrcFolder, '', True) <> Count.Files then
raise EFWZipUnitTestException.Create('Ошибка инициализации архива. Неверное количество добавленных файлов/папок');
// Сначала ставим пароли всем элементам включая папки (что делать нельзя)
for I := 0 to Writer.Count - 1 do
begin
Item := Writer[I];
// Изменим коментарий
Item.Comment := string('Тестовый коментарий к файлу ') + Item.FileName;
// Установим пароль
Item.Password := 'password' + IntToStr(Byte(I mod 3));
// Изменим тип сжатия
Item.CompressionLevel := TCompressionLevel(Byte(I mod 3));
end;
M := TFWFileMultiStream.CreateWrite(DstFolder + ZipName);
try
CheckBuildResult(Writer.BuildZip(M));
finally
M.Free;
end;
// архив должен открыться корретно
M := TFWFileMultiStream.CreateRead(DstFolder + ZipName);
try
Reader.LoadFromStream(M);
CheckCount(Reader.Count, 22);
finally
M.Free;
end;
Reader.Clear;
ClearFolder(DstFolder);
// теперь скинем пароли с папок
for I := 0 to Writer.Count - 1 do
begin
Item := Writer[I];
if Item.IsFolder then
begin
Item.Password := '';
Item.CompressionLevel := clNone;
end;
end;
// теперь сбилдится должно успешно
M := TFWFileMultiStream.CreateWrite(DstFolder + ZipName);
try
CheckBuildResult(Writer.BuildZip(M));
finally
M.Free;
end;
M := TFWFileMultiStream.CreateRead(DstFolder + ZipName);
try
Reader.LoadFromStream(M);
CheckCount(Reader.Count, 22);
CheckReaderWidthExcept; // без пароля обязано зарайзиться
Reader.PasswordList.Add('password0');
Reader.PasswordList.Add('password1');
CheckReaderWidthExcept; // без отстутсвующего пароля обязано зарайзиться
Method.Code := @OnPassword;
Method.Data := Reader;
Reader.OnPassword := TZipNeedPasswordEvent(Method);
Reader.Check; // повторная проверка, теперь все пароли должны быть на месте
Reader.ExtractAll(DstFolder);
finally
M.Free;
end;
for I := 0 to TestFolderData.Count - 1 do
begin
SrcFile := SrcFolder + TestFolderData[I];
DstFile := DstFolder + TestFolderData[I];
if DirectoryExists(SrcFile) then Continue;
CheckFiles(SrcFile, DstFile);
end;
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultyPartBuildWithPassword1;
var
Count: TDataCount;
SrcFolder, DstFolder, SrcFile, DstFile: string;
I: Integer;
Item: TFWZipWriterItem;
M: TFWFileMultiStream;
begin
Clear;
SrcFolder := GetTestFolderPath(204, True, True);
DstFolder := GetTestFolderPath(204, False, True);
Count := CreateTestDataInSrcFolder(SrcFolder);
Writer.AlwaysAddEmptyFolder := True;
if Writer.AddFolder('', SrcFolder, '', True) <> Count.Files then
raise EFWZipUnitTestException.Create('Ошибка инициализации архива. Неверное количество добавленных файлов/папок');
// Сначала ставим пароли всем элементам включая папки (что делать нельзя)
for I := 0 to Writer.Count - 1 do
begin
Item := Writer[I];
// Изменим коментарий
Item.Comment := string('Тестовый коментарий к файлу ') + Item.FileName;
// Установим пароль
Item.Password := 'password' + IntToStr(Byte(I mod 3));
// Вместе с дескриптором
Item.NeedDescriptor := True;
// Изменим тип сжатия
Item.CompressionLevel := TCompressionLevel(Byte(I mod 3));
end;
M := TFWFileMultiStream.CreateWrite(DstFolder + ZipName);
try
CheckBuildResult(Writer.BuildZip(M));
finally
M.Free;
end;
// архив должен открыться корретно
M := TFWFileMultiStream.CreateRead(DstFolder + ZipName);
try
Reader.LoadFromStream(M);
CheckCount(Reader.Count, 22);
finally
M.Free;
end;
Reader.Clear;
ClearFolder(DstFolder);
// теперь скинем пароли с папок
for I := 0 to Writer.Count - 1 do
begin
Item := Writer[I];
if Item.IsFolder then
begin
Item.Password := '';
Item.NeedDescriptor := False;
Item.CompressionLevel := clNone;
end;
end;
// теперь сбилдится должно успешно
M := TFWFileMultiStream.CreateWrite(DstFolder + ZipName);
try
CheckBuildResult(Writer.BuildZip(M));
finally
M.Free;
end;
M := TFWFileMultiStream.CreateRead(DstFolder + ZipName);
try
Reader.LoadFromStream(M);
CheckCount(Reader.Count, 22);
CheckReaderWidthExcept; // без пароля обязано зарайзиться
Reader.PasswordList.Add('password0');
Reader.PasswordList.Add('password1');
CheckReaderWidthExcept; // без отстутсвующего пароля обязано зарайзиться
Method.Code := @OnPassword;
Method.Data := Reader;
Reader.OnPassword := TZipNeedPasswordEvent(Method);
Reader.Check; // повторная проверка, теперь все пароли должны быть на месте
Reader.ExtractAll(DstFolder);
finally
M.Free;
end;
for I := 0 to TestFolderData.Count - 1 do
begin
SrcFile := SrcFolder + TestFolderData[I];
DstFile := DstFolder + TestFolderData[I];
if DirectoryExists(SrcFile) then Continue;
CheckFiles(SrcFile, DstFile);
end;
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultyPartBuildWithStream;
var
S: TStringStream;
ItemIndex: Integer;
SrcFolder, DstFolder: string;
M: TFWFileMultiStream;
begin
Clear;
ItemIndex := AddItem(Writer, 'test.txt', TestStringBlock[0]);
CheckResult(ItemIndex);
Writer.Item[ItemIndex].Comment := TestStringBlock[2];
S := TStringStream.Create(TestStringBlock[1]);
S.Position := 0;
ItemIndex := Writer.AddStream('test2.txt', S, soOwned);
CheckResult(ItemIndex);
S := TStringStream.Create(TestStringBlock[0]);
S.Position := 0;
ItemIndex := Writer.InsertStream('test0.txt', 0, S, soOwned);
CheckResult(ItemIndex);
CheckResult(AddItem(Writer,
_L('AddStreamData\SubFolder1\Subfolder2\Test.txt'), TestStringBlock[2]));
SrcFolder := GetTestFolderPath(201, True, True);
M := TFWFileMultiStream.CreateWrite(SrcFolder + ZipName, 100);
try
CheckBuildResult(Writer.BuildZip(M));
finally
M.Free;
end;
M := TFWFileMultiStream.CreateRead(SrcFolder + ZipName);
try
CheckLoadReaderWidthExcept(SrcFolder + ZipName);
Reader.LoadFromStream(M);
Reader.Check;
DstFolder := GetTestFolderPath(201, False, True);
Reader.ExtractAll(DstFolder);
finally
M.Free;
end;
CheckStream(0, DstFolder + 'test.txt');
CheckStream(0, DstFolder + 'test0.txt');
CheckStream(1, DstFolder + 'test2.txt');
CheckStream(2, DstFolder + _L('AddStreamData\SubFolder1\Subfolder2\Test.txt'));
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultyPartChangeZip;
var
SrcFolder, DstFolder: string;
Modifier: TFWZipModifier;
Index: TReaderIndex;
M, M1: TFWFileMultiStream;
begin
Clear;
SrcFolder := GetTestFolderPath(206, True, True);
CreateTestDataInSrcFolder(SrcFolder);
Writer.AddFile(SrcFolder + TestFolderData[0]);
Writer.AddFile(SrcFolder + TestFolderData[1]);
Writer.AddFile(SrcFolder + TestFolderData[2]);
M := TFWFileMultiStream.CreateWrite(SrcFolder + ZipName);
try
CheckBuildResult(Writer.BuildZip(M));
finally
M.Free;
end;
DstFolder := GetTestFolderPath(206, False, True);
Modifier := TFWZipModifier.Create;
try
M1 := TFWFileMultiStream.CreateRead(SrcFolder + ZipName);
try
Index := Modifier.AddZipFile(M1);
Modifier.AddFromZip(Index, TestFolderData[0]);
Modifier.AddFromZip(Index, TestFolderData[1], RenamedZipName);
Modifier.AddFile(SrcFolder + TestFolderData[12]);
Modifier.AddFromZip(Index, TestFolderData[2]);
CheckCount(Modifier.Count, 4);
M := TFWFileMultiStream.CreateWrite(DstFolder + ZipName);
try
CheckBuildResult(Modifier.BuildZip(M));
finally
M.Free;
end;
finally
M1.Free;
end;
finally
Modifier.Free;
end;
M := TFWFileMultiStream.CreateRead(DstFolder + ZipName);
try
Reader.LoadFromStream(M);
Reader.Check;
Reader.ExtractAll(DstFolder);
finally
M.Free;
end;
CheckFiles(SrcFolder + TestFolderData[0], DstFolder + TestFolderData[0]);
CheckFiles(SrcFolder + TestFolderData[1], DstFolder + RenamedZipName);
CheckFiles(SrcFolder + TestFolderData[2], DstFolder + TestFolderData[2]);
CheckFiles(SrcFolder + TestFolderData[12],
DstFolder + ExtractFileName(TestFolderData[12]));
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultyPartDeleteFromZip;
var
SrcFolder, DstFolder: string;
Modifier: TFWZipModifier;
Index: TReaderIndex;
M, M1: TFWFileMultiStream;
begin
Clear;
SrcFolder := GetTestFolderPath(207, True, True);
CreateTestDataInSrcFolder(SrcFolder);
Writer.AddFile(SrcFolder + TestFolderData[0]);
Writer.AddFile(SrcFolder + TestFolderData[1]);
Writer.AddFile(SrcFolder + TestFolderData[2]);
M := TFWFileMultiStream.CreateWrite(SrcFolder + ZipName);
try
CheckBuildResult(Writer.BuildZip(M));
finally
M.Free;
end;
DstFolder := GetTestFolderPath(207, False, True);
Modifier := TFWZipModifier.Create;
try
M1 := TFWFileMultiStream.CreateRead(SrcFolder + ZipName);
try
Index := Modifier.AddZipFile(M1);
Modifier.AddFromZip(Index);
Modifier.DeleteItem(0);
CheckCount(Modifier.Count, 2);
M := TFWFileMultiStream.CreateWrite(DstFolder + ZipName);
try
CheckBuildResult(Modifier.BuildZip(M));
finally
M.Free;
end;
finally
M1.Free;
end;
finally
Modifier.Free;
end;
M := TFWFileMultiStream.CreateRead(DstFolder + ZipName);
try
Reader.LoadFromStream(M);
Reader.Check;
Reader.ExtractAll(DstFolder);
finally
M.Free;
end;
CheckFiles(SrcFolder + TestFolderData[1], DstFolder + TestFolderData[1]);
CheckFiles(SrcFolder + TestFolderData[2], DstFolder + TestFolderData[2]);
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultyPartExData;
var
SrcFolder, DstFolder, SrcFile, DstFile: string;
I: Integer;
M: TFWFileMultiStream;
begin
Clear;
SrcFolder := GetTestFolderPath(212, True, True);
CreateTestDataInSrcFolder(SrcFolder);
Writer.AddFolder('', SrcFolder, '*.*', True);
Method.Code := @OnSaveExData;
Method.Data := Writer;
Writer.OnSaveExData := TZipSaveExDataEvent(Method);
M := TFWFileMultiStream.CreateWrite(SrcFolder + ZipName);
try
CheckBuildResult(Writer.BuildZip(M));
finally
M.Free;
end;
DstFolder := GetTestFolderPath(212, False, True);
Method.Code := @OnLoadExData;
Method.Data := Reader;
Reader.OnLoadExData := TZipLoadExDataEvent(Method);
M := TFWFileMultiStream.CreateRead(SrcFolder + ZipName);
try
Reader.LoadFromStream(M);
Reader.Check;
Reader.ExtractAll(DstFolder);
for I := 0 to TestFolderData.Count - 1 do
begin
SrcFile := SrcFolder + TestFolderData[I];
DstFile := DstFolder + TestFolderData[I];
if DirectoryExists(SrcFile) then Continue;
CheckFiles(SrcFile, DstFile);
end;
finally
M.Free;
end;
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
{$IFNDEF WINE}
procedure TFWZipUnitTest.TestMultyPartExtractOverride;
var
SrcFolder, DstFolder, SrcFile, DstFile: string;
I, A: Integer;
M: TFWFileMultiStream;
begin
Clear;
SrcFolder := GetTestFolderPath(210, True, True);
CreateTestDataInSrcFolder(SrcFolder);
Writer.AddFolder(SrcFolder);
M := TFWFileMultiStream.CreateWrite(SrcFolder + ZipName);
try
CheckBuildResult(Writer.BuildZip(M));
finally
M.Free;
end;
DstFolder := GetTestFolderPath(210, False, True);
M := TFWFileMultiStream.CreateRead(SrcFolder + ZipName);
try
Reader.LoadFromStream(M);
Reader.Check;
Reader.ExtractAll(DstFolder);
Method.Code := @OnDuplicate;
Method.Data := Reader;
Reader.OnDuplicate := TZipDuplicateEvent(Method);
NewFilePath := TStringList.Create;
try
Reader.ExtractAll(DstFolder);
for I := 0 to TestFolderData.Count - 1 do
begin
SrcFile := _L(SrcFolder + TestFolderData[I]);
DstFile := _L(DstFolder + 'test_210\' + TestFolderData[I]);
if DirectoryExists(SrcFile) then Continue;
CheckFiles(SrcFile, DstFile);
A := NewFilePath.IndexOfName(_L(DstFolder + 'test_210\' + TestFolderData[I]));
CheckFiles(SrcFile, NewFilePath.ValueFromIndex[A]);
end;
finally
NewFilePath.Free;
end;
finally
M.Free;
end;
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
{$ENDIF}
procedure TFWZipUnitTest.TestMultyPartMerge2Zip;
var
SrcFolder, DstFolder: string;
Modifier: TFWZipModifier;
Index1, Index2: TReaderIndex;
M, M1, M2: TFWFileMultiStream;
begin
Clear;
SrcFolder := GetTestFolderPath(205, True, True);
CreateTestDataInSrcFolder(SrcFolder);
Writer.AddFile(SrcFolder + TestFolderData[1]);
M := TFWFileMultiStream.CreateWrite(SrcFolder + ZipName1);
try
CheckBuildResult(Writer.BuildZip(M));
finally
M.Free;
end;
Clear;
Writer.AddFile(SrcFolder + TestFolderData[2]);
M := TFWFileMultiStream.CreateWrite(SrcFolder + ZipName2);
try
CheckBuildResult(Writer.BuildZip(M));
finally
M.Free;
end;
DstFolder := GetTestFolderPath(205, False, True);
Modifier := TFWZipModifier.Create;
try
M1 := TFWFileMultiStream.CreateRead(SrcFolder + ZipName1);
try
Index1 := Modifier.AddZipFile(M1);
M2 := TFWFileMultiStream.CreateRead(SrcFolder + ZipName2);
try
Index2 := Modifier.AddZipFile(M2);
Modifier.AddFromZip(Index1);
Modifier.AddFromZip(Index2);
CheckCount(Modifier.Count, 2);
M := TFWFileMultiStream.CreateWrite(DstFolder + ZipName);
try
CheckBuildResult(Modifier.BuildZip(M));
finally
M.Free;
end;
finally
M2.Free;
end;
finally
M1.Free;
end;
finally
Modifier.Free;
end;
M := TFWFileMultiStream.CreateRead(DstFolder + ZipName);
try
Reader.LoadFromStream(M);
Reader.Check;
Reader.ExtractAll(DstFolder);
finally
M.Free;
end;
CheckFiles(SrcFolder + TestFolderData[1], DstFolder + TestFolderData[1]);
CheckFiles(SrcFolder + TestFolderData[2], DstFolder + TestFolderData[2]);
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultyPartSplitZip;
var
Modifier: TFWZipModifier;
Index: TReaderIndex;
SrcFolder, DstFolder: string;
M, M1: TFWFileMultiStream;
begin
Clear;
AddItem(Writer, 'test1.txt', 'первый элемент');
AddItem(Writer, 'test2.txt', 'второй элемент');
AddItem(Writer, 'test3.txt', 'третий элемент');
AddItem(Writer, 'test4.txt', 'четвертый элемент');
SrcFolder := GetTestFolderPath(208, True, True);
DstFolder := GetTestFolderPath(208, False, True);
M := TFWFileMultiStream.CreateWrite(SrcFolder + ZipName);
try
CheckBuildResult(Writer.BuildZip(M));
finally
M.Free;
end;
M1 := TFWFileMultiStream.CreateRead(SrcFolder + ZipName);
try
Modifier := TFWZipModifier.Create;
try
// подключаем ранее созданный архив
Index := Modifier.AddZipFile(M);
// добавляем из него первые два элемента
Modifier.AddFromZip(Index, 'test1.txt');
Modifier.AddFromZip(Index, 'test2.txt');
// и сохраняем в новый архив
// при этом реальной перепаковки данных не произойдет,
// данные возьмутся как есть в виде массива байт прямо в сжатом виде
// из оригинального архива
CheckCount(Modifier.Count, 2);
M := TFWFileMultiStream.CreateWrite(DstFolder + ZipName1);
try
CheckBuildResult(Modifier.BuildZip(M));
finally
M.Free;
end;
// теперь удаляем добавленные элементы и добавляем вторые два
Modifier.Clear;
Modifier.AddFromZip(Index, 'test3.txt');
Modifier.AddFromZip(Index, 'test4.txt');
// сохраняем во торой архив
CheckCount(Modifier.Count, 2);
M := TFWFileMultiStream.CreateWrite(DstFolder + ZipName2);
try
CheckBuildResult(Modifier.BuildZip(M));
finally
M.Free;
end;
finally
Modifier.Free;
end;
finally
M1.Free;
end;
M := TFWFileMultiStream.CreateRead(DstFolder + ZipName1);
try
Reader.LoadFromStream(M);
Reader.Check;
CheckCount(Reader.Count, 2);
if Reader.Item[0].FileName <> 'test1.txt' then
raise EFWZipUnitTestException.Create('Имя файла должно быть test1.txt');
if Reader.Item[1].FileName <> 'test2.txt' then
raise EFWZipUnitTestException.Create('Имя файла должно быть test2.txt');
finally
M.Free;
end;
M := TFWFileMultiStream.CreateRead(DstFolder + ZipName2);
try
Reader.LoadFromStream(M);
Reader.Check;
CheckCount(Reader.Count, 2);
if Reader.Item[0].FileName <> 'test3.txt' then
raise EFWZipUnitTestException.Create('Имя файла должно быть test3.txt');
if Reader.Item[1].FileName <> 'test4.txt' then
raise EFWZipUnitTestException.Create('Имя файла должно быть test4.txt');
finally
M.Free;
end;
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultyPartZip64_BigFiles;
var
SrcFolder, DstFolder: string;
M: TFWFileMultiStream;
begin
Clear;
SrcFolder := GetTestFolderPath(210, True, True);
DstFolder := GetTestFolderPath(210, False, True);
CreateBigFilesInFolder(SrcFolder, True);
Writer.AddFolder(SrcFolder, False);
M := TFWFileMultiStream.CreateWrite(DstFolder + ZipName, 1024 * 1024 * 8);
try
CheckBuildResult(Writer.BuildZip(M));
finally
M.Free;
end;
M := TFWFileMultiStream.CreateRead(DstFolder + ZipName);
try
Reader.LoadFromStream(M);
Reader.Check;
finally
M.Free;
end;
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestMultyPartZip64_BigFilesCount;
var
SrcFolder, DstFolder: string;
M: TFWFileMultiStream;
begin
Clear;
SrcFolder := GetTestFolderPath(221, True, True);
DstFolder := GetTestFolderPath(221, False, True);
CreateManyFilesInFolder(SrcFolder);
Writer.AddFolder(SrcFolder, False);
M := TFWFileMultiStream.CreateWrite(DstFolder + ZipName, 1024 * 1024 * 8);
try
CheckBuildResult(Writer.BuildZip(M));
finally
M.Free;
end;
M := TFWFileMultiStream.CreateRead(DstFolder + ZipName);
try
Reader.LoadFromStream(M);
Reader.Check;
finally
M.Free;
end;
Clear;
DeleteManyFilesInFolder(SrcFolder);
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestSplitZip;
var
Modifier: TFWZipModifier;
S: TMemoryStream;
Index: TReaderIndex;
DstFolder: string;
begin
Clear;
AddItem(Writer, 'test1.txt', 'первый элемент');
AddItem(Writer, 'test2.txt', 'второй элемент');
AddItem(Writer, 'test3.txt', 'третий элемент');
AddItem(Writer, 'test4.txt', 'четвертый элемент');
DstFolder := GetTestFolderPath(8, False, True);
S := TMemoryStream.Create;
try
Writer.BuildZip(S);
Modifier := TFWZipModifier.Create;
try
// подключаем ранее созданный архив
Index := Modifier.AddZipFile(S);
// добавляем из него первые два элемента
Modifier.AddFromZip(Index, 'test1.txt');
Modifier.AddFromZip(Index, 'test2.txt');
// и сохраняем в новый архив
// при этом реальной перепаковки данных не произойдет,
// данные возьмутся как есть в виде массива байт прямо в сжатом виде
// из оригинального архива
CheckCount(Modifier.Count, 2);
CheckBuildResult(Modifier.BuildZip(DstFolder + ZipName1));
// теперь удаляем добавленные элементы и добавляем вторые два
Modifier.Clear;
Modifier.AddFromZip(Index, 'test3.txt');
Modifier.AddFromZip(Index, 'test4.txt');
// сохраняем во торой архив
CheckCount(Modifier.Count, 2);
CheckBuildResult(Modifier.BuildZip(DstFolder + ZipName2));
finally
Modifier.Free;
end;
finally
S.Free;
end;
Reader.LoadFromFile(DstFolder + ZipName1);
Reader.Check;
CheckCount(Reader.Count, 2);
if Reader.Item[0].FileName <> 'test1.txt' then
raise EFWZipUnitTestException.Create('Имя файла должно быть test1.txt');
if Reader.Item[1].FileName <> 'test2.txt' then
raise EFWZipUnitTestException.Create('Имя файла должно быть test2.txt');
Reader.LoadFromFile(DstFolder + ZipName2);
Reader.Check;
CheckCount(Reader.Count, 2);
if Reader.Item[0].FileName <> 'test3.txt' then
raise EFWZipUnitTestException.Create('Имя файла должно быть test3.txt');
if Reader.Item[1].FileName <> 'test4.txt' then
raise EFWZipUnitTestException.Create('Имя файла должно быть test4.txt');
Clear;
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestZip64_BigFiles;
var
SrcFolder, DstFolder: string;
begin
Clear;
SrcFolder := GetTestFolderPath(100, True, True);
DstFolder := GetTestFolderPath(100, False, True);
CreateBigFilesInFolder(SrcFolder);
Writer.AddFolder(SrcFolder, False);
CheckBuildResult(Writer.BuildZip(DstFolder + ZipName));
Reader.LoadFromFile(DstFolder + ZipName);
Reader.Check;
Clear;
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
procedure TFWZipUnitTest.TestZip64_BigFilesCount;
var
SrcFolder, DstFolder: string;
begin
Clear;
SrcFolder := GetTestFolderPath(120, True, True);
DstFolder := GetTestFolderPath(120, False, True);
CreateManyFilesInFolder(SrcFolder);
Writer.AddFolder(SrcFolder, False);
CheckBuildResult(Writer.BuildZip(DstFolder + ZipName));
Reader.LoadFromFile(DstFolder + ZipName);
Reader.Check;
Clear;
DeleteManyFilesInFolder(SrcFolder);
DeleteFolder(SrcFolder);
DeleteFolder(DstFolder);
end;
function TFWZipUnitTest.Writer: TFWZipWriter;
begin
Result := FZipWriter;
end;
initialization
InitFolders;
{$IFDEF FPC}
RegisterTest(TFWZipUnitTest);
{$ELSE}
RegisterTest(TFWZipUnitTest.Suite);
{$ENDIF}
finalization
TestFolderData.Free;
end.