📄 unzip4.pas
字号:
if (c1=#0) then
begin
if c2=#0 then
strcmpcasenosensitive_internal := 0
else
strcmpcasenosensitive_internal := -1;
exit;
end;
if (c2=#0) then
begin
strcmpcasenosensitive_internal := 1;
exit;
end;
if (c1<c2) then
begin
strcmpcasenosensitive_internal := -1;
exit;
end;
if (c1>c2) then
begin
strcmpcasenosensitive_internal := 1;
exit;
end;
until false;
end;
const
CASESENSITIVITYDEFAULTVALUE = 2;
function unzStringFileNameCompare(const fileName1 : PChar;
const fileName2 : PChar;
iCaseSensitivity : int) : int; { ZEXPORT }
{ 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)
}
begin
if (iCaseSensitivity=0) then
iCaseSensitivity := CASESENSITIVITYDEFAULTVALUE;
if (iCaseSensitivity=1) then
begin
unzStringFileNameCompare := strComp(fileName1,fileName2);
exit;
end;
unzStringFileNameCompare := strcmpcasenosensitive_internal(fileName1,fileName2);
end;
const
BUFREADCOMMENT = $400;
{ Locate the Central directory of a zipfile (at the end, just before
the global comment) }
function unzlocal_SearchCentralDir(fin : FILEptr) : uLong;
var
buf : pzByteArray;
uSizeFile : uLong;
uBackRead : uLong;
uMaxBack : uLong;
uPosFound : uLong;
var
uReadSize,uReadPos : uLong;
i : int;
begin
uMaxBack := $ffff; { maximum size of global comment }
uPosFound := 0;
if (fseek(fin,0,SEEK_END) <> 0) then
begin
unzlocal_SearchCentralDir := 0;
exit;
end;
uSizeFile := ftell(fin);
if (uMaxBack>uSizeFile) then
uMaxBack := uSizeFile;
buf := pzByteArray(ALLOC(BUFREADCOMMENT+4));
if (buf=NIL) then
begin
unzlocal_SearchCentralDir := 0;
exit;
end;
uBackRead := 4;
while (uBackRead<uMaxBack) do
begin
if (uBackRead+BUFREADCOMMENT>uMaxBack) then
uBackRead := uMaxBack
else
Inc(uBackRead, BUFREADCOMMENT);
uReadPos := uSizeFile-uBackRead ;
if ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) then
uReadSize := (BUFREADCOMMENT+4)
else
uReadSize := (uSizeFile-uReadPos);
if fseek(fin,uReadPos,SEEK_SET)<>0 then
break;
if fread(buf, uInt(uReadSize), 1, fin)<>1 then
break;
i := int(uReadSize)-3;
while (i>0) do
begin
Dec(i);
if (buf^[i] = $50) and (buf^[i+1] = $4b) and { ENDHEADERMAGIC }
(buf^[i+2] = $05) and (buf^[i+3] = $06) then
begin
uPosFound := uReadPos+uLong(i);//changed by 謒黵, original:uInt(i);
break;
end;
end;
if (uPosFound <> 0) then
break;
end;
TRYFREE(buf);
unzlocal_SearchCentralDir := uPosFound;
end;
{ 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 unzOpen (const path : PChar) : unzFile; { ZEXPORT }
var
us : unz_s;
s : unz_s_ptr;
central_pos,uL : uLong;
fin : FILEptr;
number_disk : uLong; { number of the current dist, used for spaning ZIP,
unsupported, always 0 }
number_disk_with_CD : uLong; { number the the disk with central dir,
used for spaning ZIP, unsupported, always 0 }
number_entry_CD : uLong; { total number of entries in the central dir
(same than number_entry on nospan) }
err : int;
begin
err := UNZ_OK;
if (unz_copyright[0]<>' ') then
begin
unzOpen := NIL;
exit;
end;
fin := fopen(path,fopenread);
if (fin=NIL) then
begin
unzOpen := NIL;
exit;
end;
central_pos := unzlocal_SearchCentralDir(fin);
if (central_pos = 0) then
err := UNZ_ERRNO;
if (fseek(fin,central_pos,SEEK_SET) <> 0) then
err := UNZ_ERRNO;
{ the signature, already checked }
if (unzlocal_getLong(fin,uL) <> UNZ_OK) then
err := UNZ_ERRNO;
{ number of this disk }
if (unzlocal_getShort(fin,number_disk) <> UNZ_OK) then
err := UNZ_ERRNO;
{ number of the disk with the start of the central directory }
if (unzlocal_getShort(fin,number_disk_with_CD) <> UNZ_OK) then
err := UNZ_ERRNO;
{ total number of entries in the central dir on this disk }
if (unzlocal_getShort(fin,us.gi.number_entry) <> UNZ_OK) then
err := UNZ_ERRNO;
{ total number of entries in the central dir }
if (unzlocal_getShort(fin,number_entry_CD) <> UNZ_OK) then
err := UNZ_ERRNO;
if ((number_entry_CD <> us.gi.number_entry) or
(number_disk_with_CD <> 0) or
(number_disk <> 0)) then
err := UNZ_BADZIPFILE;
{ size of the central directory }
if (unzlocal_getLong(fin,us.size_central_dir)<>UNZ_OK) then
err := UNZ_ERRNO;
{ offset of start of central directory with respect to the
starting disk number }
if (unzlocal_getLong(fin,us.offset_central_dir)<>UNZ_OK) then
err := UNZ_ERRNO;
{ zipfile comment length }
if (unzlocal_getShort(fin,us.gi.size_comment)<>UNZ_OK) then
err := UNZ_ERRNO;
if ((central_pos < us.offset_central_dir+us.size_central_dir) and
(err = UNZ_OK)) then
err := UNZ_BADZIPFILE;
if (err<>UNZ_OK) then
begin
fclose(fin);
unzOpen := NIL;
exit;
end;
us.afile := fin;
us.byte_before_the_zipfile := central_pos -
(us.offset_central_dir + us.size_central_dir);
us.central_pos := central_pos;
us.pfile_in_zip_read := NIL;
s := unz_s_ptr(ALLOC(sizeof(unz_s)));
s^ := us;
unzGoToFirstFile(unzFile(s));
unzOpen := unzFile(s);
end;
{ 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 unzClose (afile : unzFile) : int; { ZEXPORT }
var
s : unz_s_ptr;
begin
if (afile=NIL) then
begin
unzClose := UNZ_PARAMERROR;
exit;
end;
s := unz_s_ptr(afile);
if (s^.pfile_in_zip_read<>NIL) then
unzCloseCurrentFile(afile);
fclose(s^.afile);
TRYFREE(s);
unzClose := UNZ_OK;
end;
{ 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 unzGetGlobalInfo (afile : unzFile;
var pglobal_info : unz_global_info) : int; { ZEXPORT }
var
s : unz_s_ptr;
begin
if (afile=NIL) then
begin
unzGetGlobalInfo := UNZ_PARAMERROR;
exit;
end;
s := unz_s_ptr(afile);
pglobal_info := s^.gi;
unzGetGlobalInfo := UNZ_OK;
end;
{ Translate date/time from Dos format to tm_unz (more easily readable) }
procedure unzlocal_DosDateToTmuDate (ulDosDate : uLong;
var ptm : tm_unz);
var
uDate : uLong;
begin
uDate := uLong(ulDosDate shr 16);
ptm.tm_mday := uInt(uDate and $1f) ;
ptm.tm_mon := uInt((( (uDate) and $1E0) div $20)-1) ;
ptm.tm_year := uInt(((uDate and $0FE00) div $0200)+1980) ;
ptm.tm_hour := uInt ((ulDosDate and $F800) div $800);
ptm.tm_min := uInt ((ulDosDate and $7E0) div $20) ;
ptm.tm_sec := uInt (2*(ulDosDate and $1f)) ;
end;
{ Get Info about the current file in the zipfile, with internal only info }
{$HINTS OFF}
function unzlocal_GetCurrentFileInfoInternal (
afile : unzFile;
pfile_info : unz_file_info_ptr;
pfile_info_internal : unz_file_info_internal_ptr;
szFileName : PChar;
fileNameBufferSize : uLong;
extraField : voidp;
extraFieldBufferSize : uLong;
szComment : PChar;
commentBufferSize : uLong ) : int;
var
s : unz_s_ptr;
file_info : unz_file_info;
file_info_internal : unz_file_info_internal;
err : int;
uMagic : uLong;
lSeek : long;
var
uSizeRead : uLong;
begin
err := UNZ_OK;
lSeek := 0;
if (afile = NIL) then
begin
unzlocal_GetCurrentFileInfoInternal := UNZ_PARAMERROR;
exit;
end;
s := unz_s_ptr(afile);
if (fseek(s^.afile,
s^.pos_in_central_dir+s^.byte_before_the_zipfile,SEEK_SET)<>0) then
err := UNZ_ERRNO;
{ we check the magic }
if (err=UNZ_OK) then
if (unzlocal_getLong(s^.afile, uMagic) <> UNZ_OK) then
err := UNZ_ERRNO
else
if (uMagic<> CENTRALHEADERMAGIC) then
err := UNZ_BADZIPFILE;
if (unzlocal_getShort(s^.afile, file_info.version) <> UNZ_OK) then
err := UNZ_ERRNO;
if (unzlocal_getShort(s^.afile, file_info.version_needed) <> UNZ_OK) then
err := UNZ_ERRNO;
if (unzlocal_getShort(s^.afile, file_info.flag) <> UNZ_OK) then
err := UNZ_ERRNO;
if (unzlocal_getShort(s^.afile, file_info.compression_method) <> UNZ_OK) then
err := UNZ_ERRNO;
if (unzlocal_getLong(s^.afile, file_info.dosDate) <> UNZ_OK) then
err := UNZ_ERRNO;
unzlocal_DosDateToTmuDate(file_info.dosDate, file_info.tmu_date);
if (unzlocal_getLong(s^.afile, file_info.crc) <> UNZ_OK) then
err := UNZ_ERRNO;
if (unzlocal_getLong(s^.afile, file_info.compressed_size) <> UNZ_OK) then
err := UNZ_ERRNO;
if (unzlocal_getLong(s^.afile, file_info.uncompressed_size) <> UNZ_OK) then
err := UNZ_ERRNO;
if (unzlocal_getShort(s^.afile, file_info.size_filename) <> UNZ_OK) then
err := UNZ_ERRNO;
if (unzlocal_getShort(s^.afile, file_info.size_file_extra) <> UNZ_OK) then
err := UNZ_ERRNO;
if (unzlocal_getShort(s^.afile, file_info.size_file_comment) <> UNZ_OK) then
err := UNZ_ERRNO;
if (unzlocal_getShort(s^.afile, file_info.disk_num_start) <> UNZ_OK) then
err := UNZ_ERRNO;
if (unzlocal_getShort(s^.afile, file_info.internal_fa) <> UNZ_OK) then
err := UNZ_ERRNO;
if (unzlocal_getLong(s^.afile, file_info.external_fa) <> UNZ_OK) then
err := UNZ_ERRNO;
if (unzlocal_getLong(s^.afile, file_info_internal.offset_curfile) <> UNZ_OK) then
err := UNZ_ERRNO;
Inc(lSeek, file_info.size_filename);
if ((err=UNZ_OK) and (szFileName<>NIL)) then
begin
if (file_info.size_filename<fileNameBufferSize) then
begin
(szFileName+file_info.size_filename)^:=#0;
uSizeRead := file_info.size_filename;
end
else
uSizeRead := fileNameBufferSize;
if (file_info.size_filename>0) and (fileNameBufferSize>0) then
begin
if fread(szFileName, uInt(uSizeRead),1,s^.afile)<>1 then
err := UNZ_ERRNO;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -