1 /* unzip.c -- IO on .zip files using zlib
2 Version 0.15 beta, Mar 19th, 1998,
4 Read unzip.h for more info
29 /* compile with -Dlocal if your debugger can't find static symbols */
33 #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
34 !defined(CASESENSITIVITYDEFAULT_NO)
35 #define CASESENSITIVITYDEFAULT_NO
40 #define UNZ_BUFSIZE (16384)
43 #ifndef UNZ_MAXFILENAMEINZIP
44 #define UNZ_MAXFILENAMEINZIP (256)
48 # define ALLOC(size) (malloc(size))
51 # define TRYFREE(p) {if (p) free(p);}
54 #define SIZECENTRALDIRITEM (0x2e)
55 #define SIZEZIPLOCALHEADER (0x1e)
58 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
72 const char unz_copyright
[] =
73 " unzip 0.15 Copyright 1998 Gilles Vollant ";
75 /* unz_file_info_interntal contain internal info about a file in zipfile*/
76 typedef struct unz_file_info_internal_s
78 uLong offset_curfile
;/* relative offset of local header 4 bytes */
79 } unz_file_info_internal
;
82 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
83 when reading and decompress it */
86 char *read_buffer
; /* internal buffer for compressed data */
87 z_stream stream
; /* zLib stream structure for inflate */
89 uLong pos_in_zipfile
; /* position in byte on the zipfile, for fseek*/
90 uLong stream_initialised
; /* flag set if stream structure is initialised*/
92 uLong offset_local_extrafield
;/* offset of the local extra field */
93 uInt size_local_extrafield
;/* size of the local extra field */
94 uLong pos_local_extrafield
; /* position in the local extra field in read*/
96 uLong crc32
; /* crc32 of all data uncompressed */
97 uLong crc32_wait
; /* crc32 we must obtain after decompress all */
98 uLong rest_read_compressed
; /* number of byte to be decompressed */
99 uLong rest_read_uncompressed
;/*number of byte to be obtained after decomp*/
100 FILE* file
; /* io structore of the zipfile */
101 uLong compression_method
; /* compression method (0==store) */
102 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
103 } file_in_zip_read_info_s
;
106 /* unz_s contain internal information about the zipfile
110 FILE* file
; /* io structore of the zipfile */
111 unz_global_info gi
; /* public global information */
112 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
113 uLong num_file
; /* number of the current file in the zipfile*/
114 uLong pos_in_central_dir
; /* pos of the current file in the central dir*/
115 uLong current_file_ok
; /* flag about the usability of the current file*/
116 uLong central_pos
; /* position of the beginning of the central dir*/
118 uLong size_central_dir
; /* size of the central directory */
119 uLong offset_central_dir
; /* offset of start of central directory with
120 respect to the starting disk number */
122 unz_file_info cur_file_info
; /* public info about the current file in zip*/
123 unz_file_info_internal cur_file_info_internal
; /* private info about it*/
124 file_in_zip_read_info_s
* pfile_in_zip_read
; /* structure about the current
125 file if we are decompressing it */
129 /* ===========================================================================
130 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
132 IN assertion: the stream s has been sucessfully opened for reading.
136 local
int unzlocal_getByte(fin
,pi
)
141 int err
= fread(&c
, 1, 1, fin
);
157 /* ===========================================================================
158 Reads a long in LSB order from the given gz_stream. Sets
160 local
int unzlocal_getShort (fin
,pX
)
168 err
= unzlocal_getByte(fin
,&i
);
172 err
= unzlocal_getByte(fin
,&i
);
182 local
int unzlocal_getLong (fin
,pX
)
190 err
= unzlocal_getByte(fin
,&i
);
194 err
= unzlocal_getByte(fin
,&i
);
198 err
= unzlocal_getByte(fin
,&i
);
202 err
= unzlocal_getByte(fin
,&i
);
213 /* My own strcmpi / strcasecmp */
214 local
int strcmpcasenosensitive_internal (fileName1
,fileName2
)
215 const char* fileName1
;
216 const char* fileName2
;
220 char c1
=*(fileName1
++);
221 char c2
=*(fileName2
++);
222 if ((c1
>='a') && (c1
<='z'))
224 if ((c2
>='a') && (c2
<='z'))
227 return ((c2
=='\0') ? 0 : -1);
238 #ifdef CASESENSITIVITYDEFAULT_NO
239 #define CASESENSITIVITYDEFAULTVALUE 2
241 #define CASESENSITIVITYDEFAULTVALUE 1
244 #ifndef STRCMPCASENOSENTIVEFUNCTION
245 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
249 Compare two filename (fileName1,fileName2).
250 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
251 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
253 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
254 (like 1 on Unix, 2 on Windows)
257 extern int ZEXPORT
unzStringFileNameCompare (fileName1
,fileName2
,iCaseSensitivity
)
258 const char* fileName1
;
259 const char* fileName2
;
260 int iCaseSensitivity
;
262 if (iCaseSensitivity
==0)
263 iCaseSensitivity
=CASESENSITIVITYDEFAULTVALUE
;
265 if (iCaseSensitivity
==1)
266 return strcmp(fileName1
,fileName2
);
268 return STRCMPCASENOSENTIVEFUNCTION(fileName1
,fileName2
);
271 #define BUFREADCOMMENT (0x400)
274 Locate the Central directory of a zipfile (at the end, just before
277 local uLong
unzlocal_SearchCentralDir(fin
)
283 uLong uMaxBack
=0xffff; /* maximum size of global comment */
286 if (fseek(fin
,0,SEEK_END
) != 0)
290 uSizeFile
= ftell( fin
);
292 if (uMaxBack
>uSizeFile
)
293 uMaxBack
= uSizeFile
;
295 buf
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4);
300 while (uBackRead
<uMaxBack
)
302 uLong uReadSize
,uReadPos
;
304 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
)
305 uBackRead
= uMaxBack
;
307 uBackRead
+=BUFREADCOMMENT
;
308 uReadPos
= uSizeFile
-uBackRead
;
310 uReadSize
= ((BUFREADCOMMENT
+4) < (uSizeFile
-uReadPos
)) ?
311 (BUFREADCOMMENT
+4) : (uSizeFile
-uReadPos
);
312 if (fseek(fin
,uReadPos
,SEEK_SET
)!=0)
315 if (fread(buf
,(uInt
)uReadSize
,1,fin
)!=1)
318 for (i
=(int)uReadSize
-3; (i
--)>0;)
319 if (((*(buf
+i
))==0x50) && ((*(buf
+i
+1))==0x4b) &&
320 ((*(buf
+i
+2))==0x05) && ((*(buf
+i
+3))==0x06))
322 uPosFound
= uReadPos
+i
;
334 Open a Zip file. path contain the full pathname (by example,
335 on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
337 If the zipfile cannot be opened (file don't exist or in not valid), the
338 return value is NULL.
339 Else, the return value is a unzFile Handle, usable with other function
340 of this unzip package.
342 extern unzFile ZEXPORT
unzOpen (path
)
347 uLong central_pos
,uL
;
350 uLong number_disk
; /* number of the current dist, used for
351 spaning ZIP, unsupported, always 0*/
352 uLong number_disk_with_CD
; /* number the the disk with central dir, used
353 for spaning ZIP, unsupported, always 0*/
354 uLong number_entry_CD
; /* total number of entries in
356 (same than number_entry on nospan) */
360 if (unz_copyright
[0]!=' ')
363 fin
=fopen(path
,"rb");
367 central_pos
= unzlocal_SearchCentralDir(fin
);
371 if (fseek(fin
,central_pos
,SEEK_SET
)!=0)
374 /* the signature, already checked */
375 if (unzlocal_getLong(fin
,&uL
)!=UNZ_OK
)
378 /* number of this disk */
379 if (unzlocal_getShort(fin
,&number_disk
)!=UNZ_OK
)
382 /* number of the disk with the start of the central directory */
383 if (unzlocal_getShort(fin
,&number_disk_with_CD
)!=UNZ_OK
)
386 /* total number of entries in the central dir on this disk */
387 if (unzlocal_getShort(fin
,&us
.gi
.number_entry
)!=UNZ_OK
)
390 /* total number of entries in the central dir */
391 if (unzlocal_getShort(fin
,&number_entry_CD
)!=UNZ_OK
)
394 if ((number_entry_CD
!=us
.gi
.number_entry
) ||
395 (number_disk_with_CD
!=0) ||
399 /* size of the central directory */
400 if (unzlocal_getLong(fin
,&us
.size_central_dir
)!=UNZ_OK
)
403 /* offset of start of central directory with respect to the
404 starting disk number */
405 if (unzlocal_getLong(fin
,&us
.offset_central_dir
)!=UNZ_OK
)
408 /* zipfile comment length */
409 if (unzlocal_getShort(fin
,&us
.gi
.size_comment
)!=UNZ_OK
)
412 if ((central_pos
<us
.offset_central_dir
+us
.size_central_dir
) &&
423 us
.byte_before_the_zipfile
= central_pos
-
424 (us
.offset_central_dir
+us
.size_central_dir
);
425 us
.central_pos
= central_pos
;
426 us
.pfile_in_zip_read
= NULL
;
429 s
=(unz_s
*)ALLOC(sizeof(unz_s
));
431 unzGoToFirstFile((unzFile
)s
);
437 Close a ZipFile opened with unzipOpen.
438 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
439 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
440 return UNZ_OK if there is no problem. */
441 extern int ZEXPORT
unzClose (file
)
446 return UNZ_PARAMERROR
;
449 if (s
->pfile_in_zip_read
!=NULL
)
450 unzCloseCurrentFile(file
);
459 Write info about the ZipFile in the *pglobal_info structure.
460 No preparation of the structure is needed
461 return UNZ_OK if there is no problem. */
462 extern int ZEXPORT
unzGetGlobalInfo (file
,pglobal_info
)
464 unz_global_info
*pglobal_info
;
468 return UNZ_PARAMERROR
;
476 Translate date/time from Dos format to tm_unz (readable more easilty)
478 local
void unzlocal_DosDateToTmuDate (ulDosDate
, ptm
)
483 uDate
= (uLong
)(ulDosDate
>>16);
484 ptm
->tm_mday
= (uInt
)(uDate
&0x1f) ;
485 ptm
->tm_mon
= (uInt
)((((uDate
)&0x1E0)/0x20)-1) ;
486 ptm
->tm_year
= (uInt
)(((uDate
&0x0FE00)/0x0200)+1980) ;
488 ptm
->tm_hour
= (uInt
) ((ulDosDate
&0xF800)/0x800);
489 ptm
->tm_min
= (uInt
) ((ulDosDate
&0x7E0)/0x20) ;
490 ptm
->tm_sec
= (uInt
) (2*(ulDosDate
&0x1f)) ;
494 Get Info about the current file in the zipfile, with internal only info
496 local
int unzlocal_GetCurrentFileInfoInternal
OF((unzFile file
,
497 unz_file_info
*pfile_info
,
498 unz_file_info_internal
499 *pfile_info_internal
,
501 uLong fileNameBufferSize
,
503 uLong extraFieldBufferSize
,
505 uLong commentBufferSize
));
507 local
int unzlocal_GetCurrentFileInfoInternal (file
,
510 szFileName
, fileNameBufferSize
,
511 extraField
, extraFieldBufferSize
,
512 szComment
, commentBufferSize
)
514 unz_file_info
*pfile_info
;
515 unz_file_info_internal
*pfile_info_internal
;
517 uLong fileNameBufferSize
;
519 uLong extraFieldBufferSize
;
521 uLong commentBufferSize
;
524 unz_file_info file_info
;
525 unz_file_info_internal file_info_internal
;
531 return UNZ_PARAMERROR
;
533 if (fseek(s
->file
,s
->pos_in_central_dir
+s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
537 /* we check the magic */
539 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
541 else if (uMagic
!=0x02014b50)
544 if (unzlocal_getShort(s
->file
,&file_info
.version
) != UNZ_OK
)
547 if (unzlocal_getShort(s
->file
,&file_info
.version_needed
) != UNZ_OK
)
550 if (unzlocal_getShort(s
->file
,&file_info
.flag
) != UNZ_OK
)
553 if (unzlocal_getShort(s
->file
,&file_info
.compression_method
) != UNZ_OK
)
556 if (unzlocal_getLong(s
->file
,&file_info
.dosDate
) != UNZ_OK
)
559 unzlocal_DosDateToTmuDate(file_info
.dosDate
,&file_info
.tmu_date
);
561 if (unzlocal_getLong(s
->file
,&file_info
.crc
) != UNZ_OK
)
564 if (unzlocal_getLong(s
->file
,&file_info
.compressed_size
) != UNZ_OK
)
567 if (unzlocal_getLong(s
->file
,&file_info
.uncompressed_size
) != UNZ_OK
)
570 if (unzlocal_getShort(s
->file
,&file_info
.size_filename
) != UNZ_OK
)
573 if (unzlocal_getShort(s
->file
,&file_info
.size_file_extra
) != UNZ_OK
)
576 if (unzlocal_getShort(s
->file
,&file_info
.size_file_comment
) != UNZ_OK
)
579 if (unzlocal_getShort(s
->file
,&file_info
.disk_num_start
) != UNZ_OK
)
582 if (unzlocal_getShort(s
->file
,&file_info
.internal_fa
) != UNZ_OK
)
585 if (unzlocal_getLong(s
->file
,&file_info
.external_fa
) != UNZ_OK
)
588 if (unzlocal_getLong(s
->file
,&file_info_internal
.offset_curfile
) != UNZ_OK
)
591 lSeek
+=file_info
.size_filename
;
592 if ((err
==UNZ_OK
) && (szFileName
!=NULL
))
595 if (file_info
.size_filename
<fileNameBufferSize
)
597 *(szFileName
+file_info
.size_filename
)='\0';
598 uSizeRead
= file_info
.size_filename
;
601 uSizeRead
= fileNameBufferSize
;
603 if ((file_info
.size_filename
>0) && (fileNameBufferSize
>0))
604 if (fread(szFileName
,(uInt
)uSizeRead
,1,s
->file
)!=1)
610 if ((err
==UNZ_OK
) && (extraField
!=NULL
))
613 if (file_info
.size_file_extra
<extraFieldBufferSize
)
614 uSizeRead
= file_info
.size_file_extra
;
616 uSizeRead
= extraFieldBufferSize
;
619 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
623 if ((file_info
.size_file_extra
>0) && (extraFieldBufferSize
>0))
624 if (fread(extraField
,(uInt
)uSizeRead
,1,s
->file
)!=1)
626 lSeek
+= file_info
.size_file_extra
- uSizeRead
;
629 lSeek
+=file_info
.size_file_extra
;
632 if ((err
==UNZ_OK
) && (szComment
!=NULL
))
635 if (file_info
.size_file_comment
<commentBufferSize
)
637 *(szComment
+file_info
.size_file_comment
)='\0';
638 uSizeRead
= file_info
.size_file_comment
;
641 uSizeRead
= commentBufferSize
;
644 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
648 if ((file_info
.size_file_comment
>0) && (commentBufferSize
>0))
649 if (fread(szComment
,(uInt
)uSizeRead
,1,s
->file
)!=1)
651 lSeek
+=file_info
.size_file_comment
- uSizeRead
;
654 lSeek
+=file_info
.size_file_comment
;
656 if ((err
==UNZ_OK
) && (pfile_info
!=NULL
))
657 *pfile_info
=file_info
;
659 if ((err
==UNZ_OK
) && (pfile_info_internal
!=NULL
))
660 *pfile_info_internal
=file_info_internal
;
668 Write info about the ZipFile in the *pglobal_info structure.
669 No preparation of the structure is needed
670 return UNZ_OK if there is no problem.
672 extern int ZEXPORT
unzGetCurrentFileInfo (file
,
674 szFileName
, fileNameBufferSize
,
675 extraField
, extraFieldBufferSize
,
676 szComment
, commentBufferSize
)
678 unz_file_info
*pfile_info
;
680 uLong fileNameBufferSize
;
682 uLong extraFieldBufferSize
;
684 uLong commentBufferSize
;
686 return unzlocal_GetCurrentFileInfoInternal(file
,pfile_info
,NULL
,
687 szFileName
,fileNameBufferSize
,
688 extraField
,extraFieldBufferSize
,
689 szComment
,commentBufferSize
);
693 Set the current file of the zipfile to the first file.
694 return UNZ_OK if there is no problem
696 extern int ZEXPORT
unzGoToFirstFile (file
)
702 return UNZ_PARAMERROR
;
704 s
->pos_in_central_dir
=s
->offset_central_dir
;
706 err
=unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
707 &s
->cur_file_info_internal
,
708 NULL
,0,NULL
,0,NULL
,0);
709 s
->current_file_ok
= (err
== UNZ_OK
);
715 Set the current file of the zipfile to the next file.
716 return UNZ_OK if there is no problem
717 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
719 extern int ZEXPORT
unzGoToNextFile (file
)
726 return UNZ_PARAMERROR
;
728 if (!s
->current_file_ok
)
729 return UNZ_END_OF_LIST_OF_FILE
;
730 if (s
->num_file
+1==s
->gi
.number_entry
)
731 return UNZ_END_OF_LIST_OF_FILE
;
733 s
->pos_in_central_dir
+= SIZECENTRALDIRITEM
+ s
->cur_file_info
.size_filename
+
734 s
->cur_file_info
.size_file_extra
+ s
->cur_file_info
.size_file_comment
;
736 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
737 &s
->cur_file_info_internal
,
738 NULL
,0,NULL
,0,NULL
,0);
739 s
->current_file_ok
= (err
== UNZ_OK
);
745 Try locate the file szFileName in the zipfile.
746 For the iCaseSensitivity signification, see unzipStringFileNameCompare
749 UNZ_OK if the file is found. It becomes the current file.
750 UNZ_END_OF_LIST_OF_FILE if the file is not found
752 extern int ZEXPORT
unzLocateFile (file
, szFileName
, iCaseSensitivity
)
754 const char *szFileName
;
755 int iCaseSensitivity
;
762 uLong pos_in_central_dirSaved
;
766 return UNZ_PARAMERROR
;
768 if (strlen(szFileName
)>=UNZ_MAXFILENAMEINZIP
)
769 return UNZ_PARAMERROR
;
772 if (!s
->current_file_ok
)
773 return UNZ_END_OF_LIST_OF_FILE
;
775 num_fileSaved
= s
->num_file
;
776 pos_in_central_dirSaved
= s
->pos_in_central_dir
;
778 err
= unzGoToFirstFile(file
);
780 while (err
== UNZ_OK
)
782 char szCurrentFileName
[UNZ_MAXFILENAMEINZIP
+1];
783 unzGetCurrentFileInfo(file
,NULL
,
784 szCurrentFileName
,sizeof(szCurrentFileName
)-1,
786 if (unzStringFileNameCompare(szCurrentFileName
,
787 szFileName
,iCaseSensitivity
)==0)
789 err
= unzGoToNextFile(file
);
792 s
->num_file
= num_fileSaved
;
793 s
->pos_in_central_dir
= pos_in_central_dirSaved
;
799 Read the local header of the current zipfile
800 Check the coherency of the local header and info in the end of central
801 directory about this file
802 store in *piSizeVar the size of extra info in local header
803 (filename and size of extra field data)
805 local
int unzlocal_CheckCurrentFileCoherencyHeader (s
,piSizeVar
,
806 poffset_local_extrafield
,
807 psize_local_extrafield
)
810 uLong
*poffset_local_extrafield
;
811 uInt
*psize_local_extrafield
;
813 uLong uMagic
,uData
,uFlags
;
815 uLong size_extra_field
;
819 *poffset_local_extrafield
= 0;
820 *psize_local_extrafield
= 0;
822 if (fseek(s
->file
,s
->cur_file_info_internal
.offset_curfile
+
823 s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
828 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
830 else if (uMagic
!=0x04034b50)
833 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
836 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
839 if (unzlocal_getShort(s
->file
,&uFlags
) != UNZ_OK
)
842 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
844 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compression_method
))
847 if ((err
==UNZ_OK
) && (s
->cur_file_info
.compression_method
!=0) &&
848 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
851 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* date/time */
854 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* crc */
856 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.crc
) &&
860 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size compr */
862 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compressed_size
) &&
866 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size uncompr */
868 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.uncompressed_size
) &&
873 if (unzlocal_getShort(s
->file
,&size_filename
) != UNZ_OK
)
875 else if ((err
==UNZ_OK
) && (size_filename
!=s
->cur_file_info
.size_filename
))
878 *piSizeVar
+= (uInt
)size_filename
;
880 if (unzlocal_getShort(s
->file
,&size_extra_field
) != UNZ_OK
)
882 *poffset_local_extrafield
= s
->cur_file_info_internal
.offset_curfile
+
883 SIZEZIPLOCALHEADER
+ size_filename
;
884 *psize_local_extrafield
= (uInt
)size_extra_field
;
886 *piSizeVar
+= (uInt
)size_extra_field
;
892 Open for reading data the current file in the zipfile.
893 If there is no error and the file is opened, the return value is UNZ_OK.
895 extern int ZEXPORT
unzOpenCurrentFile (file
)
902 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
903 uLong offset_local_extrafield
; /* offset of the local extra field */
904 uInt size_local_extrafield
; /* size of the local extra field */
907 return UNZ_PARAMERROR
;
909 if (!s
->current_file_ok
)
910 return UNZ_PARAMERROR
;
912 if (s
->pfile_in_zip_read
!= NULL
)
913 unzCloseCurrentFile(file
);
915 if (unzlocal_CheckCurrentFileCoherencyHeader(s
,&iSizeVar
,
916 &offset_local_extrafield
,&size_local_extrafield
)!=UNZ_OK
)
917 return UNZ_BADZIPFILE
;
919 pfile_in_zip_read_info
= (file_in_zip_read_info_s
*)
920 ALLOC(sizeof(file_in_zip_read_info_s
));
921 if (pfile_in_zip_read_info
==NULL
)
922 return UNZ_INTERNALERROR
;
924 pfile_in_zip_read_info
->read_buffer
=(char*)ALLOC(UNZ_BUFSIZE
);
925 pfile_in_zip_read_info
->offset_local_extrafield
= offset_local_extrafield
;
926 pfile_in_zip_read_info
->size_local_extrafield
= size_local_extrafield
;
927 pfile_in_zip_read_info
->pos_local_extrafield
=0;
929 if (pfile_in_zip_read_info
->read_buffer
==NULL
)
931 TRYFREE(pfile_in_zip_read_info
);
932 return UNZ_INTERNALERROR
;
935 pfile_in_zip_read_info
->stream_initialised
=0;
937 if ((s
->cur_file_info
.compression_method
!=0) &&
938 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
940 Store
= s
->cur_file_info
.compression_method
==0;
942 pfile_in_zip_read_info
->crc32_wait
=s
->cur_file_info
.crc
;
943 pfile_in_zip_read_info
->crc32
=0;
944 pfile_in_zip_read_info
->compression_method
=
945 s
->cur_file_info
.compression_method
;
946 pfile_in_zip_read_info
->file
=s
->file
;
947 pfile_in_zip_read_info
->byte_before_the_zipfile
=s
->byte_before_the_zipfile
;
949 pfile_in_zip_read_info
->stream
.total_out
= 0;
953 pfile_in_zip_read_info
->stream
.zalloc
= (alloc_func
)0;
954 pfile_in_zip_read_info
->stream
.zfree
= (free_func
)0;
955 pfile_in_zip_read_info
->stream
.opaque
= (voidpf
)0;
957 err
=inflateInit2(&pfile_in_zip_read_info
->stream
, -MAX_WBITS
);
959 pfile_in_zip_read_info
->stream_initialised
=1;
960 /* windowBits is passed < 0 to tell that there is no zlib header.
961 * Note that in this case inflate *requires* an extra "dummy" byte
962 * after the compressed stream in order to complete decompression and
963 * return Z_STREAM_END.
964 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
965 * size of both compressed and uncompressed data
968 pfile_in_zip_read_info
->rest_read_compressed
=
969 s
->cur_file_info
.compressed_size
;
970 pfile_in_zip_read_info
->rest_read_uncompressed
=
971 s
->cur_file_info
.uncompressed_size
;
974 pfile_in_zip_read_info
->pos_in_zipfile
=
975 s
->cur_file_info_internal
.offset_curfile
+ SIZEZIPLOCALHEADER
+
978 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)0;
981 s
->pfile_in_zip_read
= pfile_in_zip_read_info
;
987 Read bytes from the current file.
988 buf contain buffer where data must be copied
991 return the number of byte copied if somes bytes are copied
992 return 0 if the end of file was reached
993 return <0 with error code if there is an error
994 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
996 extern int ZEXPORT
unzReadCurrentFile (file
, buf
, len
)
1004 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1006 return UNZ_PARAMERROR
;
1008 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1010 if (pfile_in_zip_read_info
==NULL
)
1011 return UNZ_PARAMERROR
;
1014 if ((pfile_in_zip_read_info
->read_buffer
== NULL
))
1015 return UNZ_END_OF_LIST_OF_FILE
;
1019 pfile_in_zip_read_info
->stream
.next_out
= (Bytef
*)buf
;
1021 pfile_in_zip_read_info
->stream
.avail_out
= (uInt
)len
;
1023 if (len
>pfile_in_zip_read_info
->rest_read_uncompressed
)
1024 pfile_in_zip_read_info
->stream
.avail_out
=
1025 (uInt
)pfile_in_zip_read_info
->rest_read_uncompressed
;
1027 while (pfile_in_zip_read_info
->stream
.avail_out
>0)
1029 if ((pfile_in_zip_read_info
->stream
.avail_in
==0) &&
1030 (pfile_in_zip_read_info
->rest_read_compressed
>0))
1032 uInt uReadThis
= UNZ_BUFSIZE
;
1033 if (pfile_in_zip_read_info
->rest_read_compressed
<uReadThis
)
1034 uReadThis
= (uInt
)pfile_in_zip_read_info
->rest_read_compressed
;
1037 if (fseek(pfile_in_zip_read_info
->file
,
1038 pfile_in_zip_read_info
->pos_in_zipfile
+
1039 pfile_in_zip_read_info
->byte_before_the_zipfile
,SEEK_SET
)!=0)
1041 if (fread(pfile_in_zip_read_info
->read_buffer
,uReadThis
,1,
1042 pfile_in_zip_read_info
->file
)!=1)
1044 pfile_in_zip_read_info
->pos_in_zipfile
+= uReadThis
;
1046 pfile_in_zip_read_info
->rest_read_compressed
-=uReadThis
;
1048 pfile_in_zip_read_info
->stream
.next_in
=
1049 (Bytef
*)pfile_in_zip_read_info
->read_buffer
;
1050 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)uReadThis
;
1053 if (pfile_in_zip_read_info
->compression_method
==0)
1056 if (pfile_in_zip_read_info
->stream
.avail_out
<
1057 pfile_in_zip_read_info
->stream
.avail_in
)
1058 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_out
;
1060 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_in
;
1062 for (i
=0;i
<uDoCopy
;i
++)
1063 *(pfile_in_zip_read_info
->stream
.next_out
+i
) =
1064 *(pfile_in_zip_read_info
->stream
.next_in
+i
);
1066 pfile_in_zip_read_info
->crc32
= crc32(pfile_in_zip_read_info
->crc32
,
1067 pfile_in_zip_read_info
->stream
.next_out
,
1069 pfile_in_zip_read_info
->rest_read_uncompressed
-=uDoCopy
;
1070 pfile_in_zip_read_info
->stream
.avail_in
-= uDoCopy
;
1071 pfile_in_zip_read_info
->stream
.avail_out
-= uDoCopy
;
1072 pfile_in_zip_read_info
->stream
.next_out
+= uDoCopy
;
1073 pfile_in_zip_read_info
->stream
.next_in
+= uDoCopy
;
1074 pfile_in_zip_read_info
->stream
.total_out
+= uDoCopy
;
1079 uLong uTotalOutBefore
,uTotalOutAfter
;
1080 const Bytef
*bufBefore
;
1082 int flush
=Z_SYNC_FLUSH
;
1084 uTotalOutBefore
= pfile_in_zip_read_info
->stream
.total_out
;
1085 bufBefore
= pfile_in_zip_read_info
->stream
.next_out
;
1088 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1089 pfile_in_zip_read_info->stream.avail_out) &&
1090 (pfile_in_zip_read_info->rest_read_compressed == 0))
1093 err
=inflate(&pfile_in_zip_read_info
->stream
,flush
);
1095 uTotalOutAfter
= pfile_in_zip_read_info
->stream
.total_out
;
1096 uOutThis
= uTotalOutAfter
-uTotalOutBefore
;
1098 pfile_in_zip_read_info
->crc32
=
1099 crc32(pfile_in_zip_read_info
->crc32
,bufBefore
,
1102 pfile_in_zip_read_info
->rest_read_uncompressed
-=
1105 iRead
+= (uInt
)(uTotalOutAfter
- uTotalOutBefore
);
1107 if (err
==Z_STREAM_END
)
1108 return (iRead
==0) ? UNZ_EOF
: iRead
;
1121 Give the current position in uncompressed data
1123 extern z_off_t ZEXPORT
unztell (file
)
1127 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1129 return UNZ_PARAMERROR
;
1131 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1133 if (pfile_in_zip_read_info
==NULL
)
1134 return UNZ_PARAMERROR
;
1136 return (z_off_t
)pfile_in_zip_read_info
->stream
.total_out
;
1141 return 1 if the end of file was reached, 0 elsewhere
1143 extern int ZEXPORT
unzeof (file
)
1147 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1149 return UNZ_PARAMERROR
;
1151 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1153 if (pfile_in_zip_read_info
==NULL
)
1154 return UNZ_PARAMERROR
;
1156 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1165 Read extra field from the current file (opened by unzOpenCurrentFile)
1166 This is the local-header version of the extra field (sometimes, there is
1167 more info in the local-header version than in the central-header)
1169 if buf==NULL, it return the size of the local extra field that can be read
1171 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1173 the return value is the number of bytes copied in buf, or (if <0)
1176 extern int ZEXPORT
unzGetLocalExtrafield (file
,buf
,len
)
1182 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1187 return UNZ_PARAMERROR
;
1189 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1191 if (pfile_in_zip_read_info
==NULL
)
1192 return UNZ_PARAMERROR
;
1194 size_to_read
= (pfile_in_zip_read_info
->size_local_extrafield
-
1195 pfile_in_zip_read_info
->pos_local_extrafield
);
1198 return (int)size_to_read
;
1200 if (len
>size_to_read
)
1201 read_now
= (uInt
)size_to_read
;
1203 read_now
= (uInt
)len
;
1208 if (fseek(pfile_in_zip_read_info
->file
,
1209 pfile_in_zip_read_info
->offset_local_extrafield
+
1210 pfile_in_zip_read_info
->pos_local_extrafield
,SEEK_SET
)!=0)
1213 if (fread(buf
,(uInt
)size_to_read
,1,pfile_in_zip_read_info
->file
)!=1)
1216 return (int)read_now
;
1220 Close the file in zip opened with unzipOpenCurrentFile
1221 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1223 extern int ZEXPORT
unzCloseCurrentFile (file
)
1229 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1231 return UNZ_PARAMERROR
;
1233 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1235 if (pfile_in_zip_read_info
==NULL
)
1236 return UNZ_PARAMERROR
;
1239 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1241 if (pfile_in_zip_read_info
->crc32
!= pfile_in_zip_read_info
->crc32_wait
)
1246 TRYFREE(pfile_in_zip_read_info
->read_buffer
);
1247 pfile_in_zip_read_info
->read_buffer
= NULL
;
1248 if (pfile_in_zip_read_info
->stream_initialised
)
1249 inflateEnd(&pfile_in_zip_read_info
->stream
);
1251 pfile_in_zip_read_info
->stream_initialised
= 0;
1252 TRYFREE(pfile_in_zip_read_info
);
1254 s
->pfile_in_zip_read
=NULL
;
1261 Get the global comment string of the ZipFile, in the szComment buffer.
1262 uSizeBuf is the size of the szComment buffer.
1263 return the number of byte copied or an error code <0
1265 extern int ZEXPORT
unzGetGlobalComment (file
, szComment
, uSizeBuf
)
1274 return UNZ_PARAMERROR
;
1277 uReadThis
= uSizeBuf
;
1278 if (uReadThis
>s
->gi
.size_comment
)
1279 uReadThis
= s
->gi
.size_comment
;
1281 if (fseek(s
->file
,s
->central_pos
+22,SEEK_SET
)!=0)
1287 if (fread(szComment
,(uInt
)uReadThis
,1,s
->file
)!=1)
1291 if ((szComment
!= NULL
) && (uSizeBuf
> s
->gi
.size_comment
))
1292 *(szComment
+s
->gi
.size_comment
)='\0';
1293 return (int)uReadThis
;