📄 unzip4.pas
字号:
Dec(lSeek, uSizeRead);
end;
if ((err=UNZ_OK) and (extraField<>NIL)) then
begin
if (file_info.size_file_extra<extraFieldBufferSize) then
uSizeRead := file_info.size_file_extra
else
uSizeRead := extraFieldBufferSize;
if (lSeek<>0) then
begin
if (fseek(s^.afile,lSeek,SEEK_CUR)=0) then
lSeek := 0
else
err := UNZ_ERRNO;
end;
if ((file_info.size_file_extra>0) and (extraFieldBufferSize>0)) then
begin
if fread(extraField, uInt(uSizeRead),1, s^.afile)<>1 then
err := UNZ_ERRNO;
end;
Inc(lSeek, file_info.size_file_extra - uSizeRead);
end
else
Inc(lSeek, file_info.size_file_extra);
if ((err=UNZ_OK) and (szComment<>NIL)) then
begin
if (file_info.size_file_comment<commentBufferSize) then
begin
(szComment+file_info.size_file_comment)^ := #0;
uSizeRead := file_info.size_file_comment;
end
else
uSizeRead := commentBufferSize;
if (lSeek<>0) then
begin
if (fseek(s^.afile,lSeek,SEEK_CUR)=0) then
lSeek := 0
else
err := UNZ_ERRNO;
end;
if ((file_info.size_file_comment>0) and (commentBufferSize>0)) then
begin
if fread(szComment, uInt(uSizeRead),1,s^.afile)<>1 then
err := UNZ_ERRNO;
end;
Inc(lSeek, file_info.size_file_comment - uSizeRead);
end
else
Inc(lSeek, file_info.size_file_comment);
if ((err=UNZ_OK) and (pfile_info<>NIL)) then
pfile_info^ := file_info;
if ((err=UNZ_OK) and (pfile_info_internal<>NIL)) then
pfile_info_internal^ := file_info_internal;
unzlocal_GetCurrentFileInfoInternal := err;
end;
{$HINTS ON}
{ 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 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) }
begin
unzGetCurrentFileInfo := unzlocal_GetCurrentFileInfoInternal(afile,
pfile_info,NIL,szFileName,fileNameBufferSize, extraField,
extraFieldBufferSize, szComment,commentBufferSize);
end;
{ Set the current file of the zipfile to the first file.
return UNZ_OK if there is no problem }
function unzGoToFirstFile(afile : unzFile) : int; { ZEXPORT }
var
err : int;
s : unz_s_ptr;
begin
if (afile=NIL) then
begin
unzGoToFirstFile := UNZ_PARAMERROR;
exit;
end;
s := unz_s_ptr(afile);
s^.pos_in_central_dir := s^.offset_central_dir;
s^.num_file := 0;
err := unzlocal_GetCurrentFileInfoInternal(afile, @s^.cur_file_info,
@s^.cur_file_info_internal, NIL,0,NIL,0,NIL,0);
s^.current_file_ok := (err = UNZ_OK);
unzGoToFirstFile := err;
end;
{ 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 unzGoToNextFile(afile : unzFile) : int; { ZEXPORT }
var
s : unz_s_ptr;
err : int;
begin
if (afile=NIL) then
begin
unzGoToNextFile := UNZ_PARAMERROR;
exit;
end;
s := unz_s_ptr(afile);
if not s^.current_file_ok then
begin
unzGoToNextFile := UNZ_END_OF_LIST_OF_FILE;
exit;
end;
if (s^.num_file+1 = s^.gi.number_entry) then
begin
unzGoToNextFile := UNZ_END_OF_LIST_OF_FILE;
exit;
end;
Inc(s^.pos_in_central_dir,
SIZECENTRALDIRITEM + s^.cur_file_info.size_filename +
s^.cur_file_info.size_file_extra + s^.cur_file_info.size_file_comment);
Inc(s^.num_file);
err := unzlocal_GetCurrentFileInfoInternal(afile, @s^.cur_file_info,
@s^.cur_file_info_internal, NIL,0,NIL,0,NIL,0);
s^.current_file_ok := (err = UNZ_OK);
unzGoToNextFile := err;
end;
{ Try locate the file szFileName in the zipfile.
For the iCaseSensitivity signification, see unzStringFileNameCompare
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 unzLocateFile(afile : unzFile;
const szFileName : PChar;
iCaseSensitivity : int) : int; { ZEXPORT }
var
s : unz_s_ptr;
err : int;
num_fileSaved : uLong;
pos_in_central_dirSaved : uLong;
var
szCurrentFileName : array[0..UNZ_MAXFILENAMEINZIP+1-1] of char;
begin
if (afile=NIL) or (Strlen(szFileName)=0) then
begin
unzLocateFile := UNZ_PARAMERROR;
exit;
end;
if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) then
begin
unzLocateFile := UNZ_PARAMERROR;
exit;
end;
s := unz_s_ptr(afile);
if (not s^.current_file_ok) then
begin
unzLocateFile := UNZ_END_OF_LIST_OF_FILE;
exit;
end;
num_fileSaved := s^.num_file;
pos_in_central_dirSaved := s^.pos_in_central_dir;
err := unzGoToFirstFile(afile);
while (err = UNZ_OK) do
begin
unzGetCurrentFileInfo(afile,NIL,
szCurrentFileName,sizeof(szCurrentFileName)-1, NIL,0,NIL,0);
if (unzStringFileNameCompare(szCurrentFileName,
szFileName,iCaseSensitivity)=0) then
begin
unzLocateFile := UNZ_OK;
exit;
end;
err := unzGoToNextFile(afile);
end;
s^.num_file := num_fileSaved;
s^.pos_in_central_dir := pos_in_central_dirSaved;
unzLocateFile := err;
end;
{ Read the local header of the current zipfile
Check the coherency of the local header and info in the end of central
directory about this file
store in *piSizeVar the size of extra info in local header
(filename and size of extra field data) }
function unzlocal_CheckCurrentFileCoherencyHeader (
s : unz_s_ptr;
var piSizeVar : uInt;
var poffset_local_extrafield : uLong;
var psize_local_extrafield : uInt) : int;
var
uMagic,uData,uFlags : uLong;
size_filename : uLong;
size_extra_field : uLong;
err : int;
begin
err := UNZ_OK;
piSizeVar := 0;
poffset_local_extrafield := 0;
psize_local_extrafield := 0;
if (fseek(s^.afile,s^.cur_file_info_internal.offset_curfile +
s^.byte_before_the_zipfile,SEEK_SET)<>0) then
begin
unzlocal_CheckCurrentFileCoherencyHeader := UNZ_ERRNO;
exit;
end;
if (err=UNZ_OK) then
if (unzlocal_getLong(s^.afile, uMagic) <> UNZ_OK) then
err := UNZ_ERRNO
else
if (uMagic<> $04034b50) then
err := UNZ_BADZIPFILE;
if (unzlocal_getShort(s^.afile, uData) <> UNZ_OK) then
err := UNZ_ERRNO;
{
else
if ((err=UNZ_OK) and (uData<>s^.cur_file_info.wVersion)) then
err := UNZ_BADZIPFILE;
}
if (unzlocal_getShort(s^.afile, uFlags) <> UNZ_OK) then
err := UNZ_ERRNO;
if (unzlocal_getShort(s^.afile, uData) <> UNZ_OK) then
err := UNZ_ERRNO
else
if ((err=UNZ_OK) and (uData<>s^.cur_file_info.compression_method)) then
err := UNZ_BADZIPFILE;
if ((err=UNZ_OK) and (s^.cur_file_info.compression_method<>0) and
(s^.cur_file_info.compression_method<>Z_DEFLATED)) then
err := UNZ_BADZIPFILE;
if (unzlocal_getLong(s^.afile, uData) <> UNZ_OK) then { date/time }
err := UNZ_ERRNO;
if (unzlocal_getLong(s^.afile, uData) <> UNZ_OK) then { crc }
err := UNZ_ERRNO
else
if ((err=UNZ_OK) and (uData<>s^.cur_file_info.crc) and
((uFlags and 8)=0)) then
err := UNZ_BADZIPFILE;
if (unzlocal_getLong(s^.afile, uData) <> UNZ_OK) then { size compr }
err := UNZ_ERRNO
else
if ((err=UNZ_OK) and (uData<>s^.cur_file_info.compressed_size) and
((uFlags and 8)=0)) then
err := UNZ_BADZIPFILE;
if (unzlocal_getLong(s^.afile, uData) <> UNZ_OK) then { size uncompr }
err := UNZ_ERRNO
else
if ((err=UNZ_OK) and (uData<>s^.cur_file_info.uncompressed_size) and
((uFlags and 8)=0)) then
err := UNZ_BADZIPFILE;
if (unzlocal_getShort(s^.afile, size_filename) <> UNZ_OK) then
err := UNZ_ERRNO
else
if ((err=UNZ_OK) and (size_filename<>s^.cur_file_info.size_filename)) then
err := UNZ_BADZIPFILE;
Inc(piSizeVar, uInt(size_filename));
if (unzlocal_getShort(s^.afile, size_extra_field) <> UNZ_OK) then
err := UNZ_ERRNO;
poffset_local_extrafield := s^.cur_file_info_internal.offset_curfile +
SIZEZIPLOCALHEADER + size_filename;
psize_local_extrafield := uInt(size_extra_field);
Inc(piSizeVar, uInt(size_extra_field));
unzlocal_CheckCurrentFileCoherencyHeader := err;
end;
{ Open for reading data the current file in the zipfile.
If there is no error, the return value is UNZ_OK. }
{$HINTS OFF}
function unzOpenCurrentFile(afile : unzFile) : int; { ZEXPORT }
var
err : int;
Store : boolean;
iSizeVar : uInt;
s : unz_s_ptr;
pfile_in_zip_read_info : file_in_zip_read_info_s_ptr;
offset_local_extrafield : uLong; { offset of the local extra field }
size_local_extrafield : uInt; { size of the local extra field }
begin
err := UNZ_OK;
if (afile=NIL) then
begin
unzOpenCurrentFile := UNZ_PARAMERROR;
exit;
end;
s := unz_s_ptr(afile);
if not s^.current_file_ok then
begin
unzOpenCurrentFile := UNZ_PARAMERROR;
exit;
end;
if (s^.pfile_in_zip_read <> NIL) then
unzCloseCurrentFile(afile);
if (unzlocal_CheckCurrentFileCoherencyHeader(s, iSizeVar,
offset_local_extrafield, size_local_extrafield)<>UNZ_OK) then
begin
unzOpenCurrentFile := UNZ_BADZIPFILE;
exit;
end;
pfile_in_zip_read_info := file_in_zip_read_info_s_ptr(
ALLOC(sizeof(file_in_zip_read_info_s)) );
if (pfile_in_zip_read_info=NIL) then
begin
unzOpenCurrentFile := UNZ_INTERNALERROR;
exit;
end;
pfile_in_zip_read_info^.read_buffer := PChar(ALLOC(UNZ_BUFSIZE));
pfile_in_zip_read_info^.offset_local_extrafield := offset_local_extrafield;
pfile_in_zip_read_info^.size_local_extrafield := size_local_extrafield;
pfile_in_zip_read_info^.pos_local_extrafield := 0;
if (pfile_in_zip_read_info^.read_buffer=NIL) then
begin
TRYFREE(pfile_in_zip_read_info);
unzOpenCurrentFile := UNZ_INTERNALERROR;
exit;
end;
pfile_in_zip_read_info^.stream_initialised := false;
if ((s^.cur_file_info.compression_method<>0) and
(s^.cur_file_info.compression_method<>Z_DEFLATED)) then
err := UNZ_BADZIPFILE;
Store := s^.cur_file_info.compression_method = 0;
pfile_in_zip_read_info^.crc32_wait := s^.cur_file_info.crc;
pfile_in_zip_read_info^.crc32 := 0;
pfile_in_zip_read_info^.compression_method := s^.cur_file_info.compression_method;
pfile_in_zip_read_info^.afile := s^.afile;
pfile_in_zip_read_info^.byte_before_the_zipfile := s^.byte_before_the_zipfile;
pfile_in_zip_read_info^.stream.total_out := 0;
if (not Store) then
begin
pfile_in_zip_read_info^.stream.zalloc := NIL;
pfile_in_zip_read_info^.stream.zfree := NIL;
pfile_in_zip_read_info^.stream.opaque := voidpf(NIL);
err := inflateInit2(pfile_in_zip_read_info^.stream, -MAX_WBITS);
if (err = Z_OK) then
pfile_in_zip_read_info^.stream_initialised := true;
{ windowBits is passed < 0 to tell that there is no zlib header.
Note that in this case inflate *requires* an extra "dummy" byte
after the compressed stream in order to complete decompression and
return Z_STREAM_END.
In unzip, i don't wait absolutely Z_STREAM_END because I known the
size of both compressed and uncompressed data }
end;
pfile_in_zip_read_info^.rest_read_compressed := s^.cur_file_info.compressed_size ;
pfile_in_zip_read_info^.rest_read_uncompressed := s^.cur_file_info.uncompressed_size ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -