📄 unzip4.pas
字号:
Unit Unzip4;
{ ----------------------------------------------------------------- }
{ unzip.c -- IO on .zip files using zlib
Version 0.15 beta, Mar 19th, 1998,
unzip.h -- IO for uncompress .zip files using zlib
Version 0.15 beta, Mar 19th, 1998,
Copyright (C) 1998 Gilles Vollant <info@winimage.com>
http://www.winimage.com/zLibDll/zip.htm
This unzip package allow extract file from .ZIP file, compatible
with PKZip 2.04g, WinZip, InfoZip tools and compatible.
Encryption and multi volume ZipFile (span) are not supported.
Old compressions used by old PKZip 1.x are not supported
Pascal tranlastion
Copyright (C) 2000 by Jacques Nomssi Nzali
For conditions of distribution and use, see copyright notice in readme.txt }
interface
{$ifdef WIN32}
{$define Delphi}
{$endif}
uses
zutil4,
zLib1104,
ziputils4;
const
UNZ_OK = (0);
UNZ_END_OF_LIST_OF_FILE = (-100);
UNZ_ERRNO = (Z_ERRNO);
UNZ_EOF = (0);
UNZ_PARAMERROR = (-102);
UNZ_BADZIPFILE = (-103);
UNZ_INTERNALERROR = (-104);
UNZ_CRCERROR = (-105);
(*
{ tm_unz contain date/time info }
type
tm_unz = record
tm_sec : uInt; { seconds after the minute - [0,59] }
tm_min : uInt; { minutes after the hour - [0,59] }
tm_hour : uInt; { hours since midnight - [0,23] }
tm_mday : uInt; { day of the month - [1,31] }
tm_mon : uInt; { months since January - [0,11] }
tm_year : uInt; { years - [1980..2044] }
end;
*)
{ unz_global_info structure contain global data about the ZIPfile
These data comes from the end of central dir }
type
unz_global_info = record
number_entry : uLong; { total number of entries in
the central dir on this disk }
size_comment : uLong; { size of the global comment of the zipfile }
end;
{ unz_file_info contain information about a file in the zipfile }
type
unz_file_info = record
version : uLong; { version made by 2 bytes }
version_needed : uLong; { version needed to extract 2 bytes }
flag : uLong; { general purpose bit flag 2 bytes }
compression_method : uLong; { compression method 2 bytes }
dosDate : uLong; { last mod file date in Dos fmt 4 bytes }
crc : uLong; { crc-32 4 bytes }
compressed_size : uLong; { compressed size 4 bytes }
uncompressed_size : uLong; { uncompressed size 4 bytes }
size_filename : uLong; { filename length 2 bytes }
size_file_extra : uLong; { extra field length 2 bytes }
size_file_comment : uLong; { file comment length 2 bytes }
disk_num_start : uLong; { disk number start 2 bytes }
internal_fa : uLong; { internal file attributes 2 bytes }
external_fa : uLong; { external file attributes 4 bytes }
tmu_date : tm_unz;
end;
unz_file_info_ptr = ^unz_file_info;
function unzStringFileNameCompare(const fileName1 : PChar;
const fileName2 : PChar;
iCaseSensitivity : int) : int;
{ Compare two filename (fileName1,fileName2).
If iCaseSenisivity = 1 (1=true),
comparision is case sensitive (like strcmp)
If iCaseSenisivity = 2 (0=false),
comparision is not case sensitive (like strcmpi or strcasecmp)
If iCaseSenisivity = 0, case sensitivity is defaut of your
operating system like 1 on Unix, 2 on Windows)
}
function unzOpen (const path : PChar) : unzFile;
{ Open a Zip file. path contain the full pathname (by example,
on a Windows NT computer "c:\zlib\zlib111.zip" or on an Unix computer
"zlib/zlib111.zip".
If the zipfile cannot be opened (file don't exist or in not valid), the
return value is NIL.
Else, the return value is a unzFile Handle, usable with other function
of this unzip package.
}
function unzClose (afile : unzFile) : int;
{ Close a ZipFile opened with unzipOpen.
If there are files inside the .Zip opened with unzOpenCurrentFile()
(see later), these files MUST be closed with unzipCloseCurrentFile()
before a call unzipClose.
return UNZ_OK if there is no problem. }
function unzGetGlobalInfo (afile : unzFile;
var pglobal_info : unz_global_info) : int;
{ Write info about the ZipFile in the *pglobal_info structure.
No preparation of the structure is needed
return UNZ_OK if there is no problem. }
function unzGetGlobalComment (afile : unzFile;
szComment : PChar;
uSizeBuf : uLong) : int;
{ Get the global comment string of the ZipFile, in the szComment buffer.
uSizeBuf is the size of the szComment buffer.
return the number of byte copied or an error code <0 }
{***************************************************************************}
{ Unzip package allow you browse the directory of the zipfile }
function unzGoToFirstFile(afile : unzFile) : int;
{ Set the current file of the zipfile to the first file.
return UNZ_OK if there is no problem }
function unzGoToNextFile(afile : unzFile) : int;
{ Set the current file of the zipfile to the next file.
return UNZ_OK if there is no problem
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. }
function unzLocateFile(afile : unzFile;
const szFileName : PChar;
iCaseSensitivity : int) : int; { ZEXPORT }
{ Try locate the file szFileName in the zipfile.
For the iCaseSensitivity signification, see unzStringFileNameCompare
1=true 2=false
return value :
UNZ_OK if the file is found. It becomes the current file.
UNZ_END_OF_LIST_OF_FILE if the file is not found }
function unzGetCurrentFileInfo(afile : unzFile;
pfile_info : unz_file_info_ptr;
szFileName : PChar;
fileNameBufferSize : uLong;
extraField : voidp;
extraFieldBufferSize : uLong;
szComment : PChar;
commentBufferSize : uLong) : int; { ZEXPORT }
{ Get Info about the current file
if pfile_info<>NIL, the pfile_info^ structure will contain somes
info about the current file
if szFileName<>NIL, the filemane string will be copied in szFileName
(fileNameBufferSize is the size of the buffer)
if extraField<>NIL, the extra field information will be copied in
extraField (extraFieldBufferSize is the size of the buffer).
This is the Central-header version of the extra field
if szComment<>NIL, the comment string of the file will be copied in
szComment (commentBufferSize is the size of the buffer) }
{***************************************************************************}
{* for reading the content of the current zipfile, you can open it, read data
from it, and close it (you can close it before reading all the file) }
function unzOpenCurrentFile(afile : unzFile) : int; { ZEXPORT }
{ Open for reading data the current file in the zipfile.
If there is no error, the return value is UNZ_OK. }
function unzCloseCurrentFile(afile : unzFile) : int; { ZEXPORT }
{ Close the file in zip opened with unzOpenCurrentFile
Return UNZ_CRCERROR if all the file was read but the CRC is not good }
function unzReadCurrentFile(afile : unzFile;
buf : voidp;
len : unsigned) : int; { ZEXPORT }
{ Read bytes from the current file (opened by unzOpenCurrentFile)
buf contain buffer where data must be copied
len the size of buf.
return the number of byte copied if somes bytes are copied
return 0 if the end of file was reached
return <0 with error code if there is an error
(UNZ_ERRNO for IO error, or zLib error for uncompress error) }
function unztell(afile : unzFile) : z_off_t;
{ Give the current position in uncompressed data }
function unzeof(afile : unzFile) : int;
{ return 1 if the end of file was reached, 0 elsewhere
! checks for valid params }
function unzGetLocalExtrafield (afile : unzFile;
buf : voidp;
len : unsigned) : int;
{ Read extra field from the current file (opened by unzOpenCurrentFile)
This is the local-header version of the extra field (sometimes, there is
more info in the local-header version than in the central-header)
if buf=NIL, it return the size of the local extra field
if buf<>NIL, len is the size of the buffer, the extra header is copied in
buf.
the return value is the number of bytes copied in buf, or (if <0)
the error code }
{ ----------------------------------------------------------------- }
implementation
uses
SysUtils, crc4,
zInflate4; //
{$ifdef unix and not def (CASESENSITIVITYDEFAULT_YES) and \
!defined(CASESENSITIVITYDEFAULT_NO)}
{$define CASESENSITIVITYDEFAULT_NO}
{$endif}
const
UNZ_BUFSIZE = Z_BUFSIZE;
UNZ_MAXFILENAMEINZIP = Z_MAXFILENAMEINZIP;
const
unz_copyright : PChar = ' unzip 0.15 Copyright 1998 Gilles Vollant ';
{ unz_file_info_internal contain internal info about a file in zipfile }
type
unz_file_info_internal = record
offset_curfile : uLong; { relative offset of local header 4 bytes }
end;
unz_file_info_internal_ptr = ^unz_file_info_internal;
{ file_in_zip_read_info_s contain internal information about a file
in zipfile, when reading and decompress it }
type
file_in_zip_read_info_s = record
read_buffer : PChar; { internal buffer for compressed data }
stream : z_stream; { zLib stream structure for inflate }
pos_in_zipfile : uLong; { position in byte on the zipfile, for fseek}
stream_initialised : boolean; { flag set if stream structure is initialised}
offset_local_extrafield : uLong;{ offset of the local extra field }
size_local_extrafield : uInt;{ size of the local extra field }
pos_local_extrafield : uLong; { position in the local extra field in read}
crc32 : uLong; { crc32 of all data uncompressed }
crc32_wait : uLong; { crc32 we must obtain after decompress all }
rest_read_compressed : uLong; { number of byte to be decompressed }
rest_read_uncompressed : uLong;{number of byte to be obtained after decomp}
afile : FILEptr; { io structure of the zipfile }
compression_method : uLong; { compression method (0=store) }
byte_before_the_zipfile : uLong;{ byte before the zipfile, (>0 for sfx) }
end;
file_in_zip_read_info_s_ptr = ^file_in_zip_read_info_s;
{ unz_s contain internal information about the zipfile }
type
unz_s = record
afile : FILEptr; { io structore of the zipfile }
gi : unz_global_info; { public global information }
byte_before_the_zipfile : uLong;{ byte before the zipfile, (>0 for sfx)}
num_file : uLong; { number of the current file in the zipfile}
pos_in_central_dir : uLong; { pos of the current file in the central dir}
current_file_ok : boolean; { flag about the usability of the current file}
central_pos : uLong; { position of the beginning of the central dir}
size_central_dir : uLong; { size of the central directory }
offset_central_dir : uLong; { offset of start of central directory with
respect to the starting disk number }
cur_file_info : unz_file_info; { public info about the current file in zip}
cur_file_info_internal : unz_file_info_internal; { private info about it}
pfile_in_zip_read : file_in_zip_read_info_s_ptr; { structure about the current
file if we are decompressing it }
end;
unz_s_ptr = ^unz_s;
{ ===========================================================================
Read a byte from a gz_stream; update next_in and avail_in. Return EOF
for end of file.
IN assertion: the stream s has been sucessfully opened for reading. }
function unzlocal_getByte(fin : FILEptr; var pi : int) : int;
var
c : Byte;
err : int;
begin
err := fread(@c, 1, 1, fin);
if (err = 1) then
begin
pi := int(c);
unzlocal_getByte := UNZ_OK;
{exit;}
end
else
begin
if feof(fin)=1 then {if ferror(fin) then}
unzlocal_getByte := UNZ_ERRNO
else
unzlocal_getByte := UNZ_EOF;
{exit;}
end;
end;
{ ===========================================================================
Reads a long in LSB order from the given gz_stream. Sets }
function unzlocal_getShort (fin : FILEptr;
var pX : uLong) : int;
var
x : uLong;
i : int;
err : int;
begin
err := unzlocal_getByte(fin, i);
x := uLong(i);
if (err=UNZ_OK) then
err := unzlocal_getByte(fin,i);
Inc(x, uLong(i) shl 8);
if (err=UNZ_OK) then
pX := x
else
pX := 0;
unzlocal_getShort := err;
end;
function unzlocal_getLong (fin : FILEptr; var pX : uLong) : int;
var
x : uLong;
i : int;
err : int;
begin
err := unzlocal_getByte(fin,i);
x := uLong(i);
if (err=UNZ_OK) then
err := unzlocal_getByte(fin,i);
Inc(x, uLong(i) shl 8);
if (err=UNZ_OK) then
err := unzlocal_getByte(fin,i);
Inc(x, uLong(i) shl 16);
if (err=UNZ_OK) then
err := unzlocal_getByte(fin,i);
Inc(x, uLong(i) shl 24);
if (err=UNZ_OK) then
pX := x
else
pX := 0;
unzlocal_getLong := err;
end;
{ My own strcmpi / strcasecmp }
function strcmpcasenosensitive_internal (fileName1 : PChar;
fileName2 : PChar) : int;
var
c1, c2 : char;
begin
repeat
c1 := fileName1^; Inc(fileName1);
c2 := fileName2^; Inc(fileName2);
if (c1>='a') and (c1<='z') then
Dec(c1,$20);
if (c2>='a') and (c2<='z') then
Dec(c2, $20);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -