Стартовый пул

This commit is contained in:
2024-04-02 08:46:59 +03:00
parent fd57fffd3a
commit 3bb34d000b
5591 changed files with 3291734 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
program FWZipUnitTest;
{$IFDEF FPC}
{$MODE Delphi}
{$ELSE}
{$IFDEF CONSOLE_TESTRUNNER}
{$APPTYPE CONSOLE}
{$ENDIF}
{$ENDIF}
uses
{$IFDEF FPC}
{$IFDEF CONSOLE_TESTRUNNER}
consoletestrunner,
{$ELSE}
Interfaces, Forms, GuiTestRunner,
{$ENDIF}
{$ELSE}
DUnitTestRunner,
{$ENDIF}
FWZipTests in '..\FWZipTests.pas';
{$IFDEF FPC}
{$IFDEF CONSOLE_TESTRUNNER}
var Application: TTestRunner;
{$ENDIF}
{$ELSE}
{$R *.res}
{$ENDIF}
begin
{$IFDEF FPC}
{$IFDEF CONSOLE_TESTRUNNER}
Application := TTestRunner.Create(nil);
Application.Initialize;
Application.Run;
Application.Free;
{$ELSE}
Application.Initialize;
Application.CreateForm(TGuiTestRunner, TestRunner);
Application.Run;
{$ENDIF}
{$ELSE}
DUnitTestRunner.RunRegisteredTests;
{$ENDIF}
end.

View File

@@ -0,0 +1,136 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{9C63EEE9-BA18-476B-8ED3-D7A379E5133A}</ProjectGuid>
<MainSource>FWZipUnitTest.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>3</TargetedPlatforms>
<AppType>Console</AppType>
<FrameworkType>None</FrameworkType>
<ProjectVersion>19.2</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win64</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win64)'!=''">
<Cfg_2_Win64>true</Cfg_2_Win64>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_E>false</DCC_E>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
<DCC_N>false</DCC_N>
<DCC_S>false</DCC_S>
<DCC_ImageBase>00400000</DCC_ImageBase>
<SanitizedProjectName>FWZipUnitTest</SanitizedProjectName>
<VerInfo_Locale>1049</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=</VerInfo_Keys>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;DUnitX;$(DCC_Namespace)</DCC_Namespace>
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns>
<DCC_Define>UNIT_TEST;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_DebugInformation>0</DCC_DebugInformation>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)</VerInfo_Keys>
<Manifest_File>(None)</Manifest_File>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win64)'!=''">
<DCC_UnitSearchPath>../;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<Manifest_File>(None)</Manifest_File>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="..\FWZipTests.pas"/>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">FWZipUnitTest.dpr</Source>
</Source>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k270.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp270.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Platforms>
<Platform value="Win32">True</Platform>
<Platform value="Win64">True</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>

View File

@@ -0,0 +1,109 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="FWZipUnitTest"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<BuildModes>
<Item Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<RequiredPackages>
<Item>
<PackageName Value="FWZipLCL"/>
</Item>
<Item>
<PackageName Value="fpcunittestrunner"/>
</Item>
<Item>
<PackageName Value="LCL"/>
</Item>
</RequiredPackages>
<Units>
<Unit>
<Filename Value="FWZipUnitTest.dpr"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="..\FWZipTests.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="..\FWZipStream.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<OtherUnitFiles Value=".."/>
<UnitOutputDirectory Value="."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="Delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2Set"/>
</Debugging>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
<Other>
<CompilerMessages>
<IgnoredMessages idx5024="True"/>
</CompilerMessages>
<CustomOptions Value="-dUNIT_TEST"/>
<OtherDefines Count="1">
<Define0 Value="UNIT_TEST"/>
</OtherDefines>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions>
<Item>
<Name Value="EAbort"/>
</Item>
<Item>
<Name Value="ECodetoolError"/>
</Item>
<Item>
<Name Value="EFOpenError"/>
</Item>
<Item>
<Name Value="EZipWriterWrite"/>
</Item>
<Item>
<Name Value="EWrongPasswordException"/>
</Item>
<Item>
<Name Value="EZipReader"/>
</Item>
</Exceptions>
</Debugging>
</CONFIG>

24
fwzip/.UnitTest/clear.bat Normal file
View File

@@ -0,0 +1,24 @@
rd /S /Q "%cd%\backup\"
rd /S /Q "%cd%\ConverterBackup\"
rd /S /Q "%cd%\lib\"
rd /S /Q "%cd%\__history\"
rd /S /Q "%cd%\__recovery\"
del "%cd%\*.o"
del "%cd%\*.a"
del "%cd%\*.or"
del "%cd%\*.lps"
del "%cd%\*.obj"
del "%cd%\*.exe"
del "%cd%\*.ppu"
del "%cd%\*.dcu"
del "%cd%\*.log"
del "%cd%\*.compiled"
del "%cd%\*.cfg"
del "%cd%\*.dof"
del "%cd%\*.dproj.local"
del "%cd%\*.identcache"
del "%cd%\*.dsk"
del "%cd%\*.skincfg"
del "%cd%\*.bak"
del "%cd%\*.rsm"
del "%cd%\*.~*"

22
fwzip/.gitattributes vendored Normal file
View File

@@ -0,0 +1,22 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

215
fwzip/.gitignore vendored Normal file
View File

@@ -0,0 +1,215 @@
#################
## Eclipse
#################
*.pydevproject
.project
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
#################
## Visual Studio
#################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
*.pubxml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
#############
## Windows detritus
#############
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac crap
.DS_Store
#############
## Python
#############
*.py[co]
# Packages
*.egg
*.egg-info
dist/
build/
eggs/
parts/
var/
sdist/
develop-eggs/
.installed.cfg
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
#Translations
*.mo
#Mr Developer
.mr.developer.cfg

View File

@@ -0,0 +1,210 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : CreateZIPDemo1
// * Purpose : Демонстрация создания архива используя различные
// * : варианты добавления данных
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2023.
// * Version : 2.0.0
// * 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/
//
// Данный пример показывает различные варианты добавления информации в архив
// Для каждого из способов добавления в архиве будет создана отдельная папка
program CreateZIPDemo1;
{$IFDEF FPC}
{$MODE Delphi}
{$H+}
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}
uses
SysUtils,
Classes,
TypInfo,
FWZipWriter,
FWZipUtils;
procedure CheckResult(Value: Integer);
begin
if Value < 0 then
raise Exception.Create('Ошибка добавления данных');
end;
var
Zip: TFWZipWriter;
S: TStringStream;
PresentFiles: TStringList;
SR: TSearchRec;
I, ItemIndex: Integer;
BuildZipResult: TBuildZipResult;
begin
SetCurrentDir(ExtractFilePath(ParamStr(0)));
try
Zip := TFWZipWriter.Create;
try
// У всего архива включим UTF8 кодировку (если необходимо)
Zip.UseUTF8String := True;
// добавим комментарий по необходимости
Zip.Comment := 'Общий комментарий к архиву';
// Сначала добавим в архив файлы и папки
// не существующие физически на диске
// Создаем и добавляем текстовый файл в корень архива (AddStream)
{$IFDEF FPC}
S := TStringStream.Create(AnsiString('Тестовый текстовый файл №1'));
{$ELSE}
S := TStringStream.Create('Тестовый текстовый файл №1');
{$ENDIF}
try
S.Position := 0;
ItemIndex := Zip.AddStream('test.txt', S);
CheckResult(ItemIndex);
// Можно добавить коментарий к самому элементу
Zip.Item[ItemIndex].Comment := 'Мой тестовый комментарий';
finally
S.Free;
end;
// Создаем и добавляем текстовый файл в корень архива (AddStream)
// владельцем стрима данных будет сам архив
{$IFDEF FPC}
S := TStringStream.Create(AnsiString('Тестовый текстовый файл №2'));
{$ELSE}
S := TStringStream.Create('Тестовый текстовый файл №2');
{$ENDIF}
S.Position := 0;
ItemIndex := Zip.AddStream('Тестовый файл номер №2.txt', S, soOwned);
CheckResult(ItemIndex);
// Для сохранении файла в определенной папке
// достаточно указать ее наличие в пути к файлу, например вот так
{$IFDEF FPC}
S := TStringStream.Create(AnsiString('Тестовый текстовый файл №3'));
{$ELSE}
S := TStringStream.Create('Тестовый текстовый файл №3');
{$ENDIF}
try
S.Position := 0;
CheckResult(Zip.AddStream(
'AddStreamData\SubFolder1\Subfolder2\Тестовый файл номер №3.txt', S));
finally
S.Free;
end;
// Теперь будут показаны пять вариантов добавления файлов
// физически присутствующих на диске
// Вариант первый:
// добавляем в архив содержимое папки "Create ZIP 2" вызовом
// базоовго метода AddFolder
if Zip.AddFolder('..\Create ZIP 2\') = 0 then
raise Exception.Create('Ошибка добавления данных');
// Вариант второй:
// добавляем содержимое нашей корневой директории в папку AddFolderDemo
// при помощи вызова расширенной функции AddFolder,
// в которой можем указать наименование папки внутри архива и указать
// необходимость добавления подпапок (третий параметр)
if Zip.AddFolder('AddFolderDemo', '..\..\', '*.pas', False) = 0 then
raise Exception.Create('Ошибка добавления данных');
// Вариант третий. Используем те-же файлы из корневой директории,
// Только добавлять будем руками при помощи метода AddFile
PresentFiles := TStringList.Create;
try
// Для начала их все найдем
if FindFirst(PathCanonicalize('..\..\*.pas'), faAnyFile, SR) = 0 then
try
repeat
if (SR.Name = '.') or (SR.Name = '..') then Continue;
if SR.Attr and faDirectory <> 0 then
Continue
else
PresentFiles.Add(SR.Name);
until FindNext(SR) <> 0;
finally
FindClose(SR);
end;
// Теперь добавим по одному,
// указывая в какой папке и под каким именем их размещать.
for I := 0 to PresentFiles.Count - 1 do
CheckResult(Zip.AddFile('..\..\' + PresentFiles[I],
'AddFile\' + PresentFiles[I]));
// Четвертый вариант - добавление списком при помощи метода AddFiles.
// Каждый элемент списка должен быть сформирован следующим образом:
// "Относительный путь и имя в архиве"="Путь к файлу"
// Т.е. ValueFromIndex указывает на путь к файлу,
// а Names - относительный путь в архиве
// Если не указать относительный путь, то будет браться только имя файла.
for I := 0 to PresentFiles.Count - 1 do
PresentFiles[I] :=
'AddFiles\' + PresentFiles[I] + '=..\..\' + PresentFiles[I];
if Zip.AddFiles(PresentFiles) <> PresentFiles.Count then
raise Exception.Create('Ошибка добавления данных');
finally
PresentFiles.Free;
end;
// И последний вариант, то-же добавление списком,
// только в данный список можно помещать папки. Метод AddFilesAndFolders.
// Файлы помещаются в список по тому-же принципу что и в методе AddFiles.
// Записи для папок формируются по принципу: "Относительный путь в архиве"="Путь к папке"
// Т.е. ValueFromIndex указывает на путь к папке,
// а Names - относительный путь в архиве от корня
// Здесь добавим все файлы и папки из корня проекта
PresentFiles := TStringList.Create;
try
if FindFirst(PathCanonicalize('..\..\*'), faAnyFile, SR) = 0 then
try
repeat
if (SR.Name = '.') or (SR.Name = '..') then Continue;
// пропускаем папку demos, т.к. там могут быть залоченные сейчас файлы
if AnsiLowerCase(SR.Name) = 'demos' then
Continue;
PresentFiles.Add('AddFilesAndFolders\' + SR.Name + '=..\..\' + SR.Name);
until FindNext(SR) <> 0;
finally
FindClose(SR);
end;
Zip.AddFilesAndFolders(PresentFiles, True);
finally
PresentFiles.Free;
end;
// Вот собственно и все - осталось создать сам архив...
BuildZipResult := Zip.BuildZip('..\DemoResults\CreateZIPDemo1.zip');
// ... и вывести результат
Writeln(GetEnumName(TypeInfo(TBuildZipResult), Integer(BuildZipResult)));
finally
Zip.Free;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.

View File

@@ -0,0 +1,112 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{BDE6D9AD-8405-415D-A34C-F47E1BF78ED3}</ProjectGuid>
<MainSource>CreateZIPDemo1.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>
<FrameworkType>None</FrameworkType>
<ProjectVersion>19.2</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_E>false</DCC_E>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
<DCC_N>false</DCC_N>
<DCC_S>false</DCC_S>
<DCC_ImageBase>00400000</DCC_ImageBase>
<SanitizedProjectName>CreateZIPDemo1</SanitizedProjectName>
<VerInfo_Locale>1049</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=</VerInfo_Keys>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_DebugInformation>0</DCC_DebugInformation>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<DCC_UnitSearchPath>../../;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)</VerInfo_Keys>
<Manifest_File>(None)</Manifest_File>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">CreateZIPDemo1.dpr</Source>
</Source>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k270.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp270.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Platforms>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="CreateZIPDemo1"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<BuildModes>
<Item Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<RequiredPackages>
<Item>
<PackageName Value="LCL"/>
</Item>
</RequiredPackages>
<Units>
<Unit>
<Filename Value="CreateZIPDemo1.dpr"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<SearchPaths>
<IncludeFiles Value="..\..;$(ProjOutDir)"/>
<Libraries Value="..\..\fpc_lib"/>
<OtherUnitFiles Value="..\.."/>
<UnitOutputDirectory Value="."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="Delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2Set"/>
</Debugging>
</Linking>
<Other>
<CustomOptions Value="-dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions>
<Item>
<Name Value="EAbort"/>
</Item>
<Item>
<Name Value="ECodetoolError"/>
</Item>
<Item>
<Name Value="EFOpenError"/>
</Item>
</Exceptions>
</Debugging>
</CONFIG>

View File

@@ -0,0 +1,24 @@
rd /S /Q "%cd%\backup\"
rd /S /Q "%cd%\ConverterBackup\"
rd /S /Q "%cd%\lib\"
rd /S /Q "%cd%\__history\"
rd /S /Q "%cd%\__recovery\"
del "%cd%\*.o"
del "%cd%\*.a"
del "%cd%\*.or"
del "%cd%\*.lps"
del "%cd%\*.obj"
del "%cd%\*.exe"
del "%cd%\*.ppu"
del "%cd%\*.dcu"
del "%cd%\*.log"
del "%cd%\*.compiled"
del "%cd%\*.cfg"
del "%cd%\*.dof"
del "%cd%\*.dproj.local"
del "%cd%\*.identcache"
del "%cd%\*.dsk"
del "%cd%\*.skincfg"
del "%cd%\*.bak"
del "%cd%\*.rsm"
del "%cd%\*.~*"

View File

@@ -0,0 +1,84 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : CreateZIPDemo2
// * Purpose : Демонстрация изменения добавленных записей
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2023.
// * Version : 2.0.0
// * 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/
//
// Данный пример показывает различные варианты изменения записей
// в еще не сформированном архиве.
program CreateZIPDemo2;
{$IFDEF FPC}
{$MODE Delphi}
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}
uses
SysUtils,
TypInfo,
FWZipZLib,
FWZipWriter;
var
Zip: TFWZipWriter;
Item: TFWZipWriterItem;
I: Integer;
BuildZipResult: TBuildZipResult;
begin
SetCurrentDir(ExtractFilePath(ParamStr(0)));
try
Zip := TFWZipWriter.Create;
try
// Для начала добавим в корень архива файлы из корневой директории
Zip.AddFolder('..\..\', False);
// Теперь изменим им свойства:
for I := 0 to Zip.Count - 1 do
begin
Item := Zip[I];
// Изменим коментарий
Item.Comment := string('Тестовый коментарий к файлу ') + Item.FileName;
// Установим пароль
Item.Password := 'password';
// Изменим тип сжатия
Item.CompressionLevel := TCompressionLevel(Byte(I mod 3));
end;
// Теперь каждый элемент архива имеет коментарий, зашифрован паролем и
// имеет собственную степень сжатия в зависимости от своей
// порядковой позиции в архиве.
// Ну и сам архив так-же имеет коментарий.
Zip.Comment := 'Тестовый коментарий ко всему архиву';
// создаем архив и выводим результат
BuildZipResult := Zip.BuildZip('..\DemoResults\CreateZIPDemo2.zip');
// ... и вывести результат
Writeln(GetEnumName(TypeInfo(TBuildZipResult), Integer(BuildZipResult)));
finally
Zip.Free;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.

View File

@@ -0,0 +1,152 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{15CDC38C-E807-44D8-BC70-FBEB85865A1B}</ProjectGuid>
<MainSource>CreateZIPDemo2.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>
<FrameworkType>None</FrameworkType>
<ProjectVersion>19.2</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_S>false</DCC_S>
<DCC_K>false</DCC_K>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;UIDeviceFamily=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;UISupportedInterfaceOrientations=;CFBundleExecutable=;CFBundleResourceSpecification=;LSRequiresIPhoneOS=;CFBundleInfoDictionaryVersion=;CFBundleDevelopmentRegion=</VerInfo_Keys>
<DCC_F>false</DCC_F>
<VerInfo_Locale>1049</VerInfo_Locale>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
<DCC_ImageBase>00400000</DCC_ImageBase>
<SanitizedProjectName>CreateZIPDemo2</SanitizedProjectName>
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)</VerInfo_Keys>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_DebugInformation>0</DCC_DebugInformation>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<DCC_UnitSearchPath>..\..\;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)</VerInfo_Keys>
<Manifest_File>(None)</Manifest_File>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">CreateZIPDemo2.dpr</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="CFBundleName"/>
<VersionInfoKeys Name="CFBundleDisplayName"/>
<VersionInfoKeys Name="UIDeviceFamily"/>
<VersionInfoKeys Name="CFBundleIdentifier"/>
<VersionInfoKeys Name="CFBundleVersion"/>
<VersionInfoKeys Name="CFBundlePackageType"/>
<VersionInfoKeys Name="CFBundleSignature"/>
<VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
<VersionInfoKeys Name="UISupportedInterfaceOrientations"/>
<VersionInfoKeys Name="CFBundleExecutable"/>
<VersionInfoKeys Name="CFBundleResourceSpecification"/>
<VersionInfoKeys Name="LSRequiresIPhoneOS"/>
<VersionInfoKeys Name="CFBundleInfoDictionaryVersion"/>
<VersionInfoKeys Name="CFBundleDevelopmentRegion"/>
</VersionInfoKeys>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k270.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp270.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Platforms>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="CreateZIPDemo2"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<BuildModes>
<Item Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<RequiredPackages>
<Item>
<PackageName Value="LCL"/>
</Item>
</RequiredPackages>
<Units>
<Unit>
<Filename Value="CreateZIPDemo2.dpr"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<SearchPaths>
<IncludeFiles Value="..\..;$(ProjOutDir)"/>
<Libraries Value="..\..\fpc_lib"/>
<OtherUnitFiles Value="..\.."/>
<UnitOutputDirectory Value="."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="Delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2Set"/>
</Debugging>
</Linking>
<Other>
<CustomOptions Value="-dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions>
<Item>
<Name Value="EAbort"/>
</Item>
<Item>
<Name Value="ECodetoolError"/>
</Item>
<Item>
<Name Value="EFOpenError"/>
</Item>
</Exceptions>
</Debugging>
</CONFIG>

View File

@@ -0,0 +1,24 @@
rd /S /Q "%cd%\backup\"
rd /S /Q "%cd%\ConverterBackup\"
rd /S /Q "%cd%\lib\"
rd /S /Q "%cd%\__history\"
rd /S /Q "%cd%\__recovery\"
del "%cd%\*.o"
del "%cd%\*.a"
del "%cd%\*.or"
del "%cd%\*.lps"
del "%cd%\*.obj"
del "%cd%\*.exe"
del "%cd%\*.ppu"
del "%cd%\*.dcu"
del "%cd%\*.log"
del "%cd%\*.compiled"
del "%cd%\*.cfg"
del "%cd%\*.dof"
del "%cd%\*.dproj.local"
del "%cd%\*.identcache"
del "%cd%\*.dsk"
del "%cd%\*.skincfg"
del "%cd%\*.bak"
del "%cd%\*.rsm"
del "%cd%\*.~*"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,107 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : ExctractZIPDemo1
// * Purpose : Демонстрация распаковки архива.
// * : Используется архив созданный демоприложением CreateZIPDemo1
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2023.
// * Version : 2.0.1
// * 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/
//
// Данный пример показывает два варианта извлечения информации из архива.
program ExctractZIPDemo1;
{$IFDEF FPC}
{$MODE Delphi}
{$H+}
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}
uses
Classes,
SysUtils,
TypInfo,
FWZipReader,
FWZipUtils;
function ExtractResultStr(Value: TExtractResult): string;
begin
Result := GetEnumName(TypeInfo(TExtractResult), Integer(Value));
end;
var
Zip: TFWZipReader;
Index: Integer;
M: TStringStream;
begin
SetCurrentDir(ExtractFilePath(ParamStr(0)));
try
Zip := TFWZipReader.Create;
try
// Открываем ранее созданный архив
Zip.LoadFromFile('..\DemoResults\CreateZIPDemo1.zip');
// Первый вариант распаковки - ручной доступ к каждому элементу архива
// В примере CreateZIPDemo1 мы создали в корне архива файл Test.txt
// Нам необходимо получить индекс этого элемента в архиве
Index := Zip.GetElementIndex('test.txt');
if Index >= 0 then
begin
// Распаковать можно в память:
M := TStringStream.Create('');
try
Zip[Index].ExtractToStream(M, '');
// Файл извлечен, выведем его содержимое в окно консоли
{$IFDEF UNICODE}
Writeln(M.DataString);
{$ELSE}
{$IFDEF FPC}
Writeln(M.DataString);
{$ELSE}
Writeln(ConvertToOemString(AnsiString(M.DataString)));
{$ENDIF}
{$ENDIF}
finally
M.Free;
end;
// Распаковать так-же можно на диск:
Write('Extract "', Zip[Index].FileName, '": ');
Writeln(ExtractResultStr(
Zip[Index].Extract('..\DemoResults\CreateZIPDemo1\ManualExtract\', '')));
end;
// Таким-же образом можно получить содержимое остальных файлов
// Второй вариант распаковки - автоматической распаковка архива
// в указанную папку на диске
Zip.ExtractAll('..\DemoResults\CreateZIPDemo1\');
// Третий вариант распаковки - автоматическая распаковка по маске
// (данный код распакует все файлы находящиеся в папке AddFolderDemo архива)
Zip.ExtractAll('AddFolderDemo*', '..\DemoResults\CreateZIPDemo1\ExtractMasked\');
finally
Zip.Free;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.

View File

@@ -0,0 +1,868 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{B06883A2-58D3-4606-BFC2-63551788655E}</ProjectGuid>
<MainSource>ExctractZIPDemo1.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>
<FrameworkType>None</FrameworkType>
<ProjectVersion>19.2</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_S>false</DCC_S>
<DCC_K>false</DCC_K>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;UIDeviceFamily=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;UISupportedInterfaceOrientations=;CFBundleExecutable=;CFBundleResourceSpecification=;LSRequiresIPhoneOS=;CFBundleInfoDictionaryVersion=;CFBundleDevelopmentRegion=</VerInfo_Keys>
<DCC_F>false</DCC_F>
<VerInfo_Locale>1049</VerInfo_Locale>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace)</DCC_Namespace>
<DCC_ImageBase>00400000</DCC_ImageBase>
<SanitizedProjectName>ExctractZIPDemo1</SanitizedProjectName>
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)</VerInfo_Keys>
<DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_DebugInformation>0</DCC_DebugInformation>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<DCC_UnitSearchPath>..\..\;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)</VerInfo_Keys>
<Manifest_File>(None)</Manifest_File>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">ExctractZIPDemo1.dpr</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="CFBundleName"/>
<VersionInfoKeys Name="CFBundleDisplayName"/>
<VersionInfoKeys Name="UIDeviceFamily"/>
<VersionInfoKeys Name="CFBundleIdentifier"/>
<VersionInfoKeys Name="CFBundleVersion"/>
<VersionInfoKeys Name="CFBundlePackageType"/>
<VersionInfoKeys Name="CFBundleSignature"/>
<VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
<VersionInfoKeys Name="UISupportedInterfaceOrientations"/>
<VersionInfoKeys Name="CFBundleExecutable"/>
<VersionInfoKeys Name="CFBundleResourceSpecification"/>
<VersionInfoKeys Name="LSRequiresIPhoneOS"/>
<VersionInfoKeys Name="CFBundleInfoDictionaryVersion"/>
<VersionInfoKeys Name="CFBundleDevelopmentRegion"/>
</VersionInfoKeys>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k270.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp270.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Platforms>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
<Deployment Version="3">
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="OSX32">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="iOSSimulator">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libpcre.dylib" Class="DependencyModule">
<Platform Name="iOSSimulator">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ExctractZIPDemo1.exe" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>ExctractZIPDemo1.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClassesDexFile">
<Platform Name="Android">
<RemoteDir>classes</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>classes</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidFileProvider">
<Platform Name="Android">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidGDBServer">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiFile">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiv7aFile">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeMipsFile">
<Platform Name="Android">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput_Android32">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashImageDef">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStyles">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStylesV21">
<Platform Name="Android">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Colors">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_DefaultAppIcon">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon144">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon192">
<Platform Name="Android">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon24">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage426">
<Platform Name="Android">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage470">
<Platform Name="Android">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage640">
<Platform Name="Android">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage960">
<Platform Name="Android">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Strings">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyFramework">
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyModule">
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="DependencyPackage">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Name="File">
<Platform Name="Android">
<Operation>0</Operation>
</Platform>
<Platform Name="Android64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX64">
<Operation>0</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iOS_AppStore1024">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_AppIcon152">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_AppIcon167">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Notification40">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Setting58">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_SpotLight80">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_AppIcon120">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_AppIcon180">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Notification40">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Notification60">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Setting58">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Setting87">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Spotlight120">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Spotlight80">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectAndroidManifest">
<Platform Name="Android">
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceDebug">
<Platform Name="iOSDevice32">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSEntitlements"/>
<DeployClass Name="ProjectiOSInfoPList"/>
<DeployClass Name="ProjectiOSLaunchScreen"/>
<DeployClass Name="ProjectiOSResource">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXDebug"/>
<DeployClass Name="ProjectOSXEntitlements"/>
<DeployClass Name="ProjectOSXInfoPList"/>
<DeployClass Name="ProjectOSXResource">
<Platform Name="OSX32">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="ProjectOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="Linux64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOutput_Android32">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectUWPManifest">
<Platform Name="Win32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo150">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo44">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Android64" Name="$(PROJECTNAME)"/>
</Deployment>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
<Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/>
</Project>

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="ExctractZIPDemo1"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<BuildModes>
<Item Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<RequiredPackages>
<Item>
<PackageName Value="LCL"/>
</Item>
</RequiredPackages>
<Units>
<Unit>
<Filename Value="ExctractZIPDemo1.dpr"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<SearchPaths>
<IncludeFiles Value="../..;$(ProjOutDir)"/>
<Libraries Value="../../fpc_lib"/>
<OtherUnitFiles Value="../.."/>
<UnitOutputDirectory Value="."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="Delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2Set"/>
</Debugging>
</Linking>
<Other>
<CustomOptions Value="-dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions>
<Item>
<Name Value="EAbort"/>
</Item>
<Item>
<Name Value="ECodetoolError"/>
</Item>
<Item>
<Name Value="EFOpenError"/>
</Item>
</Exceptions>
</Debugging>
</CONFIG>

View File

@@ -0,0 +1,24 @@
rd /S /Q "%cd%\backup\"
rd /S /Q "%cd%\ConverterBackup\"
rd /S /Q "%cd%\lib\"
rd /S /Q "%cd%\__history\"
rd /S /Q "%cd%\__recovery\"
del "%cd%\*.o"
del "%cd%\*.a"
del "%cd%\*.or"
del "%cd%\*.lps"
del "%cd%\*.obj"
del "%cd%\*.exe"
del "%cd%\*.ppu"
del "%cd%\*.dcu"
del "%cd%\*.log"
del "%cd%\*.compiled"
del "%cd%\*.cfg"
del "%cd%\*.dof"
del "%cd%\*.dproj.local"
del "%cd%\*.identcache"
del "%cd%\*.dsk"
del "%cd%\*.skincfg"
del "%cd%\*.bak"
del "%cd%\*.rsm"
del "%cd%\*.~*"

View File

@@ -0,0 +1,135 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : ExctractZIPDemo2
// * Purpose : Демонстрация распаковки зашифрованного архива.
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2023.
// * Version : 2.0.0
// * 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/
//
// Данный пример показывает создание и распаковку зашифрованного архива.
// Для демонстрации работы со списком паролей мы создадим архив,
// в котором каждому элементу назначим произвольный пароль из списка.
// При чем код излечения данных не будет знать какому файлу
// какой из паролей соответствует и есть ли пароль вообще.
program ExctractZIPDemo2;
{$IFDEF FPC}
{$MODE Delphi}
{$H+}
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}
uses
SysUtils,
FWZipWriter,
FWZipReader,
FWZipConsts;
const
PasswordList: array [0..3] of string = (
'', 'password1', 'password2', 'password3');
procedure OnPassword(Self, Sender: TObject; const FileName: string;
var Password: string; var CancelExtract: Boolean);
begin
{$IFDEF FPC}
// FPC ворнинги прописывает, просто чтобы не орала.
if (Self <> nil) and (FileName <> '') then
CancelExtract := False;
{$ENDIF}
Password := PasswordList[3];
end;
var
Writer: TFWZipWriter;
Reader: TFWZipReader;
Item: TFWZipWriterItem;
I: Integer;
ExtractResult: TExtractResult;
Method: TMethod;
begin
SetCurrentDir(ExtractFilePath(ParamStr(0)));
try
Writer := TFWZipWriter.Create;
try
// Для начала добавим в корень архива файлы из корневой директории
Writer.AddFolder('..\..\', False);
// Теперь назначим им пароли случайным образом
Randomize;
// У первого элемента пароль всегда будет присутствовать (для демонстрации)
Item := Writer[0];
Item.Password := PasswordList[Random(3) + 1];
Item.NeedDescriptor := True;
for I := 1 to Writer.Count - 1 do
begin
Item := Writer[I];
// Если используется шифрование желательно включать дескриптор файла
// см. Readme.txt
Item.NeedDescriptor := True;
Item.Password := PasswordList[Random(4)];
end;
// Сохраняем результат
Writer.BuildZip('..\DemoResults\ExctractZIPDemo2.zip');
finally
Writer.Free;
end;
Reader := TFWZipReader.Create;
try
Reader.LoadFromFile('..\DemoResults\ExctractZIPDemo2.zip');
// Теперь наша задача извлечь данные из архива
// В ручном режиме распаковки придется перебирать пароли самостоятельно
// Например вот так:
I := 0;
repeat
ExtractResult := Reader[0].Extract(
'..\DemoResults\ExctractZIPDemo2\ManualExtract\', PasswordList[I]);
Inc(I);
until ExtractResult <> erNeedPassword;
// Если предполагается использовать режим автоматической распаковки,
// то указать пароли можно двумя способами
// 1. через список паролей
Reader.PasswordList.Add(PasswordList[1]);
Reader.PasswordList.Add(PasswordList[2]);
// 2. через обработчик
Method.Code := @OnPassword;
Method.Data := Reader;
Reader.OnPassword := TZipNeedPasswordEvent(Method);
// для демонстрации в список паролей добавлены только два пароля
// третий будет передан через обработчик события OnPassword
Reader.ExtractAll('..\DemoResults\ExctractZIPDemo2\');
finally
Reader.Free;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.

View File

@@ -0,0 +1,152 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{307D5F68-F671-4EF6-85EA-CF49C71350C7}</ProjectGuid>
<MainSource>ExctractZIPDemo2.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>
<FrameworkType>None</FrameworkType>
<ProjectVersion>19.2</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_S>false</DCC_S>
<DCC_K>false</DCC_K>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;UIDeviceFamily=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;UISupportedInterfaceOrientations=;CFBundleExecutable=;CFBundleResourceSpecification=;LSRequiresIPhoneOS=;CFBundleInfoDictionaryVersion=;CFBundleDevelopmentRegion=</VerInfo_Keys>
<DCC_F>false</DCC_F>
<VerInfo_Locale>1049</VerInfo_Locale>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
<DCC_ImageBase>00400000</DCC_ImageBase>
<SanitizedProjectName>ExctractZIPDemo2</SanitizedProjectName>
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)</VerInfo_Keys>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_DebugInformation>0</DCC_DebugInformation>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<DCC_UnitSearchPath>../../;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)</VerInfo_Keys>
<Manifest_File>(None)</Manifest_File>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">ExctractZIPDemo2.dpr</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="CFBundleName"/>
<VersionInfoKeys Name="CFBundleDisplayName"/>
<VersionInfoKeys Name="UIDeviceFamily"/>
<VersionInfoKeys Name="CFBundleIdentifier"/>
<VersionInfoKeys Name="CFBundleVersion"/>
<VersionInfoKeys Name="CFBundlePackageType"/>
<VersionInfoKeys Name="CFBundleSignature"/>
<VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
<VersionInfoKeys Name="UISupportedInterfaceOrientations"/>
<VersionInfoKeys Name="CFBundleExecutable"/>
<VersionInfoKeys Name="CFBundleResourceSpecification"/>
<VersionInfoKeys Name="LSRequiresIPhoneOS"/>
<VersionInfoKeys Name="CFBundleInfoDictionaryVersion"/>
<VersionInfoKeys Name="CFBundleDevelopmentRegion"/>
</VersionInfoKeys>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k270.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp270.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Platforms>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="ExctractZIPDemo2"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<BuildModes>
<Item Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<RequiredPackages>
<Item>
<PackageName Value="LCL"/>
</Item>
</RequiredPackages>
<Units>
<Unit>
<Filename Value="ExctractZIPDemo2.dpr"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<SearchPaths>
<IncludeFiles Value="../..;$(ProjOutDir)"/>
<Libraries Value="../../fpc_lib"/>
<OtherUnitFiles Value="../.."/>
<UnitOutputDirectory Value="."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="Delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2Set"/>
</Debugging>
</Linking>
<Other>
<CustomOptions Value="-dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions>
<Item>
<Name Value="EAbort"/>
</Item>
<Item>
<Name Value="ECodetoolError"/>
</Item>
<Item>
<Name Value="EFOpenError"/>
</Item>
</Exceptions>
</Debugging>
</CONFIG>

View File

@@ -0,0 +1,24 @@
rd /S /Q "%cd%\backup\"
rd /S /Q "%cd%\ConverterBackup\"
rd /S /Q "%cd%\lib\"
rd /S /Q "%cd%\__history\"
rd /S /Q "%cd%\__recovery\"
del "%cd%\*.o"
del "%cd%\*.a"
del "%cd%\*.or"
del "%cd%\*.lps"
del "%cd%\*.obj"
del "%cd%\*.exe"
del "%cd%\*.ppu"
del "%cd%\*.dcu"
del "%cd%\*.log"
del "%cd%\*.compiled"
del "%cd%\*.cfg"
del "%cd%\*.dof"
del "%cd%\*.dproj.local"
del "%cd%\*.identcache"
del "%cd%\*.dsk"
del "%cd%\*.skincfg"
del "%cd%\*.bak"
del "%cd%\*.rsm"
del "%cd%\*.~*"

View File

@@ -0,0 +1,216 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{DEBDAF2E-104F-436D-8AFC-8BAC60505E64}</ProjectGuid>
</PropertyGroup>
<ItemGroup>
<Projects Include="Create ZIP 1\CreateZIPDemo1.dproj">
<Dependencies/>
</Projects>
<Projects Include="Create ZIP 2\CreateZIPDemo2.dproj">
<Dependencies/>
</Projects>
<Projects Include="Extract ZIP 1\ExctractZIPDemo1.dproj">
<Dependencies/>
</Projects>
<Projects Include="Extract ZIP 2\ExctractZIPDemo2.dproj">
<Dependencies/>
</Projects>
<Projects Include="PerfomanceTest\FWZipPerfomance.dproj">
<Dependencies/>
</Projects>
<Projects Include="Test Build With Exception\BuildWithException.dproj">
<Dependencies/>
</Projects>
<Projects Include="Use ZIP ExData\UseExDataBlob.dproj">
<Dependencies/>
</Projects>
<Projects Include="ZipAnalizer\ZipAnalizer.dproj">
<Dependencies/>
</Projects>
<Projects Include="ZipAnalizer2\ZipAnalizer2.dproj">
<Dependencies/>
</Projects>
<Projects Include="Modify ZIP\Split ZIP\SplitZip.dproj">
<Dependencies/>
</Projects>
<Projects Include="Modify ZIP\Merge two ZIP\MergeZip.dproj">
<Dependencies/>
</Projects>
<Projects Include="Modify ZIP\Replace data in ZIP\ReplaceZipItemData.dproj">
<Dependencies/>
</Projects>
<Projects Include="..\.UnitTest\FWZipUnitTest.dproj">
<Dependencies/>
</Projects>
<Projects Include="MultyPart ZIP\Create MultiPart ZIP\CreateMultiPartZip.dproj">
<Dependencies/>
</Projects>
<Projects Include="MultyPart ZIP\Modify MultiPart Zip\ModifyMultiPartZip.dproj">
<Dependencies/>
</Projects>
<Projects Include="MultyPart ZIP\Read MultiPart ZIP\ReadMultiPartZip.dproj">
<Dependencies/>
</Projects>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Default.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Default.Personality/>
</BorlandProject>
</ProjectExtensions>
<Target Name="CreateZIPDemo1">
<MSBuild Projects="Create ZIP 1\CreateZIPDemo1.dproj"/>
</Target>
<Target Name="CreateZIPDemo1:Clean">
<MSBuild Projects="Create ZIP 1\CreateZIPDemo1.dproj" Targets="Clean"/>
</Target>
<Target Name="CreateZIPDemo1:Make">
<MSBuild Projects="Create ZIP 1\CreateZIPDemo1.dproj" Targets="Make"/>
</Target>
<Target Name="CreateZIPDemo2">
<MSBuild Projects="Create ZIP 2\CreateZIPDemo2.dproj"/>
</Target>
<Target Name="CreateZIPDemo2:Clean">
<MSBuild Projects="Create ZIP 2\CreateZIPDemo2.dproj" Targets="Clean"/>
</Target>
<Target Name="CreateZIPDemo2:Make">
<MSBuild Projects="Create ZIP 2\CreateZIPDemo2.dproj" Targets="Make"/>
</Target>
<Target Name="ExctractZIPDemo1">
<MSBuild Projects="Extract ZIP 1\ExctractZIPDemo1.dproj"/>
</Target>
<Target Name="ExctractZIPDemo1:Clean">
<MSBuild Projects="Extract ZIP 1\ExctractZIPDemo1.dproj" Targets="Clean"/>
</Target>
<Target Name="ExctractZIPDemo1:Make">
<MSBuild Projects="Extract ZIP 1\ExctractZIPDemo1.dproj" Targets="Make"/>
</Target>
<Target Name="ExctractZIPDemo2">
<MSBuild Projects="Extract ZIP 2\ExctractZIPDemo2.dproj"/>
</Target>
<Target Name="ExctractZIPDemo2:Clean">
<MSBuild Projects="Extract ZIP 2\ExctractZIPDemo2.dproj" Targets="Clean"/>
</Target>
<Target Name="ExctractZIPDemo2:Make">
<MSBuild Projects="Extract ZIP 2\ExctractZIPDemo2.dproj" Targets="Make"/>
</Target>
<Target Name="FWZipPerfomance">
<MSBuild Projects="PerfomanceTest\FWZipPerfomance.dproj"/>
</Target>
<Target Name="FWZipPerfomance:Clean">
<MSBuild Projects="PerfomanceTest\FWZipPerfomance.dproj" Targets="Clean"/>
</Target>
<Target Name="FWZipPerfomance:Make">
<MSBuild Projects="PerfomanceTest\FWZipPerfomance.dproj" Targets="Make"/>
</Target>
<Target Name="BuildWithException">
<MSBuild Projects="Test Build With Exception\BuildWithException.dproj"/>
</Target>
<Target Name="BuildWithException:Clean">
<MSBuild Projects="Test Build With Exception\BuildWithException.dproj" Targets="Clean"/>
</Target>
<Target Name="BuildWithException:Make">
<MSBuild Projects="Test Build With Exception\BuildWithException.dproj" Targets="Make"/>
</Target>
<Target Name="UseExDataBlob">
<MSBuild Projects="Use ZIP ExData\UseExDataBlob.dproj"/>
</Target>
<Target Name="UseExDataBlob:Clean">
<MSBuild Projects="Use ZIP ExData\UseExDataBlob.dproj" Targets="Clean"/>
</Target>
<Target Name="UseExDataBlob:Make">
<MSBuild Projects="Use ZIP ExData\UseExDataBlob.dproj" Targets="Make"/>
</Target>
<Target Name="ZipAnalizer">
<MSBuild Projects="ZipAnalizer\ZipAnalizer.dproj"/>
</Target>
<Target Name="ZipAnalizer:Clean">
<MSBuild Projects="ZipAnalizer\ZipAnalizer.dproj" Targets="Clean"/>
</Target>
<Target Name="ZipAnalizer:Make">
<MSBuild Projects="ZipAnalizer\ZipAnalizer.dproj" Targets="Make"/>
</Target>
<Target Name="ZipAnalizer2">
<MSBuild Projects="ZipAnalizer2\ZipAnalizer2.dproj"/>
</Target>
<Target Name="ZipAnalizer2:Clean">
<MSBuild Projects="ZipAnalizer2\ZipAnalizer2.dproj" Targets="Clean"/>
</Target>
<Target Name="ZipAnalizer2:Make">
<MSBuild Projects="ZipAnalizer2\ZipAnalizer2.dproj" Targets="Make"/>
</Target>
<Target Name="SplitZip">
<MSBuild Projects="Modify ZIP\Split ZIP\SplitZip.dproj"/>
</Target>
<Target Name="SplitZip:Clean">
<MSBuild Projects="Modify ZIP\Split ZIP\SplitZip.dproj" Targets="Clean"/>
</Target>
<Target Name="SplitZip:Make">
<MSBuild Projects="Modify ZIP\Split ZIP\SplitZip.dproj" Targets="Make"/>
</Target>
<Target Name="MergeZip">
<MSBuild Projects="Modify ZIP\Merge two ZIP\MergeZip.dproj"/>
</Target>
<Target Name="MergeZip:Clean">
<MSBuild Projects="Modify ZIP\Merge two ZIP\MergeZip.dproj" Targets="Clean"/>
</Target>
<Target Name="MergeZip:Make">
<MSBuild Projects="Modify ZIP\Merge two ZIP\MergeZip.dproj" Targets="Make"/>
</Target>
<Target Name="ReplaceZipItemData">
<MSBuild Projects="Modify ZIP\Replace data in ZIP\ReplaceZipItemData.dproj"/>
</Target>
<Target Name="ReplaceZipItemData:Clean">
<MSBuild Projects="Modify ZIP\Replace data in ZIP\ReplaceZipItemData.dproj" Targets="Clean"/>
</Target>
<Target Name="ReplaceZipItemData:Make">
<MSBuild Projects="Modify ZIP\Replace data in ZIP\ReplaceZipItemData.dproj" Targets="Make"/>
</Target>
<Target Name="FWZipUnitTest">
<MSBuild Projects="..\.UnitTest\FWZipUnitTest.dproj"/>
</Target>
<Target Name="FWZipUnitTest:Clean">
<MSBuild Projects="..\.UnitTest\FWZipUnitTest.dproj" Targets="Clean"/>
</Target>
<Target Name="FWZipUnitTest:Make">
<MSBuild Projects="..\.UnitTest\FWZipUnitTest.dproj" Targets="Make"/>
</Target>
<Target Name="CreateMultiPartZip">
<MSBuild Projects="MultyPart ZIP\Create MultiPart ZIP\CreateMultiPartZip.dproj"/>
</Target>
<Target Name="CreateMultiPartZip:Clean">
<MSBuild Projects="MultyPart ZIP\Create MultiPart ZIP\CreateMultiPartZip.dproj" Targets="Clean"/>
</Target>
<Target Name="CreateMultiPartZip:Make">
<MSBuild Projects="MultyPart ZIP\Create MultiPart ZIP\CreateMultiPartZip.dproj" Targets="Make"/>
</Target>
<Target Name="ModifyMultiPartZip">
<MSBuild Projects="MultyPart ZIP\Modify MultiPart Zip\ModifyMultiPartZip.dproj"/>
</Target>
<Target Name="ModifyMultiPartZip:Clean">
<MSBuild Projects="MultyPart ZIP\Modify MultiPart Zip\ModifyMultiPartZip.dproj" Targets="Clean"/>
</Target>
<Target Name="ModifyMultiPartZip:Make">
<MSBuild Projects="MultyPart ZIP\Modify MultiPart Zip\ModifyMultiPartZip.dproj" Targets="Make"/>
</Target>
<Target Name="ReadMultiPartZip">
<MSBuild Projects="MultyPart ZIP\Read MultiPart ZIP\ReadMultiPartZip.dproj"/>
</Target>
<Target Name="ReadMultiPartZip:Clean">
<MSBuild Projects="MultyPart ZIP\Read MultiPart ZIP\ReadMultiPartZip.dproj" Targets="Clean"/>
</Target>
<Target Name="ReadMultiPartZip:Make">
<MSBuild Projects="MultyPart ZIP\Read MultiPart ZIP\ReadMultiPartZip.dproj" Targets="Make"/>
</Target>
<Target Name="Build">
<CallTarget Targets="CreateZIPDemo1;CreateZIPDemo2;ExctractZIPDemo1;ExctractZIPDemo2;FWZipPerfomance;BuildWithException;UseExDataBlob;ZipAnalizer;ZipAnalizer2;SplitZip;MergeZip;ReplaceZipItemData;FWZipUnitTest;CreateMultiPartZip;ModifyMultiPartZip;ReadMultiPartZip"/>
</Target>
<Target Name="Clean">
<CallTarget Targets="CreateZIPDemo1:Clean;CreateZIPDemo2:Clean;ExctractZIPDemo1:Clean;ExctractZIPDemo2:Clean;FWZipPerfomance:Clean;BuildWithException:Clean;UseExDataBlob:Clean;ZipAnalizer:Clean;ZipAnalizer2:Clean;SplitZip:Clean;MergeZip:Clean;ReplaceZipItemData:Clean;FWZipUnitTest:Clean;CreateMultiPartZip:Clean;ModifyMultiPartZip:Clean;ReadMultiPartZip:Clean"/>
</Target>
<Target Name="Make">
<CallTarget Targets="CreateZIPDemo1:Make;CreateZIPDemo2:Make;ExctractZIPDemo1:Make;ExctractZIPDemo2:Make;FWZipPerfomance:Make;BuildWithException:Make;UseExDataBlob:Make;ZipAnalizer:Make;ZipAnalizer2:Make;SplitZip:Make;MergeZip:Make;ReplaceZipItemData:Make;FWZipUnitTest:Make;CreateMultiPartZip:Make;ModifyMultiPartZip:Make;ReadMultiPartZip:Make"/>
</Target>
<Import Project="$(BDS)\Bin\CodeGear.Group.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Group.Targets')"/>
</Project>

View File

@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectGroup FileVersion="2">
<Targets>
<Target FileName="Create ZIP 1\CreateZIPDemo1.lpi">
<BuildModes>
<Mode Name="Default"/>
</BuildModes>
</Target>
<Target FileName="Create ZIP 2\CreateZIPDemo2.lpi">
<BuildModes>
<Mode Name="Default"/>
</BuildModes>
</Target>
<Target FileName="Extract ZIP 1\ExctractZIPDemo1.lpi">
<BuildModes>
<Mode Name="Default"/>
</BuildModes>
</Target>
<Target FileName="Extract ZIP 2\ExctractZIPDemo2.lpi">
<BuildModes>
<Mode Name="Default"/>
</BuildModes>
</Target>
<Target FileName="Modify ZIP\Split ZIP\SplitZip.lpi">
<BuildModes>
<Mode Name="Default"/>
</BuildModes>
</Target>
<Target FileName="Modify ZIP\Merge two ZIP\MergeZip.lpi">
<BuildModes>
<Mode Name="Default"/>
</BuildModes>
</Target>
<Target FileName="Modify ZIP\Replace data in ZIP\ReplaceZipItemData.lpi">
<BuildModes>
<Mode Name="Default"/>
</BuildModes>
</Target>
<Target FileName="MultyPart ZIP\Create MultiPart ZIP\CreateMultiPartZip.lpi">
<BuildModes>
<Mode Name="Default"/>
</BuildModes>
</Target>
<Target FileName="MultyPart ZIP\Read MultiPart ZIP\ReadMultiPartZip.lpi">
<BuildModes>
<Mode Name="Default"/>
</BuildModes>
</Target>
<Target FileName="MultyPart ZIP\Modify MultiPart ZIP\ModifyMultiPartZip.lpi">
<BuildModes>
<Mode Name="Default"/>
</BuildModes>
</Target>
<Target FileName="PerfomanceTest\FWZipPerfomance.lpi">
<BuildModes>
<Mode Name="Default"/>
</BuildModes>
</Target>
<Target FileName="Test Build With Exception\BuildWithException.lpi">
<BuildModes>
<Mode Name="Default"/>
</BuildModes>
</Target>
<Target FileName="Use ZIP ExData\UseExDataBlob.lpi">
<BuildModes>
<Mode Name="Default"/>
</BuildModes>
</Target>
<Target FileName="ZipAnalizer\ZipAnalizer.lpi">
<BuildModes>
<Mode Name="Default"/>
</BuildModes>
</Target>
<Target FileName="ZipAnalizer2\ZipAnalizer2.lpi">
<BuildModes>
<Mode Name="Default"/>
</BuildModes>
</Target>
</Targets>
</ProjectGroup>
</CONFIG>

View File

@@ -0,0 +1,71 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : MergeZip
// * Purpose : Демонстрация обьединения нескольких архивов
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2023.
// * Version : 2.0.0
// * 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/
//
// Данный пример показывает как можно обьединить несколько
// ранее созданных архивов в один,
// без необходимости распаковки данных и повторного сжатия.
program MergeZip;
{$IFDEF FPC}
{$MODE Delphi}
{$H+}
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}
uses
SysUtils,
FWZipModifier;
var
Modifier: TFWZipModifier;
Index1, Index2: TReaderIndex;
begin
SetCurrentDir(ExtractFilePath(ParamStr(0)));
try
// создаем экземпляр модификатора архивов
Modifier := TFWZipModifier.Create;
try
// подключаем первый архив, который был создан в примере SplitZip
Index1 := Modifier.AddZipFile('..\..\DemoResults\splited_archive1.zip');
// подключаем второй архив
Index2 := Modifier.AddZipFile('..\..\DemoResults\splited_archive2.zip');
// добавляем все элементы из первого архива
Modifier.AddFromZip(Index1);
// и из второго
Modifier.AddFromZip(Index2);
// теперь создаем новый архив который будет включать в себя все элементы обоих архивов
// и технически будет идентичен архиву split_main_archive.zip, который
// был создан в примере SplitZip (оба архива будут совпадать вплоть до контрольной суммы)
Modifier.BuildZip('..\..\DemoResults\merged_archive.zip')
finally
Modifier.Free;
end;
// пример изменения данных, не трогая остальные элементы архива
// можно увидеть в примере ReplaceZipItemData
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.

View File

@@ -0,0 +1,152 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{0C461837-3166-43B0-98D4-CEA909363C55}</ProjectGuid>
<MainSource>MergeZip.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>
<FrameworkType>None</FrameworkType>
<ProjectVersion>19.2</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_K>false</DCC_K>
<DCC_ImageBase>00400000</DCC_ImageBase>
<DCC_F>false</DCC_F>
<VerInfo_Locale>1049</VerInfo_Locale>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
<DCC_S>false</DCC_S>
<DCC_N>false</DCC_N>
<DCC_E>false</DCC_E>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;UIDeviceFamily=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;UISupportedInterfaceOrientations=;CFBundleExecutable=;CFBundleResourceSpecification=;LSRequiresIPhoneOS=;CFBundleInfoDictionaryVersion=;CFBundleDevelopmentRegion=</VerInfo_Keys>
<SanitizedProjectName>MergeZip</SanitizedProjectName>
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<VerInfo_Locale>1033</VerInfo_Locale>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_DebugInformation>0</DCC_DebugInformation>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<DCC_UnitSearchPath>../../../;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)</VerInfo_Keys>
<Manifest_File>(None)</Manifest_File>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">MergeZip.dpr</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="CFBundleName"/>
<VersionInfoKeys Name="CFBundleDisplayName"/>
<VersionInfoKeys Name="UIDeviceFamily"/>
<VersionInfoKeys Name="CFBundleIdentifier"/>
<VersionInfoKeys Name="CFBundleVersion"/>
<VersionInfoKeys Name="CFBundlePackageType"/>
<VersionInfoKeys Name="CFBundleSignature"/>
<VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
<VersionInfoKeys Name="UISupportedInterfaceOrientations"/>
<VersionInfoKeys Name="CFBundleExecutable"/>
<VersionInfoKeys Name="CFBundleResourceSpecification"/>
<VersionInfoKeys Name="LSRequiresIPhoneOS"/>
<VersionInfoKeys Name="CFBundleInfoDictionaryVersion"/>
<VersionInfoKeys Name="CFBundleDevelopmentRegion"/>
</VersionInfoKeys>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k270.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp270.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Platforms>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="MergeZip"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<BuildModes>
<Item Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<RequiredPackages>
<Item>
<PackageName Value="LCL"/>
</Item>
</RequiredPackages>
<Units>
<Unit>
<Filename Value="MergeZip.dpr"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<IncludeFiles Value="..\..\..;$(ProjOutDir)"/>
<Libraries Value="..\..\..\fpc_lib"/>
<OtherUnitFiles Value="..\..\.."/>
<UnitOutputDirectory Value="."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="Delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2Set"/>
</Debugging>
</Linking>
<Other>
<CustomOptions Value="-dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions>
<Item>
<Name Value="EAbort"/>
</Item>
<Item>
<Name Value="ECodetoolError"/>
</Item>
<Item>
<Name Value="EFOpenError"/>
</Item>
</Exceptions>
</Debugging>
</CONFIG>

View File

@@ -0,0 +1,24 @@
rd /S /Q "%cd%\backup\"
rd /S /Q "%cd%\ConverterBackup\"
rd /S /Q "%cd%\lib\"
rd /S /Q "%cd%\__history\"
rd /S /Q "%cd%\__recovery\"
del "%cd%\*.o"
del "%cd%\*.a"
del "%cd%\*.or"
del "%cd%\*.lps"
del "%cd%\*.obj"
del "%cd%\*.exe"
del "%cd%\*.ppu"
del "%cd%\*.dcu"
del "%cd%\*.log"
del "%cd%\*.compiled"
del "%cd%\*.cfg"
del "%cd%\*.dof"
del "%cd%\*.dproj.local"
del "%cd%\*.identcache"
del "%cd%\*.dsk"
del "%cd%\*.skincfg"
del "%cd%\*.bak"
del "%cd%\*.rsm"
del "%cd%\*.~*"

View File

@@ -0,0 +1,196 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : ReplaceZipItemData
// * Purpose : Демонстрация изменения данных в уже созданном архиве
// * 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/
// http://www.base2ti.com/
//
// Данный пример показывает как можно изменить данные в уже созданном архиве
// без необходимости распаковки неизмененных элементов и их повторного сжатия.
program ReplaceZipItemData;
{$IFDEF FPC}
{$MODE Delphi}
{$H+}
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}
uses
SysUtils,
Classes,
FWZipReader,
FWZipModifier;
var
Modifier: TFWZipModifier;
Reader: TFWZipReader;
Index: TReaderIndex;
S: TStringStream;
I: Integer;
begin
SetCurrentDir(ExtractFilePath(ParamStr(0)));
try
// создаем экземпляр модификатора архивов
Modifier := TFWZipModifier.Create;
try
// подключаем ранее созданный архив
Index := Modifier.AddZipFile('..\..\DemoResults\split_main_archive.zip');
// добавляем из него первый элемент указывая его имя
Modifier.AddFromZip(Index, 'test1.txt');
// добавляем второй элемент, взяв имя из внутреннего ридера
Modifier.AddFromZip(Index, Modifier.Reader[Index].Item[1].FileName);
// вместо третьего пишем новые данные
S := TStringStream.Create('новые данные для третьего элемента архива');
try
S.Position := 0;
Modifier.AddStream('test3.txt', S);
finally
S.Free;
end;
// ну и добавляем последний элемент с одновременным изменением имени
Modifier.AddFromZip(Index, 'test4.txt', 'New test4.txt');
// теперь делаем новый архив,
// при этом данные от первого второго и четвертого элемента
// скопируются как есть без распаковки,
// а вместо третьего элемента будет добавлен новый блок данных
Modifier.BuildZip('..\..\DemoResults\replaced_data_archive1.zip');
finally
Modifier.Free;
end;
// предыдущий вариант был с сохранением порядка элемента в архиве
// если же порядок не важен, то можно сделать еще проще:
// создаем экземпляр модификатора архивов
Modifier := TFWZipModifier.Create;
try
// подключаем ранее созданный архив
Index := Modifier.AddZipFile('..\..\DemoResults\split_main_archive.zip');
// добавляем все элементы
Modifier.AddFromZip(Index);
// теперь удалим запись о третьем элементе
Modifier.DeleteItem(2);
// и пишем новые данные
S := TStringStream.Create('новые данные для третьего элемента архива');
try
S.Position := 0;
Modifier.AddStream('test3.txt', S);
finally
S.Free;
end;
// теперь делаем новый архив, принцип тот же самый
Modifier.BuildZip('..\..\DemoResults\replaced_data_archive2.zip');
finally
Modifier.Free;
end;
// третий вариант с передачей ридера снаружи, причем время жизни ридера
// контролирем мы сами
// Содаем ридер который будем использовать не только для модификации
// но и для каких-то своих задач
Reader := TFWZipReader.Create;
try
// читаем данные из ранее созданного тестового архива
Reader.LoadFromFile('..\..\DemoResults\split_main_archive.zip');
// создаем экземпляр модификатора архивов
Modifier := TFWZipModifier.Create;
try
// подключаем архив через доступный нам ридер
Index := Modifier.AddZipFile(Reader);
// добавляем из него все элементы кроме последнего
for I := 0 to Modifier.Reader[Index].Count - 2 do
Modifier.AddFromZip(Index, Modifier.Reader[Index].Item[I].FileName);
// вместо последнего пишем новые данные
S := TStringStream.Create('новые данные для последнего элемента архива');
try
S.Position := 0;
Modifier.AddStream('test4.txt', S);
finally
S.Free;
end;
// и ребилдим архив
Modifier.BuildZip('..\..\DemoResults\replaced_data_archive3.zip');
finally
Modifier.Free;
end;
finally
Reader.Free;
end;
// четвертый вариант, это небольшая модификация епрвого варианта,
// только подключение архива происходит так-же как и в третьем через ридер
// но в этот раз время жизни ридера будет контролировать модификатор
// создаем экземпляр модификатора архивов
Modifier := TFWZipModifier.Create;
try
// создаем экземпляр ридера
Reader := TFWZipReader.Create;
// открываем ранее созданный архив
Reader.LoadFromFile('..\..\DemoResults\split_main_archive.zip');
// и подкючаем его к модификатору указывая вторым параметром,
// что разрушать ридер должен модификатор
Index := Modifier.AddZipFile(Reader, roOwned);
// добавляем из него первый элемент указывая его имя
Modifier.AddFromZip(Index, 'test1.txt');
// добавляем второй элемент, взяв имя из внутреннего ридера
Modifier.AddFromZip(Index, Modifier.Reader[Index].Item[1].FileName);
// вместо третьего пишем новые данные
S := TStringStream.Create('новые данные для третьего элемента архива');
try
S.Position := 0;
Modifier.AddStream('test3.txt', S);
finally
S.Free;
end;
// ну и добавляем последний элемент
Modifier.AddFromZip(Index, 'test4.txt');
// теперь делаем новый архив,
// при этом данные от первого второго и четвертого элемента
// скопируются как есть без распаковки,
// а вместо третьего элемента будет добавлен новый блок данных
Modifier.BuildZip('..\..\DemoResults\replaced_data_archive4.zip');
finally
Modifier.Free;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.

View File

@@ -0,0 +1,152 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{8453DFA8-0B2E-4EEF-AC75-7BBE052C1943}</ProjectGuid>
<MainSource>ReplaceZipItemData.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>
<FrameworkType>None</FrameworkType>
<ProjectVersion>19.2</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_K>false</DCC_K>
<DCC_ImageBase>00400000</DCC_ImageBase>
<DCC_F>false</DCC_F>
<VerInfo_Locale>1049</VerInfo_Locale>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
<DCC_S>false</DCC_S>
<DCC_N>false</DCC_N>
<DCC_E>false</DCC_E>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;UIDeviceFamily=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;UISupportedInterfaceOrientations=;CFBundleExecutable=;CFBundleResourceSpecification=;LSRequiresIPhoneOS=;CFBundleInfoDictionaryVersion=;CFBundleDevelopmentRegion=</VerInfo_Keys>
<SanitizedProjectName>ReplaceZipItemData</SanitizedProjectName>
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<VerInfo_Locale>1033</VerInfo_Locale>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_DebugInformation>0</DCC_DebugInformation>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<DCC_UnitSearchPath>../../../;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)</VerInfo_Keys>
<Manifest_File>(None)</Manifest_File>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">ReplaceZipItemData.dpr</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="CFBundleName"/>
<VersionInfoKeys Name="CFBundleDisplayName"/>
<VersionInfoKeys Name="UIDeviceFamily"/>
<VersionInfoKeys Name="CFBundleIdentifier"/>
<VersionInfoKeys Name="CFBundleVersion"/>
<VersionInfoKeys Name="CFBundlePackageType"/>
<VersionInfoKeys Name="CFBundleSignature"/>
<VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
<VersionInfoKeys Name="UISupportedInterfaceOrientations"/>
<VersionInfoKeys Name="CFBundleExecutable"/>
<VersionInfoKeys Name="CFBundleResourceSpecification"/>
<VersionInfoKeys Name="LSRequiresIPhoneOS"/>
<VersionInfoKeys Name="CFBundleInfoDictionaryVersion"/>
<VersionInfoKeys Name="CFBundleDevelopmentRegion"/>
</VersionInfoKeys>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k270.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp270.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Platforms>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="ReplaceZipItemData"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<BuildModes>
<Item Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<RequiredPackages>
<Item>
<PackageName Value="LCL"/>
</Item>
</RequiredPackages>
<Units>
<Unit>
<Filename Value="ReplaceZipItemData.dpr"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<IncludeFiles Value="..\..\..;$(ProjOutDir)"/>
<Libraries Value="..\..\..\fpc_lib"/>
<OtherUnitFiles Value="..\..\.."/>
<UnitOutputDirectory Value="."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="Delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2Set"/>
</Debugging>
</Linking>
<Other>
<CustomOptions Value="-dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions>
<Item>
<Name Value="EAbort"/>
</Item>
<Item>
<Name Value="ECodetoolError"/>
</Item>
<Item>
<Name Value="EFOpenError"/>
</Item>
</Exceptions>
</Debugging>
</CONFIG>

View File

@@ -0,0 +1,24 @@
rd /S /Q "%cd%\backup\"
rd /S /Q "%cd%\ConverterBackup\"
rd /S /Q "%cd%\lib\"
rd /S /Q "%cd%\__history\"
rd /S /Q "%cd%\__recovery\"
del "%cd%\*.o"
del "%cd%\*.a"
del "%cd%\*.or"
del "%cd%\*.lps"
del "%cd%\*.obj"
del "%cd%\*.exe"
del "%cd%\*.ppu"
del "%cd%\*.dcu"
del "%cd%\*.log"
del "%cd%\*.compiled"
del "%cd%\*.cfg"
del "%cd%\*.dof"
del "%cd%\*.dproj.local"
del "%cd%\*.identcache"
del "%cd%\*.dsk"
del "%cd%\*.skincfg"
del "%cd%\*.bak"
del "%cd%\*.rsm"
del "%cd%\*.~*"

View File

@@ -0,0 +1,106 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : SplitZip
// * Purpose : Демонстрация работы c разбитием архива
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2023.
// * Version : 2.0.0
// * 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/
//
// Данный пример показывает как можно разделить архив на несколько частей,
// без необходимости распаковки данных и повторного сжатия.
program SplitZip;
{$IFDEF FPC}
{$MODE Delphi}
{$H+}
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}
uses
SysUtils,
Classes,
FWZipWriter,
FWZipModifier;
procedure AddItem(AWriter: TFWZipWriter; const AName, AData: string);
var
S: TStringStream;
begin
S := TStringStream.Create(AData);
try
S.Position := 0;
AWriter.AddStream(AName, S);
finally
S.Free;
end;
end;
var
Writer: TFWZipWriter;
Modifier: TFWZipModifier;
Index: TReaderIndex;
begin
SetCurrentDir(ExtractFilePath(ParamStr(0)));
try
// создаем архив который будем разделять
Writer := TFWZipWriter.Create;
try
// добавляем 4 элемента в архив
AddItem(Writer, 'test1.txt', 'первый элемент');
AddItem(Writer, 'test2.txt', 'второй элемент');
AddItem(Writer, 'test3.txt', 'третий элемент');
AddItem(Writer, 'test4.txt', 'четвертый элемент');
// сохраняем
Writer.BuildZip('..\..\DemoResults\split_main_archive.zip');
finally
Writer.Free;
end;
// создаем экземпляр модификатора архивов
Modifier := TFWZipModifier.Create;
try
// подключаем ранее созданный архив
Index := Modifier.AddZipFile('..\..\DemoResults\split_main_archive.zip');
// добавляем из него первые два элемента
Modifier.AddFromZip(Index, 'test1.txt');
Modifier.AddFromZip(Index, 'test2.txt');
// и сохраняем в новый архив
// при этом реальной перепаковки данных не произойдет,
// данные возьмутся как есть в виде массива байт прямо в сжатом виде
// из оригинального архива
Modifier.BuildZip('..\..\DemoResults\splited_archive1.zip');
// теперь удаляем добавленные элементы и добавляем вторые два
Modifier.Clear;
Modifier.AddFromZip(Index, 'test3.txt');
Modifier.AddFromZip(Index, 'test4.txt');
// сохраняем во торой архив
Modifier.BuildZip('..\..\DemoResults\splited_archive2.zip');
finally
Modifier.Free;
end;
// вот и все, мы разделили изначальный архив на две части
// не занимаясь перепаковкой данных
// как обьединять смотрите в примере MergeZip
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.

View File

@@ -0,0 +1,152 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{CEAA2516-64BD-4590-AA4E-B25AFD2A0DF3}</ProjectGuid>
<MainSource>SplitZip.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>
<FrameworkType>None</FrameworkType>
<ProjectVersion>19.2</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_K>false</DCC_K>
<DCC_ImageBase>00400000</DCC_ImageBase>
<DCC_F>false</DCC_F>
<VerInfo_Locale>1049</VerInfo_Locale>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
<DCC_S>false</DCC_S>
<DCC_N>false</DCC_N>
<DCC_E>false</DCC_E>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;UIDeviceFamily=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;UISupportedInterfaceOrientations=;CFBundleExecutable=;CFBundleResourceSpecification=;LSRequiresIPhoneOS=;CFBundleInfoDictionaryVersion=;CFBundleDevelopmentRegion=</VerInfo_Keys>
<SanitizedProjectName>SplitZip</SanitizedProjectName>
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<VerInfo_Locale>1033</VerInfo_Locale>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_DebugInformation>0</DCC_DebugInformation>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<DCC_UnitSearchPath>../../../;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)</VerInfo_Keys>
<Manifest_File>(None)</Manifest_File>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">SplitZip.dpr</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="CFBundleName"/>
<VersionInfoKeys Name="CFBundleDisplayName"/>
<VersionInfoKeys Name="UIDeviceFamily"/>
<VersionInfoKeys Name="CFBundleIdentifier"/>
<VersionInfoKeys Name="CFBundleVersion"/>
<VersionInfoKeys Name="CFBundlePackageType"/>
<VersionInfoKeys Name="CFBundleSignature"/>
<VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
<VersionInfoKeys Name="UISupportedInterfaceOrientations"/>
<VersionInfoKeys Name="CFBundleExecutable"/>
<VersionInfoKeys Name="CFBundleResourceSpecification"/>
<VersionInfoKeys Name="LSRequiresIPhoneOS"/>
<VersionInfoKeys Name="CFBundleInfoDictionaryVersion"/>
<VersionInfoKeys Name="CFBundleDevelopmentRegion"/>
</VersionInfoKeys>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k270.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp270.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Platforms>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="SplitZip"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<BuildModes>
<Item Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<RequiredPackages>
<Item>
<PackageName Value="LCL"/>
</Item>
</RequiredPackages>
<Units>
<Unit>
<Filename Value="SplitZip.dpr"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<IncludeFiles Value="..\..\..;$(ProjOutDir)"/>
<Libraries Value="..\..\..\fpc_lib"/>
<OtherUnitFiles Value="..\..\.."/>
<UnitOutputDirectory Value="."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="Delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2Set"/>
</Debugging>
</Linking>
<Other>
<CustomOptions Value="-dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions>
<Item>
<Name Value="EAbort"/>
</Item>
<Item>
<Name Value="ECodetoolError"/>
</Item>
<Item>
<Name Value="EFOpenError"/>
</Item>
</Exceptions>
</Debugging>
</CONFIG>

View File

@@ -0,0 +1,24 @@
rd /S /Q "%cd%\backup\"
rd /S /Q "%cd%\ConverterBackup\"
rd /S /Q "%cd%\lib\"
rd /S /Q "%cd%\__history\"
rd /S /Q "%cd%\__recovery\"
del "%cd%\*.o"
del "%cd%\*.a"
del "%cd%\*.or"
del "%cd%\*.lps"
del "%cd%\*.obj"
del "%cd%\*.exe"
del "%cd%\*.ppu"
del "%cd%\*.dcu"
del "%cd%\*.log"
del "%cd%\*.compiled"
del "%cd%\*.cfg"
del "%cd%\*.dof"
del "%cd%\*.dproj.local"
del "%cd%\*.identcache"
del "%cd%\*.dsk"
del "%cd%\*.skincfg"
del "%cd%\*.bak"
del "%cd%\*.rsm"
del "%cd%\*.~*"

View File

@@ -0,0 +1,109 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : CreateMultiPartZip
// * Purpose : Демонстрация создания архива с разбитием на части по 1 килобайту
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2023.
// * Version : 2.0.0
// * 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/
//
// Данный пример показывает как можно разделить большой архив на несколько частей,
// для их последующей записи на внешние носители информации
// или передачи частями по сети при неустойчивом соединении, затрудняющем
// передачу архива большого размера
program CreateMultiPartZip;
{$IFDEF FPC}
{$MODE Delphi}
{$H+}
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}
uses
SysUtils,
TypInfo,
FWZipZLib,
FWZipWriter,
FWZipStream;
var
Zip: TFWZipWriter;
Item: TFWZipWriterItem;
I: Integer;
BuildZipResult: TBuildZipResult;
MultiStream: TFWFileMultiStream;
begin
SetCurrentDir(ExtractFilePath(ParamStr(0)));
try
Zip := TFWZipWriter.Create;
try
// Для начала добавим в корень архива файлы из корневой директории
Zip.AddFolder('..\..\..\', False);
// Теперь изменим им свойства:
for I := 0 to Zip.Count - 1 do
begin
Item := Zip[I];
// Изменим коментарий
Item.Comment := string('Тестовый коментарий к файлу ') + Item.FileName;
// Установим пароль
Item.Password := 'password';
// Изменим тип сжатия
Item.CompressionLevel := TCompressionLevel(Byte(I mod 4));
end;
Zip.Comment := 'Тестовый коментарий ко всему архиву';
// Вся логика создания многотомных архивов заключается в классе
// TFWAbstractMultiStream от которого реализуются наследники
// предоставляющие конкретную реализацию.
// В частности TFWFileMultiStream позволяет работать с архивами
// расположенными на локальном диске.
// Если потребуется работа с архивами расположенными удаленно
// на FTP или облаке, допустим SharePoint ресурсе,
// потребуется реализовывать собственный наследник.
// Первый параметром идет имя архива, вторым максимальный размер его частей.
// Созданные тома многотомного архива не обязательно будут соответствовать
// указанному значению, т.к. согласно спецификации, структуры TCentralDirectoryFileHeader
// должны целиком располагаться внутри тома, поэтому размер финальных
// томов архива может немного уменьшаться в диапазоне от 1 байта
// до SizeOf(TCentralDirectoryFileHeader).
// Так-же размер последнего тома не может быть меньше чем размер структуры
// TEndOfCentralDir, а если используется Zip64, то к этому размеру добавляется размеры
// TZip64EOFCentralDirectoryRecord и TZip64EOFCentralDirectoryLocator.
MultiStream := TFWFileMultiStream.CreateWrite(
'..\..\DemoResults\MultyPartZip\MultyPartZip.zip', $20000);
try
// Для создания многотомного архива указываем не имя файла, а сам MultiStream
BuildZipResult := Zip.BuildZip(MultiStream);
finally
MultiStream.Free;
end;
// ... и выведим результат
Writeln(GetEnumName(TypeInfo(TBuildZipResult), Integer(BuildZipResult)));
finally
Zip.Free;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.

View File

@@ -0,0 +1,112 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{FD2F810F-8C8F-48F6-83C3-CCB828985A38}</ProjectGuid>
<MainSource>CreateMultiPartZip.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>
<FrameworkType>None</FrameworkType>
<ProjectVersion>19.2</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_E>false</DCC_E>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
<DCC_N>false</DCC_N>
<DCC_S>false</DCC_S>
<DCC_ImageBase>00400000</DCC_ImageBase>
<SanitizedProjectName>CreateMultiPartZip</SanitizedProjectName>
<VerInfo_Locale>1049</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=</VerInfo_Keys>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_DebugInformation>0</DCC_DebugInformation>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<DCC_UnitSearchPath>../../../;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)</VerInfo_Keys>
<Manifest_File>(None)</Manifest_File>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">CreateMultiPartZip.dpr</Source>
</Source>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k270.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp270.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Platforms>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="CreateMultiPartZip"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<BuildModes>
<Item Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<RequiredPackages>
<Item>
<PackageName Value="LCL"/>
</Item>
</RequiredPackages>
<Units>
<Unit>
<Filename Value="CreateMultiPartZip.dpr"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<IncludeFiles Value="..\..\..;$(ProjOutDir)"/>
<Libraries Value="..\..\..\fpc_lib"/>
<OtherUnitFiles Value="..\..\.."/>
<UnitOutputDirectory Value="."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="Delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2Set"/>
</Debugging>
</Linking>
<Other>
<CustomOptions Value="-dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions>
<Item>
<Name Value="EAbort"/>
</Item>
<Item>
<Name Value="ECodetoolError"/>
</Item>
<Item>
<Name Value="EFOpenError"/>
</Item>
</Exceptions>
</Debugging>
</CONFIG>

View File

@@ -0,0 +1,24 @@
rd /S /Q "%cd%\backup\"
rd /S /Q "%cd%\ConverterBackup\"
rd /S /Q "%cd%\lib\"
rd /S /Q "%cd%\__history\"
rd /S /Q "%cd%\__recovery\"
del "%cd%\*.o"
del "%cd%\*.a"
del "%cd%\*.or"
del "%cd%\*.lps"
del "%cd%\*.obj"
del "%cd%\*.exe"
del "%cd%\*.ppu"
del "%cd%\*.dcu"
del "%cd%\*.log"
del "%cd%\*.compiled"
del "%cd%\*.cfg"
del "%cd%\*.dof"
del "%cd%\*.dproj.local"
del "%cd%\*.identcache"
del "%cd%\*.dsk"
del "%cd%\*.skincfg"
del "%cd%\*.bak"
del "%cd%\*.rsm"
del "%cd%\*.~*"

View File

@@ -0,0 +1,130 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : ModifyMultiPartZip
// * Purpose : Демонстрация модификации многотомного архива
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2023.
/// * Version : 2.0.0
// * 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/
//
// Хоть модификация многотомных архивов идея достаточно странная сама по себе,
// но архитектура фреймворка легко позволяет это осуществить.
// При чем модификатор будет спокойно работать и с обычными архивами и с многотомными
// модифицируя оба типа архивов, а так-же легко может провести конвертацию
// без этапа перепаковки данных из многотомного архива в обычный и наоборот.
program ModifyMultiPartZip;
{$IFDEF FPC}
{$MODE Delphi}
{$H+}
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}
uses
SysUtils,
Classes,
TypInfo,
FWZipZLib,
FWZipWriter,
FWZipStream,
FWZipModifier;
var
Writer: TFWZipWriter;
S: TStringStream;
MultiStreamRead, MultiStreamWrite: TFWFileMultiStream;
Modifier: TFWZipModifier;
I, Index1, Index2: Integer;
BuildZipResult: TBuildZipResult;
begin
SetCurrentDir(ExtractFilePath(ParamStr(0)));
try
// Модификация многотомного архиве ничем не отличается от модификации
// обычного архива, за исключением использования наследников
// TFWAbstractMultiStream для чтения и записи
// Например возьмем архив созданный в примере CreateMultyPartZip.dpr
// и удалим из него все *.pas файлы.
// А так-же добавим файлы из обычного не многотомного архива
MultiStreamRead := TFWFileMultiStream.CreateRead(
'..\..\DemoResults\MultyPartZip\MultyPartZip.zip');
try
Modifier := TFWZipModifier.Create;
try
// загружаем многотомный архив в модификатор
Index1 := Modifier.AddZipFile(MultiStreamRead);
// добавляем все элементы архива
Modifier.AddFromZip(Index1);
// удаляем все PAS файлы
for I := Modifier.Count - 1 downto 0 do
if AnsiLowerCase(ExtractFileExt(Modifier[I].FileName)) = '.pas' then
Modifier.DeleteItem(I);
// теперь создадим простой архив
Writer := TFWZipWriter.Create;
try
S := TStringStream.Create('Просто тестовые данные для демонстрации');
Writer.AddStream('test_stream.txt', S, soOwned);
Writer.BuildZip('..\..\DemoResults\MultyPartZip\stream.zip')
finally
Writer.Free;
end;
// загружаем обычный архив в модификатор
Index2 := Modifier.AddZipFile('..\..\DemoResults\MultyPartZip\stream.zip');
// добавляем единственный элемент простого архива
Modifier.AddFromZip(Index2, 'test_stream.txt');
// ... и сохранияем все в новый архив
// Причем!
// т.к. мы не указываем второй параметр, отвечающий за размер каждого тома
// то он берется по умолчанию и новый архив будет сформирован с томами
// другого размера, чем был в изначальном архиве.
// Все изменения произойдут на лету, вам не нужно их контролировать.
MultiStreamWrite := TFWFileMultiStream.CreateWrite(
'..\..\DemoResults\MultyPartZip\MultyPartZipWithoutPas.zip');
try
BuildZipResult := Modifier.BuildZip(MultiStreamWrite);
finally
MultiStreamWrite.Free;
end;
finally
Modifier.Free;
end;
finally
MultiStreamRead.Free;
end;
// ... выводим результат
Writeln(GetEnumName(TypeInfo(TBuildZipResult), Integer(BuildZipResult)));
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.

View File

@@ -0,0 +1,112 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{431C00A8-F08F-463E-8EBD-90AE046E4363}</ProjectGuid>
<MainSource>ModifyMultiPartZip.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>
<FrameworkType>None</FrameworkType>
<ProjectVersion>19.2</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_E>false</DCC_E>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
<DCC_N>false</DCC_N>
<DCC_S>false</DCC_S>
<DCC_ImageBase>00400000</DCC_ImageBase>
<SanitizedProjectName>ModifyMultiPartZip</SanitizedProjectName>
<VerInfo_Locale>1049</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=</VerInfo_Keys>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_DebugInformation>0</DCC_DebugInformation>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<DCC_UnitSearchPath>../../../;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)</VerInfo_Keys>
<Manifest_File>(None)</Manifest_File>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">ModifyMultiPartZip.dpr</Source>
</Source>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k270.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp270.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Platforms>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="ModifyMultiPartZip"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<BuildModes>
<Item Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<RequiredPackages>
<Item>
<PackageName Value="LCL"/>
</Item>
</RequiredPackages>
<Units>
<Unit>
<Filename Value="ModifyMultiPartZip.dpr"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<IncludeFiles Value="..\..\..;$(ProjOutDir)"/>
<Libraries Value="..\..\..\fpc_lib"/>
<OtherUnitFiles Value="..\..\.."/>
<UnitOutputDirectory Value="."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="Delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2Set"/>
</Debugging>
</Linking>
<Other>
<CustomOptions Value="-dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions>
<Item>
<Name Value="EAbort"/>
</Item>
<Item>
<Name Value="ECodetoolError"/>
</Item>
<Item>
<Name Value="EFOpenError"/>
</Item>
</Exceptions>
</Debugging>
</CONFIG>

View File

@@ -0,0 +1,24 @@
rd /S /Q "%cd%\backup\"
rd /S /Q "%cd%\ConverterBackup\"
rd /S /Q "%cd%\lib\"
rd /S /Q "%cd%\__history\"
rd /S /Q "%cd%\__recovery\"
del "%cd%\*.o"
del "%cd%\*.a"
del "%cd%\*.or"
del "%cd%\*.lps"
del "%cd%\*.obj"
del "%cd%\*.exe"
del "%cd%\*.ppu"
del "%cd%\*.dcu"
del "%cd%\*.log"
del "%cd%\*.compiled"
del "%cd%\*.cfg"
del "%cd%\*.dof"
del "%cd%\*.dproj.local"
del "%cd%\*.identcache"
del "%cd%\*.dsk"
del "%cd%\*.skincfg"
del "%cd%\*.bak"
del "%cd%\*.rsm"
del "%cd%\*.~*"

View File

@@ -0,0 +1,98 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : ReadMultiPartZip
// * Purpose : Демонстрация чтения многотомного архива
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2023.
// * Version : 2.0.0
// * 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/
//
program ReadMultiPartZip;
{$IFDEF FPC}
{$MODE Delphi}
{$H+}
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}
uses
SysUtils,
TypInfo,
FWZipStream,
FWZipReader;
var
Reader: TFWZipReader;
MultiStream: TFWFileMultiStream;
begin
SetCurrentDir(ExtractFilePath(ParamStr(0)));
try
// Для чтения многотомных архивов так-же потребуется класс
// наследник от TFWAbstractMultiStream.
// В случае чтения используется конструктор CreateRead.
// Первый параметр - путь к заголовку архива.
// Второй параметр, режим открытия.
// rsmQuick - ищутся все тома с конца не совпадающие размером с
// первым томом, вплоть до тех пор, пока не найдется равный.
// Остальные тома считаются равными первому.
// Это быстрый способ открытия многотомного архива, но не совсем надежный,
// по причине того что в тех случаях, когда один из томов
// содержащий записи TCentralDirectoryFileHeader совпадет по размерам
// с первым томом, все предыдущие будут считаться полными томами
// содержащими данные, хотя это может быть не так.
// Для гарантированного открытия нужно использовать режим rsmFull.
// В этом случае будет зачитан фактический размер каждого тома архива.
// Но, это более медленный вариант, особенно в том случае, когда
// реальных томов достаточно много.
// На количестве томов 60 тысяч и более время открытия может
// исчислятся минутами!
MultiStream := TFWFileMultiStream.CreateRead(
'..\..\DemoResults\MultyPartZip\MultyPartZip.zip', rsmQuick);
try
Reader := TFWZipReader.Create;
try
// Чтение многотомных архивов осуществляется ТОЛЬКО через вызов метода
// LoadFromStream с передачей параметров наследника класса TFWAbstractMultiStream
Reader.LoadFromStream(MultiStream);
// Вся остальная работа с архивом выглядит так-же как и с обычным.
Reader.PasswordList.Add('password');
// Например проверка целостности архива
Reader.Check;
// ... или его распаковка
Reader.ExtractAll('*.pas', '..\..\DemoResults\MultyPartZip\');
Writeln('done.');
finally
Reader.Free;
end;
finally
MultiStream.Free;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.

View File

@@ -0,0 +1,112 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{19C51B88-FFA7-4F17-A41B-4EB644FA4152}</ProjectGuid>
<MainSource>ReadMultiPartZip.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>
<FrameworkType>None</FrameworkType>
<ProjectVersion>19.2</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_E>false</DCC_E>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
<DCC_N>false</DCC_N>
<DCC_S>false</DCC_S>
<DCC_ImageBase>00400000</DCC_ImageBase>
<SanitizedProjectName>ReadMultiPartZip</SanitizedProjectName>
<VerInfo_Locale>1049</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=</VerInfo_Keys>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_DebugInformation>0</DCC_DebugInformation>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<DCC_UnitSearchPath>../../../;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)</VerInfo_Keys>
<Manifest_File>(None)</Manifest_File>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">ReadMultiPartZip.dpr</Source>
</Source>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k270.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp270.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Platforms>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="ReadMultiPartZip"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<BuildModes>
<Item Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<RequiredPackages>
<Item>
<PackageName Value="LCL"/>
</Item>
</RequiredPackages>
<Units>
<Unit>
<Filename Value="ReadMultiPartZip.dpr"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<IncludeFiles Value="..\..\..;$(ProjOutDir)"/>
<Libraries Value="..\..\..\fpc_lib"/>
<OtherUnitFiles Value="..\..\.."/>
<UnitOutputDirectory Value="."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="Delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2Set"/>
</Debugging>
</Linking>
<Other>
<CustomOptions Value="-dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions>
<Item>
<Name Value="EAbort"/>
</Item>
<Item>
<Name Value="ECodetoolError"/>
</Item>
<Item>
<Name Value="EFOpenError"/>
</Item>
</Exceptions>
</Debugging>
</CONFIG>

View File

@@ -0,0 +1,24 @@
rd /S /Q "%cd%\backup\"
rd /S /Q "%cd%\ConverterBackup\"
rd /S /Q "%cd%\lib\"
rd /S /Q "%cd%\__history\"
rd /S /Q "%cd%\__recovery\"
del "%cd%\*.o"
del "%cd%\*.a"
del "%cd%\*.or"
del "%cd%\*.lps"
del "%cd%\*.obj"
del "%cd%\*.exe"
del "%cd%\*.ppu"
del "%cd%\*.dcu"
del "%cd%\*.log"
del "%cd%\*.compiled"
del "%cd%\*.cfg"
del "%cd%\*.dof"
del "%cd%\*.dproj.local"
del "%cd%\*.identcache"
del "%cd%\*.dsk"
del "%cd%\*.skincfg"
del "%cd%\*.bak"
del "%cd%\*.rsm"
del "%cd%\*.~*"

View File

@@ -0,0 +1,19 @@
program FWZipPerfomance;
{$IFDEF FPC}
{$MODE Delphi}
{$ENDIF}
uses
{$IFDEF FPC}
Interfaces,
{$ENDIF }
Forms,
Unit1 in 'Unit1.pas' {Form1};
{$IFNDEF FPC}
{$R *.res}
{$ENDIF}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

View File

@@ -0,0 +1,918 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{69C44A8C-22A5-4248-B1C8-29A82DBA1D5C}</ProjectGuid>
<MainSource>FWZipPerfomance.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Application</AppType>
<FrameworkType>VCL</FrameworkType>
<ProjectVersion>19.2</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
<Cfg_1_Win32>true</Cfg_1_Win32>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_E>false</DCC_E>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
<DCC_N>false</DCC_N>
<DCC_S>false</DCC_S>
<DCC_ImageBase>00400000</DCC_ImageBase>
<SanitizedProjectName>FWZipPerfomance</SanitizedProjectName>
<DCC_Namespace>Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Locale>1049</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_DebugInformation>0</DCC_DebugInformation>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
<DCC_UnitSearchPath>../../;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)</VerInfo_Keys>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="Unit1.pas">
<Form>Form1</Form>
</DCCReference>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">FWZipPerfomance.dpr</Source>
</Source>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k270.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp270.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Platforms>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
<Deployment Version="3">
<DeployFile LocalName="FWZipPerfomance.exe" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>FWZipPerfomance.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClassesDexFile">
<Platform Name="Android">
<RemoteDir>classes</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>classes</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidFileProvider">
<Platform Name="Android">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidGDBServer">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiFile">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiv7aFile">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeMipsFile">
<Platform Name="Android">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput_Android32">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashImageDef">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStyles">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStylesV21">
<Platform Name="Android">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Colors">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_DefaultAppIcon">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon144">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon192">
<Platform Name="Android">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon24">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage426">
<Platform Name="Android">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage470">
<Platform Name="Android">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage640">
<Platform Name="Android">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage960">
<Platform Name="Android">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Strings">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyFramework">
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyModule">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="DependencyPackage">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Name="File">
<Platform Name="Android">
<Operation>0</Operation>
</Platform>
<Platform Name="Android64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\Resources\StartUp\</RemoteDir>
<Operation>0</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\Resources\StartUp\</RemoteDir>
<Operation>0</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iOS_AppStore1024">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_AppIcon152">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_AppIcon167">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Notification40">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Setting58">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_SpotLight80">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_AppIcon120">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_AppIcon180">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Notification40">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Notification60">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Setting58">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Setting87">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Spotlight120">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Spotlight80">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectAndroidManifest">
<Platform Name="Android">
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceDebug">
<Platform Name="iOSDevice32">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSEntitlements">
<Platform Name="iOSDevice32">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSInfoPList">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSLaunchScreen">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen</RemoteDir>
<Operation>64</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen</RemoteDir>
<Operation>64</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSResource">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXDebug">
<Platform Name="OSX64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXEntitlements">
<Platform Name="OSX32">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXInfoPList">
<Platform Name="OSX32">
<RemoteDir>Contents</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXResource">
<Platform Name="OSX32">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="ProjectOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="Linux64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX64">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOutput_Android32">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectUWPManifest">
<Platform Name="Win32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo150">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo44">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Android64" Name="$(PROJECTNAME)"/>
</Deployment>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
<Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/>
</Project>

View File

@@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="FWZipPerfomance"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<BuildModes>
<Item Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<RequiredPackages>
<Item>
<PackageName Value="LazUtils"/>
</Item>
<Item>
<PackageName Value="LCL"/>
</Item>
</RequiredPackages>
<Units>
<Unit>
<Filename Value="FWZipPerfomance.dpr"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="Unit1.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="Form1"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
</Unit>
<Unit>
<Filename Value="..\..\FWZipConsts.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="..\..\FWZipCrc32.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="..\..\FWZipCrypt.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="..\..\FWZipReader.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="..\..\FWZipStream.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="..\..\FWZipWriter.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<IncludeFiles Value="..\..;$(ProjOutDir)"/>
<Libraries Value="..\..\fpc_lib"/>
<OtherUnitFiles Value="..\.."/>
<UnitOutputDirectory Value="."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="Delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2Set"/>
</Debugging>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
<Other>
<CustomOptions Value="-dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions>
<Item>
<Name Value="EAbort"/>
</Item>
<Item>
<Name Value="ECodetoolError"/>
</Item>
<Item>
<Name Value="EFOpenError"/>
</Item>
</Exceptions>
</Debugging>
</CONFIG>

View File

@@ -0,0 +1,258 @@
object Form1: TForm1
Left = 381
Top = 183
Caption = #1058#1077#1089#1090' '#1087#1088#1086#1080#1079#1074#1086#1076#1080#1090#1077#1083#1100#1085#1086#1089#1090#1080' FWZip'
ClientHeight = 615
ClientWidth = 562
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
Position = poScreenCenter
DesignSize = (
562
615)
PixelsPerInch = 96
TextHeight = 13
object GroupBox1: TGroupBox
Left = 8
Top = 8
Width = 527
Height = 105
Anchors = [akLeft, akTop, akRight]
Caption = #1053#1072#1089#1090#1088#1086#1081#1082#1080' '#1089#1078#1072#1090#1080#1103
TabOrder = 0
DesignSize = (
527
105)
object LabeledEdit1: TLabeledEdit
Left = 16
Top = 40
Width = 469
Height = 21
Anchors = [akLeft, akTop, akRight]
EditLabel.Width = 149
EditLabel.Height = 13
EditLabel.Caption = #1042#1099#1073#1077#1088#1080#1090#1077' '#1087#1072#1087#1082#1091' '#1076#1083#1103' '#1089#1078#1072#1090#1080#1103':'
TabOrder = 0
Text = 'D:\StroyInfo 5'
OnChange = LabeledEdit1Change
end
object Button1: TButton
Left = 491
Top = 38
Width = 26
Height = 25
Hint = #1054#1073#1079#1086#1088'...'
Anchors = [akTop, akRight]
Caption = '...'
ParentShowHint = False
ShowHint = True
TabOrder = 1
OnClick = Button1Click
end
object CheckBox1: TCheckBox
Left = 16
Top = 72
Width = 145
Height = 17
Caption = #1064#1080#1092#1088#1086#1074#1072#1090#1100' '#1087#1088#1080' '#1089#1078#1072#1090#1080#1080
TabOrder = 2
OnClick = CheckBox1Click
end
object LabeledEdit2: TLabeledEdit
Left = 264
Top = 70
Width = 172
Height = 21
Anchors = [akLeft, akTop, akRight]
EditLabel.Width = 84
EditLabel.Height = 13
EditLabel.Caption = #1059#1082#1072#1078#1080#1090#1077' '#1087#1072#1088#1086#1083#1100
Enabled = False
LabelPosition = lpLeft
TabOrder = 3
end
object Button2: TButton
Left = 442
Top = 69
Width = 75
Height = 25
Anchors = [akTop, akRight]
Caption = #1057#1078#1072#1090#1100
TabOrder = 4
OnClick = Button2Click
end
end
object GroupBox2: TGroupBox
Left = 8
Top = 128
Width = 527
Height = 137
Anchors = [akLeft, akTop, akRight]
Caption = #1053#1072#1089#1090#1088#1086#1081#1082#1080' '#1088#1072#1089#1087#1072#1082#1086#1074#1082#1080
TabOrder = 1
DesignSize = (
527
137)
object LabeledEdit3: TLabeledEdit
Left = 16
Top = 40
Width = 469
Height = 21
Anchors = [akLeft, akTop, akRight]
EditLabel.Width = 171
EditLabel.Height = 13
EditLabel.Caption = #1042#1099#1073#1077#1088#1080#1090#1077' '#1072#1088#1093#1080#1074' '#1076#1083#1103' '#1088#1072#1089#1087#1072#1082#1086#1074#1082#1080':'
TabOrder = 0
OnChange = LabeledEdit3Change
end
object Button3: TButton
Left = 491
Top = 38
Width = 26
Height = 25
Hint = #1054#1073#1079#1086#1088'...'
Anchors = [akTop, akRight]
Caption = '...'
ParentShowHint = False
ShowHint = True
TabOrder = 1
OnClick = Button3Click
end
object CheckBox2: TCheckBox
Left = 16
Top = 72
Width = 145
Height = 17
Caption = #1040#1088#1093#1080#1074' '#1079#1072#1096#1080#1092#1088#1086#1074#1072#1085
TabOrder = 2
OnClick = CheckBox2Click
end
object LabeledEdit4: TLabeledEdit
Left = 264
Top = 70
Width = 167
Height = 21
Anchors = [akLeft, akTop, akRight]
EditLabel.Width = 84
EditLabel.Height = 13
EditLabel.Caption = #1059#1082#1072#1078#1080#1090#1077' '#1087#1072#1088#1086#1083#1100
Enabled = False
LabelPosition = lpLeft
TabOrder = 3
end
object Button4: TButton
Left = 442
Top = 68
Width = 75
Height = 25
Anchors = [akTop, akRight]
Caption = #1056#1072#1089#1087#1072#1082#1086#1074#1072#1090#1100
TabOrder = 4
OnClick = Button4Click
end
object Button6: TButton
Tag = 1
Left = 442
Top = 99
Width = 75
Height = 25
Anchors = [akTop, akRight]
Caption = #1055#1088#1086#1074#1077#1088#1080#1090#1100
TabOrder = 5
OnClick = Button4Click
end
end
object GroupBox3: TGroupBox
Left = 8
Top = 271
Width = 527
Height = 178
Anchors = [akLeft, akTop, akRight]
Caption = #1055#1088#1086#1080#1079#1074#1086#1076#1080#1090#1077#1083#1100#1085#1086#1089#1090#1100':'
TabOrder = 2
DesignSize = (
527
178)
object Label1: TLabel
Left = 16
Top = 24
Width = 163
Height = 13
Caption = #1058#1077#1082#1091#1097#1080#1081' '#1088#1072#1089#1093#1086#1076' '#1087#1072#1084#1103#1090#1080': 0 '#1073#1072#1081#1090
end
object Label2: TLabel
Left = 16
Top = 43
Width = 163
Height = 13
Caption = #1055#1080#1082#1086#1074#1099#1081' '#1088#1072#1089#1093#1086#1076' '#1087#1072#1084#1103#1090#1080': 0 '#1073#1072#1081#1090
end
object Label3: TLabel
Left = 16
Top = 62
Width = 166
Height = 13
Caption = #1054#1073#1097#1077#1077' '#1082#1086#1083#1080#1095#1077#1089#1090#1074#1086' '#1101#1083#1077#1084#1077#1085#1090#1086#1074': 0'
end
object Label4: TLabel
Left = 16
Top = 81
Width = 142
Height = 13
Caption = #1054#1073#1097#1077#1077' '#1088#1072#1079#1084#1077#1088' '#1101#1083#1077#1084#1077#1085#1090#1086#1074': 0'
end
object Label5: TLabel
Left = 16
Top = 109
Width = 501
Height = 13
Anchors = [akLeft, akTop, akRight]
AutoSize = False
end
object ProgressBar1: TProgressBar
Left = 16
Top = 128
Width = 498
Height = 17
Anchors = [akLeft, akTop, akRight]
TabOrder = 0
end
object ProgressBar2: TProgressBar
Left = 16
Top = 151
Width = 498
Height = 17
Anchors = [akLeft, akTop, akRight]
TabOrder = 1
end
object Button5: TButton
Left = 439
Top = 97
Width = 75
Height = 25
Anchors = [akTop, akRight]
Caption = #1054#1089#1090#1072#1085#1086#1074#1080#1090#1100
TabOrder = 2
Visible = False
OnClick = Button5Click
end
end
object Memo1: TMemo
Left = 8
Top = 456
Width = 527
Height = 146
Anchors = [akLeft, akTop, akRight, akBottom]
ScrollBars = ssVertical
TabOrder = 3
end
object OpenDialog1: TOpenDialog
Left = 376
Top = 224
end
end

View File

@@ -0,0 +1,260 @@
object Form1: TForm1
Left = 381
Height = 981
Top = 183
Width = 867
Caption = 'Тест производительности FWZip'
ClientHeight = 981
ClientWidth = 867
Color = clBtnFace
DesignTimePPI = 144
Font.Color = clWindowText
Font.Height = -17
Font.Name = 'Tahoma'
Position = poScreenCenter
LCLVersion = '2.2.6.0'
object GroupBox1: TGroupBox
Left = 12
Height = 158
Top = 12
Width = 791
Anchors = [akTop, akLeft, akRight]
Caption = 'Настройки сжатия'
ClientHeight = 132
ClientWidth = 787
TabOrder = 0
object LabeledEdit1: TLabeledEdit
Left = 21
Height = 29
Top = 39
Width = 700
Anchors = [akTop, akLeft, akRight]
EditLabel.Height = 21
EditLabel.Width = 700
EditLabel.Caption = 'Выберите папку для сжатия:'
EditLabel.ParentColor = False
TabOrder = 0
Text = 'D:\StroyInfo 5'
OnChange = LabeledEdit1Change
end
object Button1: TButton
Left = 730
Height = 38
Hint = 'Обзор...'
Top = 36
Width = 39
Anchors = [akTop, akRight]
Caption = '...'
OnClick = Button1Click
ParentShowHint = False
ShowHint = True
TabOrder = 1
end
object CheckBox1: TCheckBox
Left = 21
Height = 29
Top = 87
Width = 218
Caption = 'Шифровать при сжатии'
OnClick = CheckBox1Click
TabOrder = 2
end
object LabeledEdit2: TLabeledEdit
Left = 393
Height = 29
Top = 84
Width = 254
Anchors = [akTop, akLeft, akRight]
EditLabel.Height = 21
EditLabel.Width = 126
EditLabel.Caption = 'Укажите пароль'
EditLabel.ParentColor = False
Enabled = False
LabelPosition = lpLeft
TabOrder = 3
end
object Button2: TButton
Left = 657
Height = 38
Top = 82
Width = 112
Anchors = [akTop, akRight]
Caption = 'Сжать'
OnClick = Button2Click
TabOrder = 4
end
end
object GroupBox2: TGroupBox
Left = 12
Height = 206
Top = 192
Width = 791
Anchors = [akTop, akLeft, akRight]
Caption = 'Настройки распаковки'
ClientHeight = 180
ClientWidth = 787
TabOrder = 1
object LabeledEdit3: TLabeledEdit
Left = 21
Height = 29
Top = 39
Width = 700
Anchors = [akTop, akLeft, akRight]
EditLabel.Height = 21
EditLabel.Width = 700
EditLabel.Caption = 'Выберите архив для распаковки:'
EditLabel.ParentColor = False
TabOrder = 0
OnChange = LabeledEdit3Change
end
object Button3: TButton
Left = 730
Height = 38
Hint = 'Обзор...'
Top = 36
Width = 39
Anchors = [akTop, akRight]
Caption = '...'
OnClick = Button3Click
ParentShowHint = False
ShowHint = True
TabOrder = 1
end
object CheckBox2: TCheckBox
Left = 21
Height = 29
Top = 87
Width = 181
Caption = 'Архив зашифрован'
OnClick = CheckBox2Click
TabOrder = 2
end
object LabeledEdit4: TLabeledEdit
Left = 393
Height = 29
Top = 84
Width = 247
Anchors = [akTop, akLeft, akRight]
EditLabel.Height = 21
EditLabel.Width = 126
EditLabel.Caption = 'Укажите пароль'
EditLabel.ParentColor = False
Enabled = False
LabelPosition = lpLeft
TabOrder = 3
end
object Button4: TButton
Left = 657
Height = 38
Top = 81
Width = 112
Anchors = [akTop, akRight]
Caption = 'Распаковать'
OnClick = Button4Click
TabOrder = 4
end
object Button6: TButton
Tag = 1
Left = 657
Height = 38
Top = 128
Width = 112
Anchors = [akTop, akRight]
Caption = 'Проверить'
OnClick = Button4Click
TabOrder = 5
end
end
object GroupBox3: TGroupBox
Left = 12
Height = 267
Top = 406
Width = 791
Anchors = [akTop, akLeft, akRight]
Caption = 'Производительность:'
ClientHeight = 241
ClientWidth = 787
TabOrder = 2
object Label1: TLabel
Left = 21
Height = 21
Top = 15
Width = 248
Caption = 'Текущий расход памяти: 0 байт'
ParentColor = False
end
object Label2: TLabel
Left = 21
Height = 21
Top = 44
Width = 249
Caption = 'Пиковый расход памяти: 0 байт'
ParentColor = False
end
object Label3: TLabel
Left = 21
Height = 21
Top = 72
Width = 252
Caption = 'Общее количество элементов: 0'
ParentColor = False
end
object Label4: TLabel
Left = 21
Height = 21
Top = 100
Width = 219
Caption = 'Общее размер элементов: 0'
ParentColor = False
end
object Label5: TLabel
Left = 21
Height = 20
Top = 142
Width = 748
Anchors = [akTop, akLeft, akRight]
AutoSize = False
ParentColor = False
end
object ProgressBar1: TProgressBar
Left = 21
Height = 26
Top = 171
Width = 744
Anchors = [akTop, akLeft, akRight]
TabOrder = 0
end
object ProgressBar2: TProgressBar
Left = 21
Height = 26
Top = 206
Width = 744
Anchors = [akTop, akLeft, akRight]
TabOrder = 1
end
object Button5: TButton
Left = 653
Height = 38
Top = 124
Width = 112
Anchors = [akTop, akRight]
Caption = 'Остановить'
OnClick = Button5Click
TabOrder = 2
Visible = False
end
end
object Memo1: TMemo
Left = 12
Height = 219
Top = 684
Width = 791
Anchors = [akTop, akLeft, akRight, akBottom]
ScrollBars = ssVertical
TabOrder = 3
end
object OpenDialog1: TOpenDialog
Left = 564
Top = 336
end
end

View File

@@ -0,0 +1,323 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip - FWZipPerfomance
// * Purpose : Тестирование производительности FWZip
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2023.
// * Version : 2.0.0
// * 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 Unit1;
{$IFDEF FPC}
{$MODE Delphi}
{$ENDIF}
interface
{$WARN SYMBOL_PLATFORM OFF}
{$WARN SYMBOL_DEPRECATED OFF}
{$WARN UNIT_PLATFORM OFF}
uses
{$IFDEF FPC}
LCLIntf, LCLType,
{$ELSE}
Windows, FileCtrl,
{$ENDIF}
SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, ComCtrls,
FWZipWriter, FWZipReader, FWZipConsts;
type
TForm1 = class(TForm)
GroupBox1: TGroupBox;
LabeledEdit1: TLabeledEdit;
Button1: TButton;
CheckBox1: TCheckBox;
LabeledEdit2: TLabeledEdit;
Button2: TButton;
GroupBox2: TGroupBox;
LabeledEdit3: TLabeledEdit;
Button3: TButton;
CheckBox2: TCheckBox;
LabeledEdit4: TLabeledEdit;
Button4: TButton;
OpenDialog1: TOpenDialog;
GroupBox3: TGroupBox;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
ProgressBar1: TProgressBar;
ProgressBar2: TProgressBar;
Label5: TLabel;
Button5: TButton;
Button6: TButton;
Memo1: TMemo;
procedure CheckBox1Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure LabeledEdit1Change(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure CheckBox2Click(Sender: TObject);
procedure LabeledEdit3Change(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
private
InitialHeapSize, MaxHeapSize, AverageHeapSize: Int64;
TotalGetHeapStatusCount: Integer;
StopProcess: Boolean;
procedure OnProgress(Sender: TObject; const FileName: string;
Percent, TotalPercent: Byte; var Cancel: Boolean;
ProgressState: TProgressState);
procedure UpdateMemoryStatus;
procedure SetEnabledState(Value: Boolean);
procedure ClearZipData;
end;
var
Form1: TForm1;
implementation
{$IFDEF FPC}
{$R *.lfm}
{$ELSE}
{$R *.dfm}
{$ENDIF}
function GetTicks: UInt64;
begin
{$IFDEF FPC}
Result := GetTickCount64;
{$ELSE}
Result := GetTickCount;
{$ENDIF}
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Dir: string;
begin
if SelectDirectory('Укажите папку для сжатия', '', Dir) then
LabeledEdit1.Text := Dir;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
I: Integer;
TotalSize: Int64;
Heap: THeapStatus;
TicCount: Uint64;
Item: TFWZipWriterItem;
Writer: TFWZipWriter;
begin
Writer := TFWZipWriter.Create;
try
DeleteFile(
IncludeTrailingPathDelimiter(LabeledEdit1.Text) + 'FWZipTest.zip');
Writer.AddFolder('', LabeledEdit1.Text, '');
TotalSize := 0;
InitialHeapSize := 0;
for I := 0 to Writer.Count - 1 do
begin
Item := Writer[I];
Inc(TotalSize, Item.Size);
Inc(InitialHeapSize, SizeOf(TCentralDirectoryFileHeaderEx));
if LabeledEdit2.Text <> '' then
begin
Item.Password := LabeledEdit2.Text;
Item.NeedDescriptor := True;
end;
end;
Label3.Caption := 'Общее количество элементов: ' + IntToStr(Writer.Count);
Label4.Caption := 'Общий размер элементов: ' + IntToStr(TotalSize);
Writer.OnProgress := OnProgress;
SetEnabledState(False);
try
Heap := GetHeapStatus;
Inc(InitialHeapSize, Heap.Overhead + Heap.TotalAllocated);
MaxHeapSize := 0;
AverageHeapSize := 0;
TotalGetHeapStatusCount := 0;
StopProcess := False;
TicCount := GetTicks;
Writer.BuildZip(
IncludeTrailingPathDelimiter(LabeledEdit1.Text) + 'FWZipTest.zip');
if TotalGetHeapStatusCount = 0 then
TotalGetHeapStatusCount := 1;
ShowMessage(Format(
'Пиковый расход памяти: %d байт' + sLineBreak +
'Средний расход памяти: %d байт' + sLineBreak +
'Общее время работы: %d секунд',
[MaxHeapSize, AverageHeapSize div TotalGetHeapStatusCount,
(GetTicks - TicCount) div 1000]));
finally
SetEnabledState(True);
end;
finally
Writer.Free;
ClearZipData;
end;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
if OpenDialog1.Execute then
LabeledEdit3.Text := OpenDialog1.FileName;
end;
procedure TForm1.Button4Click(Sender: TObject);
var
I: Integer;
TotalSize: Int64;
Heap: THeapStatus;
TicCount: Uint64;
Path: string;
Reader: TFWZipReader;
begin
{$IFDEF FPC}
Path := '';
{$ENDIF}
SetLength(Path, MAX_PATH);
Path := LabeledEdit3.Text;
Path := ChangeFileExt(Path, '');
Reader := TFWZipReader.Create;
try
Reader.LoadFromFile(LabeledEdit3.Text);
TotalSize := 0;
for I := 0 to Reader.Count - 1 do
Inc(TotalSize, Reader[I].UncompressedSize);
Label3.Caption := 'Общее количество элементов: ' + IntToStr(Reader.Count);
Label4.Caption := 'Общий размер элементов: ' + IntToStr(TotalSize);
Reader.OnProgress := OnProgress;
if LabeledEdit4.Text <> '' then
Reader.PasswordList.Add(LabeledEdit4.Text);
SetEnabledState(False);
try
Heap := GetHeapStatus;
InitialHeapSize := Heap.Overhead + Heap.TotalAllocated;
MaxHeapSize := 0;
AverageHeapSize := 0;
TotalGetHeapStatusCount := 0;
StopProcess := False;
Memo1.Lines.Clear;
TicCount := GetTicks;
if TButton(Sender).Tag = 0 then
Reader.ExtractAll(Path)
else
Reader.Check;
if TotalGetHeapStatusCount = 0 then
TotalGetHeapStatusCount := 1;
ShowMessage(Format(
'Пиковый расход памяти: %d байт' + sLineBreak +
'Средний расход памяти: %d байт' + sLineBreak +
'Общее время работы: %d секунд',
[MaxHeapSize, AverageHeapSize div TotalGetHeapStatusCount,
(GetTicks - TicCount) div 1000]));
finally
SetEnabledState(True);
end;
finally
Reader.Free;
ClearZipData;
end;
end;
procedure TForm1.Button5Click(Sender: TObject);
begin
StopProcess := True;
end;
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
LabeledEdit2.Enabled := CheckBox1.Checked;
end;
procedure TForm1.CheckBox2Click(Sender: TObject);
begin
LabeledEdit4.Enabled := CheckBox2.Checked;
end;
procedure TForm1.ClearZipData;
begin
Label1.Caption := 'Текущий расход памяти: 0 байт';
Label2.Caption := 'Пиковый расход памяти: 0 байт';
Label3.Caption := 'Общее количество элементов: 0';
Label4.Caption := 'Общий размер элементов: 0';
Label5.Caption := '';
end;
procedure TForm1.LabeledEdit1Change(Sender: TObject);
begin
Button2.Enabled := DirectoryExists(LabeledEdit1.Text);
end;
procedure TForm1.LabeledEdit3Change(Sender: TObject);
begin
Button4.Enabled := FileExists(LabeledEdit3.Text);
end;
procedure TForm1.OnProgress(Sender: TObject; const FileName: string; Percent,
TotalPercent: Byte; var Cancel: Boolean; ProgressState: TProgressState);
const
p: array [TProgressState] of string = ('psStart', 'psInitialization',
'psInProgress', 'psFinalization', 'psEnd', 'psException');
begin
Cancel := StopProcess;
Label5.Caption := Format('(%d) %s', [Percent, FileName]);
ProgressBar1.Position := Percent;
ProgressBar2.Position := TotalPercent;
Memo1.Lines.Add(Format('%s - %s percent %d total %d',
[FileName, P[ProgressState], Percent, TotalPercent]));
UpdateMemoryStatus;
end;
procedure TForm1.SetEnabledState(Value: Boolean);
begin
Button1.Enabled := Value;
Button2.Enabled := Value;
Button3.Enabled := Value;
Button4.Enabled := Value;
Button5.Visible := not Value;
Button6.Enabled := Value;
LabeledEdit1.Enabled := Value;
LabeledEdit2.Enabled := Value;
LabeledEdit3.Enabled := Value;
LabeledEdit4.Enabled := Value;
CheckBox1.Enabled := Value;
CheckBox2.Enabled := Value;
end;
procedure TForm1.UpdateMemoryStatus;
var
HeapStatus: THeapStatus;
HeapSize: Int64;
begin
HeapStatus := GetHeapStatus;
HeapSize := HeapStatus.Overhead + HeapStatus.TotalAllocated;
Dec(HeapSize, InitialHeapSize);
if HeapSize > MaxHeapSize then
MaxHeapSize := HeapSize;
Inc(TotalGetHeapStatusCount);
Inc(AverageHeapSize, HeapSize);
Label1.Caption := 'Текущий расход памяти: ' + IntToStr(HeapSize) + ' байт';
Label2.Caption := 'Пиковый расход памяти: ' + IntToStr(MaxHeapSize) + ' байт';
Application.ProcessMessages;
Application.ProcessMessages;
end;
end.

View File

@@ -0,0 +1,24 @@
rd /S /Q "%cd%\backup\"
rd /S /Q "%cd%\ConverterBackup\"
rd /S /Q "%cd%\lib\"
rd /S /Q "%cd%\__history\"
rd /S /Q "%cd%\__recovery\"
del "%cd%\*.o"
del "%cd%\*.a"
del "%cd%\*.or"
del "%cd%\*.lps"
del "%cd%\*.obj"
del "%cd%\*.exe"
del "%cd%\*.ppu"
del "%cd%\*.dcu"
del "%cd%\*.log"
del "%cd%\*.compiled"
del "%cd%\*.cfg"
del "%cd%\*.dof"
del "%cd%\*.dproj.local"
del "%cd%\*.identcache"
del "%cd%\*.dsk"
del "%cd%\*.skincfg"
del "%cd%\*.bak"
del "%cd%\*.rsm"
del "%cd%\*.~*"

View File

@@ -0,0 +1,356 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : BuildWithException
// * Purpose : Демонстрация работы с исключениями
// * : при создании и распаковке архива
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2023.
// * Version : 2.0.0
// * 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/
//
// Данный пример показывает работу с различными ошибками могущими возникнуть
// в процессе создания и распаковки архива, а так-же способы их обработки.
program BuildWithException;
{$IFDEF FPC}
{$MODE Delphi}
{$H+}
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}
uses
{$IFNDEF FPC}
Windows,
{$ENDIF}
Classes,
SysUtils,
TypInfo,
FWZipConsts,
FWZipWriter,
FWZipReader,
FWZipUtils;
const
INVALID_HANDLE_VALUE = THandle(-1);
ReadLock = fmOpenRead or fmShareDenyNone;
{$IFDEF LINUX}
WriteLock = fmOpenWrite or fmShareExclusive;
{$ELSE}
WriteLock = fmOpenWrite or fmShareDenyNone;
{$ENDIF}
var
Writer: TFWZipWriter;
Reader: TFWZipReader;
Method: TMethod;
hLockedFile: THandle;
//
// Процедура выводит результат работы функции BuildZip
// =============================================================================
procedure ShowBuildResult(Value: TBuildZipResult);
begin
Writeln(GetEnumName(TypeInfo(TBuildZipResult), Integer(Value)));
end;
//
// Процедура выводит результат работы функции Extract
// =============================================================================
procedure ShowManualExtractResult(const ElementName: string;
Value: TExtractResult);
begin
Writeln(Format('%s -> %s', [ElementName,
GetEnumName(TypeInfo(TExtractResult), Integer(Value))]));
end;
procedure DropLock;
begin
FileClose(hLockedFile);
hLockedFile := INVALID_HANDLE_VALUE;
end;
//
// смотри описание обработчика ниже
// =============================================================================
procedure OnException1({%H-}Self, Sender: TObject; {%H-}E: Exception;
const ItemIndex: Integer; var Action: TExceptionAction;
var NewFilePath: string; {%H-}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({%H-}Self, Sender: TObject; {%H-}E: Exception;
const {%H-}ItemIndex: Integer; var Action: TExceptionAction;
var {%H-}NewFilePath: string; {%H-}NewFileData: TMemoryStream);
begin
DropLock;
Action := eaRetry;
end;
//
// смотри описание обработчика ниже
// =============================================================================
procedure OnException3({%H-}Self, Sender: TObject; {%H-}E: Exception;
const ItemIndex: Integer; var Action: TExceptionAction;
var {%H-}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 OnDuplicate({%H-}Self, Sender: TObject;
var Path: string; var Action: TDuplicateAction);
begin
Path := MakeUniqueName(Path);
Action := daUseNewFilePath;
end;
var
I: Integer;
begin
SetCurrentDir(ExtractFilePath(ParamStr(0)));
try
// Самая банальная ошибка при создании архива - это отсутствие доступа
// к добавляемому в архив файлу.
// Например вот такой код пытается заархивировать содержимое корневой
// папки в которой искусственно залочен один из элементов
// В этом случае возникнет ошибка доступа к залоченому файлу.
// Если не назначены обработчики исключений, то такой файл будет пропущен
// (действие по умолчанию eaSkip) и функция BuildZip
// вернет следующие коды ошибок:
// brFailed - в случае если в папке небыло других файлов
// кроме залоченного (т.е. в архив добавлять нечего)
// brPartialBuild - в случае если в архив все-же были добавлены какие-либо файлы,
// но некоторые из них были пропущены
Writer := TFWZipWriter.Create;
try
Writer.AddFolder('', '..\..\', '*.pas', False);
// лочим один из файлов для демонстрации
hLockedFile := FileOpen(PathCanonicalize('..\..\' + Writer[0].FileName), WriteLock);
try
Write('BuildWithException1.zip -> ');
ShowBuildResult(Writer.BuildZip('..\DemoResults\BuildWithException1.zip'));
finally
FileClose(hLockedFile);
end;
finally
Writer.Free;
end;
// узнать какие файлы были пропущены и попытаться исправить данную ситуацию
// можно перекрытием события OnException
// В следующем примере будет показано как все-же обработать такую ошибку
// и добавить проблемный файл в архив
Writer := TFWZipWriter.Create;
try
Writer.AddFolder('', '..\..\', '*.pas', False);
// лочим один из файлов для демонстрации
hLockedFile := FileOpen(PathCanonicalize('..\..\' + Writer[0].FileName), WriteLock);
try
// Назначаем обработчик через который мы будем обрабатывать ошибку
// В обработчике OnException1 будет создаваться копия файла
// после чего мы укажем в параметре NewFilePath новый путь к файлу,
// а свойство Action выставим eaUseNewFilePathAndDel
// Таким образом мы уведомляем FWZip что нужно повторить попытку
// архивации файла, при этом необходимо использовать новый путь к файлу,
// после чего данный файл следует удалить.
Method.Code := @OnException1;
Method.Data := Writer;
Writer.OnException := TZipBuildExceptionEvent(Method);
Write('BuildWithException2.zip -> ');
ShowBuildResult(Writer.BuildZip('..\DemoResults\BuildWithException2.zip'));
{$IFDEF LINUX}
if hLockedFile = INVALID_HANDLE_VALUE then
hLockedFile := FileOpen(PathCanonicalize('..\..\' + Writer[0].FileName), WriteLock);
{$ENDIF}
// второй вариант, обработки показан в обработчике OnException2
// в нем мы снимаем исскуственную блокировку файла и выставляем
// свойство Action в eaRetry.
// Таким образом мы уведомляем FWZip что нужно повторить попытку
// архивации файла
Method.Code := @OnException2;
Method.Data := Writer;
Writer.OnException := TZipBuildExceptionEvent(Method);
Write('BuildWithException3.zip -> ');
ShowBuildResult(Writer.BuildZip('..\DemoResults\BuildWithException3.zip'));
// для демонстрации возвращаем блокировку на место
if hLockedFile = INVALID_HANDLE_VALUE then
hLockedFile := FileOpen(PathCanonicalize('..\..\' + Writer[0].FileName), WriteLock);
// третий вариант, обработки показан в обработчике OnException3
// в нем мы загружаем любым способом данные файла в стрим и
// выставляем свойство Action в eaUseNewFileData
// Таким образом данные будут браться непосредственно из стрима
// NewFileData
Method.Code := @OnException3;
Method.Data := Writer;
Writer.OnException := TZipBuildExceptionEvent(Method);
Write('BuildWithException4.zip -> ');
ShowBuildResult(Writer.BuildZip('..\DemoResults\BuildWithException4.zip'));
// ориентируясь на тип исключения можно реализовывать разнулю логику обработчика.
// если вы не знаете как обработать то или иное исключение,
// следует выставить свойство Action в eaSkip (выставлено по умолчанию)
// для того чтобы пропустить проблемный файл, или eaAbort,
// прервав таким образом создание архива.
finally
if hLockedFile <> INVALID_HANDLE_VALUE then
FileClose(hLockedFile);
end;
finally
Writer.Free;
end;
// При распаковке частой ошибочной ситуацией является попытка
// перезаписи уже существующего на диске файла, либо ошибка
// распаковки архива, созданного сторонним архиватором.
// Обработка ошибки распаковки решается использованием более
// новой версии ZLib (см. Readme.txt пункт 9)
// Возникновение ошибки по другим причинам приведет к возникновению
// события OnException. Если данное событие не перекрыто,
// то в случае вызова метода TFWZipReader.ExtractAll
// распаковка архива будет остановлена.
// В случае, если данное событие перекрыто, то решение
// о остановке распаковки должен принимать программист,
// выставлением флага Handled:
// (Handled = True, исключение обработано, можно продолжить распаковку)
// для демонстрации проэмулируем ошибку перезаписи,
// для этого нужно дважды распаковать один и тот-же архив
// в одну и ту-же папку
Reader := TFWZipReader.Create;
try
Reader.LoadFromFile('..\DemoResults\BuildWithException1.zip');
// распаковываем первый раз
Reader.ExtractAll('..\DemoResults\BuildWithExceptionUnpack\');
// теперь пробуем распаковать повторно.
// исключения в данном случае не произойдет, но все элементы будут пропущены
Reader.ExtractAll('..\DemoResults\BuildWithExceptionUnpack\');
// пропуск элементов можно увидеть и при ручной распаковке.
// т.к. вызов Reader[I].Extract в отличие от Reader.ExtractAll
// возвращает результат
Writeln('Manual extract:');
for I := 0 to Reader.Count - 1 do
ShowManualExtractResult(
string(Reader[I].FileName),
Reader[I].Extract('..\DemoResults\BuildWithExceptionUnpack\', ''));
// как можно заметить, все элементы действительно были пропущены
// (Reader[I].Extract вернул erSkiped для каждого элемента)
// Для обработки данной ситуации в режиме автоматической распаковки (ExtractAll)
// необходимо перекрыть событие OnDuplicate у класса TFWZipReader.
// В случае ручной распаковки, перекрывать событие OnDuplicate требуется
// у каждого элемента (Reader.Items[индекс элемента].OnDuplicate)
Method.Code := @OnDuplicate;
Method.Data := Reader;
Reader.OnDuplicate := TZipDuplicateEvent(Method);
// теперь попробуем повторно распаковать.
// при возникновении события OnDuplicate в обработчике элементу будет
// назначено новое имя и параметр Action будет выставлен в daUseNewFilePath.
// Таким образом мы укажем TFWZipReader-у что необходимо распаковать
// файл с новым именем...
// (т.е. получим аналог создания файлов в проводнике Windows, например:
// New folder -> New folder (2) -> New folder (3) и т.д.)
Reader.ExtractAll('..\DemoResults\BuildWithExceptionUnpack\');
finally
Reader.Free;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.

View File

@@ -0,0 +1,152 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{D336C006-9204-4B8B-A8C2-88CAB9F2693C}</ProjectGuid>
<MainSource>BuildWithException.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>
<FrameworkType>None</FrameworkType>
<ProjectVersion>19.2</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_S>false</DCC_S>
<DCC_K>false</DCC_K>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;UIDeviceFamily=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;UISupportedInterfaceOrientations=;CFBundleExecutable=;CFBundleResourceSpecification=;LSRequiresIPhoneOS=;CFBundleInfoDictionaryVersion=;CFBundleDevelopmentRegion=</VerInfo_Keys>
<DCC_F>false</DCC_F>
<VerInfo_Locale>1049</VerInfo_Locale>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace)</DCC_Namespace>
<DCC_ImageBase>00400000</DCC_ImageBase>
<SanitizedProjectName>BuildWithException</SanitizedProjectName>
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)</VerInfo_Keys>
<DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_DebugInformation>0</DCC_DebugInformation>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<DCC_UnitSearchPath>../../;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)</VerInfo_Keys>
<Manifest_File>(None)</Manifest_File>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">BuildWithException.dpr</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="CFBundleName"/>
<VersionInfoKeys Name="CFBundleDisplayName"/>
<VersionInfoKeys Name="UIDeviceFamily"/>
<VersionInfoKeys Name="CFBundleIdentifier"/>
<VersionInfoKeys Name="CFBundleVersion"/>
<VersionInfoKeys Name="CFBundlePackageType"/>
<VersionInfoKeys Name="CFBundleSignature"/>
<VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
<VersionInfoKeys Name="UISupportedInterfaceOrientations"/>
<VersionInfoKeys Name="CFBundleExecutable"/>
<VersionInfoKeys Name="CFBundleResourceSpecification"/>
<VersionInfoKeys Name="LSRequiresIPhoneOS"/>
<VersionInfoKeys Name="CFBundleInfoDictionaryVersion"/>
<VersionInfoKeys Name="CFBundleDevelopmentRegion"/>
</VersionInfoKeys>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k270.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp270.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Platforms>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>

View File

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="BuildWithException"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<BuildModes>
<Item Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<RequiredPackages>
<Item>
<PackageName Value="LazUtils"/>
</Item>
<Item>
<PackageName Value="LCL"/>
</Item>
</RequiredPackages>
<Units>
<Unit>
<Filename Value="BuildWithException.dpr"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="..\DemoResults\MultyPartZip\ZIP\FWZipConsts.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="..\DemoResults\MultyPartZip\ZIP\FWZipReader.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="..\DemoResults\MultyPartZip\ZIP\FWZipWriter.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<IncludeFiles Value="..\..;$(ProjOutDir)"/>
<Libraries Value="..\..\fpc_lib"/>
<OtherUnitFiles Value="..\.."/>
<UnitOutputDirectory Value="."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="Delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2Set"/>
</Debugging>
</Linking>
<Other>
<CustomOptions Value="-dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions>
<Item>
<Name Value="EAbort"/>
</Item>
<Item>
<Name Value="ECodetoolError"/>
</Item>
<Item>
<Name Value="EFOpenError"/>
</Item>
</Exceptions>
</Debugging>
</CONFIG>

View File

@@ -0,0 +1,24 @@
rd /S /Q "%cd%\backup\"
rd /S /Q "%cd%\ConverterBackup\"
rd /S /Q "%cd%\lib\"
rd /S /Q "%cd%\__history\"
rd /S /Q "%cd%\__recovery\"
del "%cd%\*.o"
del "%cd%\*.a"
del "%cd%\*.or"
del "%cd%\*.lps"
del "%cd%\*.obj"
del "%cd%\*.exe"
del "%cd%\*.ppu"
del "%cd%\*.dcu"
del "%cd%\*.log"
del "%cd%\*.compiled"
del "%cd%\*.cfg"
del "%cd%\*.dof"
del "%cd%\*.dproj.local"
del "%cd%\*.identcache"
del "%cd%\*.dsk"
del "%cd%\*.skincfg"
del "%cd%\*.bak"
del "%cd%\*.rsm"
del "%cd%\*.~*"

View File

@@ -0,0 +1,223 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : UseExDataBlob
// * Purpose : Демонстрация работы с блоками ExData
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2023.
// * Version : 2.0.0
// * 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/
//
// Данный пример показывает работу с блоками ExData.
// Их добавление при создании архива и извлечение.
// Данные блоки могут содержать любые дополнительные параметры связанные
// с элементом архива. Список зарезервированных блоков см. в коментарии
// обработчика OnSaveExData.
program UseExDataBlob;
{$IFDEF FPC}
{$MODE Delphi}
{$H+}
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}
uses
SysUtils,
Classes,
FWZipWriter,
FWZipReader,
FWZipConsts;
const
TestExDataBlob: Cardinal = $DEADBEEF;
var
Writer: TFWZipWriter;
Reader: TFWZipReader;
Method: TMethod;
//
// Обработчик при помощи которого мы добавляем блок расширенных данных ExData
// к каждому элементу массива
// =============================================================================
procedure OnSaveExData({%H-}Self, Sender: TObject; {%H-}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({%H-}Self, Sender: TObject; {%H-}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');
Value := 0;
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);
// Сохраняем результат
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.

View File

@@ -0,0 +1,152 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{02A43576-9D18-4FA2-9764-51DAB3B92B77}</ProjectGuid>
<MainSource>UseExDataBlob.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>
<FrameworkType>None</FrameworkType>
<ProjectVersion>19.2</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_S>false</DCC_S>
<DCC_K>false</DCC_K>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;UIDeviceFamily=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;UISupportedInterfaceOrientations=;CFBundleExecutable=;CFBundleResourceSpecification=;LSRequiresIPhoneOS=;CFBundleInfoDictionaryVersion=;CFBundleDevelopmentRegion=</VerInfo_Keys>
<DCC_F>false</DCC_F>
<VerInfo_Locale>1049</VerInfo_Locale>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
<DCC_ImageBase>00400000</DCC_ImageBase>
<SanitizedProjectName>UseExDataBlob</SanitizedProjectName>
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)</VerInfo_Keys>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_DebugInformation>0</DCC_DebugInformation>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)</VerInfo_Keys>
<Manifest_File>(None)</Manifest_File>
<DCC_UnitSearchPath>../../;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">UseExDataBlob.dpr</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="CFBundleName"/>
<VersionInfoKeys Name="CFBundleDisplayName"/>
<VersionInfoKeys Name="UIDeviceFamily"/>
<VersionInfoKeys Name="CFBundleIdentifier"/>
<VersionInfoKeys Name="CFBundleVersion"/>
<VersionInfoKeys Name="CFBundlePackageType"/>
<VersionInfoKeys Name="CFBundleSignature"/>
<VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
<VersionInfoKeys Name="UISupportedInterfaceOrientations"/>
<VersionInfoKeys Name="CFBundleExecutable"/>
<VersionInfoKeys Name="CFBundleResourceSpecification"/>
<VersionInfoKeys Name="LSRequiresIPhoneOS"/>
<VersionInfoKeys Name="CFBundleInfoDictionaryVersion"/>
<VersionInfoKeys Name="CFBundleDevelopmentRegion"/>
</VersionInfoKeys>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k270.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp270.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Platforms>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="UseExDataBlob"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<BuildModes>
<Item Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<RequiredPackages>
<Item>
<PackageName Value="LCL"/>
</Item>
</RequiredPackages>
<Units>
<Unit>
<Filename Value="UseExDataBlob.dpr"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<IncludeFiles Value="..\..;$(ProjOutDir)"/>
<Libraries Value="..\..\fpc_lib"/>
<OtherUnitFiles Value="..\.."/>
<UnitOutputDirectory Value="."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="Delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2Set"/>
</Debugging>
</Linking>
<Other>
<CustomOptions Value="-dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions>
<Item>
<Name Value="EAbort"/>
</Item>
<Item>
<Name Value="ECodetoolError"/>
</Item>
<Item>
<Name Value="EFOpenError"/>
</Item>
</Exceptions>
</Debugging>
</CONFIG>

View File

@@ -0,0 +1,24 @@
rd /S /Q "%cd%\backup\"
rd /S /Q "%cd%\ConverterBackup\"
rd /S /Q "%cd%\lib\"
rd /S /Q "%cd%\__history\"
rd /S /Q "%cd%\__recovery\"
del "%cd%\*.o"
del "%cd%\*.a"
del "%cd%\*.or"
del "%cd%\*.lps"
del "%cd%\*.obj"
del "%cd%\*.exe"
del "%cd%\*.ppu"
del "%cd%\*.dcu"
del "%cd%\*.log"
del "%cd%\*.compiled"
del "%cd%\*.cfg"
del "%cd%\*.dof"
del "%cd%\*.dproj.local"
del "%cd%\*.identcache"
del "%cd%\*.dsk"
del "%cd%\*.skincfg"
del "%cd%\*.bak"
del "%cd%\*.rsm"
del "%cd%\*.~*"

View File

@@ -0,0 +1,23 @@
program ZipAnalizer;
{$IFDEF FPC}
{$MODE Delphi}
{$ENDIF}
uses
{$IFnDEF FPC}
{$ELSE}
Interfaces,
{$ENDIF}
Forms,
uZipAnalizer in 'uZipAnalizer.pas' {dlgZipAnalizer};
{$IFNDEF FPC}
{$R *.res}
{$ENDIF}
begin
Application.Initialize;
Application.CreateForm(TdlgZipAnalizer, dlgZipAnalizer);
Application.Run;
end.

View File

@@ -0,0 +1,173 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{48B210D8-1C88-400C-8596-80BA4942AF52}</ProjectGuid>
<MainSource>ZipAnalizer.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Application</AppType>
<FrameworkType>VCL</FrameworkType>
<ProjectVersion>19.2</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_N>false</DCC_N>
<DCC_ImageBase>00400000</DCC_ImageBase>
<DCC_E>false</DCC_E>
<VerInfo_Locale>1049</VerInfo_Locale>
<DCC_Namespace>Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace)</DCC_Namespace>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;UIDeviceFamily=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;UISupportedInterfaceOrientations=;CFBundleExecutable=;CFBundleResourceSpecification=;LSRequiresIPhoneOS=;CFBundleInfoDictionaryVersion=;CFBundleDevelopmentRegion=</VerInfo_Keys>
<DCC_S>false</DCC_S>
<SanitizedProjectName>ZipAnalizer</SanitizedProjectName>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale>
<Icon_MainIcon>ZipAnalizer_Icon.ico</Icon_MainIcon>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)</VerInfo_Keys>
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<Icon_MainIcon>ZipAnalizer_Icon.ico</Icon_MainIcon>
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_DebugInformation>0</DCC_DebugInformation>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<BT_BuildType>Debug</BT_BuildType>
<DCC_UnitSearchPath>../../;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)</VerInfo_Keys>
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="uZipAnalizer.pas">
<Form>dlgZipAnalizer</Form>
</DCCReference>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">ZipAnalizer.dpr</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="CFBundleName"/>
<VersionInfoKeys Name="CFBundleDisplayName"/>
<VersionInfoKeys Name="UIDeviceFamily"/>
<VersionInfoKeys Name="CFBundleIdentifier"/>
<VersionInfoKeys Name="CFBundleVersion"/>
<VersionInfoKeys Name="CFBundlePackageType"/>
<VersionInfoKeys Name="CFBundleSignature"/>
<VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
<VersionInfoKeys Name="UISupportedInterfaceOrientations"/>
<VersionInfoKeys Name="CFBundleExecutable"/>
<VersionInfoKeys Name="CFBundleResourceSpecification"/>
<VersionInfoKeys Name="LSRequiresIPhoneOS"/>
<VersionInfoKeys Name="CFBundleInfoDictionaryVersion"/>
<VersionInfoKeys Name="CFBundleDevelopmentRegion"/>
</VersionInfoKeys>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k270.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp270.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Platforms>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

View File

@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="ZipAnalizer"/>
<Scaled Value="True"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
<UseXPManifest Value="True"/>
<XPManifest>
<DpiAware Value="True/PM_V2"/>
<UIAccess Value="True"/>
<LongPathAware Value="True"/>
</XPManifest>
<Icon Value="0"/>
</General>
<BuildModes>
<Item Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<RequiredPackages>
<Item>
<PackageName Value="LCL"/>
</Item>
</RequiredPackages>
<Units>
<Unit>
<Filename Value="ZipAnalizer.dpr"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="uZipAnalizer.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="dlgZipAnalizer"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<IncludeFiles Value="..\..;$(ProjOutDir)"/>
<Libraries Value="..\..\fpc_lib"/>
<OtherUnitFiles Value="..\.."/>
<UnitOutputDirectory Value="."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="Delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2Set"/>
</Debugging>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
<Other>
<CustomOptions Value="-dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions>
<Item>
<Name Value="EAbort"/>
</Item>
<Item>
<Name Value="ECodetoolError"/>
</Item>
<Item>
<Name Value="EFOpenError"/>
</Item>
</Exceptions>
</Debugging>
</CONFIG>

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

View File

@@ -0,0 +1,24 @@
rd /S /Q "%cd%\backup\"
rd /S /Q "%cd%\ConverterBackup\"
rd /S /Q "%cd%\lib\"
rd /S /Q "%cd%\__history\"
rd /S /Q "%cd%\__recovery\"
del "%cd%\*.o"
del "%cd%\*.a"
del "%cd%\*.or"
del "%cd%\*.lps"
del "%cd%\*.obj"
del "%cd%\*.exe"
del "%cd%\*.ppu"
del "%cd%\*.dcu"
del "%cd%\*.log"
del "%cd%\*.compiled"
del "%cd%\*.cfg"
del "%cd%\*.dof"
del "%cd%\*.dproj.local"
del "%cd%\*.identcache"
del "%cd%\*.dsk"
del "%cd%\*.skincfg"
del "%cd%\*.bak"
del "%cd%\*.rsm"
del "%cd%\*.~*"

View File

@@ -0,0 +1,104 @@
object dlgZipAnalizer: TdlgZipAnalizer
Left = 301
Top = 184
Caption = #1042#1099#1074#1086#1076' '#1087#1072#1088#1072#1084#1077#1090#1088#1086#1074' ZIP '#1072#1088#1093#1080#1074#1072
ClientHeight = 300
ClientWidth = 685
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
Position = poScreenCenter
OnCreate = FormCreate
OnDestroy = FormDestroy
DesignSize = (
685
300)
PixelsPerInch = 96
TextHeight = 13
object edPath: TLabeledEdit
Left = 8
Top = 24
Width = 550
Height = 21
Anchors = [akLeft, akTop, akRight]
EditLabel.Width = 124
EditLabel.Height = 13
EditLabel.Caption = #1059#1082#1072#1078#1080#1090#1077' '#1087#1091#1090#1100' '#1082' '#1072#1088#1093#1080#1074#1091':'
TabOrder = 0
OnChange = edPathChange
end
object btnBrowse: TButton
Left = 560
Top = 22
Width = 25
Height = 25
Anchors = [akTop, akRight]
Caption = '...'
TabOrder = 1
OnClick = btnBrowseClick
end
object btnAnalize: TButton
Left = 589
Top = 22
Width = 75
Height = 25
Anchors = [akTop, akRight]
Caption = #1057#1090#1072#1088#1090
Enabled = False
TabOrder = 2
OnClick = btnAnalizeClick
end
object GroupBox: TGroupBox
Left = 8
Top = 56
Width = 669
Height = 233
Anchors = [akLeft, akTop, akRight, akBottom]
Caption = #1055#1072#1088#1072#1084#1077#1090#1088#1099' '#1072#1088#1093#1080#1074#1072':'
TabOrder = 3
object edReport: TMemo
Left = 2
Top = 15
Width = 665
Height = 216
Align = alClient
Font.Charset = RUSSIAN_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
PopupMenu = PopupMenu
ReadOnly = True
ScrollBars = ssBoth
TabOrder = 0
end
end
object OpenDialog: TOpenDialog
DefaultExt = 'zip'
Filter = 'ZIP '#1072#1088#1093#1080#1074#1099' (*.zip)|*.zip|'#1042#1089#1077' '#1092#1072#1081#1083#1099' (*.*)|*.*'
Options = [ofHideReadOnly, ofFileMustExist, ofEnableSizing]
Left = 48
Top = 88
end
object PopupMenu: TPopupMenu
OnPopup = PopupMenuPopup
Left = 120
Top = 88
object mnuSave: TMenuItem
Caption = #1057#1086#1093#1088#1072#1085#1080#1090#1100'...'
ShortCut = 16467
OnClick = mnuSaveClick
end
end
object SaveDialog: TSaveDialog
DefaultExt = 'txt'
Filter = #1058#1077#1082#1089#1090#1086#1074#1099#1077' '#1092#1072#1081#1083#1099' (*.txt)|*.txt|'#1042#1089#1077' '#1092#1072#1081#1083#1099' (*.*)|*.*'
Left = 208
Top = 88
end
end

View File

@@ -0,0 +1,102 @@
object dlgZipAnalizer: TdlgZipAnalizer
Left = 1082
Height = 341
Top = 637
Width = 728
Caption = 'Вывод параметров ZIP архива'
ClientHeight = 341
ClientWidth = 728
Color = clBtnFace
DesignTimePPI = 144
Font.Color = clWindowText
Font.Height = -17
Font.Name = 'Tahoma'
OnCreate = FormCreate
OnDestroy = FormDestroy
Position = poScreenCenter
LCLVersion = '2.2.6.0'
object edPath: TLabeledEdit
Left = 12
Height = 29
Top = 36
Width = 526
Anchors = [akTop, akLeft, akRight]
EditLabel.Height = 21
EditLabel.Width = 526
EditLabel.Caption = 'Укажите путь к архиву:'
EditLabel.ParentColor = False
TabOrder = 0
OnChange = edPathChange
end
object btnBrowse: TButton
Left = 540
Height = 38
Top = 30
Width = 38
Anchors = [akTop, akRight]
Caption = '...'
OnClick = btnBrowseClick
TabOrder = 1
end
object btnAnalize: TButton
Left = 588
Height = 38
Top = 30
Width = 112
Anchors = [akTop, akRight]
Caption = 'Старт'
Enabled = False
OnClick = btnAnalizeClick
TabOrder = 2
end
object GroupBox: TGroupBox
Left = 12
Height = 241
Top = 84
Width = 704
Anchors = [akTop, akLeft, akRight, akBottom]
Caption = 'Параметры архива:'
ClientHeight = 215
ClientWidth = 700
TabOrder = 3
object edReport: TMemo
Left = 0
Height = 215
Top = 0
Width = 700
Align = alClient
Font.CharSet = RUSSIAN_CHARSET
Font.Color = clWindowText
Font.Height = -17
Font.Name = 'Tahoma'
ParentFont = False
PopupMenu = PopupMenu
ReadOnly = True
ScrollBars = ssBoth
TabOrder = 0
end
end
object OpenDialog: TOpenDialog
DefaultExt = '.zip'
Filter = 'ZIP архивы (*.zip)|*.zip|Все файлы (*.*)|*.*'
Options = [ofHideReadOnly, ofFileMustExist, ofEnableSizing]
Left = 72
Top = 132
end
object PopupMenu: TPopupMenu
OnPopup = PopupMenuPopup
Left = 180
Top = 132
object mnuSave: TMenuItem
Caption = 'Сохранить...'
ShortCut = 16467
OnClick = mnuSaveClick
end
end
object SaveDialog: TSaveDialog
DefaultExt = '.txt'
Filter = 'Текстовые файлы (*.txt)|*.txt|Все файлы (*.*)|*.*'
Left = 312
Top = 132
end
end

View File

@@ -0,0 +1,372 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip - ZipAnalizer
// * Unit Name : uZipAnalizer
// * Purpose : Вывод параметров архива используя возможности FWZipReader
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2023.
// * Version : 2.0.0
// * 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 uZipAnalizer;
{$IFDEF FPC}
{$MODE Delphi}
{$ENDIF}
interface
uses
{$IFnDEF FPC}
Windows,
{$ELSE}
LCLIntf, LCLType,
{$ENDIF}
SysUtils, Classes, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ExtCtrls, Menus,
FWZipReader,
FWZipConsts,
FWZipUtils;
type
TFWZipReaderFriendly = class(TFWZipReader);
TFWZipReaderItemFriendly = class(TFWZipReaderItem);
TExDataRecord = record
Index: Integer;
Tag: Word;
Stream: TMemoryStream;
end;
TExDataRecords = array of TExDataRecord;
TdlgZipAnalizer = class(TForm)
edPath: TLabeledEdit;
btnBrowse: TButton;
btnAnalize: TButton;
GroupBox: TGroupBox;
edReport: TMemo;
OpenDialog: TOpenDialog;
PopupMenu: TPopupMenu;
mnuSave: TMenuItem;
SaveDialog: TSaveDialog;
procedure btnBrowseClick(Sender: TObject);
procedure edPathChange(Sender: TObject);
procedure btnAnalizeClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure mnuSaveClick(Sender: TObject);
procedure PopupMenuPopup(Sender: TObject);
private
ExDataRecords: TExDataRecords;
Zip: TFWZipReaderFriendly;
procedure OnLoadExData(Sender: TObject; ItemIndex: Integer;
Tag: Word; Data: TStream);
private
procedure ClearExData;
procedure Log(const Value: string);
procedure ShowEndOfCentralDir;
procedure ShowZip64EOFCentralDirectoryLocator;
procedure ShowZip64EOFCentralDirectoryRecord;
procedure ShowItemData(Index: Integer);
end;
var
dlgZipAnalizer: TdlgZipAnalizer;
implementation
const
Delim = '===================================================================';
{$IFnDEF FPC}
{$R *.dfm}
{$ELSE}
{$R *.lfm}
{$ENDIF}
procedure TdlgZipAnalizer.btnAnalizeClick(Sender: TObject);
var
I: Integer;
begin
edReport.Lines.BeginUpdate;
try
edReport.Clear;
Log(edPath.Text);
Log(Delim);
ClearExData;
Zip.Clear;
Zip.LoadFromFile(edPath.Text);
ShowEndOfCentralDir;
ShowZip64EOFCentralDirectoryLocator;
ShowZip64EOFCentralDirectoryRecord;
for I := 0 to Zip.Count - 1 do
ShowItemData(I);
Log('DONE');
finally
edReport.Lines.EndUpdate;
end;
end;
procedure TdlgZipAnalizer.btnBrowseClick(Sender: TObject);
begin
UseLongNamePrefix := False;
OpenDialog.InitialDir :=
PathCanonicalize(ExtractFilePath(ParamStr(0)) + '..\DemoResults');
if OpenDialog.Execute then
begin
edPath.Text := OpenDialog.FileName;
edReport.Clear;
end;
end;
procedure TdlgZipAnalizer.ClearExData;
var
I: Integer;
begin
for I := 0 to Length(ExDataRecords) - 1 do
ExDataRecords[I].Stream.Free;
SetLength(ExDataRecords, 0);;
end;
procedure TdlgZipAnalizer.edPathChange(Sender: TObject);
begin
btnAnalize.Enabled := FileExists(edPath.Text);
end;
procedure TdlgZipAnalizer.FormCreate(Sender: TObject);
begin
Zip := TFWZipReaderFriendly.Create;
Zip.OnLoadExData := OnLoadExData;
end;
procedure TdlgZipAnalizer.FormDestroy(Sender: TObject);
begin
ClearExData;
Zip.Free;
end;
procedure TdlgZipAnalizer.Log(const Value: string);
begin
edReport.Lines.Add(Value);
end;
procedure TdlgZipAnalizer.mnuSaveClick(Sender: TObject);
begin
if SaveDialog.Execute then
edReport.Lines.SaveToFile(SaveDialog.FileName);
end;
procedure TdlgZipAnalizer.OnLoadExData(Sender: TObject; ItemIndex: Integer;
Tag: Word; Data: TStream);
var
Count: Integer;
begin
Count := Length(ExDataRecords);
SetLength(ExDataRecords, Count + 1);
ExDataRecords[Count].Index := ItemIndex;
ExDataRecords[Count].Tag := Tag;
ExDataRecords[Count].Stream := TMemoryStream.Create;
ExDataRecords[Count].Stream.CopyFrom(Data, 0);
end;
procedure TdlgZipAnalizer.PopupMenuPopup(Sender: TObject);
begin
mnuSave.Enabled := edReport.Lines.Count > 1;
end;
procedure TdlgZipAnalizer.ShowEndOfCentralDir;
begin
Log('END_OF_CENTRAL_DIR_SIGNATURE found');
with Zip.EndOfCentralDir do
begin
Log(Format('NumberOfThisDisk: %d', [NumberOfThisDisk]));
Log(Format('NumberOfTheDiskWithTheStart: %d', [DiskNumberStart]));
Log(Format('TotalNumberOfEntriesOnThisDisk: %d', [TotalNumberOfEntriesOnThisDisk]));
Log(Format('TotalNumberOfEntries: %d', [TotalNumberOfEntries]));
Log(Format('SizeOfTheCentralDirectory: %d', [SizeOfTheCentralDirectory]));
Log(Format('OffsetOfStartOfCentralDirectory: %d', [RelativeOffsetOfCentralDirectory]));
Log(Format('ZipfileCommentLength: %d', [ZipfileCommentLength]));
if ZipfileCommentLength > 0 then
Log(Format('Comment: %s', [Zip.Comment]));
end;
Log(Delim);
end;
procedure TdlgZipAnalizer.ShowItemData(Index: Integer);
function ByteToStr(Bytes: PByte; Size: Integer): string;
const
BytesHex: array[0..15] of char =
('0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
var
I: integer;
begin
{$IFDEF FPC}
Result := '';
{$ENDIF}
SetLength(Result, Size shl 1);
for I := 0 to Size - 1 do
begin
Result[I * 2 + 1] := BytesHex[Bytes^ shr 4];
Result[I * 2 + 2] := BytesHex[Bytes^ and $0F];
Inc(Bytes);
end;
end;
function GPBFToStr(Value: Word): string;
procedure AddValue(const S: string);
begin
if Result = '' then
Result := S
else
Result := Result + ', ' + S;
end;
begin
if Value = 0 then
begin
Result := 'EMPTY';
Exit;
end;
if PBF_CRYPTED and Value <> 0 then
AddValue('PBF_CRYPTED');
if PBF_DESCRIPTOR and Value <> 0 then
AddValue('PBF_DESCRIPTOR');
if PBF_UTF8 and Value <> 0 then
AddValue('PBF_UTF8');
if PBF_STRONG_CRYPT and Value <> 0 then
AddValue('PBF_STRONG_CRYPT');
end;
var
I: Integer;
Item: TFWZipReaderItemFriendly;
begin
Log('CENTRAL_FILE_HEADER_SIGNATURE found');
Item := TFWZipReaderItemFriendly(Zip.Item[Index]);
with Item.CentralDirFileHeader do
begin
Log(Format('VersionMadeBy: %d', [VersionMadeBy]));
Log(Format('VersionNeededToExtract: %d', [VersionNeededToExtract]));
Log(Format('GeneralPurposeBitFlag: %d (%s)', [GeneralPurposeBitFlag,
GPBFToStr(GeneralPurposeBitFlag)]));
Log(Format('CompressionMethod: %d', [CompressionMethod]));
Log(Format('LastModFileTimeTime: %d', [LastModFileTimeTime]));
Log(Format('LastModFileTimeDate: %d', [LastModFileTimeDate]));
Log(Format('Crc32: %d', [Crc32]));
Log(Format('CompressedSize: %d', [CompressedSize]));
Log(Format('UncompressedSize: %d', [UncompressedSize]));
Log(Format('FilenameLength: %d', [FilenameLength]));
if FilenameLength > 0 then
Log('>>> FileName: ' + Item.FileName);
Log(Format('ExtraFieldLength: %d', [ExtraFieldLength]));
Log(Format('FileCommentLength: %d', [FileCommentLength]));
if FileCommentLength > 0 then
Log('>>> FileComment: ' + Item.Comment);
Log(Format('DiskNumberStart: %d', [DiskNumberStart]));
Log(Format('InternalFileAttributes: %d', [InternalFileAttributes]));
Log(Format('ExternalFileAttributes: %d', [ExternalFileAttributes]));
Log(Format('RelativeOffsetOfLocalHeader: %d', [RelativeOffsetOfLocalHeader]));
end;
Log('');
Item.LoadLocalFileHeader;
Log('LOCAL_FILE_HEADER_SIGNATURE found');
with Item.LocalFileHeader do
begin
Log(Format('VersionNeededToExtract: %d', [VersionNeededToExtract]));
Log(Format('GeneralPurposeBitFlag: %d (%s)', [GeneralPurposeBitFlag,
GPBFToStr(GeneralPurposeBitFlag)]));
Log(Format('CompressionMethod: %d', [CompressionMethod]));
Log(Format('LastModFileTimeTime: %d', [LastModFileTimeTime]));
Log(Format('LastModFileTimeDate: %d', [LastModFileTimeDate]));
Log(Format('Crc32: %d', [Crc32]));
Log(Format('CompressedSize: %d', [CompressedSize]));
Log(Format('UncompressedSize: %d', [UncompressedSize]));
Log(Format('FilenameLength: %d', [FilenameLength]));
Log(Format('ExtraFieldLength: %d', [ExtraFieldLength]));
end;
if ssZIP64 in Item.PresentStreams then
begin
Log('');
Log('SUPPORTED_EXDATA_ZIP64 found');
with Item do
begin
Log(Format('UncompressedSize: %d', [UncompressedSize]));
Log(Format('CompressedSize: %d', [CompressedSize]));
Log(Format('RelativeOffsetOfLocalHeader: %d', [RelativeOffsetOfLocalHeader]));
Log(Format('DiskNumberStart: %d', [DiskNumberStart]));
end;
end;
if ssNTFS in Item.PresentStreams then
begin
Log('');
Log('SUPPORTED_EXDATA_NTFSTIME found');
end;
for I := 0 to Length(ExDataRecords) - 1 do
if ExDataRecords[I].Index = Index then
begin
Log('');
Log(Format('UNKNOWN TAG (%d) found', [ExDataRecords[I].Tag]));
Log(Format('ExData size %d', [ExDataRecords[I].Stream.Size]));
Log('ExData dump:');
Log(ByteToStr(ExDataRecords[I].Stream.Memory, ExDataRecords[I].Stream.Size));
end;
Log(Delim);
end;
procedure TdlgZipAnalizer.ShowZip64EOFCentralDirectoryLocator;
begin
with Zip.Zip64EOFCentralDirectoryLocator do
begin
if Signature <> ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE then Exit;
Log('ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE found');
Log(Format('NumberOfTheDisk: %d', [DiskNumberStart]));
Log(Format('RelativeOffset: %d', [RelativeOffset]));
Log(Format('TotalNumberOfDisks: %d', [TotalNumberOfDisks]));
end;
Log(Delim);
end;
procedure TdlgZipAnalizer.ShowZip64EOFCentralDirectoryRecord;
begin
with Zip.Zip64EOFCentralDirectoryRecord do
begin
if Zip64EndOfCentralDirSignature <> ZIP64_END_OF_CENTRAL_DIR_SIGNATURE then Exit;
Log('ZIP64_END_OF_CENTRAL_DIR_SIGNATURE found');
Log(Format('SizeOfZip64EOFCentralDirectoryRecord: %d', [SizeOfZip64EOFCentralDirectoryRecord]));
Log(Format('VersionMadeBy: %d', [VersionMadeBy]));
Log(Format('VersionNeededToExtract: %d', [VersionNeededToExtract]));
Log(Format('number of this disk: %d', [NumberOfThisDisk]));
Log(Format('number of the disk with the start of the central directory: %d', [DiskNumberStart]));
Log(Format('total number of entries in the central directory on this disk: %d', [TotalNumberOfEntriesOnThisDisk]));
Log(Format('total number of entries in the central directory: %d', [TotalNumberOfEntries]));
Log(Format('size of the central directory: %d', [SizeOfTheCentralDirectory]));
Log(Format('offset of start of central directory with respect to the starting disk number: %d', [RelativeOffsetOfCentralDirectory]));
end;
Log(Delim);
end;
end.

View File

@@ -0,0 +1,23 @@
program ZipAnalizer2;
{$IFDEF FPC}
{$MODE Delphi}
{$ENDIF}
uses
{$IFnDEF FPC}
{$ELSE}
Interfaces,
{$ENDIF}
Forms,
uZipAnalizer2 in 'uZipAnalizer2.pas' {dlgZipAnalizer};
{$IFNDEF FPC}
{$R *.res}
{$ENDIF}
begin
Application.Initialize;
Application.CreateForm(TdlgZipAnalizer, dlgZipAnalizer);
Application.Run;
end.

View File

@@ -0,0 +1,173 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{59E61B6B-6187-41F8-947A-693BE9101356}</ProjectGuid>
<MainSource>ZipAnalizer2.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Application</AppType>
<FrameworkType>VCL</FrameworkType>
<ProjectVersion>19.2</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_N>false</DCC_N>
<DCC_ImageBase>00400000</DCC_ImageBase>
<DCC_E>false</DCC_E>
<VerInfo_Locale>1049</VerInfo_Locale>
<DCC_Namespace>Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace)</DCC_Namespace>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;UIDeviceFamily=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;UISupportedInterfaceOrientations=;CFBundleExecutable=;CFBundleResourceSpecification=;LSRequiresIPhoneOS=;CFBundleInfoDictionaryVersion=;CFBundleDevelopmentRegion=</VerInfo_Keys>
<DCC_S>false</DCC_S>
<SanitizedProjectName>ZipAnalizer2</SanitizedProjectName>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale>
<Icon_MainIcon>ZipAnalizer_Icon.ico</Icon_MainIcon>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)</VerInfo_Keys>
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<Icon_MainIcon>ZipAnalizer_Icon.ico</Icon_MainIcon>
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_DebugInformation>0</DCC_DebugInformation>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<BT_BuildType>Debug</BT_BuildType>
<DCC_UnitSearchPath>../../;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)</VerInfo_Keys>
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="uZipAnalizer2.pas">
<Form>dlgZipAnalizer</Form>
</DCCReference>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">ZipAnalizer2.dpr</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="CFBundleName"/>
<VersionInfoKeys Name="CFBundleDisplayName"/>
<VersionInfoKeys Name="UIDeviceFamily"/>
<VersionInfoKeys Name="CFBundleIdentifier"/>
<VersionInfoKeys Name="CFBundleVersion"/>
<VersionInfoKeys Name="CFBundlePackageType"/>
<VersionInfoKeys Name="CFBundleSignature"/>
<VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
<VersionInfoKeys Name="UISupportedInterfaceOrientations"/>
<VersionInfoKeys Name="CFBundleExecutable"/>
<VersionInfoKeys Name="CFBundleResourceSpecification"/>
<VersionInfoKeys Name="LSRequiresIPhoneOS"/>
<VersionInfoKeys Name="CFBundleInfoDictionaryVersion"/>
<VersionInfoKeys Name="CFBundleDevelopmentRegion"/>
</VersionInfoKeys>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k270.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp270.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Platforms>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>

View File

@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="ZipAnalizer2"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<BuildModes>
<Item Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<RequiredPackages>
<Item>
<PackageName Value="LCL"/>
</Item>
</RequiredPackages>
<Units>
<Unit>
<Filename Value="ZipAnalizer2.dpr"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="uZipAnalizer2.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="dlgZipAnalizer"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<IncludeFiles Value="..\..;$(ProjOutDir)"/>
<Libraries Value="..\..\fpc_lib"/>
<OtherUnitFiles Value="..\.."/>
<UnitOutputDirectory Value="."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="Delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2Set"/>
</Debugging>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
<Other>
<CustomOptions Value="-dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions>
<Item>
<Name Value="EAbort"/>
</Item>
<Item>
<Name Value="ECodetoolError"/>
</Item>
<Item>
<Name Value="EFOpenError"/>
</Item>
</Exceptions>
</Debugging>
</CONFIG>

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

View File

@@ -0,0 +1,24 @@
rd /S /Q "%cd%\backup\"
rd /S /Q "%cd%\ConverterBackup\"
rd /S /Q "%cd%\lib\"
rd /S /Q "%cd%\__history\"
rd /S /Q "%cd%\__recovery\"
del "%cd%\*.o"
del "%cd%\*.a"
del "%cd%\*.or"
del "%cd%\*.lps"
del "%cd%\*.obj"
del "%cd%\*.exe"
del "%cd%\*.ppu"
del "%cd%\*.dcu"
del "%cd%\*.log"
del "%cd%\*.compiled"
del "%cd%\*.cfg"
del "%cd%\*.dof"
del "%cd%\*.dproj.local"
del "%cd%\*.identcache"
del "%cd%\*.dsk"
del "%cd%\*.skincfg"
del "%cd%\*.bak"
del "%cd%\*.rsm"
del "%cd%\*.~*"

View File

@@ -0,0 +1,102 @@
object dlgZipAnalizer: TdlgZipAnalizer
Left = 301
Top = 184
Caption = #1042#1099#1074#1086#1076' '#1087#1072#1088#1072#1084#1077#1090#1088#1086#1074' ZIP '#1072#1088#1093#1080#1074#1072
ClientHeight = 300
ClientWidth = 685
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
Position = poScreenCenter
DesignSize = (
685
300)
PixelsPerInch = 96
TextHeight = 13
object edPath: TLabeledEdit
Left = 8
Top = 24
Width = 550
Height = 21
Anchors = [akLeft, akTop, akRight]
EditLabel.Width = 124
EditLabel.Height = 13
EditLabel.Caption = #1059#1082#1072#1078#1080#1090#1077' '#1087#1091#1090#1100' '#1082' '#1072#1088#1093#1080#1074#1091':'
TabOrder = 0
OnChange = edPathChange
end
object btnBrowse: TButton
Left = 560
Top = 22
Width = 25
Height = 25
Anchors = [akTop, akRight]
Caption = '...'
TabOrder = 1
OnClick = btnBrowseClick
end
object btnAnalize: TButton
Left = 591
Top = 22
Width = 75
Height = 25
Anchors = [akTop, akRight]
Caption = #1057#1090#1072#1088#1090
Enabled = False
TabOrder = 2
OnClick = btnAnalizeClick
end
object GroupBox: TGroupBox
Left = 8
Top = 56
Width = 669
Height = 233
Anchors = [akLeft, akTop, akRight, akBottom]
Caption = #1055#1072#1088#1072#1084#1077#1090#1088#1099' '#1072#1088#1093#1080#1074#1072':'
TabOrder = 3
object edReport: TMemo
Left = 2
Top = 15
Width = 665
Height = 216
Align = alClient
Font.Charset = RUSSIAN_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
PopupMenu = PopupMenu
ReadOnly = True
ScrollBars = ssBoth
TabOrder = 0
end
end
object OpenDialog: TOpenDialog
DefaultExt = 'zip'
Filter = 'ZIP '#1072#1088#1093#1080#1074#1099' (*.zip)|*.zip|'#1042#1089#1077' '#1092#1072#1081#1083#1099' (*.*)|*.*'
Options = [ofHideReadOnly, ofFileMustExist, ofEnableSizing]
Left = 48
Top = 88
end
object PopupMenu: TPopupMenu
OnPopup = PopupMenuPopup
Left = 120
Top = 88
object mnuSave: TMenuItem
Caption = #1057#1086#1093#1088#1072#1085#1080#1090#1100'...'
ShortCut = 16467
OnClick = mnuSaveClick
end
end
object SaveDialog: TSaveDialog
DefaultExt = 'txt'
Filter = #1058#1077#1082#1089#1090#1086#1074#1099#1077' '#1092#1072#1081#1083#1099' (*.txt)|*.txt|'#1042#1089#1077' '#1092#1072#1081#1083#1099' (*.*)|*.*'
Left = 208
Top = 88
end
end

View File

@@ -0,0 +1,101 @@
object dlgZipAnalizer: TdlgZipAnalizer
Left = 301
Height = 300
Top = 184
Width = 685
Caption = 'Вывод параметров ZIP архива'
ClientHeight = 300
ClientWidth = 685
Color = clBtnFace
DesignTimePPI = 144
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Position = poScreenCenter
LCLVersion = '2.2.6.0'
object edPath: TLabeledEdit
Left = 8
Height = 21
Top = 24
Width = 550
Anchors = [akTop, akLeft, akRight]
EditLabel.Height = 13
EditLabel.Width = 550
EditLabel.Caption = 'Укажите путь к архиву:'
EditLabel.ParentColor = False
TabOrder = 0
Text = 'E:\2\tst.zip'
OnChange = edPathChange
end
object btnBrowse: TButton
Left = 560
Height = 25
Top = 22
Width = 25
Anchors = [akTop, akRight]
Caption = '...'
OnClick = btnBrowseClick
TabOrder = 1
end
object btnAnalize: TButton
Left = 591
Height = 25
Top = 22
Width = 75
Anchors = [akTop, akRight]
Caption = 'Старт'
Enabled = False
OnClick = btnAnalizeClick
TabOrder = 2
end
object GroupBox: TGroupBox
Left = 8
Height = 233
Top = 56
Width = 669
Anchors = [akTop, akLeft, akRight, akBottom]
Caption = 'Параметры архива:'
ClientHeight = 215
ClientWidth = 665
TabOrder = 3
object edReport: TMemo
Left = 0
Height = 215
Top = 0
Width = 665
Align = alClient
Font.CharSet = RUSSIAN_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
ParentFont = False
PopupMenu = PopupMenu
ReadOnly = True
ScrollBars = ssBoth
TabOrder = 0
end
end
object OpenDialog: TOpenDialog
DefaultExt = '.zip'
Filter = 'ZIP архивы (*.zip)|*.zip|Все файлы (*.*)|*.*'
Options = [ofHideReadOnly, ofFileMustExist, ofEnableSizing]
Left = 48
Top = 88
end
object PopupMenu: TPopupMenu
OnPopup = PopupMenuPopup
Left = 120
Top = 88
object mnuSave: TMenuItem
Caption = 'Сохранить...'
ShortCut = 16467
OnClick = mnuSaveClick
end
end
object SaveDialog: TSaveDialog
DefaultExt = '.txt'
Filter = 'Текстовые файлы (*.txt)|*.txt|Все файлы (*.*)|*.*'
Left = 208
Top = 88
end
end

View File

@@ -0,0 +1,642 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip - ZipAnalizer2
// * Unit Name : uZipAnalizer2
// * Purpose : Вывод параметров архива при помощи поиска сигнатур
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2023.
// * Version : 2.0.0
// * 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 uZipAnalizer2;
{$IFDEF FPC}
{$MODE Delphi}
{$H+}
{$ENDIF}
interface
uses
{$IFDEF FPC}
LCLIntf, LCLType,
{$ENDIF}
SysUtils, Classes, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ExtCtrls, Menus,
FWZipConsts, FWZipZLib, FWZipUtils;
type
TdlgZipAnalizer = class(TForm)
edPath: TLabeledEdit;
btnBrowse: TButton;
btnAnalize: TButton;
GroupBox: TGroupBox;
edReport: TMemo;
OpenDialog: TOpenDialog;
PopupMenu: TPopupMenu;
mnuSave: TMenuItem;
SaveDialog: TSaveDialog;
procedure btnBrowseClick(Sender: TObject);
procedure edPathChange(Sender: TObject);
procedure btnAnalizeClick(Sender: TObject);
procedure mnuSaveClick(Sender: TObject);
procedure PopupMenuPopup(Sender: TObject);
private
procedure Log(const Value: string);
procedure Scan(const Value: string);
function FindSing(Stream: TStream): DWORD;
procedure ShowLocalFileHeader(Stream: TStream);
procedure ShowDataDescryptor(Stream: TStream);
procedure ShowCentralFileHeader(Stream: TStream);
procedure ShowExtraFields(Stream: TStream; Size: Integer;
FileHeader: TCentralDirectoryFileHeader);
procedure ShowZip64(Stream: TStream);
procedure ShowZip64Locator(Stream: TStream);
procedure ShowEndOfCentralDir(Stream: TStream);
procedure LoadStringValue(Stream: TStream; out Value: string;
nSize: Cardinal; UTF: Boolean);
end;
var
dlgZipAnalizer: TdlgZipAnalizer;
implementation
const
Delim = '===================================================================';
{$R *.dfm}
function CompressionMethodToStr(Value: Integer): string;
begin
case Value of
Z_NO_COMPRESSION: Result := 'NO_COMPRESSION';
Z_DEFLATED: Result := 'DEFLATE';
1: Result := 'Shrunk';
2..5: Result := 'Reduced with compression factor ' + IntToStr(Value - 1);
6: Result := 'Imploding';
9: Result := 'DEFLATE64';
10: Result := 'PKWARE Imploding';
11, 13, 15..17: Result := 'Reserved by PKWARE';
12: Result := 'BZIP2';
14: Result := 'LZMA';
18: Result := 'IBM TERSE';
19: Result := 'IBM LZ77';
97: Result := 'WavPack';
98: Result := 'PPMd';
else
Result := 'unknown';
end;
end;
function GPBFToStr(Value: Word): string;
procedure AddValue(const S: string);
begin
if Result = '' then
Result := S
else
Result := Result + ', ' + S;
end;
begin
if Value = 0 then
begin
Result := 'PBF_COMPRESS_NORMAL';
Exit;
end;
if (Value and 7) in [PBF_COMPRESS_NORMAL, PBF_CRYPTED] then
AddValue('PBF_COMPRESS_NORMAL');
case Value and 6 of
PBF_COMPRESS_MAXIMUM: AddValue('PBF_COMPRESS_MAXIMUM');
PBF_COMPRESS_FAST: AddValue('PBF_COMPRESS_FAST');
PBF_COMPRESS_SUPERFAST: AddValue('PBF_COMPRESS_SUPERFAST');
end;
if PBF_CRYPTED and Value = PBF_CRYPTED then
AddValue('PBF_CRYPTED');
if PBF_DESCRIPTOR and Value = PBF_DESCRIPTOR then
AddValue('PBF_DESCRIPTOR');
if PBF_UTF8 and Value = PBF_UTF8 then
AddValue('PBF_UTF8');
if PBF_STRONG_CRYPT and Value = PBF_STRONG_CRYPT then
AddValue('PBF_STRONG_CRYPT');
end;
procedure TdlgZipAnalizer.btnAnalizeClick(Sender: TObject);
begin
edReport.Lines.BeginUpdate;
try
edReport.Clear;
Log(edPath.Text);
Log(Delim);
Scan(edPath.Text);
Log('DONE');
finally
edReport.Lines.EndUpdate;
end;
end;
procedure TdlgZipAnalizer.btnBrowseClick(Sender: TObject);
begin
UseLongNamePrefix := False;
OpenDialog.InitialDir :=
PathCanonicalize(ExtractFilePath(ParamStr(0)) + '..\DemoResults');
if OpenDialog.Execute then
begin
edPath.Text := OpenDialog.FileName;
edReport.Clear;
end;
end;
procedure TdlgZipAnalizer.edPathChange(Sender: TObject);
begin
btnAnalize.Enabled := FileExists(edPath.Text);
end;
function TdlgZipAnalizer.FindSing(Stream: TStream): DWORD;
const
KnownSigns: array [0..5] of DWORD = (
LOCAL_FILE_HEADER_SIGNATURE,
DATA_DESCRIPTOR_SIGNATURE,
CENTRAL_FILE_HEADER_SIGNATURE,
ZIP64_END_OF_CENTRAL_DIR_SIGNATURE,
ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE,
END_OF_CENTRAL_DIR_SIGNATURE
);
function CalcLen: Integer;
begin
Result := Stream.Size - Stream.Position;
if Result > 1024 then
Result := 1024;
end;
var
pBuff, pCursor: PByte;
I, A, Len: Integer;
OldPosition: Int64;
begin
Result := 0;
GetMem(pBuff, 1024);
try
Len := CalcLen;
while (Result = 0) and (Len > 4) do
begin
OldPosition := Stream.Position;
Stream.ReadBuffer(pBuff^, Len);
pCursor := pBuff;
for I := 0 to Len - 4 do
begin
for A := 0 to 5 do
if PCardinal(pCursor)^ = KnownSigns[A] then
begin
Result := KnownSigns[A];
Break;
end;
if Result = 0 then
Inc(pCursor)
else
begin
Stream.Position := OldPosition + I;
Break;
end;
end;
if Result = 0 then
begin
Len := CalcLen;
if Len > 0 then
Stream.Position := Stream.Position - 4;
end;
end;
finally
FreeMem(pBuff);
end;
end;
procedure TdlgZipAnalizer.LoadStringValue(Stream: TStream;
out Value: string; nSize: Cardinal; UTF: Boolean);
var
aString: AnsiString;
begin
if Integer(nSize) > 0 then
begin
{$IFDEF FPC}
aString := '';
{$ENDIF}
SetLength(aString, nSize);
Stream.ReadBuffer(aString[1], nSize);
if UTF then
begin
{$IFDEF UNICODE}
Value := string(UTF8ToUnicodeString(aString))
{$ELSE}
Value := string(UTF8Decode(aString));
Value := StringReplace(Value, '?', '_', [rfReplaceAll]);
{$ENDIF}
end
else
Value := string(ConvertFromOemString(aString));
end;
end;
procedure TdlgZipAnalizer.Log(const Value: string);
begin
edReport.Lines.Add(Value);
end;
procedure TdlgZipAnalizer.mnuSaveClick(Sender: TObject);
begin
if SaveDialog.Execute then
edReport.Lines.SaveToFile(SaveDialog.FileName);
end;
procedure TdlgZipAnalizer.PopupMenuPopup(Sender: TObject);
begin
mnuSave.Enabled := edReport.Lines.Count > 1;
end;
procedure TdlgZipAnalizer.Scan(const Value: string);
var
F: TFileStream;
Sign: DWORD;
begin
F := TFileStream.Create(Value, fmOpenRead or fmShareDenyWrite);
try
Sign := FindSing(F);
while Sign <> 0 do
begin
case Sign of
LOCAL_FILE_HEADER_SIGNATURE: ShowLocalFileHeader(F);
DATA_DESCRIPTOR_SIGNATURE: ShowDataDescryptor(F);
CENTRAL_FILE_HEADER_SIGNATURE: ShowCentralFileHeader(F);
ZIP64_END_OF_CENTRAL_DIR_SIGNATURE: ShowZip64(F);
ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE: ShowZip64Locator(F);
END_OF_CENTRAL_DIR_SIGNATURE: ShowEndOfCentralDir(F);
end;
Sign := FindSing(F);
end;
finally
F.Free;
end;
end;
procedure TdlgZipAnalizer.ShowCentralFileHeader(Stream: TStream);
var
Data: TCentralDirectoryFileHeader;
FileName, Comment: string;
begin
Log('CENTRAL_FILE_HEADER_SIGNATURE found at offset: ' + IntToStr(Stream.Position));
{$IFDEF FPC}
Data := Default(TCentralDirectoryFileHeader);
{$ENDIF}
Stream.ReadBuffer(Data, SizeOf(TCentralDirectoryFileHeader));
with Data do
begin
if CentralFileHeaderSignature <> CENTRAL_FILE_HEADER_SIGNATURE then
Log('INVALID SIGNATURE!!!!');
Log(Format('VersionMadeBy: %d', [VersionMadeBy]));
Log(Format('VersionNeededToExtract: %d', [VersionNeededToExtract]));
Log(Format('GeneralPurposeBitFlag: %d (%s)', [GeneralPurposeBitFlag,
GPBFToStr(GeneralPurposeBitFlag)]));
Log(Format('CompressionMethod: %d (%s)', [CompressionMethod, CompressionMethodToStr(CompressionMethod)]));
Log(Format('LastModFileTimeTime: %d', [LastModFileTimeTime]));
Log(Format('LastModFileTimeDate: %d', [LastModFileTimeDate]));
Log(Format('Crc32: %d', [Crc32]));
Log(Format('CompressedSize: %d', [CompressedSize]));
Log(Format('UncompressedSize: %d', [UncompressedSize]));
Log(Format('FilenameLength: %d', [FilenameLength]));
Log(Format('ExtraFieldLength: %d', [ExtraFieldLength]));
Log(Format('FileCommentLength: %d', [FileCommentLength]));
Log(Format('DiskNumberStart: %d', [DiskNumberStart]));
Log(Format('InternalFileAttributes: %d', [InternalFileAttributes]));
Log(Format('ExternalFileAttributes: %d', [ExternalFileAttributes]));
Log(Format('RelativeOffsetOfLocalHeader: %d', [RelativeOffsetOfLocalHeader]));
LoadStringValue(Stream, FileName, FilenameLength,
GeneralPurposeBitFlag and PBF_UTF8 <> 0);
Log('>>> FileName: ' + FileName);
Log(Delim);
ShowExtraFields(Stream, ExtraFieldLength, Data);
if FileCommentLength > 0 then
begin
LoadStringValue(Stream, Comment, FileCommentLength,
GeneralPurposeBitFlag and PBF_UTF8 <> 0);
Log('>>> FileComment: ' + Comment);
Log(Delim);
end;
end;
end;
procedure TdlgZipAnalizer.ShowDataDescryptor(Stream: TStream);
var
Data: TDataDescriptor;
StartPos: Int64;
begin
StartPos := Stream.Position;
{$IFDEF FPC}
Data := Default(TDataDescriptor);
{$ENDIF}
Stream.ReadBuffer(Data, SizeOf(TDataDescriptor));
if Data.Crc32 = LOCAL_FILE_HEADER_SIGNATURE then
begin
Log('SPAN_DESCRIPTOR_SIGNATURE found at offset: ' + IntToStr(StartPos));
Log(Delim);
Stream.Position := StartPos + SizeOf(DWORD);
Exit;
end;
Log('DATA_DESCRIPTOR_SIGNATURE found at offset: ' + IntToStr(StartPos));
with Data do
begin
if DescriptorSignature <> DATA_DESCRIPTOR_SIGNATURE then
Log('INVALID SIGNATURE!!!!');
Log(Format('Crc32: %d', [Crc32]));
Log(Format('CompressedSize: %d', [CompressedSize]));
Log(Format('UncompressedSize: %d', [UncompressedSize]));
end;
Log(Delim);
end;
procedure TdlgZipAnalizer.ShowEndOfCentralDir(Stream: TStream);
var
Data: TEndOfCentralDir;
Comment: string;
begin
Log('END_OF_CENTRAL_DIR_SIGNATURE found at offset: ' + IntToStr(Stream.Position));
{$IFDEF FPC}
Data := Default(TEndOfCentralDir);
{$ENDIF}
Stream.ReadBuffer(Data, SizeOf(TEndOfCentralDir));
with Data do
begin
if EndOfCentralDirSignature <> END_OF_CENTRAL_DIR_SIGNATURE then
Log('INVALID SIGNATURE!!!!');
Log(Format('NumberOfThisDisk: %d', [NumberOfThisDisk]));
Log(Format('DiskNumberStart: %d', [DiskNumberStart]));
Log(Format('TotalNumberOfEntriesOnThisDisk: %d', [TotalNumberOfEntriesOnThisDisk]));
Log(Format('TotalNumberOfEntries: %d', [TotalNumberOfEntries]));
Log(Format('SizeOfTheCentralDirectory: %d', [SizeOfTheCentralDirectory]));
Log(Format('RelativeOffsetOfCentralDirectory: %d', [RelativeOffsetOfCentralDirectory]));
Log(Format('ZipfileCommentLength: %d', [ZipfileCommentLength]));
if ZipfileCommentLength > 0 then
begin
LoadStringValue(Stream, Comment, ZipfileCommentLength, False);
Log(Format('>>> Comment: %s', [Comment]));
end;
end;
Log(Delim);
end;
procedure TdlgZipAnalizer.ShowExtraFields(Stream: TStream; Size: Integer;
FileHeader: TCentralDirectoryFileHeader);
var
Buff, EOFBuff: Pointer;
BuffCount: Integer;
HeaderID, BlockSize: Word;
function GetOffset(Value: Integer): Pointer;
begin
Result := UIntToPtr(PtrToUInt(EOFBuff) - NativeUInt(Value));
end;
function ByteToStr(Bytes: PByte; Size: Integer): string;
const
BytesHex: array[0..15] of char =
('0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
var
I: Integer;
begin
{$IFDEF FPC}
Result := '';
{$ENDIF}
SetLength(Result, Size shl 1);
for I := 0 to Size - 1 do
begin
Result[I * 2 + 1] := BytesHex[Bytes^ shr 4];
Result[I * 2 + 2] := BytesHex[Bytes^ and $0F];
Inc(Bytes);
end;
end;
var
ExDataStream: TMemoryStream;
StartPos: Int64;
FileTime: TFileTime;
begin
if Size = 0 then Exit;
StartPos := Stream.Position;
Log('EXDATA found at offset: ' + IntToStr(StartPos));
Log(Delim);
GetMem(Buff, Size);
try
BuffCount := Size;
Stream.ReadBuffer(Buff^, BuffCount);
EOFBuff := UIntToPtr(PtrToUInt(Buff) + NativeUInt(BuffCount));
while BuffCount > 0 do
begin
HeaderID := PWord(GetOffset(BuffCount))^;
Dec(BuffCount, 2);
BlockSize := PWord(GetOffset(BuffCount))^;
Dec(BuffCount, 2);
case HeaderID of
SUPPORTED_EXDATA_ZIP64:
begin
Log('SUPPORTED_EXDATA_ZIP64 found at offset: ' +
IntToStr(StartPos + Size - BuffCount - 4));
if FileHeader.UncompressedSize = MAXDWORD then
begin
if BuffCount < 8 then Break;
Log('UncompressedSize: ' + IntToStr(PInt64(GetOffset(BuffCount))^));
Dec(BuffCount, 8);
Dec(BlockSize, 8);
end;
if FileHeader.CompressedSize = MAXDWORD then
begin
if BuffCount < 8 then Break;
Log('CompressedSize: ' + IntToStr(PInt64(GetOffset(BuffCount))^));
Dec(BuffCount, 8);
Dec(BlockSize, 8);
end;
if FileHeader.RelativeOffsetOfLocalHeader = MAXDWORD then
begin
if BuffCount < 8 then Break;
Log('RelativeOffsetOfLocalHeader: ' + IntToStr(PInt64(GetOffset(BuffCount))^));
Dec(BuffCount, 8);
Dec(BlockSize, 8);
end;
if FileHeader.DiskNumberStart = MAXWORD then
begin
if BuffCount < 4 then Break;
Log('DiskNumberStart: ' + IntToStr(PInt64(GetOffset(BuffCount))^));
Dec(BuffCount, 4);
Dec(BlockSize, 4);
end;
Dec(BuffCount, BlockSize);
Log(Delim);
end;
SUPPORTED_EXDATA_NTFSTIME:
begin
if BuffCount < 32 then Break;
if BlockSize <> 32 then
begin
Dec(BuffCount, BlockSize);
Continue;
end;
Dec(BuffCount, 4);
Dec(BlockSize, 4);
if PWord(GetOffset(BuffCount))^ <> 1 then
begin
Dec(BuffCount, BlockSize);
Continue;
end;
Dec(BuffCount, 2);
Dec(BlockSize, 2);
if PWord(GetOffset(BuffCount))^ <> SizeOf(TNTFSFileTime) then
begin
Dec(BuffCount, BlockSize);
Continue;
end;
Dec(BuffCount, 2);
Dec(BlockSize, 2);
Log('SUPPORTED_EXDATA_NTFSTIME found at offset: ' +
IntToStr(StartPos + Size - BuffCount - 12));
FileTime := PFileTime(GetOffset(BuffCount))^;
Dec(BuffCount, SizeOf(TFileTime));
Dec(BlockSize, SizeOf(TFileTime));
Log(Format('Last Write Time: %s', [DateTimeToStr(FileTimeToLocalDateTime(FileTime))]));
FileTime := PFileTime(GetOffset(BuffCount))^;
Dec(BuffCount, SizeOf(TFileTime));
Dec(BlockSize, SizeOf(TFileTime));
Log(Format('Last Access Time: %s', [DateTimeToStr(FileTimeToLocalDateTime(FileTime))]));
FileTime := PFileTime(GetOffset(BuffCount))^;
Dec(BuffCount, SizeOf(TFileTime));
Dec(BlockSize, SizeOf(TFileTime));
Log(Format('Creation Time: %s', [DateTimeToStr(FileTimeToLocalDateTime(FileTime))]));
Log(Delim);
end;
else
Log(Format('UNKNOWN EXDATA TAG %d found at offset: %d',
[HeaderID, StartPos + Size - BuffCount - 8]));
ExDataStream := TMemoryStream.Create;
try
ExDataStream.WriteBuffer(GetOffset(BuffCount)^, BlockSize);
ExDataStream.Position := 0;
Log(ByteToStr(ExDataStream.Memory, ExDataStream.Size));
finally
ExDataStream.Free;
end;
Log(Delim);
end;
Dec(BuffCount, BlockSize);
end;
finally
FreeMem(Buff);
end;
end;
procedure TdlgZipAnalizer.ShowLocalFileHeader(Stream: TStream);
var
Data: TLocalFileHeader;
FileName: string;
begin
Log('LOCAL_FILE_HEADER_SIGNATURE found at offset: ' + IntToStr(Stream.Position));
{$IFDEF FPC}
Data := Default(TLocalFileHeader);
{$ENDIF}
Stream.ReadBuffer(Data, SizeOf(TLocalFileHeader));
with Data do
begin
if LocalFileHeaderSignature <> LOCAL_FILE_HEADER_SIGNATURE then
Log('INVALID SIGNATURE!!!!');
Log(Format('VersionNeededToExtract: %d', [VersionNeededToExtract]));
Log(Format('GeneralPurposeBitFlag: %d (%s)', [GeneralPurposeBitFlag,
GPBFToStr(GeneralPurposeBitFlag)]));
Log(Format('CompressionMethod: %d (%s)', [CompressionMethod, CompressionMethodToStr(CompressionMethod)]));
Log(Format('LastModFileTimeTime: %d', [LastModFileTimeTime]));
Log(Format('LastModFileTimeDate: %d', [LastModFileTimeDate]));
Log(Format('Crc32: %d', [Crc32]));
Log(Format('CompressedSize: %d', [CompressedSize]));
Log(Format('UncompressedSize: %d', [UncompressedSize]));
Log(Format('FilenameLength: %d', [FilenameLength]));
Log(Format('ExtraFieldLength: %d', [ExtraFieldLength]));
LoadStringValue(Stream, FileName, FilenameLength,
GeneralPurposeBitFlag and PBF_UTF8 <> 0);
Log('>>> FileName: ' + FileName);
end;
Log(Delim);
end;
procedure TdlgZipAnalizer.ShowZip64(Stream: TStream);
var
Data: TZip64EOFCentralDirectoryRecord;
begin
Log('ZIP64_END_OF_CENTRAL_DIR_SIGNATURE found at offset: ' + IntToStr(Stream.Position));
{$IFDEF FPC}
Data := Default(TZip64EOFCentralDirectoryRecord);
{$ENDIF}
Stream.ReadBuffer(Data, SizeOf(TZip64EOFCentralDirectoryRecord));
with Data do
begin
if Zip64EndOfCentralDirSignature <> ZIP64_END_OF_CENTRAL_DIR_SIGNATURE then
Log('INVALID SIGNATURE!!!!');
Log(Format('SizeOfZip64EOFCentralDirectoryRecord: %d', [SizeOfZip64EOFCentralDirectoryRecord]));
Log(Format('VersionMadeBy: %d', [VersionMadeBy]));
Log(Format('VersionNeededToExtract: %d', [VersionNeededToExtract]));
Log(Format('number of this disk: %d', [NumberOfThisDisk]));
Log(Format('number of the disk with the start of the central directory: %d', [DiskNumberStart]));
Log(Format('total number of entries in the central directory on this disk: %d', [TotalNumberOfEntriesOnThisDisk]));
Log(Format('total number of entries in the central directory: %d', [TotalNumberOfEntries]));
Log(Format('size of the central directory: %d', [SizeOfTheCentralDirectory]));
Log(Format('offset of start of central directory with respect to the starting disk number: %d', [RelativeOffsetOfCentralDirectory]));
end;
Log(Delim);
end;
procedure TdlgZipAnalizer.ShowZip64Locator(Stream: TStream);
var
Data: TZip64EOFCentralDirectoryLocator;
begin
Log('ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE found at offset: ' + IntToStr(Stream.Position));
{$IFDEF FPC}
Data := Default(TZip64EOFCentralDirectoryLocator);
{$ENDIF}
Stream.ReadBuffer(Data, SizeOf(TZip64EOFCentralDirectoryLocator));
with Data do
begin
if Signature <> ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE then
Log('INVALID SIGNATURE!!!!');
Log(Format('NumberOfTheDisk: %d', [DiskNumberStart]));
Log(Format('RelativeOffset: %d', [RelativeOffset]));
Log(Format('TotalNumberOfDisks: %d', [TotalNumberOfDisks]));
end;
Log(Delim);
end;
end.

619
fwzip/Doc/rfc1950.txt Normal file
View File

@@ -0,0 +1,619 @@
Network Working Group P. Deutsch
Request for Comments: 1950 Aladdin Enterprises
Category: Informational J-L. Gailly
Info-ZIP
May 1996
ZLIB Compressed Data Format Specification version 3.3
Status of This Memo
This memo provides information for the Internet community. This memo
does not specify an Internet standard of any kind. Distribution of
this memo is unlimited.
IESG Note:
The IESG takes no position on the validity of any Intellectual
Property Rights statements contained in this document.
Notices
Copyright (c) 1996 L. Peter Deutsch and Jean-Loup Gailly
Permission is granted to copy and distribute this document for any
purpose and without charge, including translations into other
languages and incorporation into compilations, provided that the
copyright notice and this notice are preserved, and that any
substantive changes or deletions from the original are clearly
marked.
A pointer to the latest version of this and related documentation in
HTML format can be found at the URL
<ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
Abstract
This specification defines a lossless compressed data format. The
data can be produced or consumed, even for an arbitrarily long
sequentially presented input data stream, using only an a priori
bounded amount of intermediate storage. The format presently uses
the DEFLATE compression method but can be easily extended to use
other compression methods. It can be implemented readily in a manner
not covered by patents. This specification also defines the ADLER-32
checksum (an extension and improvement of the Fletcher checksum),
used for detection of data corruption, and provides an algorithm for
computing it.
Deutsch & Gailly Informational [Page 1]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
Table of Contents
1. Introduction ................................................... 2
1.1. Purpose ................................................... 2
1.2. Intended audience ......................................... 3
1.3. Scope ..................................................... 3
1.4. Compliance ................................................ 3
1.5. Definitions of terms and conventions used ................ 3
1.6. Changes from previous versions ............................ 3
2. Detailed specification ......................................... 3
2.1. Overall conventions ....................................... 3
2.2. Data format ............................................... 4
2.3. Compliance ................................................ 7
3. References ..................................................... 7
4. Source code .................................................... 8
5. Security Considerations ........................................ 8
6. Acknowledgements ............................................... 8
7. Authors' Addresses ............................................. 8
8. Appendix: Rationale ............................................ 9
9. Appendix: Sample code ..........................................10
1. Introduction
1.1. Purpose
The purpose of this specification is to define a lossless
compressed data format that:
* Is independent of CPU type, operating system, file system,
and character set, and hence can be used for interchange;
* Can be produced or consumed, even for an arbitrarily long
sequentially presented input data stream, using only an a
priori bounded amount of intermediate storage, and hence can
be used in data communications or similar structures such as
Unix filters;
* Can use a number of different compression methods;
* Can be implemented readily in a manner not covered by
patents, and hence can be practiced freely.
The data format defined by this specification does not attempt to
allow random access to compressed data.
Deutsch & Gailly Informational [Page 2]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
1.2. Intended audience
This specification is intended for use by implementors of software
to compress data into zlib format and/or decompress data from zlib
format.
The text of the specification assumes a basic background in
programming at the level of bits and other primitive data
representations.
1.3. Scope
The specification specifies a compressed data format that can be
used for in-memory compression of a sequence of arbitrary bytes.
1.4. Compliance
Unless otherwise indicated below, a compliant decompressor must be
able to accept and decompress any data set that conforms to all
the specifications presented here; a compliant compressor must
produce data sets that conform to all the specifications presented
here.
1.5. Definitions of terms and conventions used
byte: 8 bits stored or transmitted as a unit (same as an octet).
(For this specification, a byte is exactly 8 bits, even on
machines which store a character on a number of bits different
from 8.) See below, for the numbering of bits within a byte.
1.6. Changes from previous versions
Version 3.1 was the first public release of this specification.
In version 3.2, some terminology was changed and the Adler-32
sample code was rewritten for clarity. In version 3.3, the
support for a preset dictionary was introduced, and the
specification was converted to RFC style.
2. Detailed specification
2.1. Overall conventions
In the diagrams below, a box like this:
+---+
| | <-- the vertical bars might be missing
+---+
Deutsch & Gailly Informational [Page 3]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
represents one byte; a box like this:
+==============+
| |
+==============+
represents a variable number of bytes.
Bytes stored within a computer do not have a "bit order", since
they are always treated as a unit. However, a byte considered as
an integer between 0 and 255 does have a most- and least-
significant bit, and since we write numbers with the most-
significant digit on the left, we also write bytes with the most-
significant bit on the left. In the diagrams below, we number the
bits of a byte so that bit 0 is the least-significant bit, i.e.,
the bits are numbered:
+--------+
|76543210|
+--------+
Within a computer, a number may occupy multiple bytes. All
multi-byte numbers in the format described here are stored with
the MOST-significant byte first (at the lower memory address).
For example, the decimal number 520 is stored as:
0 1
+--------+--------+
|00000010|00001000|
+--------+--------+
^ ^
| |
| + less significant byte = 8
+ more significant byte = 2 x 256
2.2. Data format
A zlib stream has the following structure:
0 1
+---+---+
|CMF|FLG| (more-->)
+---+---+
Deutsch & Gailly Informational [Page 4]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
(if FLG.FDICT set)
0 1 2 3
+---+---+---+---+
| DICTID | (more-->)
+---+---+---+---+
+=====================+---+---+---+---+
|...compressed data...| ADLER32 |
+=====================+---+---+---+---+
Any data which may appear after ADLER32 are not part of the zlib
stream.
CMF (Compression Method and flags)
This byte is divided into a 4-bit compression method and a 4-
bit information field depending on the compression method.
bits 0 to 3 CM Compression method
bits 4 to 7 CINFO Compression info
CM (Compression method)
This identifies the compression method used in the file. CM = 8
denotes the "deflate" compression method with a window size up
to 32K. This is the method used by gzip and PNG (see
references [1] and [2] in Chapter 3, below, for the reference
documents). CM = 15 is reserved. It might be used in a future
version of this specification to indicate the presence of an
extra field before the compressed data.
CINFO (Compression info)
For CM = 8, CINFO is the base-2 logarithm of the LZ77 window
size, minus eight (CINFO=7 indicates a 32K window size). Values
of CINFO above 7 are not allowed in this version of the
specification. CINFO is not defined in this specification for
CM not equal to 8.
FLG (FLaGs)
This flag byte is divided as follows:
bits 0 to 4 FCHECK (check bits for CMF and FLG)
bit 5 FDICT (preset dictionary)
bits 6 to 7 FLEVEL (compression level)
The FCHECK value must be such that CMF and FLG, when viewed as
a 16-bit unsigned integer stored in MSB order (CMF*256 + FLG),
is a multiple of 31.
Deutsch & Gailly Informational [Page 5]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
FDICT (Preset dictionary)
If FDICT is set, a DICT dictionary identifier is present
immediately after the FLG byte. The dictionary is a sequence of
bytes which are initially fed to the compressor without
producing any compressed output. DICT is the Adler-32 checksum
of this sequence of bytes (see the definition of ADLER32
below). The decompressor can use this identifier to determine
which dictionary has been used by the compressor.
FLEVEL (Compression level)
These flags are available for use by specific compression
methods. The "deflate" method (CM = 8) sets these flags as
follows:
0 - compressor used fastest algorithm
1 - compressor used fast algorithm
2 - compressor used default algorithm
3 - compressor used maximum compression, slowest algorithm
The information in FLEVEL is not needed for decompression; it
is there to indicate if recompression might be worthwhile.
compressed data
For compression method 8, the compressed data is stored in the
deflate compressed data format as described in the document
"DEFLATE Compressed Data Format Specification" by L. Peter
Deutsch. (See reference [3] in Chapter 3, below)
Other compressed data formats are not specified in this version
of the zlib specification.
ADLER32 (Adler-32 checksum)
This contains a checksum value of the uncompressed data
(excluding any dictionary data) computed according to Adler-32
algorithm. This algorithm is a 32-bit extension and improvement
of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073
standard. See references [4] and [5] in Chapter 3, below)
Adler-32 is composed of two sums accumulated per byte: s1 is
the sum of all bytes, s2 is the sum of all s1 values. Both sums
are done modulo 65521. s1 is initialized to 1, s2 to zero. The
Adler-32 checksum is stored as s2*65536 + s1 in most-
significant-byte first (network) order.
Deutsch & Gailly Informational [Page 6]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
2.3. Compliance
A compliant compressor must produce streams with correct CMF, FLG
and ADLER32, but need not support preset dictionaries. When the
zlib data format is used as part of another standard data format,
the compressor may use only preset dictionaries that are specified
by this other data format. If this other format does not use the
preset dictionary feature, the compressor must not set the FDICT
flag.
A compliant decompressor must check CMF, FLG, and ADLER32, and
provide an error indication if any of these have incorrect values.
A compliant decompressor must give an error indication if CM is
not one of the values defined in this specification (only the
value 8 is permitted in this version), since another value could
indicate the presence of new features that would cause subsequent
data to be interpreted incorrectly. A compliant decompressor must
give an error indication if FDICT is set and DICTID is not the
identifier of a known preset dictionary. A decompressor may
ignore FLEVEL and still be compliant. When the zlib data format
is being used as a part of another standard format, a compliant
decompressor must support all the preset dictionaries specified by
the other format. When the other format does not use the preset
dictionary feature, a compliant decompressor must reject any
stream in which the FDICT flag is set.
3. References
[1] Deutsch, L.P.,"GZIP Compressed Data Format Specification",
available in ftp://ftp.uu.net/pub/archiving/zip/doc/
[2] Thomas Boutell, "PNG (Portable Network Graphics) specification",
available in ftp://ftp.uu.net/graphics/png/documents/
[3] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification",
available in ftp://ftp.uu.net/pub/archiving/zip/doc/
[4] Fletcher, J. G., "An Arithmetic Checksum for Serial
Transmissions," IEEE Transactions on Communications, Vol. COM-30,
No. 1, January 1982, pp. 247-252.
[5] ITU-T Recommendation X.224, Annex D, "Checksum Algorithms,"
November, 1993, pp. 144, 145. (Available from
gopher://info.itu.ch). ITU-T X.244 is also the same as ISO 8073.
Deutsch & Gailly Informational [Page 7]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
4. Source code
Source code for a C language implementation of a "zlib" compliant
library is available at ftp://ftp.uu.net/pub/archiving/zip/zlib/.
5. Security Considerations
A decoder that fails to check the ADLER32 checksum value may be
subject to undetected data corruption.
6. Acknowledgements
Trademarks cited in this document are the property of their
respective owners.
Jean-Loup Gailly and Mark Adler designed the zlib format and wrote
the related software described in this specification. Glenn
Randers-Pehrson converted this document to RFC and HTML format.
7. Authors' Addresses
L. Peter Deutsch
Aladdin Enterprises
203 Santa Margarita Ave.
Menlo Park, CA 94025
Phone: (415) 322-0103 (AM only)
FAX: (415) 322-1734
EMail: <ghost@aladdin.com>
Jean-Loup Gailly
EMail: <gzip@prep.ai.mit.edu>
Questions about the technical content of this specification can be
sent by email to
Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
Mark Adler <madler@alumni.caltech.edu>
Editorial comments on this specification can be sent by email to
L. Peter Deutsch <ghost@aladdin.com> and
Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
Deutsch & Gailly Informational [Page 8]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
8. Appendix: Rationale
8.1. Preset dictionaries
A preset dictionary is specially useful to compress short input
sequences. The compressor can take advantage of the dictionary
context to encode the input in a more compact manner. The
decompressor can be initialized with the appropriate context by
virtually decompressing a compressed version of the dictionary
without producing any output. However for certain compression
algorithms such as the deflate algorithm this operation can be
achieved without actually performing any decompression.
The compressor and the decompressor must use exactly the same
dictionary. The dictionary may be fixed or may be chosen among a
certain number of predefined dictionaries, according to the kind
of input data. The decompressor can determine which dictionary has
been chosen by the compressor by checking the dictionary
identifier. This document does not specify the contents of
predefined dictionaries, since the optimal dictionaries are
application specific. Standard data formats using this feature of
the zlib specification must precisely define the allowed
dictionaries.
8.2. The Adler-32 algorithm
The Adler-32 algorithm is much faster than the CRC32 algorithm yet
still provides an extremely low probability of undetected errors.
The modulo on unsigned long accumulators can be delayed for 5552
bytes, so the modulo operation time is negligible. If the bytes
are a, b, c, the second sum is 3a + 2b + c + 3, and so is position
and order sensitive, unlike the first sum, which is just a
checksum. That 65521 is prime is important to avoid a possible
large class of two-byte errors that leave the check unchanged.
(The Fletcher checksum uses 255, which is not prime and which also
makes the Fletcher check insensitive to single byte changes 0 <->
255.)
The sum s1 is initialized to 1 instead of zero to make the length
of the sequence part of s2, so that the length does not have to be
checked separately. (Any sequence of zeroes has a Fletcher
checksum of zero.)
Deutsch & Gailly Informational [Page 9]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
9. Appendix: Sample code
The following C code computes the Adler-32 checksum of a data buffer.
It is written for clarity, not for speed. The sample code is in the
ANSI C programming language. Non C users may find it easier to read
with these hints:
& Bitwise AND operator.
>> Bitwise right shift operator. When applied to an
unsigned quantity, as here, right shift inserts zero bit(s)
at the left.
<< Bitwise left shift operator. Left shift inserts zero
bit(s) at the right.
++ "n++" increments the variable n.
% modulo operator: a % b is the remainder of a divided by b.
#define BASE 65521 /* largest prime smaller than 65536 */
/*
Update a running Adler-32 checksum with the bytes buf[0..len-1]
and return the updated checksum. The Adler-32 checksum should be
initialized to 1.
Usage example:
unsigned long adler = 1L;
while (read_buffer(buffer, length) != EOF) {
adler = update_adler32(adler, buffer, length);
}
if (adler != original_adler) error();
*/
unsigned long update_adler32(unsigned long adler,
unsigned char *buf, int len)
{
unsigned long s1 = adler & 0xffff;
unsigned long s2 = (adler >> 16) & 0xffff;
int n;
for (n = 0; n < len; n++) {
s1 = (s1 + buf[n]) % BASE;
s2 = (s2 + s1) % BASE;
}
return (s2 << 16) + s1;
}
/* Return the adler32 of the bytes buf[0..len-1] */
Deutsch & Gailly Informational [Page 10]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
unsigned long adler32(unsigned char *buf, int len)
{
return update_adler32(1L, buf, len);
}
Deutsch & Gailly Informational [Page 11]

955
fwzip/Doc/rfc1951.txt Normal file
View File

@@ -0,0 +1,955 @@
Network Working Group P. Deutsch
Request for Comments: 1951 Aladdin Enterprises
Category: Informational May 1996
DEFLATE Compressed Data Format Specification version 1.3
Status of This Memo
This memo provides information for the Internet community. This memo
does not specify an Internet standard of any kind. Distribution of
this memo is unlimited.
IESG Note:
The IESG takes no position on the validity of any Intellectual
Property Rights statements contained in this document.
Notices
Copyright (c) 1996 L. Peter Deutsch
Permission is granted to copy and distribute this document for any
purpose and without charge, including translations into other
languages and incorporation into compilations, provided that the
copyright notice and this notice are preserved, and that any
substantive changes or deletions from the original are clearly
marked.
A pointer to the latest version of this and related documentation in
HTML format can be found at the URL
<ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
Abstract
This specification defines a lossless compressed data format that
compresses data using a combination of the LZ77 algorithm and Huffman
coding, with efficiency comparable to the best currently available
general-purpose compression methods. The data can be produced or
consumed, even for an arbitrarily long sequentially presented input
data stream, using only an a priori bounded amount of intermediate
storage. The format can be implemented readily in a manner not
covered by patents.
Deutsch Informational [Page 1]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
Table of Contents
1. Introduction ................................................... 2
1.1. Purpose ................................................... 2
1.2. Intended audience ......................................... 3
1.3. Scope ..................................................... 3
1.4. Compliance ................................................ 3
1.5. Definitions of terms and conventions used ................ 3
1.6. Changes from previous versions ............................ 4
2. Compressed representation overview ............................. 4
3. Detailed specification ......................................... 5
3.1. Overall conventions ....................................... 5
3.1.1. Packing into bytes .................................. 5
3.2. Compressed block format ................................... 6
3.2.1. Synopsis of prefix and Huffman coding ............... 6
3.2.2. Use of Huffman coding in the "deflate" format ....... 7
3.2.3. Details of block format ............................. 9
3.2.4. Non-compressed blocks (BTYPE=00) ................... 11
3.2.5. Compressed blocks (length and distance codes) ...... 11
3.2.6. Compression with fixed Huffman codes (BTYPE=01) .... 12
3.2.7. Compression with dynamic Huffman codes (BTYPE=10) .. 13
3.3. Compliance ............................................... 14
4. Compression algorithm details ................................. 14
5. References .................................................... 16
6. Security Considerations ....................................... 16
7. Source code ................................................... 16
8. Acknowledgements .............................................. 16
9. Author's Address .............................................. 17
1. Introduction
1.1. Purpose
The purpose of this specification is to define a lossless
compressed data format that:
* Is independent of CPU type, operating system, file system,
and character set, and hence can be used for interchange;
* Can be produced or consumed, even for an arbitrarily long
sequentially presented input data stream, using only an a
priori bounded amount of intermediate storage, and hence
can be used in data communications or similar structures
such as Unix filters;
* Compresses data with efficiency comparable to the best
currently available general-purpose compression methods,
and in particular considerably better than the "compress"
program;
* Can be implemented readily in a manner not covered by
patents, and hence can be practiced freely;
Deutsch Informational [Page 2]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
* Is compatible with the file format produced by the current
widely used gzip utility, in that conforming decompressors
will be able to read data produced by the existing gzip
compressor.
The data format defined by this specification does not attempt to:
* Allow random access to compressed data;
* Compress specialized data (e.g., raster graphics) as well
as the best currently available specialized algorithms.
A simple counting argument shows that no lossless compression
algorithm can compress every possible input data set. For the
format defined here, the worst case expansion is 5 bytes per 32K-
byte block, i.e., a size increase of 0.015% for large data sets.
English text usually compresses by a factor of 2.5 to 3;
executable files usually compress somewhat less; graphical data
such as raster images may compress much more.
1.2. Intended audience
This specification is intended for use by implementors of software
to compress data into "deflate" format and/or decompress data from
"deflate" format.
The text of the specification assumes a basic background in
programming at the level of bits and other primitive data
representations. Familiarity with the technique of Huffman coding
is helpful but not required.
1.3. Scope
The specification specifies a method for representing a sequence
of bytes as a (usually shorter) sequence of bits, and a method for
packing the latter bit sequence into bytes.
1.4. Compliance
Unless otherwise indicated below, a compliant decompressor must be
able to accept and decompress any data set that conforms to all
the specifications presented here; a compliant compressor must
produce data sets that conform to all the specifications presented
here.
1.5. Definitions of terms and conventions used
Byte: 8 bits stored or transmitted as a unit (same as an octet).
For this specification, a byte is exactly 8 bits, even on machines
Deutsch Informational [Page 3]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
which store a character on a number of bits different from eight.
See below, for the numbering of bits within a byte.
String: a sequence of arbitrary bytes.
1.6. Changes from previous versions
There have been no technical changes to the deflate format since
version 1.1 of this specification. In version 1.2, some
terminology was changed. Version 1.3 is a conversion of the
specification to RFC style.
2. Compressed representation overview
A compressed data set consists of a series of blocks, corresponding
to successive blocks of input data. The block sizes are arbitrary,
except that non-compressible blocks are limited to 65,535 bytes.
Each block is compressed using a combination of the LZ77 algorithm
and Huffman coding. The Huffman trees for each block are independent
of those for previous or subsequent blocks; the LZ77 algorithm may
use a reference to a duplicated string occurring in a previous block,
up to 32K input bytes before.
Each block consists of two parts: a pair of Huffman code trees that
describe the representation of the compressed data part, and a
compressed data part. (The Huffman trees themselves are compressed
using Huffman encoding.) The compressed data consists of a series of
elements of two types: literal bytes (of strings that have not been
detected as duplicated within the previous 32K input bytes), and
pointers to duplicated strings, where a pointer is represented as a
pair <length, backward distance>. The representation used in the
"deflate" format limits distances to 32K bytes and lengths to 258
bytes, but does not limit the size of a block, except for
uncompressible blocks, which are limited as noted above.
Each type of value (literals, distances, and lengths) in the
compressed data is represented using a Huffman code, using one code
tree for literals and lengths and a separate code tree for distances.
The code trees for each block appear in a compact form just before
the compressed data for that block.
Deutsch Informational [Page 4]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
3. Detailed specification
3.1. Overall conventions In the diagrams below, a box like this:
+---+
| | <-- the vertical bars might be missing
+---+
represents one byte; a box like this:
+==============+
| |
+==============+
represents a variable number of bytes.
Bytes stored within a computer do not have a "bit order", since
they are always treated as a unit. However, a byte considered as
an integer between 0 and 255 does have a most- and least-
significant bit, and since we write numbers with the most-
significant digit on the left, we also write bytes with the most-
significant bit on the left. In the diagrams below, we number the
bits of a byte so that bit 0 is the least-significant bit, i.e.,
the bits are numbered:
+--------+
|76543210|
+--------+
Within a computer, a number may occupy multiple bytes. All
multi-byte numbers in the format described here are stored with
the least-significant byte first (at the lower memory address).
For example, the decimal number 520 is stored as:
0 1
+--------+--------+
|00001000|00000010|
+--------+--------+
^ ^
| |
| + more significant byte = 2 x 256
+ less significant byte = 8
3.1.1. Packing into bytes
This document does not address the issue of the order in which
bits of a byte are transmitted on a bit-sequential medium,
since the final data format described here is byte- rather than
Deutsch Informational [Page 5]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
bit-oriented. However, we describe the compressed block format
in below, as a sequence of data elements of various bit
lengths, not a sequence of bytes. We must therefore specify
how to pack these data elements into bytes to form the final
compressed byte sequence:
* Data elements are packed into bytes in order of
increasing bit number within the byte, i.e., starting
with the least-significant bit of the byte.
* Data elements other than Huffman codes are packed
starting with the least-significant bit of the data
element.
* Huffman codes are packed starting with the most-
significant bit of the code.
In other words, if one were to print out the compressed data as
a sequence of bytes, starting with the first byte at the
*right* margin and proceeding to the *left*, with the most-
significant bit of each byte on the left as usual, one would be
able to parse the result from right to left, with fixed-width
elements in the correct MSB-to-LSB order and Huffman codes in
bit-reversed order (i.e., with the first bit of the code in the
relative LSB position).
3.2. Compressed block format
3.2.1. Synopsis of prefix and Huffman coding
Prefix coding represents symbols from an a priori known
alphabet by bit sequences (codes), one code for each symbol, in
a manner such that different symbols may be represented by bit
sequences of different lengths, but a parser can always parse
an encoded string unambiguously symbol-by-symbol.
We define a prefix code in terms of a binary tree in which the
two edges descending from each non-leaf node are labeled 0 and
1 and in which the leaf nodes correspond one-for-one with (are
labeled with) the symbols of the alphabet; then the code for a
symbol is the sequence of 0's and 1's on the edges leading from
the root to the leaf labeled with that symbol. For example:
Deutsch Informational [Page 6]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
/\ Symbol Code
0 1 ------ ----
/ \ A 00
/\ B B 1
0 1 C 011
/ \ D 010
A /\
0 1
/ \
D C
A parser can decode the next symbol from an encoded input
stream by walking down the tree from the root, at each step
choosing the edge corresponding to the next input bit.
Given an alphabet with known symbol frequencies, the Huffman
algorithm allows the construction of an optimal prefix code
(one which represents strings with those symbol frequencies
using the fewest bits of any possible prefix codes for that
alphabet). Such a code is called a Huffman code. (See
reference [1] in Chapter 5, references for additional
information on Huffman codes.)
Note that in the "deflate" format, the Huffman codes for the
various alphabets must not exceed certain maximum code lengths.
This constraint complicates the algorithm for computing code
lengths from symbol frequencies. Again, see Chapter 5,
references for details.
3.2.2. Use of Huffman coding in the "deflate" format
The Huffman codes used for each alphabet in the "deflate"
format have two additional rules:
* All codes of a given bit length have lexicographically
consecutive values, in the same order as the symbols
they represent;
* Shorter codes lexicographically precede longer codes.
Deutsch Informational [Page 7]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
We could recode the example above to follow this rule as
follows, assuming that the order of the alphabet is ABCD:
Symbol Code
------ ----
A 10
B 0
C 110
D 111
I.e., 0 precedes 10 which precedes 11x, and 110 and 111 are
lexicographically consecutive.
Given this rule, we can define the Huffman code for an alphabet
just by giving the bit lengths of the codes for each symbol of
the alphabet in order; this is sufficient to determine the
actual codes. In our example, the code is completely defined
by the sequence of bit lengths (2, 1, 3, 3). The following
algorithm generates the codes as integers, intended to be read
from most- to least-significant bit. The code lengths are
initially in tree[I].Len; the codes are produced in
tree[I].Code.
1) Count the number of codes for each code length. Let
bl_count[N] be the number of codes of length N, N >= 1.
2) Find the numerical value of the smallest code for each
code length:
code = 0;
bl_count[0] = 0;
for (bits = 1; bits <= MAX_BITS; bits++) {
code = (code + bl_count[bits-1]) << 1;
next_code[bits] = code;
}
3) Assign numerical values to all codes, using consecutive
values for all codes of the same length with the base
values determined at step 2. Codes that are never used
(which have a bit length of zero) must not be assigned a
value.
for (n = 0; n <= max_code; n++) {
len = tree[n].Len;
if (len != 0) {
tree[n].Code = next_code[len];
next_code[len]++;
}
Deutsch Informational [Page 8]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
}
Example:
Consider the alphabet ABCDEFGH, with bit lengths (3, 3, 3, 3,
3, 2, 4, 4). After step 1, we have:
N bl_count[N]
- -----------
2 1
3 5
4 2
Step 2 computes the following next_code values:
N next_code[N]
- ------------
1 0
2 0
3 2
4 14
Step 3 produces the following code values:
Symbol Length Code
------ ------ ----
A 3 010
B 3 011
C 3 100
D 3 101
E 3 110
F 2 00
G 4 1110
H 4 1111
3.2.3. Details of block format
Each block of compressed data begins with 3 header bits
containing the following data:
first bit BFINAL
next 2 bits BTYPE
Note that the header bits do not necessarily begin on a byte
boundary, since a block does not necessarily occupy an integral
number of bytes.
Deutsch Informational [Page 9]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
BFINAL is set if and only if this is the last block of the data
set.
BTYPE specifies how the data are compressed, as follows:
00 - no compression
01 - compressed with fixed Huffman codes
10 - compressed with dynamic Huffman codes
11 - reserved (error)
The only difference between the two compressed cases is how the
Huffman codes for the literal/length and distance alphabets are
defined.
In all cases, the decoding algorithm for the actual data is as
follows:
do
read block header from input stream.
if stored with no compression
skip any remaining bits in current partially
processed byte
read LEN and NLEN (see next section)
copy LEN bytes of data to output
otherwise
if compressed with dynamic Huffman codes
read representation of code trees (see
subsection below)
loop (until end of block code recognized)
decode literal/length value from input stream
if value < 256
copy value (literal byte) to output stream
otherwise
if value = end of block (256)
break from loop
otherwise (value = 257..285)
decode distance from input stream
move backwards distance bytes in the output
stream, and copy length bytes from this
position to the output stream.
end loop
while not last block
Note that a duplicated string reference may refer to a string
in a previous block; i.e., the backward distance may cross one
or more block boundaries. However a distance cannot refer past
the beginning of the output stream. (An application using a
Deutsch Informational [Page 10]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
preset dictionary might discard part of the output stream; a
distance can refer to that part of the output stream anyway)
Note also that the referenced string may overlap the current
position; for example, if the last 2 bytes decoded have values
X and Y, a string reference with <length = 5, distance = 2>
adds X,Y,X,Y,X to the output stream.
We now specify each compression method in turn.
3.2.4. Non-compressed blocks (BTYPE=00)
Any bits of input up to the next byte boundary are ignored.
The rest of the block consists of the following information:
0 1 2 3 4...
+---+---+---+---+================================+
| LEN | NLEN |... LEN bytes of literal data...|
+---+---+---+---+================================+
LEN is the number of data bytes in the block. NLEN is the
one's complement of LEN.
3.2.5. Compressed blocks (length and distance codes)
As noted above, encoded data blocks in the "deflate" format
consist of sequences of symbols drawn from three conceptually
distinct alphabets: either literal bytes, from the alphabet of
byte values (0..255), or <length, backward distance> pairs,
where the length is drawn from (3..258) and the distance is
drawn from (1..32,768). In fact, the literal and length
alphabets are merged into a single alphabet (0..285), where
values 0..255 represent literal bytes, the value 256 indicates
end-of-block, and values 257..285 represent length codes
(possibly in conjunction with extra bits following the symbol
code) as follows:
Deutsch Informational [Page 11]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
Extra Extra Extra
Code Bits Length(s) Code Bits Lengths Code Bits Length(s)
---- ---- ------ ---- ---- ------- ---- ---- -------
257 0 3 267 1 15,16 277 4 67-82
258 0 4 268 1 17,18 278 4 83-98
259 0 5 269 2 19-22 279 4 99-114
260 0 6 270 2 23-26 280 4 115-130
261 0 7 271 2 27-30 281 5 131-162
262 0 8 272 2 31-34 282 5 163-194
263 0 9 273 3 35-42 283 5 195-226
264 0 10 274 3 43-50 284 5 227-257
265 1 11,12 275 3 51-58 285 0 258
266 1 13,14 276 3 59-66
The extra bits should be interpreted as a machine integer
stored with the most-significant bit first, e.g., bits 1110
represent the value 14.
Extra Extra Extra
Code Bits Dist Code Bits Dist Code Bits Distance
---- ---- ---- ---- ---- ------ ---- ---- --------
0 0 1 10 4 33-48 20 9 1025-1536
1 0 2 11 4 49-64 21 9 1537-2048
2 0 3 12 5 65-96 22 10 2049-3072
3 0 4 13 5 97-128 23 10 3073-4096
4 1 5,6 14 6 129-192 24 11 4097-6144
5 1 7,8 15 6 193-256 25 11 6145-8192
6 2 9-12 16 7 257-384 26 12 8193-12288
7 2 13-16 17 7 385-512 27 12 12289-16384
8 3 17-24 18 8 513-768 28 13 16385-24576
9 3 25-32 19 8 769-1024 29 13 24577-32768
3.2.6. Compression with fixed Huffman codes (BTYPE=01)
The Huffman codes for the two alphabets are fixed, and are not
represented explicitly in the data. The Huffman code lengths
for the literal/length alphabet are:
Lit Value Bits Codes
--------- ---- -----
0 - 143 8 00110000 through
10111111
144 - 255 9 110010000 through
111111111
256 - 279 7 0000000 through
0010111
280 - 287 8 11000000 through
11000111
Deutsch Informational [Page 12]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
The code lengths are sufficient to generate the actual codes,
as described above; we show the codes in the table for added
clarity. Literal/length values 286-287 will never actually
occur in the compressed data, but participate in the code
construction.
Distance codes 0-31 are represented by (fixed-length) 5-bit
codes, with possible additional bits as shown in the table
shown in Paragraph 3.2.5, above. Note that distance codes 30-
31 will never actually occur in the compressed data.
3.2.7. Compression with dynamic Huffman codes (BTYPE=10)
The Huffman codes for the two alphabets appear in the block
immediately after the header bits and before the actual
compressed data, first the literal/length code and then the
distance code. Each code is defined by a sequence of code
lengths, as discussed in Paragraph 3.2.2, above. For even
greater compactness, the code length sequences themselves are
compressed using a Huffman code. The alphabet for code lengths
is as follows:
0 - 15: Represent code lengths of 0 - 15
16: Copy the previous code length 3 - 6 times.
The next 2 bits indicate repeat length
(0 = 3, ... , 3 = 6)
Example: Codes 8, 16 (+2 bits 11),
16 (+2 bits 10) will expand to
12 code lengths of 8 (1 + 6 + 5)
17: Repeat a code length of 0 for 3 - 10 times.
(3 bits of length)
18: Repeat a code length of 0 for 11 - 138 times
(7 bits of length)
A code length of 0 indicates that the corresponding symbol in
the literal/length or distance alphabet will not occur in the
block, and should not participate in the Huffman code
construction algorithm given earlier. If only one distance
code is used, it is encoded using one bit, not zero bits; in
this case there is a single code length of one, with one unused
code. One distance code of zero bits means that there are no
distance codes used at all (the data is all literals).
We can now define the format of the block:
5 Bits: HLIT, # of Literal/Length codes - 257 (257 - 286)
5 Bits: HDIST, # of Distance codes - 1 (1 - 32)
4 Bits: HCLEN, # of Code Length codes - 4 (4 - 19)
Deutsch Informational [Page 13]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
(HCLEN + 4) x 3 bits: code lengths for the code length
alphabet given just above, in the order: 16, 17, 18,
0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
These code lengths are interpreted as 3-bit integers
(0-7); as above, a code length of 0 means the
corresponding symbol (literal/length or distance code
length) is not used.
HLIT + 257 code lengths for the literal/length alphabet,
encoded using the code length Huffman code
HDIST + 1 code lengths for the distance alphabet,
encoded using the code length Huffman code
The actual compressed data of the block,
encoded using the literal/length and distance Huffman
codes
The literal/length symbol 256 (end of data),
encoded using the literal/length Huffman code
The code length repeat codes can cross from HLIT + 257 to the
HDIST + 1 code lengths. In other words, all code lengths form
a single sequence of HLIT + HDIST + 258 values.
3.3. Compliance
A compressor may limit further the ranges of values specified in
the previous section and still be compliant; for example, it may
limit the range of backward pointers to some value smaller than
32K. Similarly, a compressor may limit the size of blocks so that
a compressible block fits in memory.
A compliant decompressor must accept the full range of possible
values defined in the previous section, and must accept blocks of
arbitrary size.
4. Compression algorithm details
While it is the intent of this document to define the "deflate"
compressed data format without reference to any particular
compression algorithm, the format is related to the compressed
formats produced by LZ77 (Lempel-Ziv 1977, see reference [2] below);
since many variations of LZ77 are patented, it is strongly
recommended that the implementor of a compressor follow the general
algorithm presented here, which is known not to be patented per se.
The material in this section is not part of the definition of the
Deutsch Informational [Page 14]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
specification per se, and a compressor need not follow it in order to
be compliant.
The compressor terminates a block when it determines that starting a
new block with fresh trees would be useful, or when the block size
fills up the compressor's block buffer.
The compressor uses a chained hash table to find duplicated strings,
using a hash function that operates on 3-byte sequences. At any
given point during compression, let XYZ be the next 3 input bytes to
be examined (not necessarily all different, of course). First, the
compressor examines the hash chain for XYZ. If the chain is empty,
the compressor simply writes out X as a literal byte and advances one
byte in the input. If the hash chain is not empty, indicating that
the sequence XYZ (or, if we are unlucky, some other 3 bytes with the
same hash function value) has occurred recently, the compressor
compares all strings on the XYZ hash chain with the actual input data
sequence starting at the current point, and selects the longest
match.
The compressor searches the hash chains starting with the most recent
strings, to favor small distances and thus take advantage of the
Huffman encoding. The hash chains are singly linked. There are no
deletions from the hash chains; the algorithm simply discards matches
that are too old. To avoid a worst-case situation, very long hash
chains are arbitrarily truncated at a certain length, determined by a
run-time parameter.
To improve overall compression, the compressor optionally defers the
selection of matches ("lazy matching"): after a match of length N has
been found, the compressor searches for a longer match starting at
the next input byte. If it finds a longer match, it truncates the
previous match to a length of one (thus producing a single literal
byte) and then emits the longer match. Otherwise, it emits the
original match, and, as described above, advances N bytes before
continuing.
Run-time parameters also control this "lazy match" procedure. If
compression ratio is most important, the compressor attempts a
complete second search regardless of the length of the first match.
In the normal case, if the current match is "long enough", the
compressor reduces the search for a longer match, thus speeding up
the process. If speed is most important, the compressor inserts new
strings in the hash table only when no match was found, or when the
match is not "too long". This degrades the compression ratio but
saves time since there are both fewer insertions and fewer searches.
Deutsch Informational [Page 15]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
5. References
[1] Huffman, D. A., "A Method for the Construction of Minimum
Redundancy Codes", Proceedings of the Institute of Radio
Engineers, September 1952, Volume 40, Number 9, pp. 1098-1101.
[2] Ziv J., Lempel A., "A Universal Algorithm for Sequential Data
Compression", IEEE Transactions on Information Theory, Vol. 23,
No. 3, pp. 337-343.
[3] Gailly, J.-L., and Adler, M., ZLIB documentation and sources,
available in ftp://ftp.uu.net/pub/archiving/zip/doc/
[4] Gailly, J.-L., and Adler, M., GZIP documentation and sources,
available as gzip-*.tar in ftp://prep.ai.mit.edu/pub/gnu/
[5] Schwartz, E. S., and Kallick, B. "Generating a canonical prefix
encoding." Comm. ACM, 7,3 (Mar. 1964), pp. 166-169.
[6] Hirschberg and Lelewer, "Efficient decoding of prefix codes,"
Comm. ACM, 33,4, April 1990, pp. 449-459.
6. Security Considerations
Any data compression method involves the reduction of redundancy in
the data. Consequently, any corruption of the data is likely to have
severe effects and be difficult to correct. Uncompressed text, on
the other hand, will probably still be readable despite the presence
of some corrupted bytes.
It is recommended that systems using this data format provide some
means of validating the integrity of the compressed data. See
reference [3], for example.
7. Source code
Source code for a C language implementation of a "deflate" compliant
compressor and decompressor is available within the zlib package at
ftp://ftp.uu.net/pub/archiving/zip/zlib/.
8. Acknowledgements
Trademarks cited in this document are the property of their
respective owners.
Phil Katz designed the deflate format. Jean-Loup Gailly and Mark
Adler wrote the related software described in this specification.
Glenn Randers-Pehrson converted this document to RFC and HTML format.
Deutsch Informational [Page 16]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
9. Author's Address
L. Peter Deutsch
Aladdin Enterprises
203 Santa Margarita Ave.
Menlo Park, CA 94025
Phone: (415) 322-0103 (AM only)
FAX: (415) 322-1734
EMail: <ghost@aladdin.com>
Questions about the technical content of this specification can be
sent by email to:
Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
Mark Adler <madler@alumni.caltech.edu>
Editorial comments on this specification can be sent by email to:
L. Peter Deutsch <ghost@aladdin.com> and
Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
Deutsch Informational [Page 17]

675
fwzip/Doc/rfc1952.txt Normal file
View File

@@ -0,0 +1,675 @@
Network Working Group P. Deutsch
Request for Comments: 1952 Aladdin Enterprises
Category: Informational May 1996
GZIP file format specification version 4.3
Status of This Memo
This memo provides information for the Internet community. This memo
does not specify an Internet standard of any kind. Distribution of
this memo is unlimited.
IESG Note:
The IESG takes no position on the validity of any Intellectual
Property Rights statements contained in this document.
Notices
Copyright (c) 1996 L. Peter Deutsch
Permission is granted to copy and distribute this document for any
purpose and without charge, including translations into other
languages and incorporation into compilations, provided that the
copyright notice and this notice are preserved, and that any
substantive changes or deletions from the original are clearly
marked.
A pointer to the latest version of this and related documentation in
HTML format can be found at the URL
<ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
Abstract
This specification defines a lossless compressed data format that is
compatible with the widely used GZIP utility. The format includes a
cyclic redundancy check value for detecting data corruption. The
format presently uses the DEFLATE method of compression but can be
easily extended to use other compression methods. The format can be
implemented readily in a manner not covered by patents.
Deutsch Informational [Page 1]
RFC 1952 GZIP File Format Specification May 1996
Table of Contents
1. Introduction ................................................... 2
1.1. Purpose ................................................... 2
1.2. Intended audience ......................................... 3
1.3. Scope ..................................................... 3
1.4. Compliance ................................................ 3
1.5. Definitions of terms and conventions used ................. 3
1.6. Changes from previous versions ............................ 3
2. Detailed specification ......................................... 4
2.1. Overall conventions ....................................... 4
2.2. File format ............................................... 5
2.3. Member format ............................................. 5
2.3.1. Member header and trailer ........................... 6
2.3.1.1. Extra field ................................... 8
2.3.1.2. Compliance .................................... 9
3. References .................................................. 9
4. Security Considerations .................................... 10
5. Acknowledgements ........................................... 10
6. Author's Address ........................................... 10
7. Appendix: Jean-Loup Gailly's gzip utility .................. 11
8. Appendix: Sample CRC Code .................................. 11
1. Introduction
1.1. Purpose
The purpose of this specification is to define a lossless
compressed data format that:
* Is independent of CPU type, operating system, file system,
and character set, and hence can be used for interchange;
* Can compress or decompress a data stream (as opposed to a
randomly accessible file) to produce another data stream,
using only an a priori bounded amount of intermediate
storage, and hence can be used in data communications or
similar structures such as Unix filters;
* Compresses data with efficiency comparable to the best
currently available general-purpose compression methods,
and in particular considerably better than the "compress"
program;
* Can be implemented readily in a manner not covered by
patents, and hence can be practiced freely;
* Is compatible with the file format produced by the current
widely used gzip utility, in that conforming decompressors
will be able to read data produced by the existing gzip
compressor.
Deutsch Informational [Page 2]
RFC 1952 GZIP File Format Specification May 1996
The data format defined by this specification does not attempt to:
* Provide random access to compressed data;
* Compress specialized data (e.g., raster graphics) as well as
the best currently available specialized algorithms.
1.2. Intended audience
This specification is intended for use by implementors of software
to compress data into gzip format and/or decompress data from gzip
format.
The text of the specification assumes a basic background in
programming at the level of bits and other primitive data
representations.
1.3. Scope
The specification specifies a compression method and a file format
(the latter assuming only that a file can store a sequence of
arbitrary bytes). It does not specify any particular interface to
a file system or anything about character sets or encodings
(except for file names and comments, which are optional).
1.4. Compliance
Unless otherwise indicated below, a compliant decompressor must be
able to accept and decompress any file that conforms to all the
specifications presented here; a compliant compressor must produce
files that conform to all the specifications presented here. The
material in the appendices is not part of the specification per se
and is not relevant to compliance.
1.5. Definitions of terms and conventions used
byte: 8 bits stored or transmitted as a unit (same as an octet).
(For this specification, a byte is exactly 8 bits, even on
machines which store a character on a number of bits different
from 8.) See below for the numbering of bits within a byte.
1.6. Changes from previous versions
There have been no technical changes to the gzip format since
version 4.1 of this specification. In version 4.2, some
terminology was changed, and the sample CRC code was rewritten for
clarity and to eliminate the requirement for the caller to do pre-
and post-conditioning. Version 4.3 is a conversion of the
specification to RFC style.
Deutsch Informational [Page 3]
RFC 1952 GZIP File Format Specification May 1996
2. Detailed specification
2.1. Overall conventions
In the diagrams below, a box like this:
+---+
| | <-- the vertical bars might be missing
+---+
represents one byte; a box like this:
+==============+
| |
+==============+
represents a variable number of bytes.
Bytes stored within a computer do not have a "bit order", since
they are always treated as a unit. However, a byte considered as
an integer between 0 and 255 does have a most- and least-
significant bit, and since we write numbers with the most-
significant digit on the left, we also write bytes with the most-
significant bit on the left. In the diagrams below, we number the
bits of a byte so that bit 0 is the least-significant bit, i.e.,
the bits are numbered:
+--------+
|76543210|
+--------+
This document does not address the issue of the order in which
bits of a byte are transmitted on a bit-sequential medium, since
the data format described here is byte- rather than bit-oriented.
Within a computer, a number may occupy multiple bytes. All
multi-byte numbers in the format described here are stored with
the least-significant byte first (at the lower memory address).
For example, the decimal number 520 is stored as:
0 1
+--------+--------+
|00001000|00000010|
+--------+--------+
^ ^
| |
| + more significant byte = 2 x 256
+ less significant byte = 8
Deutsch Informational [Page 4]
RFC 1952 GZIP File Format Specification May 1996
2.2. File format
A gzip file consists of a series of "members" (compressed data
sets). The format of each member is specified in the following
section. The members simply appear one after another in the file,
with no additional information before, between, or after them.
2.3. Member format
Each member has the following structure:
+---+---+---+---+---+---+---+---+---+---+
|ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->)
+---+---+---+---+---+---+---+---+---+---+
(if FLG.FEXTRA set)
+---+---+=================================+
| XLEN |...XLEN bytes of "extra field"...| (more-->)
+---+---+=================================+
(if FLG.FNAME set)
+=========================================+
|...original file name, zero-terminated...| (more-->)
+=========================================+
(if FLG.FCOMMENT set)
+===================================+
|...file comment, zero-terminated...| (more-->)
+===================================+
(if FLG.FHCRC set)
+---+---+
| CRC16 |
+---+---+
+=======================+
|...compressed blocks...| (more-->)
+=======================+
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| CRC32 | ISIZE |
+---+---+---+---+---+---+---+---+
Deutsch Informational [Page 5]
RFC 1952 GZIP File Format Specification May 1996
2.3.1. Member header and trailer
ID1 (IDentification 1)
ID2 (IDentification 2)
These have the fixed values ID1 = 31 (0x1f, \037), ID2 = 139
(0x8b, \213), to identify the file as being in gzip format.
CM (Compression Method)
This identifies the compression method used in the file. CM
= 0-7 are reserved. CM = 8 denotes the "deflate"
compression method, which is the one customarily used by
gzip and which is documented elsewhere.
FLG (FLaGs)
This flag byte is divided into individual bits as follows:
bit 0 FTEXT
bit 1 FHCRC
bit 2 FEXTRA
bit 3 FNAME
bit 4 FCOMMENT
bit 5 reserved
bit 6 reserved
bit 7 reserved
If FTEXT is set, the file is probably ASCII text. This is
an optional indication, which the compressor may set by
checking a small amount of the input data to see whether any
non-ASCII characters are present. In case of doubt, FTEXT
is cleared, indicating binary data. For systems which have
different file formats for ascii text and binary data, the
decompressor can use FTEXT to choose the appropriate format.
We deliberately do not specify the algorithm used to set
this bit, since a compressor always has the option of
leaving it cleared and a decompressor always has the option
of ignoring it and letting some other program handle issues
of data conversion.
If FHCRC is set, a CRC16 for the gzip header is present,
immediately before the compressed data. The CRC16 consists
of the two least significant bytes of the CRC32 for all
bytes of the gzip header up to and not including the CRC16.
[The FHCRC bit was never set by versions of gzip up to
1.2.4, even though it was documented with a different
meaning in gzip 1.2.4.]
If FEXTRA is set, optional extra fields are present, as
described in a following section.
Deutsch Informational [Page 6]
RFC 1952 GZIP File Format Specification May 1996
If FNAME is set, an original file name is present,
terminated by a zero byte. The name must consist of ISO
8859-1 (LATIN-1) characters; on operating systems using
EBCDIC or any other character set for file names, the name
must be translated to the ISO LATIN-1 character set. This
is the original name of the file being compressed, with any
directory components removed, and, if the file being
compressed is on a file system with case insensitive names,
forced to lower case. There is no original file name if the
data was compressed from a source other than a named file;
for example, if the source was stdin on a Unix system, there
is no file name.
If FCOMMENT is set, a zero-terminated file comment is
present. This comment is not interpreted; it is only
intended for human consumption. The comment must consist of
ISO 8859-1 (LATIN-1) characters. Line breaks should be
denoted by a single line feed character (10 decimal).
Reserved FLG bits must be zero.
MTIME (Modification TIME)
This gives the most recent modification time of the original
file being compressed. The time is in Unix format, i.e.,
seconds since 00:00:00 GMT, Jan. 1, 1970. (Note that this
may cause problems for MS-DOS and other systems that use
local rather than Universal time.) If the compressed data
did not come from a file, MTIME is set to the time at which
compression started. MTIME = 0 means no time stamp is
available.
XFL (eXtra FLags)
These flags are available for use by specific compression
methods. The "deflate" method (CM = 8) sets these flags as
follows:
XFL = 2 - compressor used maximum compression,
slowest algorithm
XFL = 4 - compressor used fastest algorithm
OS (Operating System)
This identifies the type of file system on which compression
took place. This may be useful in determining end-of-line
convention for text files. The currently defined values are
as follows:
Deutsch Informational [Page 7]
RFC 1952 GZIP File Format Specification May 1996
0 - FAT filesystem (MS-DOS, OS/2, NT/Win32)
1 - Amiga
2 - VMS (or OpenVMS)
3 - Unix
4 - VM/CMS
5 - Atari TOS
6 - HPFS filesystem (OS/2, NT)
7 - Macintosh
8 - Z-System
9 - CP/M
10 - TOPS-20
11 - NTFS filesystem (NT)
12 - QDOS
13 - Acorn RISCOS
255 - unknown
XLEN (eXtra LENgth)
If FLG.FEXTRA is set, this gives the length of the optional
extra field. See below for details.
CRC32 (CRC-32)
This contains a Cyclic Redundancy Check value of the
uncompressed data computed according to CRC-32 algorithm
used in the ISO 3309 standard and in section 8.1.1.6.2 of
ITU-T recommendation V.42. (See http://www.iso.ch for
ordering ISO documents. See gopher://info.itu.ch for an
online version of ITU-T V.42.)
ISIZE (Input SIZE)
This contains the size of the original (uncompressed) input
data modulo 2^32.
2.3.1.1. Extra field
If the FLG.FEXTRA bit is set, an "extra field" is present in
the header, with total length XLEN bytes. It consists of a
series of subfields, each of the form:
+---+---+---+---+==================================+
|SI1|SI2| LEN |... LEN bytes of subfield data ...|
+---+---+---+---+==================================+
SI1 and SI2 provide a subfield ID, typically two ASCII letters
with some mnemonic value. Jean-Loup Gailly
<gzip@prep.ai.mit.edu> is maintaining a registry of subfield
IDs; please send him any subfield ID you wish to use. Subfield
IDs with SI2 = 0 are reserved for future use. The following
IDs are currently defined:
Deutsch Informational [Page 8]
RFC 1952 GZIP File Format Specification May 1996
SI1 SI2 Data
---------- ---------- ----
0x41 ('A') 0x70 ('P') Apollo file type information
LEN gives the length of the subfield data, excluding the 4
initial bytes.
2.3.1.2. Compliance
A compliant compressor must produce files with correct ID1,
ID2, CM, CRC32, and ISIZE, but may set all the other fields in
the fixed-length part of the header to default values (255 for
OS, 0 for all others). The compressor must set all reserved
bits to zero.
A compliant decompressor must check ID1, ID2, and CM, and
provide an error indication if any of these have incorrect
values. It must examine FEXTRA/XLEN, FNAME, FCOMMENT and FHCRC
at least so it can skip over the optional fields if they are
present. It need not examine any other part of the header or
trailer; in particular, a decompressor may ignore FTEXT and OS
and always produce binary output, and still be compliant. A
compliant decompressor must give an error indication if any
reserved bit is non-zero, since such a bit could indicate the
presence of a new field that would cause subsequent data to be
interpreted incorrectly.
3. References
[1] "Information Processing - 8-bit single-byte coded graphic
character sets - Part 1: Latin alphabet No.1" (ISO 8859-1:1987).
The ISO 8859-1 (Latin-1) character set is a superset of 7-bit
ASCII. Files defining this character set are available as
iso_8859-1.* in ftp://ftp.uu.net/graphics/png/documents/
[2] ISO 3309
[3] ITU-T recommendation V.42
[4] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification",
available in ftp://ftp.uu.net/pub/archiving/zip/doc/
[5] Gailly, J.-L., GZIP documentation, available as gzip-*.tar in
ftp://prep.ai.mit.edu/pub/gnu/
[6] Sarwate, D.V., "Computation of Cyclic Redundancy Checks via Table
Look-Up", Communications of the ACM, 31(8), pp.1008-1013.
Deutsch Informational [Page 9]
RFC 1952 GZIP File Format Specification May 1996
[7] Schwaderer, W.D., "CRC Calculation", April 85 PC Tech Journal,
pp.118-133.
[8] ftp://ftp.adelaide.edu.au/pub/rocksoft/papers/crc_v3.txt,
describing the CRC concept.
4. Security Considerations
Any data compression method involves the reduction of redundancy in
the data. Consequently, any corruption of the data is likely to have
severe effects and be difficult to correct. Uncompressed text, on
the other hand, will probably still be readable despite the presence
of some corrupted bytes.
It is recommended that systems using this data format provide some
means of validating the integrity of the compressed data, such as by
setting and checking the CRC-32 check value.
5. Acknowledgements
Trademarks cited in this document are the property of their
respective owners.
Jean-Loup Gailly designed the gzip format and wrote, with Mark Adler,
the related software described in this specification. Glenn
Randers-Pehrson converted this document to RFC and HTML format.
6. Author's Address
L. Peter Deutsch
Aladdin Enterprises
203 Santa Margarita Ave.
Menlo Park, CA 94025
Phone: (415) 322-0103 (AM only)
FAX: (415) 322-1734
EMail: <ghost@aladdin.com>
Questions about the technical content of this specification can be
sent by email to:
Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
Mark Adler <madler@alumni.caltech.edu>
Editorial comments on this specification can be sent by email to:
L. Peter Deutsch <ghost@aladdin.com> and
Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
Deutsch Informational [Page 10]
RFC 1952 GZIP File Format Specification May 1996
7. Appendix: Jean-Loup Gailly's gzip utility
The most widely used implementation of gzip compression, and the
original documentation on which this specfication is based, were
created by Jean-Loup Gailly <gzip@prep.ai.mit.edu>. Since this
implementation is a de facto standard, we mention some more of its
features here. Again, the material in this section is not part of
the specification per se, and implementations need not follow it to
be compliant.
When compressing or decompressing a file, gzip preserves the
protection, ownership, and modification time attributes on the local
file system, since there is no provision for representing protection
attributes in the gzip file format itself. Since the file format
includes a modification time, the gzip decompressor provides a
command line switch that assigns the modification time from the file,
rather than the local modification time of the compressed input, to
the decompressed output.
8. Appendix: Sample CRC Code
The following sample code represents a practical implementation of
the CRC (Cyclic Redundancy Check). (See also ISO 3309 and ITU-T V.42
for a formal specification.)
The sample code is in the ANSI C programming language. Non C users
may find it easier to read with these hints:
& Bitwise AND operator.
^ Bitwise exclusive-OR operator.
>> Bitwise right shift operator. When applied to an
unsigned quantity, as here, right shift inserts zero
bit(s) at the left.
! Logical NOT operator.
++ "n++" increments the variable n.
0xNNN 0x introduces a hexadecimal (base 16) constant.
Suffix L indicates a long value (at least 32 bits).
/* Table of CRCs of all 8-bit messages. */
unsigned long crc_table[256];
/* Flag: has the table been computed? Initially false. */
int crc_table_computed = 0;
/* Make the table for a fast CRC. */
void make_crc_table(void)
{
unsigned long c;
Deutsch Informational [Page 11]
RFC 1952 GZIP File Format Specification May 1996
int n, k;
for (n = 0; n < 256; n++) {
c = (unsigned long) n;
for (k = 0; k < 8; k++) {
if (c & 1) {
c = 0xedb88320L ^ (c >> 1);
} else {
c = c >> 1;
}
}
crc_table[n] = c;
}
crc_table_computed = 1;
}
/*
Update a running crc with the bytes buf[0..len-1] and return
the updated crc. The crc should be initialized to zero. Pre- and
post-conditioning (one's complement) is performed within this
function so it shouldn't be done by the caller. Usage example:
unsigned long crc = 0L;
while (read_buffer(buffer, length) != EOF) {
crc = update_crc(crc, buffer, length);
}
if (crc != original_crc) error();
*/
unsigned long update_crc(unsigned long crc,
unsigned char *buf, int len)
{
unsigned long c = crc ^ 0xffffffffL;
int n;
if (!crc_table_computed)
make_crc_table();
for (n = 0; n < len; n++) {
c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
}
return c ^ 0xffffffffL;
}
/* Return the CRC of the bytes buf[0..len-1]. */
unsigned long crc(unsigned char *buf, int len)
{
return update_crc(0L, buf, len);
}
Deutsch Informational [Page 12]

3495
fwzip/Doc/zip_format.txt Normal file

File diff suppressed because it is too large Load Diff

404
fwzip/FWZipConsts.pas Normal file
View File

@@ -0,0 +1,404 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : FWZipConsts
// * Purpose : Типы и константы используемые для работы с ZIP архивами
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2024.
// * Version : 2.0.4
// * 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.3.1.tar.gz
// http://www.base2ti.com/
//
unit FWZipConsts;
{$IFDEF FPC}
{$MODE Delphi}
{$H+}
{$ENDIF}
interface
uses
{$IFDEF MSWINDOWS}
Windows,
{$ELSE}
Types,
{$ENDIF}
SysUtils,
Classes;
const
FWZipVersionInt = $02000004;
FWZipVersionStr = '2.0.4';
const
MAXBYTE = 255;
MAXWORD = 65535;
MAXDWORD = DWORD(-1);
MAX_PATH = 260;
type
DWORD = Cardinal;
LOBYTE = Byte;
LOWORD = Word;
// зависит от платформы, под Windows будет праться из Windows.pas
// под остальными из Types.pas
TFileTime = FILETIME;
PFileTime = ^TFileTime;
TFileAttributeData = record
dwFileAttributes: DWORD;
ftCreationTime: TFileTime;
ftLastAccessTime: TFileTime;
ftLastWriteTime: TFileTime;
nFileSizeHigh: DWORD;
nFileSizeLow: DWORD;
end;
{
IV. General Format of a .ZIP file
---------------------------------
Files stored in arbitrary order. Large .ZIP files can span multiple
diskette media or be split into user-defined segment sizes. [The
minimum user-defined segment size for a split .ZIP file is 64K.
(removed by PKWare 2003-06-01)]
Overall .ZIP file format:
[local file header 1]
[file data 1]
[data descriptor 1]
.
.
.
[local file header n]
[file data n]
[data descriptor n]
[archive decryption header] (EFS)
[archive extra data record] (EFS)
[central directory]
[zip64 end of central directory record]
[zip64 end of central directory locator]
[end of central directory record]
}
PLocalFileHeader = ^TLocalFileHeader;
TLocalFileHeader = packed record
LocalFileHeaderSignature: Cardinal; // (0x04034b50)
VersionNeededToExtract,
GeneralPurposeBitFlag,
CompressionMethod,
LastModFileTimeTime,
LastModFileTimeDate: Word;
Crc32,
CompressedSize,
UncompressedSize: Cardinal;
FilenameLength,
ExtraFieldLength: Word;
// file name (variable size)
// extra field (variable size)
end;
{
If bit 3 of the general purpose bit flag
is set, these fields are set to zero in the local header
and the correct values are put in the data descriptor and
in the central directory.
}
TDataDescriptor = packed record
DescriptorSignature, // (0x08074b50)
Crc32,
CompressedSize,
UncompressedSize: Cardinal;
{For Zip64 format archives, the compressed
and uncompressed sizes are 8 bytes each. ??!!}
end;
TEFS = packed record
ArchiveExtraDataSignature, // (0x08064b50)
ExtraFieldLength: Cardinal;
// extra field data (variable size)
end;
{
F. Central directory structure:
[file header 1]
.
.
.
[file header n]
[digital signature]
}
TCentralDirectoryFileHeader = packed record
CentralFileHeaderSignature: Cardinal; // (0x02014b50)
VersionMadeBy,
VersionNeededToExtract,
GeneralPurposeBitFlag,
CompressionMethod,
LastModFileTimeTime,
LastModFileTimeDate: Word;
Crc32,
CompressedSize,
UncompressedSize: Cardinal;
FilenameLength,
ExtraFieldLength,
FileCommentLength,
DiskNumberStart,
InternalFileAttributes: Word;
ExternalFileAttributes,
RelativeOffsetOfLocalHeader: Cardinal;
// file name (variable size)
// extra field (variable size)
// file comment (variable size)
end;
TCentralDirectoryFileHeaderEx = packed record
Header: TCentralDirectoryFileHeader;
UncompressedSize,
CompressedSize,
RelativeOffsetOfLocalHeader,
DataOffset: Int64;
DiskNumberStart: Integer;
FileName,
FileComment: string;
Attributes: TFileAttributeData;
ExceptOnWrite: Boolean;
end;
TNTFSFileTime = packed record
Mtime: TFileTime;
Atime: TFileTime;
Ctime: TFileTime;
end;
TExDataHeaderAndSize = packed record
Header: Word;
Size: Word;
end;
TExDataNTFS = packed record
HS: TExDataHeaderAndSize;
Reserved: Cardinal;
Tag: Word;
RecordSize: Word;
Data: TNTFSFileTime;
end;
TExDataInfo64 = packed record
HS: TExDataHeaderAndSize;
UncompressedSize, CompressedSize: Int64;
end;
TCentralDirectoryDigitalSignature = packed record
HeaderSignature: Cardinal; // (0x05054b50)
SizeOfData: Word;
// signature data (variable size)
end;
TZip64EOFCentralDirectoryRecord = packed record
Zip64EndOfCentralDirSignature: Cardinal; // (0x06064b50)
SizeOfZip64EOFCentralDirectoryRecord: int64;
VersionMadeBy,
VersionNeededToExtract: Word;
NumberOfThisDisk, // number of this disk
DiskNumberStart: Cardinal; // number of the disk with the start of the central directory
TotalNumberOfEntriesOnThisDisk, // total number of entries in the central directory on this disk
TotalNumberOfEntries, // total number of entries in the central directory
SizeOfTheCentralDirectory, // size of the central directory
RelativeOffsetOfCentralDirectory: Int64; // offset of start of central directory with respect to the starting disk number
// zip64 extensible data sector (variable size)
end;
TZip64EOFCentralDirectoryLocator = packed record
Signature, // zip64 end of central dir locator signature (0x07064b50)
DiskNumberStart: Cardinal; // number of the disk with the start of the zip64 end of central directory
RelativeOffset: Int64; // relative offset of the zip64 end of central directory record
TotalNumberOfDisks: Cardinal;
end;
TEndOfCentralDir = packed record
EndOfCentralDirSignature: Cardinal; // (0x06054b50)
NumberOfThisDisk,
DiskNumberStart,
TotalNumberOfEntriesOnThisDisk,
TotalNumberOfEntries: Word;
SizeOfTheCentralDirectory,
RelativeOffsetOfCentralDirectory: Cardinal;
ZipfileCommentLength: Word;
// .ZIP file comment (variable size)
end;
const
LOCAL_FILE_HEADER_SIGNATURE = $04034B50;
DATA_DESCRIPTOR_SIGNATURE = $08074B50;
// Маркер для разбитых на части архивов
// см. zip_format.txt 8.5.4 - 8.5.5
SPAN_DESCRIPTOR_SIGNATURE = DATA_DESCRIPTOR_SIGNATURE;
TEMPORARY_SPANING_DESCRIPTOR_SIGNATURE = $30304B50;
EXTRA_DATA_SIGNATURE = $08064B50;
CENTRAL_FILE_HEADER_SIGNATURE = $02014B50;
CENTRAL_DIRECTORY_DIGITAL_SIGNATURE = $05054B50;
ZIP64_END_OF_CENTRAL_DIR_SIGNATURE = $06064B50;
ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE = $07064B50;
END_OF_CENTRAL_DIR_SIGNATURE = $06054B50;
ZIP_SLASH = '/';
// Флаги для GeneralPurposeBitFlag
PBF_CRYPTED = 1;
// (For Methods 8 and 9 - Deflating)
PBF_COMPRESS_NORMAL = 0;
PBF_COMPRESS_MAXIMUM = 2;
PBF_COMPRESS_FAST = 4;
PBF_COMPRESS_SUPERFAST = 6;
PBF_DESCRIPTOR = 8;
PBF_STRONG_CRYPT = 64;
PBF_UTF8 = $800;
// Unsupported Zip formats
// AES is an encryption method, not a compression method.
// Since AES is an extension to the Zip file format, it reports as compression method 99.
Z_AES_COMPRESSION = 99;
// константы поддерживаемых полей ExData
SUPPORTED_EXDATA_ZIP64 = 1;
SUPPORTED_EXDATA_NTFSTIME = 10;
defaultWindowBits = -15;
type
TProgressState = (
psStart, // начало распаковки элемента, результирующий файл еще не создан
psInitialization, // результирующий файл создан и залочен, производится подготовка к распаковке
psInProgress, // идет распаковка
psFinalization, // распаковка завершена, сейчас будут разрушены все служебные объекты, результирующий файл все еще залочен
psEnd, // операция распаковки полностью завершена, результирующий файл доступен на чтение/запись
psException // ошибка
);
TZipProgressEvent = procedure(Sender: TObject; const FileName: string;
Percent, TotalPercent: Byte; var Cancel: Boolean; ProgressState: TProgressState) of object;
TZipExtractItemEvent = procedure(Sender: TObject; const FileName: string;
Extracted, TotalSize: Int64; ProgressState: TProgressState) of object;
TZipNeedPasswordEvent = procedure(Sender: TObject; const FileName: string;
var Password: string; var CancelExtract: Boolean) of object;
TZipSaveExDataEvent = procedure(Sender: TObject; ItemIndex: Integer;
UserExDataBlockCount: Integer; var Tag: Word; Data: TStream) of object;
TZipLoadExDataEvent = procedure(Sender: TObject; ItemIndex: Integer;
Tag: Word; Data: TStream) of object;
// Типы поведения TFWZipWriter при ошибке в процессе создания архива
TExceptionAction =
(
eaRetry, // повторить попытку
eaSkip, // пропустить текущий элемент
eaAbort, // остановить создание архива
eaUseNewFilePath, // использовать новый путь к файлу (пар. NewFilePath)
eaUseNewFilePathAndDel, // то-же что и acUseNewFilePath, только файл удаляется после использования
eaUseNewFileData // использовать содержимое файла из стрима (пар. NewFileData)
);
TZipBuildExceptionEvent = procedure(Sender: TObject;
E: Exception; const ItemIndex: Integer;
var Action: TExceptionAction;
var NewFilePath: string; NewFileData: TMemoryStream) of object;
TZipExtractExceptionEvent = procedure(Sender: TObject;
E: Exception; const ItemIndex: Integer;
var Handled: Boolean) of object;
// Типы поведения TFWZipReader при конфликте имен файлов
TDuplicateAction =
(
daSkip, // пропустить файл
daOverwrite, // перезаписать
daUseNewFilePath, // сохранить с новым именем
daAbort // отменить распаковку
);
TZipDuplicateEvent = procedure(Sender: TObject;
var Path: string; var Action: TDuplicateAction) of object;
const
CRC32Table: array[Byte] of Cardinal =
(
$00000000, $77073096, $EE0E612C, $990951BA, $076DC419, $706AF48F,
$E963A535, $9E6495A3, $0EDB8832, $79DCB8A4, $E0D5E91E, $97D2D988,
$09B64C2B, $7EB17CBD, $E7B82D07, $90BF1D91, $1DB71064, $6AB020F2,
$F3B97148, $84BE41DE, $1ADAD47D, $6DDDE4EB, $F4D4B551, $83D385C7,
$136C9856, $646BA8C0, $FD62F97A, $8A65C9EC, $14015C4F, $63066CD9,
$FA0F3D63, $8D080DF5, $3B6E20C8, $4C69105E, $D56041E4, $A2677172,
$3C03E4D1, $4B04D447, $D20D85FD, $A50AB56B, $35B5A8FA, $42B2986C,
$DBBBC9D6, $ACBCF940, $32D86CE3, $45DF5C75, $DCD60DCF, $ABD13D59,
$26D930AC, $51DE003A, $C8D75180, $BFD06116, $21B4F4B5, $56B3C423,
$CFBA9599, $B8BDA50F, $2802B89E, $5F058808, $C60CD9B2, $B10BE924,
$2F6F7C87, $58684C11, $C1611DAB, $B6662D3D, $76DC4190, $01DB7106,
$98D220BC, $EFD5102A, $71B18589, $06B6B51F, $9FBFE4A5, $E8B8D433,
$7807C9A2, $0F00F934, $9609A88E, $E10E9818, $7F6A0DBB, $086D3D2D,
$91646C97, $E6635C01, $6B6B51F4, $1C6C6162, $856530D8, $F262004E,
$6C0695ED, $1B01A57B, $8208F4C1, $F50FC457, $65B0D9C6, $12B7E950,
$8BBEB8EA, $FCB9887C, $62DD1DDF, $15DA2D49, $8CD37CF3, $FBD44C65,
$4DB26158, $3AB551CE, $A3BC0074, $D4BB30E2, $4ADFA541, $3DD895D7,
$A4D1C46D, $D3D6F4FB, $4369E96A, $346ED9FC, $AD678846, $DA60B8D0,
$44042D73, $33031DE5, $AA0A4C5F, $DD0D7CC9, $5005713C, $270241AA,
$BE0B1010, $C90C2086, $5768B525, $206F85B3, $B966D409, $CE61E49F,
$5EDEF90E, $29D9C998, $B0D09822, $C7D7A8B4, $59B33D17, $2EB40D81,
$B7BD5C3B, $C0BA6CAD, $EDB88320, $9ABFB3B6, $03B6E20C, $74B1D29A,
$EAD54739, $9DD277AF, $04DB2615, $73DC1683, $E3630B12, $94643B84,
$0D6D6A3E, $7A6A5AA8, $E40ECF0B, $9309FF9D, $0A00AE27, $7D079EB1,
$F00F9344, $8708A3D2, $1E01F268, $6906C2FE, $F762575D, $806567CB,
$196C3671, $6E6B06E7, $FED41B76, $89D32BE0, $10DA7A5A, $67DD4ACC,
$F9B9DF6F, $8EBEEFF9, $17B7BE43, $60B08ED5, $D6D6A3E8, $A1D1937E,
$38D8C2C4, $4FDFF252, $D1BB67F1, $A6BC5767, $3FB506DD, $48B2364B,
$D80D2BDA, $AF0A1B4C, $36034AF6, $41047A60, $DF60EFC3, $A867DF55,
$316E8EEF, $4669BE79, $CB61B38C, $BC66831A, $256FD2A0, $5268E236,
$CC0C7795, $BB0B4703, $220216B9, $5505262F, $C5BA3BBE, $B2BD0B28,
$2BB45A92, $5CB36A04, $C2D7FFA7, $B5D0CF31, $2CD99E8B, $5BDEAE1D,
$9B64C2B0, $EC63F226, $756AA39C, $026D930A, $9C0906A9, $EB0E363F,
$72076785, $05005713, $95BF4A82, $E2B87A14, $7BB12BAE, $0CB61B38,
$92D28E9B, $E5D5BE0D, $7CDCEFB7, $0BDBDF21, $86D3D2D4, $F1D4E242,
$68DDB3F8, $1FDA836E, $81BE16CD, $F6B9265B, $6FB077E1, $18B74777,
$88085AE6, $FF0F6A70, $66063BCA, $11010B5C, $8F659EFF, $F862AE69,
$616BFFD3, $166CCF45, $A00AE278, $D70DD2EE, $4E048354, $3903B3C2,
$A7672661, $D06016F7, $4969474D, $3E6E77DB, $AED16A4A, $D9D65ADC,
$40DF0B66, $37D83BF0, $A9BCAE53, $DEBB9EC5, $47B2CF7F, $30B5FFE9,
$BDBDF21C, $CABAC28A, $53B39330, $24B4A3A6, $BAD03605, $CDD70693,
$54DE5729, $23D967BF,$B3667A2E, $C4614AB8, $5D681B02, $2A6F2B94,
$B40BBE37, $C30C8EA1, $5A05DF1B, $2D02EF8D
);
CurrentVersionMadeBy = 63;
LongNamePrefix = '\\?\';
UNCLongNamePrefix = '\\?\UNC\';
var
/// <summary>
/// Глобальная переменная управляющая включением/отключением поддержки длинных путей
/// </summary>
UseLongNamePrefix: Boolean = True;
implementation
end.

150
fwzip/FWZipCrc32.pas Normal file
View File

@@ -0,0 +1,150 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : FWZipCrc32
// * Purpose : Набор функций для рассчета контрольной суммы блока данных
// * : Класс TFWZipCRC32Stream используется в качестве посредника
// * : между двумя стримами и предназначен для бастрого
// * : рассчета контрольной суммы передаваемых блоков данных
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2023.
// * Version : 2.0.0
// * 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 FWZipCrc32;
{$IFDEF FPC}
{$MODE Delphi}
{$H+}
{$ENDIF}
interface
uses
Classes,
SysUtils,
FWZipConsts;
type
TFWZipCRC32Stream = class(TStream)
private
FOwner: TStream;
FCRC32: Cardinal;
protected
function GetSize: Int64; override;
public
constructor Create(AOwner: TStream);
function Seek(Offset: Longint; Origin: Word): Longint; overload; override;
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; overload; override;
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const Buffer; Count: Longint): Longint; override;
function CRC32: Cardinal;
end;
function CRC32Calc(CurrCRC: Cardinal;
Buffer: PByte; const BufferLen: Int64): Cardinal; overload;
function CRC32Calc(Buffer: PByte; const BufferLen: Int64): Cardinal; overload;
function FileCRC32(const FileName: string): Cardinal;
implementation
function CRC32Calc(CurrCRC: Cardinal;
Buffer: PByte; const BufferLen: Int64): Cardinal;
var
I: Integer;
begin
Result := CurrCRC;
for I := 0 to BufferLen - 1 do
begin
Result := ((Result shr 8) and $00FFFFFF) xor
CRC32Table[(Result xor Buffer^) and $FF];
Inc(Buffer);
end;
end;
function CRC32Calc(Buffer: PByte; const BufferLen: Int64): Cardinal;
begin
Result := CRC32Calc($FFFFFFFF, Buffer, BufferLen) xor $FFFFFFFF;
end;
function FileCRC32(const FileName: string): Cardinal;
var
Buff: Pointer;
F: TFileStream;
Size: Integer;
begin
Result := $FFFFFFFF;
GetMem(Buff, $FFFF);
try
F := TFileStream.Create(FileName, fmOpenRead);
try
Size := 1;
while Size > 0 do
begin
Size := F.Read(Buff^, $FFFF);
Result := CRC32Calc(Result, Buff, Size);
end;
finally
F.Free;
end;
finally
FreeMem(Buff);
end;
Result := Result xor $FFFFFFFF;
end;
{ TFWZipCRC32Stream }
function TFWZipCRC32Stream.CRC32: Cardinal;
begin
Result := FCRC32 xor $FFFFFFFF;
end;
constructor TFWZipCRC32Stream.Create(AOwner: TStream);
begin
FOwner := AOwner;
FCRC32 := $FFFFFFFF;
end;
function TFWZipCRC32Stream.GetSize: Int64;
begin
Result := FOwner.Size;
end;
function TFWZipCRC32Stream.Read(var Buffer; Count: Integer): Longint;
begin
Result := FOwner.Read(Buffer, Count);
FCRC32 := CRC32Calc(FCRC32, @Buffer, Result);
end;
function TFWZipCRC32Stream.Seek(Offset: Integer; Origin: Word): Longint;
begin
Result := FOwner.Seek(Offset, Origin);
end;
function TFWZipCRC32Stream.Seek(const Offset: Int64;
Origin: TSeekOrigin): Int64;
begin
Result := FOwner.Seek(Offset, Origin);
end;
function TFWZipCRC32Stream.Write(const Buffer; Count: Integer): Longint;
begin
Result := FOwner.Write(Buffer, Count);
FCRC32 := CRC32Calc(FCRC32, @Buffer, Result);
end;
end.

376
fwzip/FWZipCrypt.pas Normal file
View File

@@ -0,0 +1,376 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : FWZipCrypt
// * Purpose : Реализация криптографии по методу PKWARE
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2023.
// * Version : 2.0.1
// * 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 FWZipCrypt;
{$IFDEF FPC}
{$MODE Delphi}
{$H+}
{$ENDIF}
interface
// Переполнения и выход за диапазон неизбежны
// поэтому отключаем данные проверки
{$OVERFLOWCHECKS OFF}
{$RANGECHECKS OFF}
uses
Classes,
{$IFDEF FPC}
LConvEncoding,
{$ENDIF}
FWZipConsts,
FWZipUtils;
{
XIII. Decryption
----------------
The encryption used in PKZIP was generously supplied by Roger
Schlafly. PKWARE is grateful to Mr. Schlafly for his expert
help and advice in the field of data encryption.
PKZIP encrypts the compressed data stream. Encrypted files must
be decrypted before they can be extracted.
Each encrypted file has an extra 12 bytes stored at the start of
the data area defining the encryption header for that file. The
encryption header is originally set to random values, and then
itself encrypted, using three, 32-bit keys. The key values are
initialized using the supplied encryption password. After each byte
is encrypted, the keys are then updated using pseudo-random number
generation techniques in combination with the same CRC-32 algorithm
used in PKZIP and described elsewhere in this document.
The following is the basic steps required to decrypt a file:
1) Initialize the three 32-bit keys with the password.
2) Read and decrypt the 12-byte encryption header, further
initializing the encryption keys.
3) Read and decrypt the compressed data stream using the
encryption keys.
Step 1 - Initializing the encryption keys
-----------------------------------------
Key(0) <- 305419896
Key(1) <- 591751049
Key(2) <- 878082192
loop for i <- 0 to length(password)-1
update_keys(password(i))
end loop
Where update_keys() is defined as:
update_keys(char):
Key(0) <- crc32(key(0),char)
Key(1) <- Key(1) + (Key(0) & 000000ffH)
Key(1) <- Key(1) * 134775813 + 1
Key(2) <- crc32(key(2),key(1) >> 24)
end update_keys
Where crc32(old_crc,char) is a routine that given a CRC value and a
character, returns an updated CRC value after applying the CRC-32
algorithm described elsewhere in this document.
Step 2 - Decrypting the encryption header
-----------------------------------------
The purpose of this step is to further initialize the encryption
keys, based on random data, to render a plaintext attack on the
data ineffective.
Read the 12-byte encryption header into Buffer, in locations
Buffer(0) thru Buffer(11).
loop for i <- 0 to 11
C <- buffer(i) ^ decrypt_byte()
update_keys(C)
buffer(i) <- C
end loop
Where decrypt_byte() is defined as:
unsigned char decrypt_byte()
local unsigned short temp
temp <- Key(2) | 2
decrypt_byte <- (temp * (temp ^ 1)) >> 8
end decrypt_byte
After the header is decrypted, the last 1 or 2 bytes in Buffer
should be the high-order word/byte of the CRC for the file being
decrypted, stored in Intel low-byte/high-byte order, or the high-order
byte of the file time if bit 3 of the general purpose bit flag is set.
Versions of PKZIP prior to 2.0 used a 2 byte CRC check; a 1 byte CRC check is
used on versions after 2.0. This can be used to test if the password
supplied is correct or not.
Step 3 - Decrypting the compressed data stream
----------------------------------------------
The compressed data stream can be decrypted as follows:
loop until done
read a character into C
Temp <- C ^ decrypt_byte()
update_keys(temp)
output Temp
end loop
}
const
EncryptedHeaderSize = 12;
LastEncryptedHeaderByte = EncryptedHeaderSize - 1;
type
TZipKeys = array [0..2] of Cardinal;
TFWZipKeys = class
private
FKeys: TZipKeys;
protected
procedure UpdateKeys(Value: Byte);
function DecryptByte: Byte;
public
constructor Create(const Password: AnsiString);
end;
TFWZipCryptor = class(TFWZipKeys)
protected
function EncryptByte(Value: Byte): Byte;
public
procedure GenerateEncryptionHeader(Stream: TStream;
IsDescryptorFlagPresent: Boolean;
CRC32, FileDate: Cardinal);
procedure EncryptBuffer(Buffer: PByte; Size: Int64);
end;
TFWZipDecryptor = class(TFWZipKeys)
public
function LoadEncryptionHeader(Stream: TStream;
IsDescryptorFlagPresent: Boolean;
CRC32, FileDate: Cardinal): Boolean;
procedure DecryptBuffer(Buffer: PByte; Size: Int64);
end;
implementation
const
DefaultKeys: TZipKeys = (305419896, 591751049, 878082192);
{ TFWZipKeys }
constructor TFWZipKeys.Create(const Password: AnsiString);
var
I: Integer;
{$IFDEF FPC}
RawBytePassword: RawByteString;
{$ENDIF}
begin
inherited Create;
{
Step 1 - Initializing the encryption keys
-----------------------------------------
Key(0) <- 305419896
Key(1) <- 591751049
Key(2) <- 878082192
loop for i <- 0 to length(password)-1
update_keys(password(i))
end loop
}
FKeys := DefaultKeys;
{$IFDEF FPC}
RawBytePassword := UTF8ToCP1251(Password);
for I := 1 to Length(RawBytePassword) do
UpdateKeys(Byte(RawBytePassword[I]));
{$ELSE}
for I := 1 to Length(Password) do
UpdateKeys(Byte(Password[I]));
{$ENDIF}
end;
function TFWZipKeys.DecryptByte: Byte;
var
temp: Word;
begin
{
Where decrypt_byte() is defined as:
unsigned char decrypt_byte()
local unsigned short temp
temp <- Key(2) | 2
decrypt_byte <- (temp * (temp ^ 1)) >> 8
end decrypt_byte
}
temp := FKeys[2] or 2;
Result := (temp * (temp xor 1)) shr 8;
end;
procedure TFWZipKeys.UpdateKeys(Value: Byte);
begin
{
Key(0) <- crc32(key(0),char)
Key(1) <- Key(1) + (Key(0) & 000000ffH)
Key(1) <- Key(1) * 134775813 + 1
Key(2) <- crc32(key(2),key(1) >> 24)
}
FKeys[0] := ((FKeys[0] shr 8) and $FFFFFF) xor
CRC32Table[(FKeys[0] xor Value) and $FF];
FKeys[1] := FKeys[1] + (FKeys[0] and $FF);
FKeys[1] := FKeys[1] * 134775813 + 1;
FKeys[2] := ((FKeys[2] shr 8) and $FFFFFF) xor
CRC32Table[(FKeys[2] xor (FKeys[1] shr 24)) and $FF];
end;
{ TFWZipCryptor }
procedure TFWZipCryptor.EncryptBuffer(Buffer: PByte; Size: Int64);
var
temp: Byte;
begin
// реверсированный вариант TFWZipDecryptor.DecryptBuffer
while Size > 0 do
begin
Dec(Size);
temp := DecryptByte;
UpdateKeys(Buffer^);
Buffer^ := temp xor Buffer^;
Inc(Buffer);
end;
end;
function TFWZipCryptor.EncryptByte(Value: Byte): Byte;
var
temp: Byte;
begin
temp := DecryptByte;
UpdateKeys(Value);
Result := temp xor Value;
end;
procedure TFWZipCryptor.GenerateEncryptionHeader(Stream: TStream;
IsDescryptorFlagPresent: Boolean; CRC32, FileDate: Cardinal);
var
{%H-}Buffer: array [0..EncryptedHeaderSize - 1] of Byte;
I: Integer;
begin
// реверсированный вариант TFWZipDecryptor.LoadEncryptionHeader
Randomize;
for I := 0 to LastEncryptedHeaderByte - 2 do
Buffer[I] := EncryptByte(Byte(Random(MAXBYTE)));
if IsDescryptorFlagPresent then
begin
Buffer[10] := EncryptByte(LoByte(LoWord(FileDate)));
Buffer[11] := EncryptByte(HiByte(LoWord(FileDate)));
end
else
begin
Buffer[10] := EncryptByte(LoByte(HiWord(CRC32)));
Buffer[11] := EncryptByte(HiByte(HiWord(CRC32)));
end;
Stream.WriteBuffer(Buffer[0], EncryptedHeaderSize);
end;
{ TFWZipDecryptor }
procedure TFWZipDecryptor.DecryptBuffer(Buffer: PByte; Size: Int64);
var
temp: Byte;
begin
{
Step 3 - Decrypting the compressed data stream
----------------------------------------------
The compressed data stream can be decrypted as follows:
loop until done
read a character into C
Temp <- C ^ decrypt_byte()
update_keys(temp)
output Temp
end loop
}
while Size > 0 do
begin
Dec(Size);
temp := Buffer^ xor DecryptByte;
UpdateKeys(temp);
Buffer^ := temp;
Inc(Buffer);
end;
end;
function TFWZipDecryptor.LoadEncryptionHeader(Stream: TStream;
IsDescryptorFlagPresent: Boolean; CRC32, FileDate: Cardinal): Boolean;
var
Buffer: array [0..EncryptedHeaderSize - 1] of Byte;
I: Integer;
C: Byte;
begin
{
Read the 12-byte encryption header into Buffer, in locations
Buffer(0) thru Buffer(11).
loop for i <- 0 to 11
C <- buffer(i) ^ decrypt_byte()
update_keys(C)
buffer(i) <- C
end loop
}
Stream.ReadBuffer({%H-}Buffer[0], EncryptedHeaderSize);
for I := 0 to LastEncryptedHeaderByte do
begin
C := Buffer[I] xor DecryptByte;
UpdateKeys(C);
Buffer[I] := C;
end;
{
After the header is decrypted, the last 1 or 2 bytes in Buffer
should be the high-order word/byte of the CRC for the file being
decrypted, stored in Intel low-byte/high-byte order, or the high-order
byte of the file time if bit 3 of the general purpose bit flag is set.
}
if IsDescryptorFlagPresent then
Result := Buffer[LastEncryptedHeaderByte] = HiByte(LoWord(FileDate))
else
Result := Buffer[LastEncryptedHeaderByte] = HiByte(HiWord(CRC32));
end;
end.

98
fwzip/FWZipLCL.lpk Normal file
View File

@@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<Package Version="5">
<PathDelim Value="\"/>
<Name Value="FWZipLCL"/>
<Author Value="Alexander (Rouse) Bagel"/>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<IncludeFiles Value=".;fpc_lib"/>
<Libraries Value="fpc_lib"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
</CompilerOptions>
<Description Value="The FWZip class set is designed for creating and unpacking ZIP archives with Store and Deflate compression methods."/>
<License Value="MIT"/>
<Version Major="2" Release="4"/>
<Files Count="14">
<Item1>
<Filename Value="FWZipConsts.pas"/>
<UnitName Value="FWZipConsts"/>
</Item1>
<Item2>
<Filename Value="FWZipCrc32.pas"/>
<UnitName Value="FWZipCrc32"/>
</Item2>
<Item3>
<Filename Value="FWZipCrypt.pas"/>
<UnitName Value="FWZipCrypt"/>
</Item3>
<Item4>
<Filename Value="FWZipModifier.pas"/>
<UnitName Value="FWZipModifier"/>
</Item4>
<Item5>
<Filename Value="FWZipReader.pas"/>
<UnitName Value="FWZipReader"/>
</Item5>
<Item6>
<Filename Value="FWZipStream.pas"/>
<UnitName Value="FWZipStream"/>
</Item6>
<Item7>
<Filename Value="FWZipUtils.pas"/>
<UnitName Value="FWZipUtils"/>
</Item7>
<Item8>
<Filename Value="FWZipWriter.pas"/>
<UnitName Value="FWZipWriter"/>
</Item8>
<Item9>
<Filename Value="FWZipZLib.pas"/>
<UnitName Value="FWZipZLib"/>
</Item9>
<Item10>
<Filename Value="FWZipZLibFPC.pas"/>
<UnitName Value="FWZipZLibFPC"/>
</Item10>
<Item11>
<Filename Value="fpc_lib\libzlib_coff_win_amd64.a"/>
<Type Value="Binary"/>
</Item11>
<Item12>
<Filename Value="fpc_lib\libzlib_coff_x386.a"/>
<Type Value="Binary"/>
</Item12>
<Item13>
<Filename Value="fpc_lib\libzlib_elf_intel_386.a"/>
<Type Value="Binary"/>
</Item13>
<Item14>
<Filename Value="fpc_lib\libzlib_elf64_for_x86-64.a"/>
<Type Value="Binary"/>
</Item14>
</Files>
<CompatibilityMode Value="True"/>
<RequiredPkgs Count="3">
<Item1>
<PackageName Value="LCLBase"/>
</Item1>
<Item2>
<PackageName Value="LazUtils"/>
</Item2>
<Item3>
<PackageName Value="FCL"/>
</Item3>
</RequiredPkgs>
<UsageOptions>
<LibraryPath Value="fpc_lib"/>
<UnitPath Value="$(PkgOutDir)"/>
</UsageOptions>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
</Package>
</CONFIG>

16
fwzip/FWZipLCL.pas Normal file
View File

@@ -0,0 +1,16 @@
{ This file was automatically created by Lazarus. Do not edit!
This source is only used to compile and install the package.
}
unit FWZipLCL;
{$warn 5023 off : no warning about unused units}
interface
uses
FWZipConsts, FWZipCrc32, FWZipCrypt, FWZipModifier, FWZipReader,
FWZipStream, FWZipUtils, FWZipWriter, FWZipZLib, FWZipZLibFPC;
implementation
end.

510
fwzip/FWZipModifier.pas Normal file
View File

@@ -0,0 +1,510 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : FWZipModifier
// * Purpose : Класс для модификации созданного ранее ZIP архива
// * 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 FWZipModifier;
{$IFDEF FPC}
{$MODE Delphi}
{$H+}
{$ENDIF}
interface
uses
Classes,
SysUtils,
FWZipConsts,
FWZipReader,
FWZipWriter,
FWZipStream,
FWZipZLib,
FWZipUtils;
type
TReaderIndex = Integer;
TFWZipModifierItem = class(TFWZipWriterItem)
private
FReaderIndex: TReaderIndex; // индекс TFWZipReader в массиве TFWZipModifier.FReaderList
FOriginalItemIndex: Integer; // оригинальный индекс элемента в изначальном архиве
FOverloadItemPath: string; // задаваемый извне путь элемента в архиве
protected
property ReaderIndex: TReaderIndex read FReaderIndex write FReaderIndex;
property OriginalItemIndex: Integer read FOriginalItemIndex write FOriginalItemIndex;
property OverloadItemPath: string read FOverloadItemPath write FOverloadItemPath;
public
constructor Create(Owner: TFWZipWriter;
const InitFilePath: string;
InitAttributes: TFileAttributeData;
const InitFileName: string = ''); override;
end;
EFWZipModifier = class(Exception);
// Данная структура хранит все блоки ExData из подключаемых архивов
TExDataRecord = record
Index: Integer;
Tag: Word;
Stream: TMemoryStream;
end;
TExDataRecords = array of TExDataRecord;
// структура для хранения подключенного архива и его блоков ExData
TReaderOwnership = (roReference, roOwned);
TReaderData = record
Reader: TFWZipReader;
ExDataRecords: TExDataRecords;
Ownership: TReaderOwnership;
end;
TReaderList = array of TReaderData;
TFWZipModifier = class(TFWZipWriter)
private
FReaderList: TReaderList;
function CheckZipFileIndex(Value: TReaderIndex): TReaderIndex;
function AddItemFromZip(AReader: TFWZipReader;
ReaderIndex: TReaderIndex; ItemIndex: Integer;
OverloadItemPath: string): Integer;
function GetReader(Index: Integer): TFWZipReader;
protected
function GetItemClass: TFWZipWriterItemClass; override;
procedure FillItemCDFHeader(CurrentItem: TFWZipWriterItem;
var Value: TCentralDirectoryFileHeaderEx); override;
procedure CompressItem(CurrentItem: TFWZipWriterItem;
Index: Integer; StreamSizeBeforeCompress: Int64; Stream: TStream); override;
procedure FillExData(Stream: TStream; Index: Integer); override;
procedure OnLoadExData(Sender: TObject; ItemIndex: Integer;
Tag: Word; Data: TStream);
public
destructor Destroy; override;
function AddZipFile(const AReader: TFWZipReader;
AOwnership: TReaderOwnership = roReference): TReaderIndex; overload;
function AddZipFile(const FilePath: string; SFXOffset: Integer = -1;
ZipEndOffset: Integer = -1): TReaderIndex; overload;
function AddZipFile(FileStream: TStream; SFXOffset: Integer = -1;
ZipEndOffset: Integer = -1): TReaderIndex; overload;
function AddFromZip(ReaderIndex: TReaderIndex): Integer; overload;
function AddFromZip(ReaderIndex: TReaderIndex; const ItemPath: string): Integer; overload;
function AddFromZip(ReaderIndex: TReaderIndex; const ItemPath, NewItemPath: string): Integer; overload;
function AddFromZip(ReaderIndex: TReaderIndex; ItemsList: TStringList): Integer; overload;
function ReadersCount: Integer;
property Reader[Index: Integer]: TFWZipReader read GetReader;
end;
implementation
type
TFWZipReaderFriendly = class(TFWZipReader);
TFWZipReaderItemFriendly = class(TFWZipReaderItem);
{ TFWZipModifierItem }
//
// В конструкторе производим первичную инициализацию полей
// Сами поля ReaderIndex и OriginalItemIndex будут инициализироваться только
// при добавлении их посредством класса TFWZipModifier
// =============================================================================
constructor TFWZipModifierItem.Create(Owner: TFWZipWriter;
const InitFilePath: string; InitAttributes: TFileAttributeData;
const InitFileName: string);
begin
inherited Create(Owner, InitFilePath, InitAttributes, InitFileName);
FReaderIndex := -1;
FOriginalItemIndex := -1;
end;
{ TFWZipModifier }
//
// Функция переносит элемент в финальный архив из ранее добавленного архива.
// В качестве результата возвращает индекс элемента в списке.
// Параметры:
// ReaderIndex - индекс ранее добавленно функцией AddZipFile архива
// ItemPath - имя элемента, которое требуется добавить
// =============================================================================
function TFWZipModifier.AddFromZip(ReaderIndex: TReaderIndex;
const ItemPath: string): Integer;
begin
Result := AddFromZip(ReaderIndex, ItemPath, EmptyStr);
end;
//
// Функция переносит все элементы из ранее добавленного архива в финальный архив.
// В качестве результата возвращает количество успешно добавленных элементов.
// Параметры:
// ReaderIndex - индекс ранее добавленно функцией AddZipFile архива
// =============================================================================
function TFWZipModifier.AddFromZip(ReaderIndex: TReaderIndex): Integer;
var
I: Integer;
Reader: TFWZipReader;
begin
CheckZipFileIndex(ReaderIndex);
Result := 0;
Reader := FReaderList[ReaderIndex].Reader;
for I := 0 to Reader.Count - 1 do
if AddItemFromZip(Reader, ReaderIndex, I, EmptyStr) >= 0 then
Inc(Result);
end;
//
// Функция переносит все элементы из ранее добавленного архива
// по списку в финальный архив.
// В качестве результата возвращает количество успешно добавленных элементов.
// Параметры:
// ReaderIndex - индекс ранее добавленно функцией AddZipFile архива
// ItemsList - список элементов к добавлению
// =============================================================================
function TFWZipModifier.AddFromZip(ReaderIndex: TReaderIndex;
ItemsList: TStringList): Integer;
var
I: Integer;
Reader: TFWZipReader;
begin
CheckZipFileIndex(ReaderIndex);
Result := 0;
Reader := FReaderList[ReaderIndex].Reader;
for I := 0 to ItemsList.Count - 1 do
if AddItemFromZip(Reader, ReaderIndex,
Reader.GetElementIndex(ItemsList[I]), EmptyStr) >= 0 then
Inc(Result);
end;
//
// Функция переносит элемент в финальный архив из ранее добавленного архива.
// В качестве результата возвращает индекс элемента в списке.
// Параметры:
// ReaderIndex - индекс ранее добавленно функцией AddZipFile архива
// ItemPath - имя элемента, которое требуется добавить
// NewItemPath - новое имя элемента в архиве
// =============================================================================
function TFWZipModifier.AddFromZip(ReaderIndex: TReaderIndex; const ItemPath,
NewItemPath: string): Integer;
var
Reader: TFWZipReader;
begin
CheckZipFileIndex(ReaderIndex);
Reader := FReaderList[ReaderIndex].Reader;
Result :=
AddItemFromZip(Reader, ReaderIndex, Reader.GetElementIndex(ItemPath),
CheckFileNameSlashes( NewItemPath));
end;
//
// Функция переносит элемент в финальный архив из ранее добавленного архива.
// В качестве результата возвращает индекс элемента в списке.
// =============================================================================
function TFWZipModifier.AddItemFromZip(AReader: TFWZipReader;
ReaderIndex: TReaderIndex; ItemIndex: Integer;
OverloadItemPath: string): Integer;
const
OldItemType: array [Boolean] of string = ('file', 'folder');
var
OldItem: TFWZipReaderItemFriendly;
NewItem: TFWZipModifierItem;
begin
Result := -1;
if ItemIndex < 0 then Exit;
// Получаем указатель на элемент из уже существующего архива
OldItem := TFWZipReaderItemFriendly(AReader.Item[ItemIndex]);
// Проверка соответствия нового имени типу старого элемента
if OverloadItemPath <> '' then
begin
if OverloadItemPath <> OldItem.FileName then
begin
if OldItem.IsFolder <>
(OverloadItemPath[Length(OverloadItemPath)] = ZIP_SLASH) then
raise EFWZipModifier.CreateFmt(
'"%s" does not match the %s path.',
[OverloadItemPath, OldItemType[OldItem.IsFolder]]);
end
else
OverloadItemPath := EmptyStr;
end;
// создаем новый элемент, который будем добавлять к новому архиву
NewItem := TFWZipModifierItem(
GetItemClass.Create(Self, '', OldItem.Attributes, OldItem.FileName));
// переключаем его в режим получения данных вручную
NewItem.UseExternalData := True;
// инициализируем ему индексы, дабы потом понять, откуда брать о нем данные
NewItem.ReaderIndex := ReaderIndex;
NewItem.OriginalItemIndex := ItemIndex;
NewItem.OverloadItemPath := OverloadItemPath;
// инициализируем внешние и рассчитываемые поля
NewItem.Comment := OldItem.Comment;
NewItem.NeedDescriptor :=
OldItem.CentralDirFileHeader.GeneralPurposeBitFlag and PBF_DESCRIPTOR <> 0;
NewItem.UseUTF8String :=
OldItem.CentralDirFileHeader.GeneralPurposeBitFlag and PBF_UTF8 <> 0;
// добавляем
Result := AddNewItem(NewItem);
end;
//
// Функция добавляет новый архив из которого можно брать готовые данные.
// В качестве результата возвращает индекс архива в списке добавленных.
// Параметры:
// FileStream - поток с данными архива
// SFXOffset и ZipEndOffset - его границы
// =============================================================================
function TFWZipModifier.AddZipFile(FileStream: TStream; SFXOffset,
ZipEndOffset: Integer): TReaderIndex;
var
AReader: TFWZipReader;
begin
AReader := TFWZipReader.Create;
Result := AddZipFile(AReader, roOwned);
AReader.OnLoadExData := OnLoadExData;
AReader.LoadFromStream(FileStream, SFXOffset, ZipEndOffset);
end;
//
// Функция добавляет новный ридер в список доступных
// Загрузка данных не производится, поэтому данный вариант добавления
// ридера не позволит работать с блоком ExData если таковой присутствует.
// =============================================================================
function TFWZipModifier.AddZipFile(const AReader: TFWZipReader;
AOwnership: TReaderOwnership): TReaderIndex;
begin
Result := Length(FReaderList);
SetLength(FReaderList, Result + 1);
FReaderList[Result].Reader := AReader;
FReaderList[Result].Ownership := AOwnership;
end;
//
// Функция добавляет новый архив из которого можно брать готовые данные.
// В качестве результата возвращает индекс архива в списке добавленных.
// Параметры:
// FilePath - путь к добавляемому архиву
// SFXOffset и ZipEndOffset - его границы
// =============================================================================
function TFWZipModifier.AddZipFile(const FilePath: string;
SFXOffset, ZipEndOffset: Integer): TReaderIndex;
var
AReader: TFWZipReader;
begin
AReader := TFWZipReader.Create;
Result := AddZipFile(AReader, roOwned);
AReader.OnLoadExData := OnLoadExData;
AReader.LoadFromFile(FilePath, SFXOffset, ZipEndOffset);
end;
//
// Функция проверяет правильность переданного индекса архива в списке
// =============================================================================
function TFWZipModifier.CheckZipFileIndex(Value: TReaderIndex): TReaderIndex;
begin
Result := Value;
if (Value < 0) or (Value >= Length(FReaderList)) then
raise EFWZipModifier.CreateFmt('Invalid index value (%d).', [Value]);
end;
//
// Процедура перекрывает сжатие данных эелемента
// и берет эти данные из ранее сформированного архива.
// =============================================================================
procedure TFWZipModifier.CompressItem(CurrentItem: TFWZipWriterItem;
Index: Integer; StreamSizeBeforeCompress: Int64; Stream: TStream);
var
OldItem: TFWZipReaderItemFriendly;
NewItem: TFWZipModifierItem;
Reader: TFWZipReaderFriendly;
Offset: Int64;
begin
NewItem := TFWZipModifierItem(CurrentItem);
// проверка, работаем ли мы с элементом, данные которого заполняются вручную?
if not NewItem.UseExternalData then
begin
inherited;
Exit;
end;
// получаем указатель на класс, который держит добавленный ранее архив
Reader := TFWZipReaderFriendly(FReaderList[NewItem.ReaderIndex].Reader);
// получаем указатель на оригинальный элемент архива
OldItem := TFWZipReaderItemFriendly(Reader.Item[NewItem.OriginalItemIndex]);
// рассчитываем его позицию в архиве
if IsMultiPartZip(Reader.ZIPStream) then
begin
TFWAbstractMultiStream(Reader.ZIPStream).Seek(
OldItem.CentralDirFileHeader.DiskNumberStart,
OldItem.CentralDirFileHeader.RelativeOffsetOfLocalHeader);
Offset := Reader.ZIPStream.Position;
end
else
Offset := OldItem.CentralDirFileHeader.RelativeOffsetOfLocalHeader;
Inc(Offset, SizeOf(TLocalFileHeader));
Inc(Offset, OldItem.CentralDirFileHeader.FilenameLength);
if OldItem.CentralDirFileHeaderEx.UncompressedSize >= MAXDWORD then
Inc(Offset, SizeOf(TExDataInfo64));
Reader.ZIPStream.Position := Offset;
// копируем данные как есть, без перепаковки
Stream.CopyFrom(Reader.ZIPStream, OldItem.CentralDirFileHeaderEx.CompressedSize);
end;
//
// Modifier слегка не оптимально расходует память, поэтому подчищаем.
// =============================================================================
destructor TFWZipModifier.Destroy;
var
I, A: Integer;
begin
for I := 0 to Length(FReaderList) - 1 do
begin
if FReaderList[I].Ownership = roOwned then
FReaderList[I].Reader.Free;
for A := 0 to Length(FReaderList[I].ExDataRecords) - 1 do
FReaderList[I].ExDataRecords[A].Stream.Free;
end;
inherited;
end;
//
// Процедура перекрывает заполнение блоков ExData
// и берет эти данные из ранее сформированного архива.
// =============================================================================
procedure TFWZipModifier.FillExData(Stream: TStream; Index: Integer);
var
NewItem: TFWZipModifierItem;
ReaderIndex: TReaderIndex;
I: Integer;
{%H-}ExDataSize: Word;
ExDataRecord: TExDataRecord;
begin
NewItem := TFWZipModifierItem(Item[Index]);
// проверка, работаем ли мы с элементом, данные которого заполняются вручную?
if not NewItem.UseExternalData then
begin
inherited;
Exit;
end;
// проверяем привязку к архиву, с елементов которого мы будем добавлять блоки ExData
ReaderIndex := CheckZipFileIndex(NewItem.ReaderIndex);
for I := 0 to Length(FReaderList[ReaderIndex].ExDataRecords) - 1 do
if FReaderList[ReaderIndex].ExDataRecords[I].Index = NewItem.OriginalItemIndex then
begin
// блоков может быть несколько, поэтому добавляем их все
ExDataRecord := FReaderList[ReaderIndex].ExDataRecords[I];
Stream.WriteBuffer(ExDataRecord.Tag, 2);
ExDataSize := ExDataRecord.Stream.Size;
Stream.WriteBuffer(ExDataSize, 2);
Stream.CopyFrom(ExDataRecord.Stream, 0);
end;
end;
//
// Процедура перекрывает заполнение структуры TCentralDirectoryFileHeaderEx
// и берет эти данные из ранее сформированного архива.
// =============================================================================
procedure TFWZipModifier.FillItemCDFHeader(CurrentItem: TFWZipWriterItem;
var Value: TCentralDirectoryFileHeaderEx);
var
OldItem: TFWZipReaderItemFriendly;
NewItem: TFWZipModifierItem;
Reader: TFWZipReader;
FileDate: Cardinal;
begin
NewItem := TFWZipModifierItem(CurrentItem);
// проверка, работаем ли мы с элементом, данные которого заполняются вручную?
if not NewItem.UseExternalData then
begin
inherited;
Exit;
end;
Reader := FReaderList[NewItem.ReaderIndex].Reader;
OldItem := TFWZipReaderItemFriendly(Reader.Item[NewItem.OriginalItemIndex]);
// полностью перезаписываем все данные структуры
// исключением является поле RelativeOffsetOfLocalHeader
// но оно реинициализируется после вызова данного метода
Value := OldItem.CentralDirFileHeaderEx;
// Rouse_ 11.11.2023
// если имя в архиве было переназначено,
// то меняем его с правкой времени последнего изменения
if NewItem.OverloadItemPath <> '' then
begin
Value.Filename := NewItem.OverloadItemPath;
Value.Header.FilenameLength :=
StringLength(NewItem.OverloadItemPath, CurrentItem.UseUTF8String);
Value.Attributes.ftLastWriteTime := GetCurrentFileTime;
FileDate := FileTimeToLocalFileDate(Value.Attributes.ftLastWriteTime);
Value.Header.LastModFileTimeTime := FileDate and $FFFF;
Value.Header.LastModFileTimeDate := FileDate shr 16;
end;
end;
//
// Расширяем коллекцию
// =============================================================================
function TFWZipModifier.GetItemClass: TFWZipWriterItemClass;
begin
Result := TFWZipModifierItem;
end;
//
// Возвращаем сылку на внутренний ридер
// =============================================================================
function TFWZipModifier.GetReader(Index: Integer): TFWZipReader;
begin
if (Index < 0) or (Index >= ReadersCount) then
raise EFWZipModifier.CreateFmt('Invalid reader index value (%d).', [Index]);
Result := FReaderList[Index].Reader;
end;
//
// Задача процедуры собрать все ExData в локальное хранилище,
// чтобы их можно было присоединить к структуре архива на этапе ребилда
// =============================================================================
procedure TFWZipModifier.OnLoadExData(Sender: TObject; ItemIndex: Integer;
Tag: Word; Data: TStream);
var
Index, ExDataCount: Integer;
ExData: TExDataRecord;
begin
Index := ReadersCount - 1;
if Index >= 0 then
begin
ExData.Index := ItemIndex;
ExData.Tag := Tag;
ExData.Stream := TMemoryStream.Create;
ExData.Stream.CopyFrom(Data, 0);
ExDataCount := Length(FReaderList[Index].ExDataRecords);
SetLength(FReaderList[Index].ExDataRecords, ExDataCount + 1);
FReaderList[Index].ExDataRecords[ExDataCount] := ExData;
end;
end;
//
// Возвращаем количество доступных ридеров
// =============================================================================
function TFWZipModifier.ReadersCount: Integer;
begin
Result := Length(FReaderList);
end;
end.

1644
fwzip/FWZipReader.pas Normal file

File diff suppressed because it is too large Load Diff

973
fwzip/FWZipStream.pas Normal file
View File

@@ -0,0 +1,973 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : FWZipStream
// * Purpose : Вспомогательные стримы для поддержки шифрования на лету,
// * : и усеченного заголовка ZLib,
// * : для поддержки разбитых на тома архивов и прочее утилитарные
// * : стримы для проверки целостности архива
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2023.
// * Version : 2.0.1
// * 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/
//
// Описание идеи TFWZipItemStream:
// При помещении в архив сжатого блока данных методом Deflate у него
// отрезается двухбайтный заголовок в котором указаны параметры сжатия.
// Т.е. в архив помещаются сами данные в чистом виде.
// Для распаковки необходимо данный заголовок восстановить.
// TFWZipItemStream позволяет добавить данный заголовок "на лету"
// абсолютно прозрачно для внешнего кода.
// Сам заголовок генерируется в конструкторе и подставляется в методе Read.
// Так-же класс, выступая посредником между двумя стримами,
// позволяет производить шифрование и дешифровку передаваемых данных.
// Шифрование производится в методе Write, в этот момент класс является
// посредником между TCompressionStream и результирующим стримом.
// Дешифрование осуществляется в методе Read, в этот момент класс является
// посредником между стримом со сжатыми и
// пошифрованными данными и TDecompressionStream.
//
unit FWZipStream;
{$IFDEF FPC}
{$MODE Delphi}
{$H+}
{$ENDIF}
interface
{$I fwzip.inc}
uses
{$IFNDEF FPC}
Windows, // для инлайн RenameFile
{$ENDIF}
Classes,
SysUtils,
Math,
FWZipCrypt,
FWZipZLib,
{$IFDEF USE_AUTOGENERATED_ZLIB_HEADER}
FWZipConsts,
{$ENDIF}
FWZipUtils;
const
NO_STREAM = -1;
MinPartSize = {$IFDEF UNIT_TEST}100{$ELSE}$10000{$ENDIF};
type
TFWZipItemStream = class(TStream)
private
FOwner: TStream;
FCryptor: TFWZipCryptor;
FDecryptor: TFWZipDecryptor;
FSize, FStart, FPosition: Int64;
{$IFDEF USE_AUTOGENERATED_ZLIB_HEADER}
FHeader: Word;
{$ENDIF}
protected
function GetSize: Int64; override;
public
constructor Create(AOwner: TStream; Cryptor: TFWZipCryptor;
Decryptor: TFWZipDecryptor; {%H-}CompressLevel: Byte; ASize: Int64);
function Seek(Offset: Longint; Origin: Word): Longint; overload; override;
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; overload; override;
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const {%H-}Buffer; Count: Longint): Longint; override;
end;
EFWZipItemItemUnpackedStreamException = class(Exception);
// Виртуальный стрим данных.
// Используется для более привычной работы с незапакованным блоком данных,
// расположенного в архиве
TFWZipItemItemUnpackedStream = class(TStream)
private
FOwnerStream: TStream;
FOffset: Int64;
FSize, FPosition: Integer;
protected
function GetSize: Int64; override;
procedure SetSize({%H-}NewSize: Longint); override;
public
constructor Create; overload;
constructor Create(Owner: TStream; Offset: Int64; ASize: Integer); overload;
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const {%H-}Buffer; {%H-}Count: Longint): Longint; override;
function Seek(Offset: Longint; Origin: Word): Longint; override;
end;
// TFakeStream предназначен для проверки архива на целостность
TFakeStream = class(TStream)
private
FSize: Int64;
FPosition: Int64;
protected
procedure SetSize(const NewSize: Int64); override;
public
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; overload; override;
function Write(const {%H-}Buffer; Count: Longint): Longint; override;
function Read(var {%H-}Buffer; {%H-}Count: Longint): Longint; override;
end;
TFWMultiStreamMode = (msmRead, msmWrite);
EFWMultiStreamException = class(Exception)
public
constructor Create(ADiskNumber: Integer); overload;
constructor Create(const AMessage: string); overload;
end;
TFWMultiStreamClass = class of TFWAbstractMultiStream;
TFWLastVolumesType = (lvtLastPart, lvtCentralDirectory);
// Данный стрим используется при работе с архивом разбитым на тома
TFWAbstractMultiStream = class(TStream)
private
FMode: TFWMultiStreamMode;
FCurrentDiskData: TStream;
FPosition: Int64;
procedure CheckMode(AMode: TFWMultiStreamMode);
function CurrentDiskNumber: Integer;
function CalcOffset(DiskNumber: Integer): Int64;
function UpdateCurrentDiskData: Integer;
protected
function GetNextWriteVolume: TStream; virtual; abstract;
procedure GetStream(DiskNumber: Integer; var DiskData: TStream); virtual; abstract;
function GetTotalSize: Int64; virtual; abstract;
function GetVolumeSizeByIndex(Index: Integer): Int64; virtual; abstract;
procedure TrimFromDiskNumber(Index: Integer); virtual; abstract;
property VolumeSize[Index: Integer]: Int64 read GetVolumeSizeByIndex;
procedure UpdateVolumeSize; virtual; abstract;
/// <summary>
/// Метод должен вызываться только для режима msmWrite после окончания
/// записи архива. Применяется для закрытия последнего дома и его переименования.
/// </summary>
procedure FinallyWrite; virtual;
protected
procedure SetSize(const NewSize: Int64); override;
public
constructor Create(AMode: TFWMultiStreamMode); reintroduce;
procedure GetRelativeInfo(out DiskNumber: Integer; out RealtiveOffset: Int64);
function GetDiskCount: Integer; virtual; abstract;
function GetWriteVolumeSize: Int64; virtual; abstract;
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const Buffer; Count: Longint): Longint; override;
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; overload; override;
function Seek(DiskNumber: Integer; Offset: Int64): Int64; overload;
/// <summary>
/// Начинает новый том архива даже если предыдущий был заполнен не до конца
/// Работает только в режиме msmWrite
/// </summary>
procedure StartNewVolume;
property Mode: TFWMultiStreamMode read FMode;
end;
EFWFileMultiStreamException = class(Exception);
TReadSizeMode = (rsmQuick, rsmFull);
// Используется для работы с томами архива доступным из файловой системы
TFWFileMultiStream = class(TFWAbstractMultiStream)
private
FCurrentStreamNumber: Integer;
FCurrentStream: TFileStream;
FFilePath: string;
FVolumesPath: TStringList;
FTotalSize, FVolumeSize: Int64;
FReadVolumesSize, FWriteVolumesSize: array of Int64;
function AddNewVolume: TStream;
procedure FillFilesList(const FilePath: string;
ReadSizeMode: TReadSizeMode);
procedure FillFilesSize(ReadSizeMode: TReadSizeMode);
protected
{%H-}constructor Create(const FilePath: string;
AMode: TFWMultiStreamMode; ReadSizeMode: TReadSizeMode;
PartSize: Int64);
function GetNextWriteVolume: TStream; override;
procedure GetStream(DiskNumber: Integer; var DiskData: TStream); override;
function GetTotalSize: Int64; override;
function GetVolumeSizeByIndex(Index: Integer): Int64; override;
procedure TrimFromDiskNumber(Index: Integer); override;
procedure UpdateVolumeSize; override;
procedure FinallyWrite; override;
protected
function GetVolumeExt(Index: Integer): string; virtual; // если имена файлов не .zХХ то перекрываем эту процедуру в наследнике
public
constructor CreateRead(const FilePath: string; ReadSizeMode: TReadSizeMode = rsmFull);
constructor CreateWrite(const FilePath: string; PartSize: Int64 = MinPartSize);
destructor Destroy; override;
function GetDiskCount: Integer; override;
function GetWriteVolumeSize: Int64; override;
end;
implementation
const
E_READONLY = 'TFWZipItemItemUnpackedStream работает только в режиме ReadOnly';
{ TFWZipItemStream }
constructor TFWZipItemStream.Create(AOwner: TStream; Cryptor: TFWZipCryptor;
Decryptor: TFWZipDecryptor; CompressLevel: Byte; ASize: Int64);
begin
inherited Create;
FOwner := AOwner;
FCryptor := Cryptor;
FDecryptor := Decryptor;
FSize := ASize;
FStart := AOwner.Position;
FPosition := 0;
// Rouse_ 30.10.2013
// Устаревший код
{$IFDEF USE_AUTOGENERATED_ZLIB_HEADER}
// Rouse_ 17.03.2011
// Размерчик все-же нужно править увеличивая на размер заголовка
Inc(FSize, 2);
// Восстанавливаем пропущенный заголовок ZLib стрима
// см. deflate.c - int ZEXPORT deflate (strm, flush)
// uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
FHeader := (Z_DEFLATED + (7 {32k Window size} shl 4)) shl 8;
// if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
// level_flags = 0;
// else if (s->level < 6)
// level_flags = 1;
// else if (s->level == 6)
// level_flags = 2;
// else
// level_flags = 3;
//
// сам CompressLevel (level_flags)
// берется из уже заполненного GeneralPurposeBitFlag
// здесь мы из битовой маски восстанавливаем оригинальные значения
case CompressLevel of
PBF_COMPRESS_SUPERFAST:
CompressLevel := 0;
PBF_COMPRESS_FAST:
CompressLevel := 1;
PBF_COMPRESS_NORMAL:
CompressLevel := 2;
PBF_COMPRESS_MAXIMUM:
CompressLevel := 3;
end;
// header |= (level_flags << 6);
FHeader := FHeader or (CompressLevel shl 6);
// if (s->strstart != 0) header |= PRESET_DICT;
// словарь не используется - оставляем без изменений
// header += 31 - (header % 31);
Inc(FHeader, 31 - (FHeader mod 31));
// putShortMSB(s, header);
FHeader := (FHeader shr 8) + (FHeader and $FF) shl 8;
{$ENDIF}
end;
function TFWZipItemStream.GetSize: Int64;
begin
Result := FSize;
end;
function TFWZipItemStream.Read(var Buffer; Count: Integer): Longint;
var
P: PByte;
DecryptBuff: Pointer;
begin
// Rouse_ 30.10.2013
// Устаревший код
{$IFDEF USE_AUTOGENERATED_ZLIB_HEADER}
if FPosition = 0 then
begin
// если зачитываются данные с самого начала
// необходимо перед ними разместить заголовок ZLib
P := @FHeader;
Move(P^, Buffer, 2);
FOwner.Position := FStart;
P := @Buffer;
Inc(P, 2);
if Count > Size then
Count := Size;
FOwner.Position := FStart;
if FDecryptor <> nil then
begin
// в случае если файл зашифрован, производим расшифровку блока
GetMem(DecryptBuff, Count - 2);
try
Result := FOwner.Read(DecryptBuff^, Count - 2);
FDecryptor.DecryptBuffer(DecryptBuff, Result);
Move(DecryptBuff^, P^, Result);
finally
FreeMem(DecryptBuff);
end;
end
else
Result := FOwner.Read(P^, Count - 2);
Inc(Result, 2);
Inc(FPosition, Result);
end
else
begin
FOwner.Position := FStart + Position - 2;
{$ELSE}
begin
FOwner.Position := FStart + Position;
{$ENDIF}
if Count > Size - Position then
Count := Size - Position;
if FDecryptor <> nil then
begin
// в случае если файл зашифрован, производим расшифровку блока
GetMem(DecryptBuff, Count);
try
Result := FOwner.Read(DecryptBuff^, Count);
FDecryptor.DecryptBuffer(DecryptBuff, Result);
P := @Buffer;
Move(DecryptBuff^, P^, Result);
finally
FreeMem(DecryptBuff);
end;
end
else
Result := FOwner.Read(Buffer, Count);
Inc(FPosition, Result);
end;
end;
function TFWZipItemStream.Seek(Offset: Integer; Origin: Word): Longint;
begin
Result := Seek(Int64(Offset), TSeekOrigin(Origin));
end;
function TFWZipItemStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
begin
case Origin of
soBeginning: FPosition := Offset;
soCurrent: Inc(FPosition, Offset);
soEnd: FPosition := Size + Offset;
end;
Result := FPosition;
end;
function TFWZipItemStream.Write(const Buffer; Count: Integer): Longint;
var
EncryptBuffer: PByte;
begin
if FCryptor = nil then
Result := FOwner.Write(Buffer, Count)
else
begin
// криптуем буфер
GetMem(EncryptBuffer, Count);
try
Move(Buffer, EncryptBuffer^, Count);
// Rouse_ 31.10.2013
// Устаревший код
{$IFDEF USE_AUTOGENERATED_ZLIB_HEADER}
// Шифровать блок нужно пропустив двубайтный заголовок ZLib
if FPosition = 0 then
begin
Inc(EncryptBuffer, 2);
FCryptor.EncryptBuffer(EncryptBuffer, Count - 2);
Dec(EncryptBuffer, 2);
end
else
{$ENDIF}
FCryptor.EncryptBuffer(EncryptBuffer, Count);
Result := FOwner.Write(EncryptBuffer^, Count);
finally
FreeMem(EncryptBuffer);
end;
end;
Inc(FPosition, Result);
end;
{ TFWZipItemItemUnpackedStream }
constructor TFWZipItemItemUnpackedStream.Create;
begin
raise EFWZipItemItemUnpackedStreamException.Create(
'Неверный вызов конструктора');
end;
constructor TFWZipItemItemUnpackedStream.Create(Owner: TStream; Offset: Int64;
ASize: Integer);
begin
FOwnerStream := Owner;
FOffset := Offset;
FSize := ASize;
end;
function TFWZipItemItemUnpackedStream.GetSize: Int64;
begin
Result := FSize;
end;
function TFWZipItemItemUnpackedStream.Read(var Buffer; Count: Longint): Longint;
begin
if FPosition + Count > FSize then
Count := FSize - FPosition;
FOwnerStream.Position := FOffset + FPosition;
Result := FOwnerStream.Read(Buffer, Count);
Inc(FPosition, Result);
end;
function TFWZipItemItemUnpackedStream.Seek(Offset: Longint;
Origin: Word): Longint;
begin
case Origin of
soFromBeginning: FPosition := Offset;
soFromCurrent: Inc(FPosition, Offset);
soFromEnd: FPosition := Size + Offset;
end;
if FPosition < 0 then
FPosition := 0;
if FPosition > FSize then
FPosition := FSize;
Result := FPosition;
end;
procedure TFWZipItemItemUnpackedStream.SetSize(NewSize: Longint);
begin
raise EFWZipItemItemUnpackedStreamException.Create(E_READONLY);
end;
function TFWZipItemItemUnpackedStream.{%H-}Write(const Buffer;
Count: Longint): Longint;
begin
raise EFWZipItemItemUnpackedStreamException.Create(E_READONLY);
end;
{ TFakeStream }
function TFakeStream.{%H-}Read(var Buffer; Count: Longint): Longint;
begin
raise Exception.Create('TFakeStream.Read');
end;
function TFakeStream.Write(const Buffer; Count: Longint): Longint;
begin
FSize := FSize + Count;
Result := Count;
end;
function TFakeStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
begin
case Origin of
soBeginning: FPosition := Offset;
soCurrent: Inc(FPosition, Offset);
soEnd: FPosition := FSize + Offset;
end;
Result := FPosition;
end;
procedure TFakeStream.SetSize(const NewSize: Int64);
begin
FSize := NewSize;
end;
{ EFWMultiStreamException }
constructor EFWMultiStreamException.Create(ADiskNumber: Integer);
begin
inherited CreateFmt('Can not find disk image №%d', [ADiskNumber]);
end;
constructor EFWMultiStreamException.Create(const AMessage: string);
begin
inherited Create(AMessage);
end;
{ TFWAbstractMultiStream }
function TFWAbstractMultiStream.CalcOffset(DiskNumber: Integer): Int64;
begin
Result := FPosition - VolumeSize[DiskNumber];
end;
procedure TFWAbstractMultiStream.CheckMode(AMode: TFWMultiStreamMode);
begin
if FMode <> AMode then
if FMode = msmRead then
raise EFWMultiStreamException.Create('Can`t write data on read.')
else
raise EFWMultiStreamException.Create('Can`t read data on write.');
end;
constructor TFWAbstractMultiStream.Create(AMode: TFWMultiStreamMode);
begin
FMode := AMode;
end;
function TFWAbstractMultiStream.CurrentDiskNumber: Integer;
var
I: Integer;
begin
Result := 0;
for I := GetDiskCount - 1 downto 0 do
begin
if VolumeSize[I] <= FPosition then
begin
Result := I;
Break;
end;
end;
end;
procedure TFWAbstractMultiStream.FinallyWrite;
begin
CheckMode(msmWrite);
end;
procedure TFWAbstractMultiStream.GetRelativeInfo(out DiskNumber: Integer;
out RealtiveOffset: Int64);
begin
DiskNumber := CurrentDiskNumber;
RealtiveOffset := CalcOffset(DiskNumber);
end;
function TFWAbstractMultiStream.Read(var Buffer; Count: Longint): Longint;
var
PartialRead: Longint;
P: PByte;
begin
CheckMode(msmRead);
Result := 0;
while Result < Count do
begin
P := PByte(@Buffer);
Inc(P, Result);
PartialRead := FCurrentDiskData.Read(P^, Count - Result);
if PartialRead = 0 then
raise EFWMultiStreamException.Create('Ошибка чтения данных.');
Inc(Result, PartialRead);
Inc(FPosition, PartialRead);
if FCurrentDiskData.Position = FCurrentDiskData.Size then
begin
GetStream(CurrentDiskNumber, FCurrentDiskData);
if FCurrentDiskData = nil then
Break;
end;
end;
end;
function TFWAbstractMultiStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
var
DiskNumber: Integer;
begin
case TSeekOrigin(Origin) of
soBeginning: FPosition := Offset;
soCurrent: Inc(FPosition, Offset);
soEnd: FPosition := GetTotalSize + Offset;
end;
if FPosition < 0 then
FPosition := 0;
if FPosition > GetTotalSize then
FPosition := GetTotalSize;
DiskNumber := UpdateCurrentDiskData;
FCurrentDiskData.Seek(CalcOffset(DiskNumber), soBeginning);
Result := FPosition;
end;
function TFWAbstractMultiStream.Seek(DiskNumber: Integer; Offset: Int64): Int64;
begin
if (DiskNumber < 0) or (DiskNumber >= GetDiskCount) then
raise EFWMultiStreamException.Create(DiskNumber);
Offset := VolumeSize[DiskNumber] + Offset;
Result := Seek(Offset, soBeginning);
end;
procedure TFWAbstractMultiStream.SetSize(const NewSize: Int64);
var
TotalRemain, MaxVolumeSize, TotalSize: Int64;
begin
CheckMode(msmWrite);
TotalSize := GetTotalSize;
// Если изменения размера нет, то и нечего делать
if TotalSize = NewSize then Exit;
// Размер стрима уменьшается
if TotalSize > NewSize then
begin
Position := NewSize;
FCurrentDiskData.Size := CalcOffset(CurrentDiskNumber);
TrimFromDiskNumber(CurrentDiskNumber);
Exit;
end;
// В противном случае увеличивать будем с самого последнего тома
GetStream(GetDiskCount - 1, FCurrentDiskData);
// Которого может и не быть
if FCurrentDiskData = nil then
FCurrentDiskData := GetNextWriteVolume;
TotalRemain := NewSize - TotalSize;
MaxVolumeSize := GetWriteVolumeSize;
while TotalRemain > 0 do
begin
if FCurrentDiskData.Size + TotalRemain <= MaxVolumeSize then
begin
FCurrentDiskData.Size := FCurrentDiskData.Size + TotalRemain;
UpdateVolumeSize;
Exit;
end;
Dec(TotalRemain, MaxVolumeSize - FCurrentDiskData.Size);
FCurrentDiskData.Size := MaxVolumeSize;
UpdateVolumeSize;
FCurrentDiskData := GetNextWriteVolume;
end;
end;
procedure TFWAbstractMultiStream.StartNewVolume;
begin
CheckMode(msmWrite);
if Position <> Size then
raise EFWMultiStreamException.Create('Нельзя завершать текущий том находясь в середине архива.');
if FCurrentDiskData <> nil then
if FCurrentDiskData.Size > 0 then
// Rouse_ 01.09.2023
// Фикс критической ошибки, не обновлялся внутренний стрим обьекта
FCurrentDiskData := GetNextWriteVolume;
end;
function TFWAbstractMultiStream.UpdateCurrentDiskData: Integer;
begin
Result := CurrentDiskNumber;
GetStream(Result, FCurrentDiskData);
if FCurrentDiskData = nil then
raise EFWMultiStreamException.Create(Result);
end;
function TFWAbstractMultiStream.Write(const Buffer; Count: Longint): Longint;
var
PartialWrite: LongInt;
WriteSize: Int64;
P: PByte;
begin
CheckMode(msmWrite);
Result := 0;
WriteSize := GetWriteVolumeSize;
if FCurrentDiskData = nil then
FCurrentDiskData := GetNextWriteVolume;
while Result < Count do
begin
PartialWrite := {%H-}Min(Count - Result, WriteSize - FCurrentDiskData.Position);
P := PByte(@Buffer);
Inc(P, Result);
if FCurrentDiskData.Write(P^, PartialWrite) <> PartialWrite then
raise EFWMultiStreamException.Create('Ошибка записи данных.');
Inc(Result, PartialWrite);
Inc(FPosition, PartialWrite);
UpdateVolumeSize;
if FCurrentDiskData.Position = WriteSize then
FCurrentDiskData := GetNextWriteVolume;
end;
end;
{ TFWFileMultiStream }
function TFWFileMultiStream.AddNewVolume: TStream;
var
NewVolumePath: string;
begin
FCurrentStreamNumber := FVolumesPath.Count;
NewVolumePath :=
ChangeFileExt(FFilePath, GetVolumeExt(FCurrentStreamNumber + 1));
FVolumesPath.Add(NewVolumePath);
SetLength(FReadVolumesSize, FVolumesPath.Count);
SetLength(FWriteVolumesSize, FVolumesPath.Count);
FreeAndNil(FCurrentStream);
ForceDirectoriesEx(ExtractFilePath(NewVolumePath));
FCurrentStream :=
TFileStream.Create(NewVolumePath, fmCreate or fmShareDenyWrite);
UpdateVolumeSize;
Result := FCurrentStream;
end;
constructor TFWFileMultiStream.Create(const FilePath: string;
AMode: TFWMultiStreamMode; ReadSizeMode: TReadSizeMode; PartSize: Int64);
begin
FCurrentStreamNumber := NO_STREAM;
FFilePath := PathCanonicalize(FilePath);
FVolumesPath := TStringList.Create;
if AMode = msmRead then
FillFilesList(FFilePath, ReadSizeMode)
else
begin
if PartSize < MinPartSize then
raise EFWFileMultiStreamException.CreateFmt(
'Указан слишком маленький размер тома (%d), минимальный размер = %d', [PartSize, MinPartSize]);
FVolumeSize := PartSize;
end;
inherited Create(AMode);
end;
constructor TFWFileMultiStream.CreateRead(const FilePath: string;
ReadSizeMode: TReadSizeMode);
begin
Create(FilePath, msmRead, ReadSizeMode, 0);
end;
constructor TFWFileMultiStream.CreateWrite(const FilePath: string;
PartSize: Int64);
begin
Create(FilePath, msmWrite, rsmQuick, PartSize);
end;
destructor TFWFileMultiStream.Destroy;
begin
if Mode = msmWrite then
FinallyWrite
else
FreeAndNil(FCurrentStream);
FVolumesPath.Free;
inherited;
end;
procedure TFWFileMultiStream.FillFilesList(
const FilePath: string; ReadSizeMode: TReadSizeMode);
var
I: Integer;
SplitFilePath: string;
begin
FVolumesPath.Clear;
if not FileExists(FilePath) then
raise EFWFileMultiStreamException.CreateFmt('File not found: "%s"', [FilePath]);
I := 1;
SplitFilePath := ChangeFileExt(FilePath, GetVolumeExt(I));
while FileExists(SplitFilePath) do
begin
FVolumesPath.Add(SplitFilePath);
Inc(I);
SplitFilePath := ChangeFileExt(FilePath, GetVolumeExt(I));
end;
FVolumesPath.Add(FilePath);
FillFilesSize(ReadSizeMode);
end;
procedure TFWFileMultiStream.FillFilesSize(ReadSizeMode: TReadSizeMode);
var
F: TFileStream;
I, FirstVolumeSize, Tmp: Integer;
begin
FTotalSize := 0;
SetLength(FReadVolumesSize, FVolumesPath.Count);
if ReadSizeMode = rsmFull then
begin
for I := 0 to FVolumesPath.Count - 1 do
begin
F := TFileStream.Create(FVolumesPath[I], fmShareDenyWrite);
try
// Каждая запись содержит размер с которого она начинается в плоском массиве
FReadVolumesSize[I] := FTotalSize;
Inc(FTotalSize, F.Size);
finally
F.Free;
end;
end;
Exit;
end;
F := TFileStream.Create(FVolumesPath[0], fmShareDenyWrite);
try
FirstVolumeSize := F.Size;
finally
F.Free;
end;
I := FVolumesPath.Count;
repeat
Dec(I);
F := TFileStream.Create(FVolumesPath[I], fmShareDenyWrite);
try
FReadVolumesSize[I] := F.Size;
finally
F.Free;
end;
until FReadVolumesSize[I] = FirstVolumeSize;
for I := 0 to FVolumesPath.Count - 1 do
begin
Tmp := FReadVolumesSize[I];
FReadVolumesSize[I] := FTotalSize;
if Tmp = 0 then
Inc(FTotalSize, FirstVolumeSize)
else
Inc(FTotalSize, Tmp);
end;
end;
procedure TFWFileMultiStream.FinallyWrite;
var
LastDiskIndex: Integer;
begin
inherited;
FreeAndNil(FCurrentStream);
FCurrentStreamNumber := NO_STREAM;
LastDiskIndex := GetDiskCount - 1;
while LastDiskIndex >= 0 do
begin
if FWriteVolumesSize[LastDiskIndex] = 0 then
begin
DeleteFile(FVolumesPath[LastDiskIndex]);
Dec(LastDiskIndex);
end
else
Break;
end;
if LastDiskIndex >= 0 then
begin
// Rouse_ 21.10.2020
// Если файл с именем архива уже существует, то RenameFile не сможет
// переименовать последний том архива.
// Спасибо Владиславу Нечепоренко за найденую ошибку.
DeleteFile(FFilePath);
RenameFile(FVolumesPath[LastDiskIndex], FFilePath);
end;
SetLength(FReadVolumesSize, 0);
SetLength(FWriteVolumesSize, 0);
FVolumesPath.Clear;
end;
function TFWFileMultiStream.GetDiskCount: Integer;
begin
Result := FVolumesPath.Count;
end;
function TFWFileMultiStream.GetNextWriteVolume: TStream;
begin
if (FCurrentStreamNumber < 0) or (FCurrentStreamNumber >= FVolumesPath.Count - 1) then
Result := AddNewVolume
else
GetStream(FCurrentStreamNumber + 1, Result);
end;
procedure TFWFileMultiStream.GetStream(DiskNumber: Integer; var DiskData: TStream);
const
OpenMode: array [TFWMultiStreamMode] of Word =
(fmShareDenyWrite, fmOpenReadWrite or fmShareExclusive);
begin
if FCurrentStreamNumber = DiskNumber then
begin
DiskData := FCurrentStream;
Exit;
end;
FCurrentStreamNumber := DiskNumber;
FreeAndNil(FCurrentStream);
DiskData := nil;
if (DiskNumber < 0) or (DiskNumber >= FVolumesPath.Count) then
begin
if FMode = msmRead then Exit;
if DiskNumber > FVolumesPath.Count then Exit;
DiskData := AddNewVolume;
Exit;
end;
if FileExists(FVolumesPath[DiskNumber]) then
begin
FCurrentStream :=
TFileStream.Create(FVolumesPath[DiskNumber], OpenMode[FMode]);
DiskData := FCurrentStream;
end;
end;
function TFWFileMultiStream.GetTotalSize: Int64;
begin
Result := FTotalSize;
end;
function TFWFileMultiStream.GetVolumeExt(Index: Integer): string;
var
Tmp, CharCount: Integer;
begin
if Index < 100 then
Result := Format('.z%.2d', [Index])
else
begin
Tmp := Index div 100;
CharCount := 2;
while Tmp > 0 do
begin
Inc(CharCount);
Tmp := Tmp div 10;
end;
Result := Format('.z%.' + IntToStr(CharCount) + 'd', [Index]);
end;
end;
function TFWFileMultiStream.GetVolumeSizeByIndex(Index: Integer): Int64;
begin
Result := FReadVolumesSize[Index];
end;
function TFWFileMultiStream.GetWriteVolumeSize: Int64;
begin
Result := FVolumeSize;
end;
procedure TFWFileMultiStream.TrimFromDiskNumber(Index: Integer);
var
I: Integer;
begin
Inc(Index);
SetLength(FReadVolumesSize, Index);
SetLength(FWriteVolumesSize, Index);
for I := FVolumesPath.Count - 1 downto Index do
begin
DeleteFile(PChar(FVolumesPath[I]));
FVolumesPath.Delete(I);
end;
UpdateVolumeSize;
end;
procedure TFWFileMultiStream.UpdateVolumeSize;
var
I: Integer;
begin
if FCurrentStream = nil then Exit;
if FCurrentStreamNumber < 0 then Exit;
FWriteVolumesSize[FCurrentStreamNumber] := FCurrentStream.Size;
FTotalSize := 0;
for I := 0 to Length(FReadVolumesSize) - 1 do
begin
FReadVolumesSize[I] := FTotalSize;
Inc(FTotalSize, FWriteVolumesSize[I]);
end;
end;
end.

2880
fwzip/FWZipTests.pas Normal file

File diff suppressed because it is too large Load Diff

713
fwzip/FWZipUtils.pas Normal file
View File

@@ -0,0 +1,713 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : FWZipUtils
// * Purpose : Набор платформозависимых методов
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2024.
// * Version : 2.0.4
// * 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.3.1.tar.gz
// http://www.base2ti.com/
//
unit FWZipUtils;
{$IFDEF FPC}
{$MODE Delphi}
{$H+}
// у FPC криво реализованы инлайны, в частности FileSizeToInt64 теряет
// значение FileSizeHi при компиляции в 32 бита, поэтому отключаем
{$IFDEF CPU32}
{$UNDEF USE_INLINE}
{$ELSE}
{$DEFINE USE_INLINE}
{$ENDIF}
{$ELSE}
{$IF COMPILERVERSION > 15.0 }
{$DEFINE USE_INLINE}
{$IFEND}
{$ENDIF}
interface
uses
{$IFDEF LINUX}
Unix, Baseunix, DateUtils, Types,
{$ELSE}
Windows,
{$ENDIF}
{$IFDEF FPC}
LConvEncoding,
{$ENDIF}
SysUtils,
FWZipConsts;
// утилитарные преобразования для отключения ворнингов под FPC
// ===========================================================================
function HiByte(W: Word): Byte; {$IFDEF USE_INLINE}inline;{$ENDIF}
function HiWord(L: DWORD): Word; {$IFDEF USE_INLINE}inline;{$ENDIF}
function PtrToUInt(Value: Pointer): NativeUInt; {$IFDEF USE_INLINE}inline;{$ENDIF}
function UIntToPtr(Value: NativeUInt): Pointer; {$IFDEF USE_INLINE}inline;{$ENDIF}
function FileSizeToInt64(FileSizeLo, FileSizeHi: DWORD): Int64; {$IFDEF USE_INLINE}inline;{$ENDIF}
function FileSizeToStr(Value: Int64): string;
// это позволит избежать сообщения об неинициализированных переменных под FPC
procedure ZeroMemory(Destination: Pointer; Length: NativeUInt); {$IFDEF USE_INLINE}inline;{$ENDIF}
// конвертация строк
// ===========================================================================
function ConvertToOemString(const Value: AnsiString): AnsiString;
function ConvertFromOemString(const Value: AnsiString): AnsiString;
function ExceptionMessage(const E: Exception): string; {$IFDEF USE_INLINE}inline;{$ENDIF}
function LongPrefixPresent(const {%H-}APath: string): Boolean; {$IFDEF USE_INLINE}inline;{$ENDIF}
function IncludeLongNamePrefix(const Value: string): string;
// работа с аттрибутами файла
// ===========================================================================
function GetDiskFreeAvailable(const AFilePath: string): Int64;
function GetFileAttributes(const AFilePath: string;
out AAttr: TFileAttributeData): Boolean;
function IsAttributesPresent(Value: TFileAttributeData): Boolean;
procedure SetNormalFileAttributes(const AFilePath: string);
procedure SetFileAttributes(const AFilePath: string; AAttr: TFileAttributeData);
// работа с путями
// ===========================================================================
function PathCanonicalize(const AFilePath: string): string;
function MakeUniqueName(const AFilePath: string): string;
function ForceDirectoriesEx(Dir: string): Boolean;
// преобразование времени
// ===========================================================================
function FileTimeToLocalFileDate(AFileTime: TFileTime): Cardinal;
function FileTimeToLocalDateTime(AFileTime: TFileTime): TDateTime;
function DateTimeToFileTime(ADateTime: TDateTime): TFileTime;
// не реализованные под Linux аналоги Windows функций
// ===========================================================================
procedure FinallyFileBuffers(AHandle: THandle);
implementation
{$IFDEF MSWINDOWS}
function PathCanonicalizeApi(lpszDes, lpszSrc: PChar): BOOL; stdcall; external 'shlwapi.dll'
name {$IFDEF UNICODE}'PathCanonicalizeW'{$ELSE}'PathCanonicalizeA'{$ENDIF};
function PathMakeUniqueName(pszUniqueName: PWideChar; cchMax: Cardinal;
pszTemplate, pszLongPlate, pszDir: PWideChar): Boolean; stdcall; external 'shell32.dll';
{$ENDIF}
function FileSizeToInt64(FileSizeLo, FileSizeHi: DWORD): Int64;
begin
Result := FileSizeHi;
Result := Result shl 32;
Inc(Result, FileSizeLo);
end;
function HiByte(W: Word): Byte;
begin
Result := W shr 8;
end;
function HiWord(L: DWORD): Word;
begin
Result := L shr 16;
end;
procedure ZeroMemory(Destination: Pointer; Length: NativeUInt);
begin
FillChar(Destination^, Length, 0);
end;
function PtrToUInt(Value: Pointer): NativeUInt;
begin
Result := {%H-}NativeUInt(Value);
end;
function UIntToPtr(Value: NativeUInt): Pointer;
begin
Result := {%H-}Pointer(Value);
end;
{$IFDEF LINUX}
// эмуляция апи для работы с NTFS атрибутами, в частности с временем
const
NSECPERSEC = 10000000;
NSECPERMSEC = 10000;
MSECPERSEC = 1000;
SECSPERMIN = 60;
MINSPERHOUR = 60;
HOURSPERDAY = 24;
EPOCHWEEKDAY = 1; // 1 января 1601 был понедельником
DAYSPERWEEK = 7;
DAYSPERQUADRICENTENNIUM = 365 * 400 + 97;
DAYSPERNORMALQUADRENNIUM = 365 * 4 + 1;
MonthLength: array [Boolean] of array [0..11] of Integer =
((31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31),
(31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31));
function SystemTimeToFileTime(
const ATime: TSystemTime; out AFileTime: TFileTime): Boolean;
function IsLeapYear: Boolean;
begin
Result := (ATime.Year mod 400 = 0) and
(ATime.Year mod 100 <> 0) or (ATime.Year mod 4 = 0);
end;
function IsDayTooBig: Boolean;
begin
Result := ATime.Day >
MonthLength[(ATime.Month = 2) and IsLeapYear][ATime.Month - 1];
end;
var
CalcYear, CalcMonth, CalcLeapCount, CalcDay: UInt64;
begin
Result := False;
// проверка входных данных
if ATime.Millisecond > 999 then Exit;
if ATime.Second > 59 then Exit;
if ATime.Minute > 59 then Exit;
if ATime.Hour > 23 then Exit;
if (ATime.Month < 1) or (ATime.Month > 12) then Exit;
if (ATime.Day < 1) or IsDayTooBig then Exit;
if (ATime.Year < 1601) or (ATime.Year > 30827) then Exit;
// преобразование с учетом високосных годов
// если текущий месяц меньше марта, то просто отнимаем год и добавляем 12 месяцев
// это учтется в дальнейшем
CalcYear := ATime.Year;
CalcMonth := ATime.Month;
if ATime.Month < 3 then
begin
Dec(CalcYear);
Inc(CalcMonth, 12);
end;
// количество високосных годов в пределах столетия
CalcLeapCount := (3 * (CalcYear div 100) + 3) shr 2;
// количество дней с 1601 года
CalcDay :=
(36525 * CalcYear) div 100 - CalcLeapCount + // год * количество дней в столетии с коррекцией по високосным
(1959 * (CalcMonth + 1)) shr 6 + // месяц * среднее кол-во дней
ATime.Day - // день
584817; // за вычетом количества дней до 1601 года
// считаем результат
PUint64(@AFileTime)^ := ((((
CalcDay * HOURSPERDAY +
ATime.Hour) * MINSPERHOUR +
ATime.Minute) * SECSPERMIN +
ATime.Second) * MSECPERSEC +
ATime.Millisecond) * NSECPERMSEC;
Result := True;
end;
function FileTimeToSystemTime(const AFileTime: TFileTime;
out ASystemTime: TSystemTime): Boolean;
var
FullTime, CalcYear, CalcMonth, CalcLeapCount,
CalcYearDay, CalcDay, CalcSecond: Int64;
begin
Result := False;
FullTime := PInt64(@AFileTime)^;
if FullTime < 0 then Exit;
// вытаскиваем количество миллисекунд и преобразуем время в секунды
ASystemTime.Millisecond := (FullTime mod NSECPERSEC) div NSECPERMSEC;
FullTime := FullTime div NSECPERSEC;
// получаем количество секунд
CalcSecond := FullTime mod SECSPERDAY;
// считаем время дня
ASystemTime.Hour := CalcSecond div SECSPERHOUR;
CalcSecond := CalcSecond mod SECSPERHOUR;
ASystemTime.Minute := CalcSecond div SECSPERMIN;
ASystemTime.Second := CalcSecond mod SECSPERMIN;
// получаем количество дней
CalcDay := FullTime div SECSPERDAY;
// считаем день недели
ASystemTime.DayOfWeek := (EPOCHWEEKDAY + CalcDay) mod DAYSPERWEEK;
// считаем год, месяц и день месяца
CalcLeapCount :=
(3 * ((CalcDay shl 2 + 1227) div DAYSPERQUADRICENTENNIUM) + 3) shr 2;
Inc(CalcDay, 28188 + CalcLeapCount);
CalcYear := (20 * CalcDay - 2442) div (5 * DAYSPERNORMALQUADRENNIUM);
CalcYearDay := CalcDay - (CalcYear * DAYSPERNORMALQUADRENNIUM) shr 2;
CalcMonth := (CalcYearDay shl 6) div 1959;
// результат для года который начинается с марта, если залазит на следущий
// то для преобразования отнимаем 12 месяцев и увеличиваем год
ASystemTime.Month := CalcMonth - 1;
ASystemTime.Year := CalcYear + 1524;
if ASystemTime.Month > 12 then
begin
Dec(ASystemTime.Month, 12);
Inc(ASystemTime.Year);
end;
ASystemTime.Day := CalcYearDay - (1959 * CalcMonth) shr 6;
end;
// преобразование из stat.st_atime (qword) в TFileTime
function UnixDateToFileTime(Value: Int64): TFileTime;
var
SystemTime: TSystemTime;
begin
DateTimeToSystemTime(UnixToDateTime(Value), SystemTime);
SystemTimeToFileTime(SystemTime, Result);
end;
function FileTimeToUnixDate(Value: TFileTime): Int64;
var
SystemTime: TSystemTime;
begin
FileTimeToSystemTime(Value, SystemTime);
Result := DateTimeToUnix(SystemTimeToDateTime(SystemTime));
end;
{$ENDIF}
function ConvertToOemString(const Value: AnsiString): AnsiString;
begin
Result := Value;
if Result = '' then Exit;
UniqueString(Result);
{$IFDEF FPC}
Result := UTF8ToCP866(Value);
{$ELSE}
AnsiToOem(PAnsiChar(Value), PAnsiChar(Result));
{$ENDIF}
end;
function ConvertFromOemString(const Value: AnsiString): AnsiString;
begin
Result := Value;
if Result = '' then Exit;
UniqueString(Result);
{$IFDEF FPC}
Result := CP866ToUTF8(Value);
{$ELSE}
OemToAnsi(PAnsiChar(Result), PAnsiChar(Result));
{$ENDIF}
end;
function ExceptionMessage(const E: Exception): string;
begin
Result := E.ClassName + ': ' + E.Message;
end;
function LongPrefixPresent(const APath: string): Boolean;
begin
{$IFDEF MSWINDOWS}
Result := (Length(APath) >= 4) and
( (APath[1] = LongNamePrefix[1]) and
(APath[2] = LongNamePrefix[2]) and
(APath[3] = LongNamePrefix[3]) and
(APath[4] = LongNamePrefix[4]));
{$ELSE}
Result := False;
{$ENDIF}
end;
function IsLocalDrive(const Value: string): Boolean;
begin
Result := (Length(Value) > 2) and (Value[2] = ':');
end;
function IsNetworkSlashPresent(const Value: string): Boolean;
begin
Result := (Length(Value) > 2) and (Value[1] = '\') and (Value[2] = '\');
end;
function FixupFilePrefix(const Value: string): string;
begin
Result := StringReplace(Value, '/', '\', [rfReplaceAll]);
if AnsiSameText(Copy(Result, 1, 7), 'file:\\') then
begin
Delete(Result, 1, 7);
if not IsLocalDrive(Result) then
Result := '\\' + Result;
end;
end;
function IncludeLongNamePrefix(const Value: string): string;
begin
{$IFDEF MSWINDOWS}
if UseLongNamePrefix and not LongPrefixPresent(Value) and (Length(Value) > MAX_PATH) then
begin
Result := FixupFilePrefix(Value);
if IsLocalDrive(Result) then
Result := LongNamePrefix + Result
else
begin
if IsNetworkSlashPresent(Result) then
Delete(Result, 1, 2);
Result := UNCLongNamePrefix + Result;
end;
end
else
{$ENDIF}
Result := Value;
end;
function GetPresentFolder(const AFilePath: string): string;
begin
Result := AFilePath;
{$IFDEF LINUX}
while (Result <> '') and not DirectoryExists(Result) do
Result := ExtractFilePath(ExcludeTrailingPathDelimiter(Result));
if Result = '' then
Result := ExpandFileName('~');
{$ELSE}
if LongPrefixPresent(Result) then
Delete(Result, 1, 4);
Result := ExtractFileDrive(Result);
{$ENDIF}
end;
function GetDiskFreeAvailable(const AFilePath: string): Int64;
{$IFDEF MSWINDOWS}
var
FreeAvailable, TotalSpace: Int64;
{$ENDIF}
begin
{$IFDEF LINUX}
Result := DiskFree(AddDisk(GetPresentFolder(AFilePath)));
{$ELSE}
{$IFDEF FPC}
FreeAvailable := -1;
TotalSpace := -1;
{$ENDIF}
if GetDiskFreeSpaceEx(PChar(GetPresentFolder(AFilePath)), FreeAvailable, TotalSpace, nil) then
Result := FreeAvailable
else
Result := -1;
{$ENDIF}
end;
function GetFileAttributes(const AFilePath: string;
out AAttr: TFileAttributeData): Boolean;
{$IFDEF LINUX}
var
Info: Stat;
SystemFileName: RawByteString;
begin
FillChar(AAttr, SizeOf(AAttr), 0);
SystemFileName := ToSingleByteFileSystemEncodedFileName(AFilePath);
Info := default(Stat);
if (fpstat(PChar(SystemFileName), Info) < 0) or fpS_ISDIR(info.st_mode) then
Result := False
else
begin
AAttr.dwFileAttributes := FileGetAttr(SystemFileName);
Result := AAttr.dwFileAttributes <> DWORD(-1);
if Result then
begin
AAttr.ftCreationTime := UnixDateToFileTime(Info.st_ctime);
AAttr.ftLastAccessTime := UnixDateToFileTime(Info.st_atime);
AAttr.ftLastWriteTime := UnixDateToFileTime(Info.st_mtime);
AAttr.nFileSizeHigh := Info.st_size shr 32;
AAttr.nFileSizeLow := DWORD(Info.st_size);
end;
end;
{$ELSE}
begin
Result := GetFileAttributesEx(PChar(AFilePath),
GetFileExInfoStandard, @AAttr);
{$ENDIF}
end;
function IsAttributesPresent(Value: TFileAttributeData): Boolean;
begin
Result := (Value.ftCreationTime.dwLowDateTime <> 0) and
(Value.ftCreationTime.dwHighDateTime <> 0);
end;
procedure SetNormalFileAttributes(const AFilePath: string);
var
AAttr: TFileAttributeData;
begin
{$IFDEF FPC}
AAttr := Default(TFileAttributeData);
{$ENDIF}
AAttr.dwFileAttributes := $80; // FILE_ATTRIBUTE_NORMAL
SetFileAttributes(AFilePath, AAttr);
end;
procedure SetFileAttributes(const AFilePath: string; AAttr: TFileAttributeData);
{$IFDEF MSWINDOWS}
var
hFile: THandle;
{$ELSE}
var
SystemFileName: RawByteString;
t: TUTimBuf;
{$ENDIF}
begin
{$IFDEF MSWINDOWS}
Windows.SetFileAttributes(PChar(AFilePath), AAttr.dwFileAttributes);
{$ENDIF}
// проверка, есть ли аттрибуты времени?
if not IsAttributesPresent(AAttr) then Exit;
{$IFDEF LINUX}
t.actime := FileTimeToUnixDate(AAttr.ftLastAccessTime);
t.modtime:= FileTimeToUnixDate(AAttr.ftLastWriteTime);
SystemFileName := ToSingleByteFileSystemEncodedFileName(AFilePath);
fputime(PChar(SystemFileName), @t);
{$ELSE}
hFile := FileOpen(AFilePath, fmOpenWrite);
try
SetFileTime(hFile,
@AAttr.ftCreationTime,
@AAttr.ftLastAccessTime,
@AAttr.ftLastWriteTime);
finally
FileClose(hFile);
end;
{$ENDIF}
end;
{$IFDEF MSWINDOWS}
function CallPathCanonicalize(const AFilePath: string): string;
begin
Result := StringOfChar(#0, MAX_PATH);
if PathCanonicalizeApi(PChar(Result), PChar(AFilePath)) then
Result := PChar(Result)
else
Result := AFilePath;
end;
{$ENDIF}
function PathCanonicalize(const AFilePath: string): string;
begin
Result := AFilePath;
if Result = '' then Exit;
if Result[1] = '.' then
Result := IncludeTrailingPathDelimiter(GetCurrentDir) + Result;
{$IFDEF MSWINDOWS}
Result := IncludeLongNamePrefix(CallPathCanonicalize(Result));
{$ELSE}
Result := ExpandFileName(Result);
{$ENDIF}
end;
function MakeUniqueName(const AFilePath: string): string;
{$IFDEF LINUX}
var
FilePath, FileName, FileExt, NewFileName: string;
I: Integer;
begin
Result := AFilePath;
if not FileExists(Result) then Exit;
FilePath := ExtractFilePath(AFilePath);
FileName := ExtractFileName(AFilePath);
FileExt := ExtractFileExt(FileName);
FileName := ChangeFileExt(FileName, '');
I := 1;
repeat
Inc(I);
NewFileName := FileName + ' (' + IntToStr(I) + ')' + FileExt;
until not FileExists(FilePath + NewFileName);
Result := FilePath + NewFileName;
{$ELSE}
{$IFDEF UNICODE}
var
FilePath, FileName: string;
begin
Result := AFilePath;
if not FileExists(Result) then Exit;
FilePath := ExtractFilePath(AFilePath);
FileName := ExtractFileName(AFilePath);
SetLength(Result, MAX_PATH);
if PathMakeUniqueName(PWideChar(Result), MAX_PATH,
nil, PWideChar(FileName), PWideChar(FilePath)) then
Result := PWideChar(Result);
{$ELSE}
var
UnicodeResult, FilePath, FileName: WideString;
begin
Result := AFilePath;
if not FileExists(Result) then Exit;
FilePath := WideString(ExtractFilePath(AFilePath));
FileName := WideString(ExtractFileName(AFilePath));
{$IFDEF FPC}
UnicodeResult := '';
{$ENDIF}
SetLength(UnicodeResult, MAX_PATH);
if PathMakeUniqueName(PWideChar(UnicodeResult), MAX_PATH,
nil, PWideChar(FileName), PWideChar(FilePath)) then
Result := AnsiString(PWideChar(UnicodeResult));
{$ENDIF}
{$ENDIF}
end;
function ForceDirectoriesEx(Dir: string): Boolean;
// Обход ошибки ForceDirectories в случае использования префикса для
// поддержки длинных имен. Проверить ошибку можно вот таким кодом:
//
// S := '\\?\w:\test\'; // этой папки быть не должно!
// ForceDirectories(S); // с префиксом она не создастся
//
// Глюк заключается в том что при вызове DirectoryExists на строке "\\?\w:"
// функция GetFileAttributes возвращает INVALID_FILE_ATTRIBUTES,
// требуя чтобы для корня был указан слэш в конце в случае использования префикса,
// причем про эту особенность в MSDN нигде не написано.
//
// Соответсвтенно т.к. это будет второй рекурсивный вызов,
// он вернет первому False и в первом не выполнится CreateDir
{$IFDEF MSWINDOWS}
function InternalForce(Dir: string): Boolean;
var
PreviosDir: string;
begin
Result := Dir <> '';
if not Result or DirectoryExists(Dir) then
Exit;
Dir := ExcludeTrailingPathDelimiter(Dir);
PreviosDir := ExtractFilePath(Dir);
if PreviosDir = Dir then
Result := True
else
Result := InternalForce(PreviosDir) and CreateDir(Dir);
end;
{$ENDIF}
begin
{$IFDEF MSWINDOWS}
if LongPrefixPresent(Dir) then
Result := InternalForce(Dir)
else
{$ENDIF}
Result := ForceDirectories(Dir);
end;
function FileTimeToLocalFileDate(AFileTime: TFileTime): Cardinal;
{$IFDEF LINUX}
var
SystemTime: TSystemTime;
{$ENDIF}
begin
{$IFDEF LINUX}
DateTimeToSystemTime(FileTimeToLocalDateTime(AFileTime), SystemTime);
if (SystemTime.Year < 1980) or (SystemTime.Year > 2107) then
Result := 0
else
with SystemTime do
begin
LongRec(Result).Lo := (Second shr 1) or (Minute shl 5) or (Hour shl 11);
LongRec(Result).Hi := Day or (Month shl 5) or ((Year - 1980) shl 9);
end;
{$ELSE}
Result := DateTimeToFileDate(FileTimeToLocalDateTime(AFileTime));
{$ENDIF}
end;
function FileTimeToLocalDateTime(AFileTime: TFileTime): TDateTime;
var
{$IFDEF LINUX}
UnixTime: Int64;
{$ELSE}
SystemTime: TSystemTime;
{$ENDIF}
begin
{$IFDEF LINUX}
UnixTime := FileTimeToUnixDate(AFileTime);
Result := UnixToDateTime(UnixTime, False);
{$ELSE}
// Rouse_ 25.10.2013
// Правка небольшой ошибки замеченой Владиславом Нечепоренко
//FileTimeToSystemTime(CurrentItem.Attributes.ftLastWriteTime, SystemTyme);
FileTimeToLocalFileTime(AFileTime, AFileTime);
{$IFDEF FPC}
SystemTime := Default(TSystemTime);
{$ENDIF}
FileTimeToSystemTime(AFileTime, SystemTime);
Result := SystemTimeToDateTime(SystemTime);
{$ENDIF}
end;
function DateTimeToFileTime(ADateTime: TDateTime): TFileTime;
{$IFDEF MSWINDOWS}
var
SystemTime: TSystemTime;
begin
{$IFDEF FPC}
Result := Default(TFileTime);
{$ENDIF}
DateTimeToSystemTime(ADateTime, SystemTime);
SystemTimeToFileTime(SystemTime, Result);
LocalFileTimeToFileTime(Result, Result);
{$ELSE}
begin
Result := UnixDateToFileTime(DateTimeToUnix(ADateTime, False));
{$ENDIF}
end;
function FileSizeToStr(Value: Int64): string;
begin
if Value < 1024 then
begin
Result := Format('%d байт', [Value]);
Exit;
end;
Value := Value div 1024;
if Value < 1024 then
begin
Result := Format('%d килобайт', [Value]);
Exit;
end;
Value := Value div 1024;
if Value < 1024 then
begin
Result := Format('%d мегабайт', [Value]);
Exit;
end;
Value := Value div 1024;
if Value < 1024 then
begin
Result := Format('%d гигабайт', [Value]);
Exit;
end;
// ну а чем бог не шутит? :)
Value := Value div 1024;
Result := Format('%d терабайт', [Value]);
end;
procedure FinallyFileBuffers(AHandle: THandle);
begin
{$IFDEF MSWINDOWS}
FlushFileBuffers(AHandle);
{$ELSE}
FileFlush(AHandle);
{$ENDIF}
end;
end.

2058
fwzip/FWZipWriter.pas Normal file

File diff suppressed because it is too large Load Diff

814
fwzip/FWZipZLib.pas Normal file
View File

@@ -0,0 +1,814 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : FWZipZLib
// * Purpose : Базовые стримы сжатия и распаковки.
// * : Вынесено из ZLibEx в отдельный модуль
// * : для совместимости со старыми версиями Delphi
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2024.
// * Version : 2.0.4
// * 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/
//
{*************************************************************************************************
* ZLibEx.pas *
* *
* copyright (c) 2000-2013 base2 technologies *
* copyright (c) 1995-2002 Borland Software Corporation *
* *
*************************************************************************************************}
unit FWZipZLib;
{$IFDEF FPC}
{$MODE Delphi}
{$H+}
{$ENDIF}
interface
{$I fwzip.inc}
uses
Classes,
SysUtils,
{$IFDEF USE_ZLIB_FPC}
FWZipZLibFPC
{$ELSE}
{$IFDEF USE_ZLIB_EX}
ZLibExApi
{$ELSE}
{$IFDEF USE_ZLIB_DLL}
ZLib_external
{$ELSE}
ZLib
{$ENDIF}
{$ENDIF}
{$ENDIF};
type
TStreamPos = Int64;
TCompressionLevel = (
clNone,
clFastest,
clDefault,
clMax,
clLevel1,
clLevel2,
clLevel3,
clLevel4,
clLevel5,
clLevel6,
clLevel7,
clLevel8,
clLevel9
);
TZStrategy = (
zsDefault,
zsFiltered,
zsHuffman,
zsRLE,
zsFixed
);
TZError = (
zeError,
zeStreamError,
zeDataError,
zeMemoryError,
zeBufferError,
zeVersionError
);
TZFlush = (
zfNoFlush,
zfPartialFlush,
zfSyncFlush,
zfFullFlush,
zfFinish,
zfBlock,
zfTrees
);
const
ZLevels: Array [TCompressionLevel] of Integer = (
Z_NO_COMPRESSION, // zcNone
Z_BEST_SPEED, // zcFastest
Z_DEFAULT_COMPRESSION, // zcDefault
Z_BEST_COMPRESSION, // zcMax
1, // zcLevel1
2, // zcLevel2
3, // zcLevel3
4, // zcLevel4
5, // zcLevel5
6, // zcLevel6
7, // zcLevel7
8, // zcLevel8
9 // zcLevel9
);
{** compression methods ***********************************************************************}
Z_DEFLATED = 8;
{** compression levels ************************************************************************}
Z_NO_COMPRESSION = 0;
Z_BEST_SPEED = 1;
Z_BEST_COMPRESSION = 9;
Z_DEFAULT_COMPRESSION = (-1);
{** flush constants ***************************************************************************}
Z_NO_FLUSH = 0;
Z_PARTIAL_FLUSH = 1;
Z_SYNC_FLUSH = 2;
Z_FULL_FLUSH = 3;
Z_FINISH = 4;
Z_BLOCK = 5;
Z_TREES = 6;
{** compression strategies ********************************************************************}
Z_FILTERED = 1;
Z_HUFFMAN_ONLY = 2;
Z_RLE = 3;
Z_FIXED = 4;
Z_DEFAULT_STRATEGY = 0;
ZStrategies: Array [TZStrategy] of Integer = (
Z_DEFAULT_STRATEGY, // zsDefault
Z_FILTERED, // zsFiltered
Z_HUFFMAN_ONLY, // zsHuffman
Z_RLE, // zsRLE
Z_FIXED // zsFixed
);
ZErrors: Array [TZError] of Integer = (
Z_ERRNO, // zeError
Z_STREAM_ERROR, // zeStreamError
Z_DATA_ERROR, // zeDataError
Z_MEM_ERROR, // zeMemoryError
Z_BUF_ERROR, // zeBufferError
Z_VERSION_ERROR // zeVersionError
);
ZFlushes: Array [TZFlush] of Integer = (
Z_NO_FLUSH, // zfNoFlush
Z_PARTIAL_FLUSH, // zfPartialFlush
Z_SYNC_FLUSH, // zfSyncFlush
Z_FULL_FLUSH, // zfFullFlush
Z_FINISH, // zfFinish
Z_BLOCK, // zfBlock
Z_TREES // zfTrees
);
{** return code messages **********************************************************************}
_z_errmsg: Array [0..9] of String = (
'Need dictionary', // Z_NEED_DICT (2)
'Stream end', // Z_STREAM_END (1)
'OK', // Z_OK (0)
'File error', // Z_ERRNO (-1)
'Stream error', // Z_STREAM_ERROR (-2)
'Data error', // Z_DATA_ERROR (-3)
'Insufficient memory', // Z_MEM_ERROR (-4)
'Buffer error', // Z_BUF_ERROR (-5)
'Incompatible version', // Z_VERSION_ERROR (-6)
''
);
type
{** TCustomZStream ****************************************************************************}
TCustomZStream = class(TStream)
private
FStream : TStream;
FStreamPos : TStreamPos;
FOnProgress: TNotifyEvent;
FZStream : TZStreamRec;
FBuffer : Array [Word] of Byte;
function GetStreamPosition: TStreamPos;
procedure SetStreamPosition(value: TStreamPos);
protected
function GetSize: Int64; override;
function StreamRead(var buffer; count: Longint): Longint;
function StreamWrite(const {%H-}buffer; count: Longint): Longint;
function StreamSeek(offset: Longint; origin: Word): Longint;
procedure StreamReadBuffer(var buffer; count: Longint);
procedure StreamWriteBuffer(const {%H-}buffer; count: Longint);
procedure DoProgress; dynamic;
property StreamPosition: TStreamPos read GetStreamPosition write SetStreamPosition;
property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;
public
constructor Create(stream: TStream);
end;
{** TZCompressionStream ***********************************************************************}
TZCompressionStream = class(TCustomZStream)
private
function GetCompressionRate: Single;
public
constructor Create(dest: TStream;
compressionLevel: TCompressionLevel = clDefault); overload;
constructor Create(dest: TStream; compressionLevel: TCompressionLevel;
windowBits, memLevel: Integer; strategy: TZStrategy); overload;
destructor Destroy; override;
function Read(var {%H-}buffer; {%H-}count: Longint): Longint; override;
function Write(const buffer; count: Longint): Longint; override;
function Seek(offset: Longint; origin: Word): Longint; override;
property CompressionRate: Single read GetCompressionRate;
property OnProgress;
end;
{** TZDecompressionStream *********************************************************************}
TZDecompressionStream = class(TCustomZStream)
private
FSource: TStream;
public
constructor Create(source: TStream); overload;
constructor Create(source: TStream; windowBits: Integer); overload;
constructor Create(source: TStream; windowBits: Integer; StreamOwned: Boolean); overload;
destructor Destroy; override;
function Read(var buffer; count: Longint): Longint; override;
function Write(const {%H-}buffer; {%H-}count: Longint): Longint; override;
function Seek(offset: Longint; origin: Word): Longint; override;
property OnProgress;
end;
type
EZLibErrorClass = class of EZlibError;
EZLibError = class(Exception)
private
FErrorCode: Integer;
public
constructor Create(code: Integer; const {%H-}dummy: String = ''); overload;
constructor Create(error: TZError; const dummy: String = ''); overload;
property ErrorCode: Integer read FErrorCode write FErrorCode;
end;
EZCompressionError = class(EZLibError);
EZDecompressionError = class(EZLibError);
{$IFDEF USE_OLDEST_METHODS}
procedure ZCompress(const inBuffer: Pointer; inSize: Integer;
out outBuffer: Pointer; out outSize: Integer;
level: TCompressionLevel = clDefault);
procedure ZDecompress(const inBuffer: Pointer; inSize: Integer;
out outBuffer: Pointer; out outSize: Integer; outEstimate: Integer = 0);
{$ENDIF}
implementation
const
SZInvalid = 'Invalid ZStream operation!';
function ZCompressCheck(code: Integer; raiseBufferError: Boolean = True): Integer;
begin
result := code;
if code < 0 then
begin
if (code <> Z_BUF_ERROR) or raiseBufferError then
raise EZCompressionError.Create(code);
end;
end;
function ZDecompressCheck(code: Integer; raiseBufferError: Boolean = True): Integer;
begin
Result := code;
if code < 0 then
begin
if (code <> Z_BUF_ERROR) or raiseBufferError then
begin
raise EZDecompressionError.Create(code);
end;
end;
end;
{** zlib deflate routines ***********************************************************************}
function ZDeflateInit(var stream: TZStreamRec;
level: TCompressionLevel): Integer;
begin
result := deflateInit_(stream, ZLevels[level], ZLIB_VERSION,
SizeOf(TZStreamRec));
end;
function ZDeflateInit2(var stream: TZStreamRec;
level: TCompressionLevel; windowBits, memLevel: Integer;
strategy: TZStrategy): Integer;
begin
{$IFDEF OLDEST_ZLIB}
result := ZDeflateInit(stream, level);
{$ELSE}
result := deflateInit2_(stream, ZLevels[level], Z_DEFLATED, windowBits,
memLevel, ZStrategies[strategy], ZLIB_VERSION, SizeOf(TZStreamRec));
{$ENDIF}
end;
function ZDeflate(var stream: TZStreamRec; flush: TZFlush): Integer;
begin
result := deflate(stream, ZFlushes[flush]);
end;
function ZDeflateEnd(var stream: TZStreamRec): Integer;
begin
result := deflateEnd(stream);
end;
{** zlib inflate routines ***********************************************************************}
function ZInflateInit(var stream: TZStreamRec): Integer;
begin
result := inflateInit_(stream, ZLIB_VERSION, SizeOf(TZStreamRec));
end;
function ZInflateInit2(var stream: TZStreamRec;
windowBits: Integer): Integer;
begin
{$IFDEF OLDEST_ZLIB}
result := ZInflateInit(stream);
{$ELSE}
result := inflateInit2_(stream, windowBits, ZLIB_VERSION,
SizeOf(TZStreamRec));
{$ENDIF}
end;
function ZInflate(var stream: TZStreamRec; flush: TZFlush): Integer;
begin
result := inflate(stream, ZFlushes[flush]);
end;
function ZInflateEnd(var stream: TZStreamRec): Integer;
begin
result := inflateEnd(stream);
end;
function ZInflateReset(var stream: TZStreamRec): Integer;
begin
result := inflateReset(stream);
end;
{** EZLibError **********************************************************************************}
constructor EZLibError.Create(code: Integer; const dummy: String);
begin
inherited Create(_z_errmsg[2 - code]);
FErrorCode := code;
end;
constructor EZLibError.Create(error: TZError; const dummy: String);
begin
Create(ZErrors[error], dummy);
end;
{** buffer routines *****************************************************************************}
{$IFDEF USE_OLDEST_METHODS}
procedure ZCompress(const inBuffer: Pointer; inSize: Integer;
out outBuffer: Pointer; out outSize: Integer;
level: TCompressionLevel);
const
delta = 256;
var
zstream: TZStreamRec;
begin
zstream := Default(TZStreamRec);
outSize := ((inSize + (inSize div 10) + 12) + 255) and not 255;
GetMem(outBuffer, outSize);
try
zstream.next_in := inBuffer;
zstream.avail_in := inSize;
zstream.next_out := outBuffer;
zstream.avail_out := outSize;
ZCompressCheck(ZDeflateInit(zstream, level));
try
while ZCompressCheck(deflate(zstream, Z_FINISH), False) <> Z_STREAM_END do
begin
Inc(outSize, delta);
ReallocMem(outBuffer, outSize);
{$IF defined(FPC) and not defined(USE_ZLIB_FPC)}
zstream.next_out := pBytef(outBuffer) + zstream.total_out;
{$ELSE}
zstream.next_out := PByte(outBuffer) + zstream.total_out;
{$ENDIF}
zstream.avail_out := delta;
end;
finally
ZCompressCheck(deflateEnd(zstream));
end;
ReallocMem(outBuffer, zstream.total_out);
outSize := zstream.total_out;
except
FreeMem(outBuffer);
raise;
end;
end;
procedure ZDecompress(const inBuffer: Pointer; inSize: Integer;
out outBuffer: Pointer; out outSize: Integer; outEstimate: Integer);
var
zstream: TZStreamRec;
delta: Integer;
begin
zstream := Default(TZStreamRec);
delta := (inSize + 255) and not 255;
if outEstimate = 0 then outSize := delta
else outSize := outEstimate;
GetMem(outBuffer, outSize);
try
zstream.next_in := inBuffer;
zstream.avail_in := inSize;
zstream.next_out := outBuffer;
zstream.avail_out := outSize;
ZDecompressCheck(ZInflateInit(zstream));
try
while ZDecompressCheck(inflate(zstream, Z_NO_FLUSH), False) <> Z_STREAM_END do
begin
Inc(outSize, delta);
ReallocMem(outBuffer, outSize);
{$IF defined(FPC) and not defined(USE_ZLIB_FPC)}
zstream.next_out := pBytef(outBuffer) + zstream.total_out;
{$ELSE}
zstream.next_out := PByte(outBuffer) + zstream.total_out;
{$ENDIF}
zstream.avail_out := delta;
end;
finally
ZDecompressCheck(inflateEnd(zstream));
end;
ReallocMem(outBuffer, zstream.total_out);
outSize := zstream.total_out;
except
FreeMem(outBuffer);
raise;
end;
end;
{$ENDIF}
{** TCustomZStream ******************************************************************************}
constructor TCustomZStream.Create(stream: TStream);
begin
inherited Create;
FStream := stream;
FStreamPos := stream.Position;
{$IFDEF OLDEST_ZLIB}
FZStream.zalloc := zlibAllocMem;
FZStream.zfree := zlibFreeMem;
{$ENDIF}
end;
function TCustomZStream.StreamRead(var buffer; count: Longint): Longint;
begin
if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
result := FStream.Read(buffer,count);
FStreamPos := FStreamPos + result;
end;
function TCustomZStream.StreamWrite(const buffer; count: Longint): Longint;
begin
if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
result := FStream.Write(buffer,count);
FStreamPos := FStreamPos + result;
end;
function TCustomZStream.StreamSeek(offset: Longint; origin: Word): Longint;
begin
if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
result := FStream.Seek(offset,origin);
FStreamPos := FStream.Position;
end;
procedure TCustomZStream.StreamReadBuffer(var buffer; count: Longint);
begin
if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
FStream.ReadBuffer(buffer,count);
FStreamPos := FStreamPos + count;
end;
procedure TCustomZStream.StreamWriteBuffer(const buffer; count: Longint);
begin
if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
FStream.WriteBuffer(buffer,count);
FStreamPos := FStreamPos + count;
end;
procedure TCustomZStream.DoProgress;
begin
if Assigned(FOnProgress) then FOnProgress(Self);
end;
function TCustomZStream.GetSize: Int64;
begin
// Rouse_ 12.11.2021
// Фиксим правки в методе TStream.CopyFrom в Delphi 11 (Alexandria)
Result := -1;
end;
function TCustomZStream.GetStreamPosition: TStreamPos;
begin
result := FStream.Position;
end;
procedure TCustomZStream.SetStreamPosition(value: TStreamPos);
begin
FStream.Position := value;
FStreamPos := FStream.Position;
end;
{** TZCompressionStream *************************************************************************}
constructor TZCompressionStream.Create(dest: TStream;
compressionLevel: TCompressionLevel);
begin
inherited Create(dest);
FZStream.next_out := @FBuffer;
FZStream.avail_out := SizeOf(FBuffer);
ZCompressCheck(ZDeflateInit(FZStream, compressionLevel));
end;
constructor TZCompressionStream.Create(dest: TStream;
compressionLevel: TCompressionLevel; windowBits, memLevel: Integer;
strategy: TZStrategy);
begin
{$IFDEF USE_AUTOGENERATED_ZLIB_HEADER}
Create(dest, compressionLevel);
{$ELSE}
inherited Create(dest);
FZStream.next_out := @FBuffer;
FZStream.avail_out := SizeOf(FBuffer);
ZCompressCheck(ZDeflateInit2(FZStream, compressionLevel, windowBits,
memLevel, strategy));
{$ENDIF}
end;
destructor TZCompressionStream.Destroy;
begin
FZStream.next_in := Nil;
FZStream.avail_in := 0;
try
while ZCompressCheck(ZDeflate(FZStream, zfFinish), False) <> Z_STREAM_END do
begin
StreamWriteBuffer(FBuffer, SizeOf(FBuffer) - FZStream.avail_out);
FZStream.next_out := @FBuffer;
FZStream.avail_out := SizeOf(FBuffer);
end;
if Integer(FZStream.avail_out) < Length(FBuffer) then
FStream.WriteBuffer(FBuffer, Length(FBuffer) - Integer(FZStream.avail_out));
finally
ZDeflateEnd(FZStream);
end;
inherited Destroy;
end;
function TZCompressionStream.{%H-}Read(var buffer; count: Longint): Longint;
begin
raise EZCompressionError.Create(SZInvalid);
end;
function TZCompressionStream.Write(const buffer; count: Longint): Longint;
var
writeCount: Longint;
begin
result := count;
FZStream.next_in := @buffer;
FZStream.avail_in := count;
while FZStream.avail_in > 0 do
begin
ZCompressCheck(ZDeflate(FZStream, zfNoFlush), False);
if FZStream.avail_out = 0 then
begin
writeCount := StreamWrite(FBuffer,SizeOf(FBuffer));
if writeCount = SizeOf(FBuffer) then
begin
FZStream.next_out := @FBuffer;
FZStream.avail_out := SizeOf(FBuffer);
DoProgress;
end
else
begin
StreamPosition := StreamPosition - writeCount;
result := Cardinal(count) - Cardinal(FZStream.avail_in);
FZStream.avail_in := 0;
end;
end;
end;
end;
function TZCompressionStream.Seek(offset: Longint; origin: Word): Longint;
begin
if (offset = 0) and (origin = soFromCurrent) then
begin
result := FZStream.total_in;
end
else raise EZCompressionError.Create(SZInvalid);
end;
function TZCompressionStream.GetCompressionRate: Single;
begin
if FZStream.total_in = 0 then result := 0
else result := (1.0 - (FZStream.total_out / FZStream.total_in)) * 100.0;
end;
{** TZDecompressionStream ***********************************************************************}
constructor TZDecompressionStream.Create(source: TStream);
begin
inherited Create(source);
FZStream.next_in := @FBuffer;
FZStream.avail_in := 0;
ZDecompressCheck(ZInflateInit(FZStream));
end;
constructor TZDecompressionStream.Create(source: TStream;
windowBits: Integer);
begin
{$IFDEF USE_AUTOGENERATED_ZLIB_HEADER}
Create(source);
{$ELSE}
inherited Create(source);
FZStream.next_in := @FBuffer;
FZStream.avail_in := 0;
ZDecompressCheck(ZInflateInit2(FZStream, windowBits));
{$ENDIF}
end;
constructor TZDecompressionStream.Create(source: TStream; windowBits: Integer;
StreamOwned: Boolean);
begin
if StreamOwned then
FSource := source;
Create(source, windowBits);
end;
destructor TZDecompressionStream.Destroy;
begin
ZInflateEnd(FZStream);
FSource.Free;
inherited Destroy;
end;
function TZDecompressionStream.Read(var buffer; count: Longint): Longint;
var
zresult: Integer;
begin
FZStream.next_out := @buffer;
FZStream.avail_out := count;
zresult := Z_OK;
while (FZStream.avail_out > 0) and (zresult <> Z_STREAM_END) do
begin
if FZStream.avail_in = 0 then
begin
FZStream.avail_in := StreamRead(FBuffer,SizeOf(FBuffer));
if FZStream.avail_in = 0 then
begin
result := Cardinal(count) - Cardinal(FZStream.avail_out);
Exit;
end;
FZStream.next_in := @FBuffer;
DoProgress;
end;
zresult := ZDecompressCheck(ZInflate(FZStream, zfNoFlush));
end;
if (zresult = Z_STREAM_END) and (FZStream.avail_in > 0) then
begin
StreamPosition := StreamPosition - FZStream.avail_in;
FZStream.avail_in := 0;
end;
result := Cardinal(count) - Cardinal(FZStream.avail_out);
end;
function TZDecompressionStream.{%H-}Write(const Buffer; Count: Longint): Longint;
begin
raise EZDecompressionError.Create(SZInvalid);
end;
function TZDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
var
buf: Array [0..8191] of Byte;
i : Integer;
begin
if (offset = 0) and (origin = soFromBeginning) then
begin
ZDecompressCheck(ZInflateReset(FZStream));
FZStream.next_in := @FBuffer;
FZStream.avail_in := 0;
StreamPosition := 0;
end
else if ((offset >= 0) and (origin = soFromCurrent)) or
(((Cardinal(offset) - Cardinal(FZStream.total_out)) > 0) and
(origin = soFromBeginning)) then
begin
if origin = soFromBeginning then Dec(offset, FZStream.total_out);
if offset > 0 then
begin
for i := 1 to offset div SizeOf(buf) do ReadBuffer(buf{%H-}, SizeOf(buf));
ReadBuffer(buf, offset mod SizeOf(buf));
end;
end
else if (offset = 0) and (origin = soFromEnd) then
begin
while Read(buf, SizeOf(buf)) > 0 do ;
end
else raise EZDecompressionError.Create(SZInvalid);
result := FZStream.total_out;
end;
end.

Some files were not shown because too many files have changed in this diff Show More