1 /* unzip.c -- IO on .zip files using zlib
2 Version 0.15 beta, Mar 19th, 1998,
4 Read unzip.h for more info
9 #if wxUSE_ZLIB && wxUSE_ZIPSTREAM
32 /* compile with -Dlocal if your debugger can't find static symbols */
36 #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
37 !defined(CASESENSITIVITYDEFAULT_NO)
38 #define CASESENSITIVITYDEFAULT_NO
43 #define UNZ_BUFSIZE (16384)
46 #ifndef UNZ_MAXFILENAMEINZIP
47 #define UNZ_MAXFILENAMEINZIP (256)
51 # define ALLOC(size) (malloc(size))
54 # define TRYFREE(p) {if (p) free(p);}
57 #define SIZECENTRALDIRITEM (0x2e)
58 #define SIZEZIPLOCALHEADER (0x1e)
61 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
75 const char unz_copyright
[] =
76 " unzip 0.15 Copyright 1998 Gilles Vollant ";
78 /* unz_file_info_interntal contain internal info about a file in zipfile*/
79 typedef struct unz_file_info_internal_s
81 uLong offset_curfile
;/* relative offset of local header 4 bytes */
82 } unz_file_info_internal
;
85 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
86 when reading and decompress it */
89 char *read_buffer
; /* internal buffer for compressed data */
90 z_stream stream
; /* zLib stream structure for inflate */
92 uLong pos_in_zipfile
; /* position in byte on the zipfile, for fseek*/
93 uLong stream_initialised
; /* flag set if stream structure is initialised*/
95 uLong offset_local_extrafield
;/* offset of the local extra field */
96 uInt size_local_extrafield
;/* size of the local extra field */
97 uLong pos_local_extrafield
; /* position in the local extra field in read*/
99 uLong crc32
; /* crc32 of all data uncompressed */
100 uLong crc32_wait
; /* crc32 we must obtain after decompress all */
101 uLong rest_read_compressed
; /* number of byte to be decompressed */
102 uLong rest_read_uncompressed
;/*number of byte to be obtained after decomp*/
103 FILE* file
; /* io structore of the zipfile */
104 uLong compression_method
; /* compression method (0==store) */
105 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
106 } file_in_zip_read_info_s
;
109 /* unz_s contain internal information about the zipfile
113 FILE* file
; /* io structore of the zipfile */
114 unz_global_info gi
; /* public global information */
115 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
116 uLong num_file
; /* number of the current file in the zipfile*/
117 uLong pos_in_central_dir
; /* pos of the current file in the central dir*/
118 uLong current_file_ok
; /* flag about the usability of the current file*/
119 uLong central_pos
; /* position of the beginning of the central dir*/
121 uLong size_central_dir
; /* size of the central directory */
122 uLong offset_central_dir
; /* offset of start of central directory with
123 respect to the starting disk number */
125 unz_file_info cur_file_info
; /* public info about the current file in zip*/
126 unz_file_info_internal cur_file_info_internal
; /* private info about it*/
127 file_in_zip_read_info_s
* pfile_in_zip_read
; /* structure about the current
128 file if we are decompressing it */
132 /* ===========================================================================
133 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
135 IN assertion: the stream s has been sucessfully opened for reading.
139 local
int unzlocal_getByte(fin
,pi
)
144 int err
= fread(&c
, 1, 1, fin
);
160 /* ===========================================================================
161 Reads a long in LSB order from the given gz_stream. Sets
163 local
int unzlocal_getShort (fin
,pX
)
171 err
= unzlocal_getByte(fin
,&i
);
175 err
= unzlocal_getByte(fin
,&i
);
185 local
int unzlocal_getLong (fin
,pX
)
193 err
= unzlocal_getByte(fin
,&i
);
197 err
= unzlocal_getByte(fin
,&i
);
201 err
= unzlocal_getByte(fin
,&i
);
205 err
= unzlocal_getByte(fin
,&i
);
216 /* My own strcmpi / strcasecmp */
217 local
int strcmpcasenosensitive_internal (fileName1
,fileName2
)
218 const char* fileName1
;
219 const char* fileName2
;
223 char c1
=*(fileName1
++);
224 char c2
=*(fileName2
++);
225 if ((c1
>='a') && (c1
<='z'))
227 if ((c2
>='a') && (c2
<='z'))
230 return ((c2
=='\0') ? 0 : -1);
241 #ifdef CASESENSITIVITYDEFAULT_NO
242 #define CASESENSITIVITYDEFAULTVALUE 2
244 #define CASESENSITIVITYDEFAULTVALUE 1
247 #ifndef STRCMPCASENOSENTIVEFUNCTION
248 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
252 Compare two filename (fileName1,fileName2).
253 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
254 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
256 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
257 (like 1 on Unix, 2 on Windows)
260 extern int ZEXPORT
unzStringFileNameCompare (fileName1
,fileName2
,iCaseSensitivity
)
261 const char* fileName1
;
262 const char* fileName2
;
263 int iCaseSensitivity
;
265 if (iCaseSensitivity
==0)
266 iCaseSensitivity
=CASESENSITIVITYDEFAULTVALUE
;
268 if (iCaseSensitivity
==1)
269 return strcmp(fileName1
,fileName2
);
271 return STRCMPCASENOSENTIVEFUNCTION(fileName1
,fileName2
);
274 #define BUFREADCOMMENT (0x400)
277 Locate the Central directory of a zipfile (at the end, just before
280 local uLong
unzlocal_SearchCentralDir(fin
)
286 uLong uMaxBack
=0xffff; /* maximum size of global comment */
289 if (fseek(fin
,0,SEEK_END
) != 0)
293 uSizeFile
= ftell( fin
);
295 if (uMaxBack
>uSizeFile
)
296 uMaxBack
= uSizeFile
;
298 buf
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4);
303 while (uBackRead
<uMaxBack
)
305 uLong uReadSize
,uReadPos
;
307 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
)
308 uBackRead
= uMaxBack
;
310 uBackRead
+=BUFREADCOMMENT
;
311 uReadPos
= uSizeFile
-uBackRead
;
313 uReadSize
= ((BUFREADCOMMENT
+4) < (uSizeFile
-uReadPos
)) ?
314 (BUFREADCOMMENT
+4) : (uSizeFile
-uReadPos
);
315 if (fseek(fin
,uReadPos
,SEEK_SET
)!=0)
318 if (fread(buf
,(uInt
)uReadSize
,1,fin
)!=1)
321 for (i
=(int)uReadSize
-3; (i
--)>0;)
322 if (((*(buf
+i
))==0x50) && ((*(buf
+i
+1))==0x4b) &&
323 ((*(buf
+i
+2))==0x05) && ((*(buf
+i
+3))==0x06))
325 uPosFound
= uReadPos
+i
;
337 Open a Zip file. path contain the full pathname (by example,
338 on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
340 If the zipfile cannot be opened (file don't exist or in not valid), the
341 return value is NULL.
342 Else, the return value is a unzFile Handle, usable with other function
343 of this unzip package.
345 extern unzFile ZEXPORT
unzOpen (path
)
350 uLong central_pos
,uL
;
353 uLong number_disk
; /* number of the current dist, used for
354 spaning ZIP, unsupported, always 0*/
355 uLong number_disk_with_CD
; /* number the the disk with central dir, used
356 for spaning ZIP, unsupported, always 0*/
357 uLong number_entry_CD
; /* total number of entries in
359 (same than number_entry on nospan) */
363 if (unz_copyright
[0]!=' ')
366 fin
=fopen(path
,"rb");
370 central_pos
= unzlocal_SearchCentralDir(fin
);
374 if (fseek(fin
,central_pos
,SEEK_SET
)!=0)
377 /* the signature, already checked */
378 if (unzlocal_getLong(fin
,&uL
)!=UNZ_OK
)
381 /* number of this disk */
382 if (unzlocal_getShort(fin
,&number_disk
)!=UNZ_OK
)
385 /* number of the disk with the start of the central directory */
386 if (unzlocal_getShort(fin
,&number_disk_with_CD
)!=UNZ_OK
)
389 /* total number of entries in the central dir on this disk */
390 if (unzlocal_getShort(fin
,&us
.gi
.number_entry
)!=UNZ_OK
)
393 /* total number of entries in the central dir */
394 if (unzlocal_getShort(fin
,&number_entry_CD
)!=UNZ_OK
)
397 if ((number_entry_CD
!=us
.gi
.number_entry
) ||
398 (number_disk_with_CD
!=0) ||
402 /* size of the central directory */
403 if (unzlocal_getLong(fin
,&us
.size_central_dir
)!=UNZ_OK
)
406 /* offset of start of central directory with respect to the
407 starting disk number */
408 if (unzlocal_getLong(fin
,&us
.offset_central_dir
)!=UNZ_OK
)
411 /* zipfile comment length */
412 if (unzlocal_getShort(fin
,&us
.gi
.size_comment
)!=UNZ_OK
)
415 if ((central_pos
<us
.offset_central_dir
+us
.size_central_dir
) &&
426 us
.byte_before_the_zipfile
= central_pos
-
427 (us
.offset_central_dir
+us
.size_central_dir
);
428 us
.central_pos
= central_pos
;
429 us
.pfile_in_zip_read
= NULL
;
432 s
=(unz_s
*)ALLOC(sizeof(unz_s
));
434 unzGoToFirstFile((unzFile
)s
);
440 Close a ZipFile opened with unzipOpen.
441 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
442 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
443 return UNZ_OK if there is no problem. */
444 extern int ZEXPORT
unzClose (file
)
449 return UNZ_PARAMERROR
;
452 if (s
->pfile_in_zip_read
!=NULL
)
453 unzCloseCurrentFile(file
);
462 Write info about the ZipFile in the *pglobal_info structure.
463 No preparation of the structure is needed
464 return UNZ_OK if there is no problem. */
465 extern int ZEXPORT
unzGetGlobalInfo (file
,pglobal_info
)
467 unz_global_info
*pglobal_info
;
471 return UNZ_PARAMERROR
;
479 Translate date/time from Dos format to tm_unz (readable more easilty)
481 local
void unzlocal_DosDateToTmuDate (ulDosDate
, ptm
)
486 uDate
= (uLong
)(ulDosDate
>>16);
487 ptm
->tm_mday
= (uInt
)(uDate
&0x1f) ;
488 ptm
->tm_mon
= (uInt
)((((uDate
)&0x1E0)/0x20)-1) ;
489 ptm
->tm_year
= (uInt
)(((uDate
&0x0FE00)/0x0200)+1980) ;
491 ptm
->tm_hour
= (uInt
) ((ulDosDate
&0xF800)/0x800);
492 ptm
->tm_min
= (uInt
) ((ulDosDate
&0x7E0)/0x20) ;
493 ptm
->tm_sec
= (uInt
) (2*(ulDosDate
&0x1f)) ;
497 Get Info about the current file in the zipfile, with internal only info
499 local
int unzlocal_GetCurrentFileInfoInternal
OF((unzFile file
,
500 unz_file_info
*pfile_info
,
501 unz_file_info_internal
502 *pfile_info_internal
,
504 uLong fileNameBufferSize
,
506 uLong extraFieldBufferSize
,
508 uLong commentBufferSize
));
510 local
int unzlocal_GetCurrentFileInfoInternal (file
,
513 szFileName
, fileNameBufferSize
,
514 extraField
, extraFieldBufferSize
,
515 szComment
, commentBufferSize
)
517 unz_file_info
*pfile_info
;
518 unz_file_info_internal
*pfile_info_internal
;
520 uLong fileNameBufferSize
;
522 uLong extraFieldBufferSize
;
524 uLong commentBufferSize
;
527 unz_file_info file_info
;
528 unz_file_info_internal file_info_internal
;
534 return UNZ_PARAMERROR
;
536 if (fseek(s
->file
,s
->pos_in_central_dir
+s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
540 /* we check the magic */
542 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
544 else if (uMagic
!=0x02014b50)
547 if (unzlocal_getShort(s
->file
,&file_info
.version
) != UNZ_OK
)
550 if (unzlocal_getShort(s
->file
,&file_info
.version_needed
) != UNZ_OK
)
553 if (unzlocal_getShort(s
->file
,&file_info
.flag
) != UNZ_OK
)
556 if (unzlocal_getShort(s
->file
,&file_info
.compression_method
) != UNZ_OK
)
559 if (unzlocal_getLong(s
->file
,&file_info
.dosDate
) != UNZ_OK
)
562 unzlocal_DosDateToTmuDate(file_info
.dosDate
,&file_info
.tmu_date
);
564 if (unzlocal_getLong(s
->file
,&file_info
.crc
) != UNZ_OK
)
567 if (unzlocal_getLong(s
->file
,&file_info
.compressed_size
) != UNZ_OK
)
570 if (unzlocal_getLong(s
->file
,&file_info
.uncompressed_size
) != UNZ_OK
)
573 if (unzlocal_getShort(s
->file
,&file_info
.size_filename
) != UNZ_OK
)
576 if (unzlocal_getShort(s
->file
,&file_info
.size_file_extra
) != UNZ_OK
)
579 if (unzlocal_getShort(s
->file
,&file_info
.size_file_comment
) != UNZ_OK
)
582 if (unzlocal_getShort(s
->file
,&file_info
.disk_num_start
) != UNZ_OK
)
585 if (unzlocal_getShort(s
->file
,&file_info
.internal_fa
) != UNZ_OK
)
588 if (unzlocal_getLong(s
->file
,&file_info
.external_fa
) != UNZ_OK
)
591 if (unzlocal_getLong(s
->file
,&file_info_internal
.offset_curfile
) != UNZ_OK
)
594 lSeek
+=file_info
.size_filename
;
595 if ((err
==UNZ_OK
) && (szFileName
!=NULL
))
598 if (file_info
.size_filename
<fileNameBufferSize
)
600 *(szFileName
+file_info
.size_filename
)='\0';
601 uSizeRead
= file_info
.size_filename
;
604 uSizeRead
= fileNameBufferSize
;
606 if ((file_info
.size_filename
>0) && (fileNameBufferSize
>0))
607 if (fread(szFileName
,(uInt
)uSizeRead
,1,s
->file
)!=1)
613 if ((err
==UNZ_OK
) && (extraField
!=NULL
))
616 if (file_info
.size_file_extra
<extraFieldBufferSize
)
617 uSizeRead
= file_info
.size_file_extra
;
619 uSizeRead
= extraFieldBufferSize
;
622 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
626 if ((file_info
.size_file_extra
>0) && (extraFieldBufferSize
>0))
627 if (fread(extraField
,(uInt
)uSizeRead
,1,s
->file
)!=1)
629 lSeek
+= file_info
.size_file_extra
- uSizeRead
;
632 lSeek
+=file_info
.size_file_extra
;
635 if ((err
==UNZ_OK
) && (szComment
!=NULL
))
638 if (file_info
.size_file_comment
<commentBufferSize
)
640 *(szComment
+file_info
.size_file_comment
)='\0';
641 uSizeRead
= file_info
.size_file_comment
;
644 uSizeRead
= commentBufferSize
;
647 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
651 if ((file_info
.size_file_comment
>0) && (commentBufferSize
>0))
652 if (fread(szComment
,(uInt
)uSizeRead
,1,s
->file
)!=1)
654 lSeek
+=file_info
.size_file_comment
- uSizeRead
;
657 lSeek
+=file_info
.size_file_comment
;
659 if ((err
==UNZ_OK
) && (pfile_info
!=NULL
))
660 *pfile_info
=file_info
;
662 if ((err
==UNZ_OK
) && (pfile_info_internal
!=NULL
))
663 *pfile_info_internal
=file_info_internal
;
671 Write info about the ZipFile in the *pglobal_info structure.
672 No preparation of the structure is needed
673 return UNZ_OK if there is no problem.
675 extern int ZEXPORT
unzGetCurrentFileInfo (file
,
677 szFileName
, fileNameBufferSize
,
678 extraField
, extraFieldBufferSize
,
679 szComment
, commentBufferSize
)
681 unz_file_info
*pfile_info
;
683 uLong fileNameBufferSize
;
685 uLong extraFieldBufferSize
;
687 uLong commentBufferSize
;
689 return unzlocal_GetCurrentFileInfoInternal(file
,pfile_info
,NULL
,
690 szFileName
,fileNameBufferSize
,
691 extraField
,extraFieldBufferSize
,
692 szComment
,commentBufferSize
);
696 Set the current file of the zipfile to the first file.
697 return UNZ_OK if there is no problem
699 extern int ZEXPORT
unzGoToFirstFile (file
)
705 return UNZ_PARAMERROR
;
707 s
->pos_in_central_dir
=s
->offset_central_dir
;
709 err
=unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
710 &s
->cur_file_info_internal
,
711 NULL
,0,NULL
,0,NULL
,0);
712 s
->current_file_ok
= (err
== UNZ_OK
);
718 Set the current file of the zipfile to the next file.
719 return UNZ_OK if there is no problem
720 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
722 extern int ZEXPORT
unzGoToNextFile (file
)
729 return UNZ_PARAMERROR
;
731 if (!s
->current_file_ok
)
732 return UNZ_END_OF_LIST_OF_FILE
;
733 if (s
->num_file
+1==s
->gi
.number_entry
)
734 return UNZ_END_OF_LIST_OF_FILE
;
736 s
->pos_in_central_dir
+= SIZECENTRALDIRITEM
+ s
->cur_file_info
.size_filename
+
737 s
->cur_file_info
.size_file_extra
+ s
->cur_file_info
.size_file_comment
;
739 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
740 &s
->cur_file_info_internal
,
741 NULL
,0,NULL
,0,NULL
,0);
742 s
->current_file_ok
= (err
== UNZ_OK
);
748 Try locate the file szFileName in the zipfile.
749 For the iCaseSensitivity signification, see unzipStringFileNameCompare
752 UNZ_OK if the file is found. It becomes the current file.
753 UNZ_END_OF_LIST_OF_FILE if the file is not found
755 extern int ZEXPORT
unzLocateFile (file
, szFileName
, iCaseSensitivity
)
757 const char *szFileName
;
758 int iCaseSensitivity
;
765 uLong pos_in_central_dirSaved
;
769 return UNZ_PARAMERROR
;
771 if (strlen(szFileName
)>=UNZ_MAXFILENAMEINZIP
)
772 return UNZ_PARAMERROR
;
775 if (!s
->current_file_ok
)
776 return UNZ_END_OF_LIST_OF_FILE
;
778 num_fileSaved
= s
->num_file
;
779 pos_in_central_dirSaved
= s
->pos_in_central_dir
;
781 err
= unzGoToFirstFile(file
);
783 while (err
== UNZ_OK
)
785 char szCurrentFileName
[UNZ_MAXFILENAMEINZIP
+1];
786 unzGetCurrentFileInfo(file
,NULL
,
787 szCurrentFileName
,sizeof(szCurrentFileName
)-1,
789 if (unzStringFileNameCompare(szCurrentFileName
,
790 szFileName
,iCaseSensitivity
)==0)
792 err
= unzGoToNextFile(file
);
795 s
->num_file
= num_fileSaved
;
796 s
->pos_in_central_dir
= pos_in_central_dirSaved
;
802 Read the local header of the current zipfile
803 Check the coherency of the local header and info in the end of central
804 directory about this file
805 store in *piSizeVar the size of extra info in local header
806 (filename and size of extra field data)
808 local
int unzlocal_CheckCurrentFileCoherencyHeader (s
,piSizeVar
,
809 poffset_local_extrafield
,
810 psize_local_extrafield
)
813 uLong
*poffset_local_extrafield
;
814 uInt
*psize_local_extrafield
;
816 uLong uMagic
,uData
,uFlags
;
818 uLong size_extra_field
;
822 *poffset_local_extrafield
= 0;
823 *psize_local_extrafield
= 0;
825 if (fseek(s
->file
,s
->cur_file_info_internal
.offset_curfile
+
826 s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
831 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
833 else if (uMagic
!=0x04034b50)
836 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
839 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
842 if (unzlocal_getShort(s
->file
,&uFlags
) != UNZ_OK
)
845 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
847 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compression_method
))
850 if ((err
==UNZ_OK
) && (s
->cur_file_info
.compression_method
!=0) &&
851 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
854 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* date/time */
857 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* crc */
859 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.crc
) &&
863 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size compr */
865 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compressed_size
) &&
869 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size uncompr */
871 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.uncompressed_size
) &&
876 if (unzlocal_getShort(s
->file
,&size_filename
) != UNZ_OK
)
878 else if ((err
==UNZ_OK
) && (size_filename
!=s
->cur_file_info
.size_filename
))
881 *piSizeVar
+= (uInt
)size_filename
;
883 if (unzlocal_getShort(s
->file
,&size_extra_field
) != UNZ_OK
)
885 *poffset_local_extrafield
= s
->cur_file_info_internal
.offset_curfile
+
886 SIZEZIPLOCALHEADER
+ size_filename
;
887 *psize_local_extrafield
= (uInt
)size_extra_field
;
889 *piSizeVar
+= (uInt
)size_extra_field
;
895 Open for reading data the current file in the zipfile.
896 If there is no error and the file is opened, the return value is UNZ_OK.
898 extern int ZEXPORT
unzOpenCurrentFile (file
)
905 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
906 uLong offset_local_extrafield
; /* offset of the local extra field */
907 uInt size_local_extrafield
; /* size of the local extra field */
910 return UNZ_PARAMERROR
;
912 if (!s
->current_file_ok
)
913 return UNZ_PARAMERROR
;
915 if (s
->pfile_in_zip_read
!= NULL
)
916 unzCloseCurrentFile(file
);
918 if (unzlocal_CheckCurrentFileCoherencyHeader(s
,&iSizeVar
,
919 &offset_local_extrafield
,&size_local_extrafield
)!=UNZ_OK
)
920 return UNZ_BADZIPFILE
;
922 pfile_in_zip_read_info
= (file_in_zip_read_info_s
*)
923 ALLOC(sizeof(file_in_zip_read_info_s
));
924 if (pfile_in_zip_read_info
==NULL
)
925 return UNZ_INTERNALERROR
;
927 pfile_in_zip_read_info
->read_buffer
=(char*)ALLOC(UNZ_BUFSIZE
);
928 pfile_in_zip_read_info
->offset_local_extrafield
= offset_local_extrafield
;
929 pfile_in_zip_read_info
->size_local_extrafield
= size_local_extrafield
;
930 pfile_in_zip_read_info
->pos_local_extrafield
=0;
932 if (pfile_in_zip_read_info
->read_buffer
==NULL
)
934 TRYFREE(pfile_in_zip_read_info
);
935 return UNZ_INTERNALERROR
;
938 pfile_in_zip_read_info
->stream_initialised
=0;
940 if ((s
->cur_file_info
.compression_method
!=0) &&
941 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
943 Store
= s
->cur_file_info
.compression_method
==0;
945 pfile_in_zip_read_info
->crc32_wait
=s
->cur_file_info
.crc
;
946 pfile_in_zip_read_info
->crc32
=0;
947 pfile_in_zip_read_info
->compression_method
=
948 s
->cur_file_info
.compression_method
;
949 pfile_in_zip_read_info
->file
=s
->file
;
950 pfile_in_zip_read_info
->byte_before_the_zipfile
=s
->byte_before_the_zipfile
;
952 pfile_in_zip_read_info
->stream
.total_out
= 0;
956 pfile_in_zip_read_info
->stream
.zalloc
= (alloc_func
)0;
957 pfile_in_zip_read_info
->stream
.zfree
= (free_func
)0;
958 pfile_in_zip_read_info
->stream
.opaque
= (voidpf
)0;
960 err
=inflateInit2(&pfile_in_zip_read_info
->stream
, -MAX_WBITS
);
962 pfile_in_zip_read_info
->stream_initialised
=1;
963 /* windowBits is passed < 0 to tell that there is no zlib header.
964 * Note that in this case inflate *requires* an extra "dummy" byte
965 * after the compressed stream in order to complete decompression and
966 * return Z_STREAM_END.
967 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
968 * size of both compressed and uncompressed data
971 pfile_in_zip_read_info
->rest_read_compressed
=
972 s
->cur_file_info
.compressed_size
;
973 pfile_in_zip_read_info
->rest_read_uncompressed
=
974 s
->cur_file_info
.uncompressed_size
;
977 pfile_in_zip_read_info
->pos_in_zipfile
=
978 s
->cur_file_info_internal
.offset_curfile
+ SIZEZIPLOCALHEADER
+
981 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)0;
984 s
->pfile_in_zip_read
= pfile_in_zip_read_info
;
990 Read bytes from the current file.
991 buf contain buffer where data must be copied
994 return the number of byte copied if somes bytes are copied
995 return 0 if the end of file was reached
996 return <0 with error code if there is an error
997 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
999 extern int ZEXPORT
unzReadCurrentFile (file
, buf
, len
)
1007 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1009 return UNZ_PARAMERROR
;
1011 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1013 if (pfile_in_zip_read_info
==NULL
)
1014 return UNZ_PARAMERROR
;
1017 if ((pfile_in_zip_read_info
->read_buffer
== NULL
))
1018 return UNZ_END_OF_LIST_OF_FILE
;
1022 pfile_in_zip_read_info
->stream
.next_out
= (Bytef
*)buf
;
1024 pfile_in_zip_read_info
->stream
.avail_out
= (uInt
)len
;
1026 if (len
>pfile_in_zip_read_info
->rest_read_uncompressed
)
1027 pfile_in_zip_read_info
->stream
.avail_out
=
1028 (uInt
)pfile_in_zip_read_info
->rest_read_uncompressed
;
1030 while (pfile_in_zip_read_info
->stream
.avail_out
>0)
1032 if ((pfile_in_zip_read_info
->stream
.avail_in
==0) &&
1033 (pfile_in_zip_read_info
->rest_read_compressed
>0))
1035 uInt uReadThis
= UNZ_BUFSIZE
;
1036 if (pfile_in_zip_read_info
->rest_read_compressed
<uReadThis
)
1037 uReadThis
= (uInt
)pfile_in_zip_read_info
->rest_read_compressed
;
1040 if (fseek(pfile_in_zip_read_info
->file
,
1041 pfile_in_zip_read_info
->pos_in_zipfile
+
1042 pfile_in_zip_read_info
->byte_before_the_zipfile
,SEEK_SET
)!=0)
1044 if (fread(pfile_in_zip_read_info
->read_buffer
,uReadThis
,1,
1045 pfile_in_zip_read_info
->file
)!=1)
1047 pfile_in_zip_read_info
->pos_in_zipfile
+= uReadThis
;
1049 pfile_in_zip_read_info
->rest_read_compressed
-=uReadThis
;
1051 pfile_in_zip_read_info
->stream
.next_in
=
1052 (Bytef
*)pfile_in_zip_read_info
->read_buffer
;
1053 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)uReadThis
;
1056 if (pfile_in_zip_read_info
->compression_method
==0)
1059 if (pfile_in_zip_read_info
->stream
.avail_out
<
1060 pfile_in_zip_read_info
->stream
.avail_in
)
1061 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_out
;
1063 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_in
;
1065 for (i
=0;i
<uDoCopy
;i
++)
1066 *(pfile_in_zip_read_info
->stream
.next_out
+i
) =
1067 *(pfile_in_zip_read_info
->stream
.next_in
+i
);
1069 pfile_in_zip_read_info
->crc32
= crc32(pfile_in_zip_read_info
->crc32
,
1070 pfile_in_zip_read_info
->stream
.next_out
,
1072 pfile_in_zip_read_info
->rest_read_uncompressed
-=uDoCopy
;
1073 pfile_in_zip_read_info
->stream
.avail_in
-= uDoCopy
;
1074 pfile_in_zip_read_info
->stream
.avail_out
-= uDoCopy
;
1075 pfile_in_zip_read_info
->stream
.next_out
+= uDoCopy
;
1076 pfile_in_zip_read_info
->stream
.next_in
+= uDoCopy
;
1077 pfile_in_zip_read_info
->stream
.total_out
+= uDoCopy
;
1082 uLong uTotalOutBefore
,uTotalOutAfter
;
1083 const Bytef
*bufBefore
;
1085 int flush
=Z_SYNC_FLUSH
;
1087 uTotalOutBefore
= pfile_in_zip_read_info
->stream
.total_out
;
1088 bufBefore
= pfile_in_zip_read_info
->stream
.next_out
;
1091 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1092 pfile_in_zip_read_info->stream.avail_out) &&
1093 (pfile_in_zip_read_info->rest_read_compressed == 0))
1096 err
=inflate(&pfile_in_zip_read_info
->stream
,flush
);
1098 uTotalOutAfter
= pfile_in_zip_read_info
->stream
.total_out
;
1099 uOutThis
= uTotalOutAfter
-uTotalOutBefore
;
1101 pfile_in_zip_read_info
->crc32
=
1102 crc32(pfile_in_zip_read_info
->crc32
,bufBefore
,
1105 pfile_in_zip_read_info
->rest_read_uncompressed
-=
1108 iRead
+= (uInt
)(uTotalOutAfter
- uTotalOutBefore
);
1110 if (err
==Z_STREAM_END
)
1111 return (iRead
==0) ? UNZ_EOF
: iRead
;
1124 Give the current position in uncompressed data
1126 extern z_off_t ZEXPORT
unztell (file
)
1130 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1132 return UNZ_PARAMERROR
;
1134 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1136 if (pfile_in_zip_read_info
==NULL
)
1137 return UNZ_PARAMERROR
;
1139 return (z_off_t
)pfile_in_zip_read_info
->stream
.total_out
;
1144 return 1 if the end of file was reached, 0 elsewhere
1146 extern int ZEXPORT
unzeof (file
)
1150 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1152 return UNZ_PARAMERROR
;
1154 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1156 if (pfile_in_zip_read_info
==NULL
)
1157 return UNZ_PARAMERROR
;
1159 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1168 Read extra field from the current file (opened by unzOpenCurrentFile)
1169 This is the local-header version of the extra field (sometimes, there is
1170 more info in the local-header version than in the central-header)
1172 if buf==NULL, it return the size of the local extra field that can be read
1174 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1176 the return value is the number of bytes copied in buf, or (if <0)
1179 extern int ZEXPORT
unzGetLocalExtrafield (file
,buf
,len
)
1185 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1190 return UNZ_PARAMERROR
;
1192 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1194 if (pfile_in_zip_read_info
==NULL
)
1195 return UNZ_PARAMERROR
;
1197 size_to_read
= (pfile_in_zip_read_info
->size_local_extrafield
-
1198 pfile_in_zip_read_info
->pos_local_extrafield
);
1201 return (int)size_to_read
;
1203 if (len
>size_to_read
)
1204 read_now
= (uInt
)size_to_read
;
1206 read_now
= (uInt
)len
;
1211 if (fseek(pfile_in_zip_read_info
->file
,
1212 pfile_in_zip_read_info
->offset_local_extrafield
+
1213 pfile_in_zip_read_info
->pos_local_extrafield
,SEEK_SET
)!=0)
1216 if (fread(buf
,(uInt
)size_to_read
,1,pfile_in_zip_read_info
->file
)!=1)
1219 return (int)read_now
;
1223 Close the file in zip opened with unzipOpenCurrentFile
1224 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1226 extern int ZEXPORT
unzCloseCurrentFile (file
)
1232 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1234 return UNZ_PARAMERROR
;
1236 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1238 if (pfile_in_zip_read_info
==NULL
)
1239 return UNZ_PARAMERROR
;
1242 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1244 if (pfile_in_zip_read_info
->crc32
!= pfile_in_zip_read_info
->crc32_wait
)
1249 TRYFREE(pfile_in_zip_read_info
->read_buffer
);
1250 pfile_in_zip_read_info
->read_buffer
= NULL
;
1251 if (pfile_in_zip_read_info
->stream_initialised
)
1252 inflateEnd(&pfile_in_zip_read_info
->stream
);
1254 pfile_in_zip_read_info
->stream_initialised
= 0;
1255 TRYFREE(pfile_in_zip_read_info
);
1257 s
->pfile_in_zip_read
=NULL
;
1264 Get the global comment string of the ZipFile, in the szComment buffer.
1265 uSizeBuf is the size of the szComment buffer.
1266 return the number of byte copied or an error code <0
1268 extern int ZEXPORT
unzGetGlobalComment (file
, szComment
, uSizeBuf
)
1277 return UNZ_PARAMERROR
;
1280 uReadThis
= uSizeBuf
;
1281 if (uReadThis
>s
->gi
.size_comment
)
1282 uReadThis
= s
->gi
.size_comment
;
1284 if (fseek(s
->file
,s
->central_pos
+22,SEEK_SET
)!=0)
1290 if (fread(szComment
,(uInt
)uReadThis
,1,s
->file
)!=1)
1294 if ((szComment
!= NULL
) && (uSizeBuf
> s
->gi
.size_comment
))
1295 *(szComment
+s
->gi
.size_comment
)='\0';
1296 return (int)uReadThis
;
1301 // the file shouldn't be empty, som compilers don't like it
1302 static const int dummyVariableInUnzip
= 17;
1304 #endif // wxUSE_ZLIB && wxUSE_ZIPSTREAM