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 */
131 #if defined (__VISAGECPP__)
132 // VA always requires prototypes
133 int unzlocal_CheckCurrentFileCoherencyHeader (unz_s
*, uInt
*, uLong
*, uInt
*);
136 /* ===========================================================================
137 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
139 IN assertion: the stream s has been sucessfully opened for reading.
143 local
int unzlocal_getByte(fin
,pi
)
148 int err
= fread(&c
, 1, 1, fin
);
164 /* ===========================================================================
165 Reads a long in LSB order from the given gz_stream. Sets
167 local
int unzlocal_getShort (fin
,pX
)
175 err
= unzlocal_getByte(fin
,&i
);
179 err
= unzlocal_getByte(fin
,&i
);
189 local
int unzlocal_getLong (fin
,pX
)
197 err
= unzlocal_getByte(fin
,&i
);
201 err
= unzlocal_getByte(fin
,&i
);
205 err
= unzlocal_getByte(fin
,&i
);
209 err
= unzlocal_getByte(fin
,&i
);
220 /* My own strcmpi / strcasecmp */
221 local
int strcmpcasenosensitive_internal (fileName1
,fileName2
)
222 const char* fileName1
;
223 const char* fileName2
;
227 char c1
=*(fileName1
++);
228 char c2
=*(fileName2
++);
229 if ((c1
>='a') && (c1
<='z'))
231 if ((c2
>='a') && (c2
<='z'))
234 return ((c2
=='\0') ? 0 : -1);
245 #ifdef CASESENSITIVITYDEFAULT_NO
246 #define CASESENSITIVITYDEFAULTVALUE 2
248 #define CASESENSITIVITYDEFAULTVALUE 1
251 #ifndef STRCMPCASENOSENTIVEFUNCTION
252 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
256 Compare two filename (fileName1,fileName2).
257 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
258 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
260 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
261 (like 1 on Unix, 2 on Windows)
264 extern int ZEXPORT
unzStringFileNameCompare (fileName1
,fileName2
,iCaseSensitivity
)
265 const char* fileName1
;
266 const char* fileName2
;
267 int iCaseSensitivity
;
269 if (iCaseSensitivity
==0)
270 iCaseSensitivity
=CASESENSITIVITYDEFAULTVALUE
;
272 if (iCaseSensitivity
==1)
273 return strcmp(fileName1
,fileName2
);
275 return STRCMPCASENOSENTIVEFUNCTION(fileName1
,fileName2
);
278 #define BUFREADCOMMENT (0x400)
281 Locate the Central directory of a zipfile (at the end, just before
284 local uLong
unzlocal_SearchCentralDir(fin
)
290 uLong uMaxBack
=0xffff; /* maximum size of global comment */
293 if (fseek(fin
,0,SEEK_END
) != 0)
297 uSizeFile
= ftell( fin
);
299 if (uMaxBack
>uSizeFile
)
300 uMaxBack
= uSizeFile
;
302 buf
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4);
307 while (uBackRead
<uMaxBack
)
309 uLong uReadSize
,uReadPos
;
311 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
)
312 uBackRead
= uMaxBack
;
314 uBackRead
+=BUFREADCOMMENT
;
315 uReadPos
= uSizeFile
-uBackRead
;
317 uReadSize
= ((BUFREADCOMMENT
+4) < (uSizeFile
-uReadPos
)) ?
318 (BUFREADCOMMENT
+4) : (uSizeFile
-uReadPos
);
319 if (fseek(fin
,uReadPos
,SEEK_SET
)!=0)
322 if (fread(buf
,(uInt
)uReadSize
,1,fin
)!=1)
325 for (i
=(int)uReadSize
-3; (i
--)>0;)
326 if (((*(buf
+i
))==0x50) && ((*(buf
+i
+1))==0x4b) &&
327 ((*(buf
+i
+2))==0x05) && ((*(buf
+i
+3))==0x06))
329 uPosFound
= uReadPos
+i
;
341 Open a Zip file. path contain the full pathname (by example,
342 on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
344 If the zipfile cannot be opened (file don't exist or in not valid), the
345 return value is NULL.
346 Else, the return value is a unzFile Handle, usable with other function
347 of this unzip package.
349 extern unzFile ZEXPORT
unzOpen (path
)
354 uLong central_pos
,uL
;
357 uLong number_disk
; /* number of the current dist, used for
358 spaning ZIP, unsupported, always 0*/
359 uLong number_disk_with_CD
; /* number the the disk with central dir, used
360 for spaning ZIP, unsupported, always 0*/
361 uLong number_entry_CD
; /* total number of entries in
363 (same than number_entry on nospan) */
367 if (unz_copyright
[0]!=' ')
370 fin
=fopen(path
,"rb");
374 central_pos
= unzlocal_SearchCentralDir(fin
);
378 if (fseek(fin
,central_pos
,SEEK_SET
)!=0)
381 /* the signature, already checked */
382 if (unzlocal_getLong(fin
,&uL
)!=UNZ_OK
)
385 /* number of this disk */
386 if (unzlocal_getShort(fin
,&number_disk
)!=UNZ_OK
)
389 /* number of the disk with the start of the central directory */
390 if (unzlocal_getShort(fin
,&number_disk_with_CD
)!=UNZ_OK
)
393 /* total number of entries in the central dir on this disk */
394 if (unzlocal_getShort(fin
,&us
.gi
.number_entry
)!=UNZ_OK
)
397 /* total number of entries in the central dir */
398 if (unzlocal_getShort(fin
,&number_entry_CD
)!=UNZ_OK
)
401 if ((number_entry_CD
!=us
.gi
.number_entry
) ||
402 (number_disk_with_CD
!=0) ||
406 /* size of the central directory */
407 if (unzlocal_getLong(fin
,&us
.size_central_dir
)!=UNZ_OK
)
410 /* offset of start of central directory with respect to the
411 starting disk number */
412 if (unzlocal_getLong(fin
,&us
.offset_central_dir
)!=UNZ_OK
)
415 /* zipfile comment length */
416 if (unzlocal_getShort(fin
,&us
.gi
.size_comment
)!=UNZ_OK
)
419 if ((central_pos
<us
.offset_central_dir
+us
.size_central_dir
) &&
429 us
.byte_before_the_zipfile
= central_pos
-
430 (us
.offset_central_dir
+us
.size_central_dir
);
431 us
.central_pos
= central_pos
;
432 us
.pfile_in_zip_read
= NULL
;
435 s
=(unz_s
*)ALLOC(sizeof(unz_s
));
437 unzGoToFirstFile((unzFile
)s
);
443 Close a ZipFile opened with unzipOpen.
444 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
445 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
446 return UNZ_OK if there is no problem. */
447 extern int ZEXPORT
unzClose (file
)
452 return UNZ_PARAMERROR
;
455 if (s
->pfile_in_zip_read
!=NULL
)
456 unzCloseCurrentFile(file
);
465 Write info about the ZipFile in the *pglobal_info structure.
466 No preparation of the structure is needed
467 return UNZ_OK if there is no problem. */
468 extern int ZEXPORT
unzGetGlobalInfo (file
,pglobal_info
)
470 unz_global_info
*pglobal_info
;
474 return UNZ_PARAMERROR
;
482 Translate date/time from Dos format to tm_unz (readable more easilty)
484 local
void unzlocal_DosDateToTmuDate (ulDosDate
, ptm
)
489 uDate
= (uLong
)(ulDosDate
>>16);
490 ptm
->tm_mday
= (uInt
)(uDate
&0x1f) ;
491 ptm
->tm_mon
= (uInt
)((((uDate
)&0x1E0)/0x20)-1) ;
492 ptm
->tm_year
= (uInt
)(((uDate
&0x0FE00)/0x0200)+1980) ;
494 ptm
->tm_hour
= (uInt
) ((ulDosDate
&0xF800)/0x800);
495 ptm
->tm_min
= (uInt
) ((ulDosDate
&0x7E0)/0x20) ;
496 ptm
->tm_sec
= (uInt
) (2*(ulDosDate
&0x1f)) ;
500 Get Info about the current file in the zipfile, with internal only info
502 local
int unzlocal_GetCurrentFileInfoInternal
OF((unzFile file
,
503 unz_file_info
*pfile_info
,
504 unz_file_info_internal
505 *pfile_info_internal
,
507 uLong fileNameBufferSize
,
509 uLong extraFieldBufferSize
,
511 uLong commentBufferSize
));
513 local
int unzlocal_GetCurrentFileInfoInternal (file
,
516 szFileName
, fileNameBufferSize
,
517 extraField
, extraFieldBufferSize
,
518 szComment
, commentBufferSize
)
520 unz_file_info
*pfile_info
;
521 unz_file_info_internal
*pfile_info_internal
;
523 uLong fileNameBufferSize
;
525 uLong extraFieldBufferSize
;
527 uLong commentBufferSize
;
530 unz_file_info file_info
;
531 unz_file_info_internal file_info_internal
;
537 return UNZ_PARAMERROR
;
539 if (fseek(s
->file
,s
->pos_in_central_dir
+s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
543 /* we check the magic */
545 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
547 else if (uMagic
!=0x02014b50)
550 if (unzlocal_getShort(s
->file
,&file_info
.version
) != UNZ_OK
)
553 if (unzlocal_getShort(s
->file
,&file_info
.version_needed
) != UNZ_OK
)
556 if (unzlocal_getShort(s
->file
,&file_info
.flag
) != UNZ_OK
)
559 if (unzlocal_getShort(s
->file
,&file_info
.compression_method
) != UNZ_OK
)
562 if (unzlocal_getLong(s
->file
,&file_info
.dosDate
) != UNZ_OK
)
565 unzlocal_DosDateToTmuDate(file_info
.dosDate
,&file_info
.tmu_date
);
567 if (unzlocal_getLong(s
->file
,&file_info
.crc
) != UNZ_OK
)
570 if (unzlocal_getLong(s
->file
,&file_info
.compressed_size
) != UNZ_OK
)
573 if (unzlocal_getLong(s
->file
,&file_info
.uncompressed_size
) != UNZ_OK
)
576 if (unzlocal_getShort(s
->file
,&file_info
.size_filename
) != UNZ_OK
)
579 if (unzlocal_getShort(s
->file
,&file_info
.size_file_extra
) != UNZ_OK
)
582 if (unzlocal_getShort(s
->file
,&file_info
.size_file_comment
) != UNZ_OK
)
585 if (unzlocal_getShort(s
->file
,&file_info
.disk_num_start
) != UNZ_OK
)
588 if (unzlocal_getShort(s
->file
,&file_info
.internal_fa
) != UNZ_OK
)
591 if (unzlocal_getLong(s
->file
,&file_info
.external_fa
) != UNZ_OK
)
594 if (unzlocal_getLong(s
->file
,&file_info_internal
.offset_curfile
) != UNZ_OK
)
597 lSeek
+=file_info
.size_filename
;
598 if ((err
==UNZ_OK
) && (szFileName
!=NULL
))
601 if (file_info
.size_filename
<fileNameBufferSize
)
603 *(szFileName
+file_info
.size_filename
)='\0';
604 uSizeRead
= file_info
.size_filename
;
607 uSizeRead
= fileNameBufferSize
;
609 if ((file_info
.size_filename
>0) && (fileNameBufferSize
>0))
610 if (fread(szFileName
,(uInt
)uSizeRead
,1,s
->file
)!=1)
616 if ((err
==UNZ_OK
) && (extraField
!=NULL
))
619 if (file_info
.size_file_extra
<extraFieldBufferSize
)
620 uSizeRead
= file_info
.size_file_extra
;
622 uSizeRead
= extraFieldBufferSize
;
625 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
629 if ((file_info
.size_file_extra
>0) && (extraFieldBufferSize
>0))
630 if (fread(extraField
,(uInt
)uSizeRead
,1,s
->file
)!=1)
632 lSeek
+= file_info
.size_file_extra
- uSizeRead
;
635 lSeek
+=file_info
.size_file_extra
;
638 if ((err
==UNZ_OK
) && (szComment
!=NULL
))
641 if (file_info
.size_file_comment
<commentBufferSize
)
643 *(szComment
+file_info
.size_file_comment
)='\0';
644 uSizeRead
= file_info
.size_file_comment
;
647 uSizeRead
= commentBufferSize
;
650 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
654 if ((file_info
.size_file_comment
>0) && (commentBufferSize
>0))
655 if (fread(szComment
,(uInt
)uSizeRead
,1,s
->file
)!=1)
657 lSeek
+=file_info
.size_file_comment
- uSizeRead
;
660 lSeek
+=file_info
.size_file_comment
;
662 if ((err
==UNZ_OK
) && (pfile_info
!=NULL
))
663 *pfile_info
=file_info
;
665 if ((err
==UNZ_OK
) && (pfile_info_internal
!=NULL
))
666 *pfile_info_internal
=file_info_internal
;
674 Write info about the ZipFile in the *pglobal_info structure.
675 No preparation of the structure is needed
676 return UNZ_OK if there is no problem.
678 extern int ZEXPORT
unzGetCurrentFileInfo (file
,
680 szFileName
, fileNameBufferSize
,
681 extraField
, extraFieldBufferSize
,
682 szComment
, commentBufferSize
)
684 unz_file_info
*pfile_info
;
686 uLong fileNameBufferSize
;
688 uLong extraFieldBufferSize
;
690 uLong commentBufferSize
;
692 return unzlocal_GetCurrentFileInfoInternal(file
,pfile_info
,NULL
,
693 szFileName
,fileNameBufferSize
,
694 extraField
,extraFieldBufferSize
,
695 szComment
,commentBufferSize
);
699 Set the current file of the zipfile to the first file.
700 return UNZ_OK if there is no problem
702 extern int ZEXPORT
unzGoToFirstFile (file
)
708 return UNZ_PARAMERROR
;
710 s
->pos_in_central_dir
=s
->offset_central_dir
;
712 err
=unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
713 &s
->cur_file_info_internal
,
714 NULL
,0,NULL
,0,NULL
,0);
715 s
->current_file_ok
= (err
== UNZ_OK
);
721 Set the current file of the zipfile to the next file.
722 return UNZ_OK if there is no problem
723 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
725 extern int ZEXPORT
unzGoToNextFile (file
)
732 return UNZ_PARAMERROR
;
734 if (!s
->current_file_ok
)
735 return UNZ_END_OF_LIST_OF_FILE
;
736 if (s
->num_file
+1==s
->gi
.number_entry
)
737 return UNZ_END_OF_LIST_OF_FILE
;
739 s
->pos_in_central_dir
+= SIZECENTRALDIRITEM
+ s
->cur_file_info
.size_filename
+
740 s
->cur_file_info
.size_file_extra
+ s
->cur_file_info
.size_file_comment
;
742 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
743 &s
->cur_file_info_internal
,
744 NULL
,0,NULL
,0,NULL
,0);
745 s
->current_file_ok
= (err
== UNZ_OK
);
751 Try locate the file szFileName in the zipfile.
752 For the iCaseSensitivity signification, see unzipStringFileNameCompare
755 UNZ_OK if the file is found. It becomes the current file.
756 UNZ_END_OF_LIST_OF_FILE if the file is not found
758 extern int ZEXPORT
unzLocateFile (file
, szFileName
, iCaseSensitivity
)
760 const char *szFileName
;
761 int iCaseSensitivity
;
768 uLong pos_in_central_dirSaved
;
772 return UNZ_PARAMERROR
;
774 if (strlen(szFileName
)>=UNZ_MAXFILENAMEINZIP
)
775 return UNZ_PARAMERROR
;
778 if (!s
->current_file_ok
)
779 return UNZ_END_OF_LIST_OF_FILE
;
781 num_fileSaved
= s
->num_file
;
782 pos_in_central_dirSaved
= s
->pos_in_central_dir
;
784 err
= unzGoToFirstFile(file
);
786 while (err
== UNZ_OK
)
788 char szCurrentFileName
[UNZ_MAXFILENAMEINZIP
+1];
789 unzGetCurrentFileInfo(file
,NULL
,
790 szCurrentFileName
,sizeof(szCurrentFileName
)-1,
792 if (unzStringFileNameCompare(szCurrentFileName
,
793 szFileName
,iCaseSensitivity
)==0)
795 err
= unzGoToNextFile(file
);
798 s
->num_file
= num_fileSaved
;
799 s
->pos_in_central_dir
= pos_in_central_dirSaved
;
805 Read the local header of the current zipfile
806 Check the coherency of the local header and info in the end of central
807 directory about this file
808 store in *piSizeVar the size of extra info in local header
809 (filename and size of extra field data)
811 local
int unzlocal_CheckCurrentFileCoherencyHeader (s
,piSizeVar
,
812 poffset_local_extrafield
,
813 psize_local_extrafield
)
816 uLong
*poffset_local_extrafield
;
817 uInt
*psize_local_extrafield
;
819 uLong uMagic
,uData
,uFlags
;
821 uLong size_extra_field
;
825 *poffset_local_extrafield
= 0;
826 *psize_local_extrafield
= 0;
828 if (fseek(s
->file
,s
->cur_file_info_internal
.offset_curfile
+
829 s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
834 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
836 else if (uMagic
!=0x04034b50)
839 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
842 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
845 if (unzlocal_getShort(s
->file
,&uFlags
) != UNZ_OK
)
848 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
850 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compression_method
))
853 if ((err
==UNZ_OK
) && (s
->cur_file_info
.compression_method
!=0) &&
854 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
857 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* date/time */
860 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* crc */
862 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.crc
) &&
866 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size compr */
868 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compressed_size
) &&
872 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size uncompr */
874 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.uncompressed_size
) &&
879 if (unzlocal_getShort(s
->file
,&size_filename
) != UNZ_OK
)
881 else if ((err
==UNZ_OK
) && (size_filename
!=s
->cur_file_info
.size_filename
))
884 *piSizeVar
+= (uInt
)size_filename
;
886 if (unzlocal_getShort(s
->file
,&size_extra_field
) != UNZ_OK
)
888 *poffset_local_extrafield
= s
->cur_file_info_internal
.offset_curfile
+
889 SIZEZIPLOCALHEADER
+ size_filename
;
890 *psize_local_extrafield
= (uInt
)size_extra_field
;
892 *piSizeVar
+= (uInt
)size_extra_field
;
898 Open for reading data the current file in the zipfile.
899 If there is no error and the file is opened, the return value is UNZ_OK.
901 extern int ZEXPORT
unzOpenCurrentFile (file
)
908 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
909 uLong offset_local_extrafield
; /* offset of the local extra field */
910 uInt size_local_extrafield
; /* size of the local extra field */
913 return UNZ_PARAMERROR
;
915 if (!s
->current_file_ok
)
916 return UNZ_PARAMERROR
;
918 if (s
->pfile_in_zip_read
!= NULL
)
919 unzCloseCurrentFile(file
);
921 if (unzlocal_CheckCurrentFileCoherencyHeader(s
,&iSizeVar
,
922 &offset_local_extrafield
,&size_local_extrafield
)!=UNZ_OK
)
923 return UNZ_BADZIPFILE
;
925 pfile_in_zip_read_info
= (file_in_zip_read_info_s
*)
926 ALLOC(sizeof(file_in_zip_read_info_s
));
927 if (pfile_in_zip_read_info
==NULL
)
928 return UNZ_INTERNALERROR
;
930 pfile_in_zip_read_info
->read_buffer
=(char*)ALLOC(UNZ_BUFSIZE
);
931 pfile_in_zip_read_info
->offset_local_extrafield
= offset_local_extrafield
;
932 pfile_in_zip_read_info
->size_local_extrafield
= size_local_extrafield
;
933 pfile_in_zip_read_info
->pos_local_extrafield
=0;
935 if (pfile_in_zip_read_info
->read_buffer
==NULL
)
937 TRYFREE(pfile_in_zip_read_info
);
938 return UNZ_INTERNALERROR
;
941 pfile_in_zip_read_info
->stream_initialised
=0;
943 if ((s
->cur_file_info
.compression_method
!=0) &&
944 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
946 Store
= s
->cur_file_info
.compression_method
==0;
948 pfile_in_zip_read_info
->crc32_wait
=s
->cur_file_info
.crc
;
949 pfile_in_zip_read_info
->crc32
=0;
950 pfile_in_zip_read_info
->compression_method
=
951 s
->cur_file_info
.compression_method
;
952 pfile_in_zip_read_info
->file
=s
->file
;
953 pfile_in_zip_read_info
->byte_before_the_zipfile
=s
->byte_before_the_zipfile
;
955 pfile_in_zip_read_info
->stream
.total_out
= 0;
959 pfile_in_zip_read_info
->stream
.zalloc
= (alloc_func
)0;
960 pfile_in_zip_read_info
->stream
.zfree
= (free_func
)0;
961 pfile_in_zip_read_info
->stream
.opaque
= (voidpf
)0;
963 err
=inflateInit2(&pfile_in_zip_read_info
->stream
, -MAX_WBITS
);
965 pfile_in_zip_read_info
->stream_initialised
=1;
966 /* windowBits is passed < 0 to tell that there is no zlib header.
967 * Note that in this case inflate *requires* an extra "dummy" byte
968 * after the compressed stream in order to complete decompression and
969 * return Z_STREAM_END.
970 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
971 * size of both compressed and uncompressed data
974 pfile_in_zip_read_info
->rest_read_compressed
=
975 s
->cur_file_info
.compressed_size
;
976 pfile_in_zip_read_info
->rest_read_uncompressed
=
977 s
->cur_file_info
.uncompressed_size
;
980 pfile_in_zip_read_info
->pos_in_zipfile
=
981 s
->cur_file_info_internal
.offset_curfile
+ SIZEZIPLOCALHEADER
+
984 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)0;
987 s
->pfile_in_zip_read
= pfile_in_zip_read_info
;
993 Read bytes from the current file.
994 buf contain buffer where data must be copied
997 return the number of byte copied if somes bytes are copied
998 return 0 if the end of file was reached
999 return <0 with error code if there is an error
1000 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1002 extern int ZEXPORT
unzReadCurrentFile (file
, buf
, len
)
1010 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1012 return UNZ_PARAMERROR
;
1014 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1016 if (pfile_in_zip_read_info
==NULL
)
1017 return UNZ_PARAMERROR
;
1020 if ((pfile_in_zip_read_info
->read_buffer
== NULL
))
1021 return UNZ_END_OF_LIST_OF_FILE
;
1025 pfile_in_zip_read_info
->stream
.next_out
= (Bytef
*)buf
;
1027 pfile_in_zip_read_info
->stream
.avail_out
= (uInt
)len
;
1029 if (len
>pfile_in_zip_read_info
->rest_read_uncompressed
)
1030 pfile_in_zip_read_info
->stream
.avail_out
=
1031 (uInt
)pfile_in_zip_read_info
->rest_read_uncompressed
;
1033 while (pfile_in_zip_read_info
->stream
.avail_out
>0)
1035 if ((pfile_in_zip_read_info
->stream
.avail_in
==0) &&
1036 (pfile_in_zip_read_info
->rest_read_compressed
>0))
1038 uInt uReadThis
= UNZ_BUFSIZE
;
1039 if (pfile_in_zip_read_info
->rest_read_compressed
<uReadThis
)
1040 uReadThis
= (uInt
)pfile_in_zip_read_info
->rest_read_compressed
;
1043 if (fseek(pfile_in_zip_read_info
->file
,
1044 pfile_in_zip_read_info
->pos_in_zipfile
+
1045 pfile_in_zip_read_info
->byte_before_the_zipfile
,SEEK_SET
)!=0)
1047 if (fread(pfile_in_zip_read_info
->read_buffer
,uReadThis
,1,
1048 pfile_in_zip_read_info
->file
)!=1)
1050 pfile_in_zip_read_info
->pos_in_zipfile
+= uReadThis
;
1052 pfile_in_zip_read_info
->rest_read_compressed
-=uReadThis
;
1054 pfile_in_zip_read_info
->stream
.next_in
=
1055 (Bytef
*)pfile_in_zip_read_info
->read_buffer
;
1056 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)uReadThis
;
1059 if (pfile_in_zip_read_info
->compression_method
==0)
1062 if (pfile_in_zip_read_info
->stream
.avail_out
<
1063 pfile_in_zip_read_info
->stream
.avail_in
)
1064 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_out
;
1066 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_in
;
1068 for (i
=0;i
<uDoCopy
;i
++)
1069 *(pfile_in_zip_read_info
->stream
.next_out
+i
) =
1070 *(pfile_in_zip_read_info
->stream
.next_in
+i
);
1072 pfile_in_zip_read_info
->crc32
= crc32(pfile_in_zip_read_info
->crc32
,
1073 pfile_in_zip_read_info
->stream
.next_out
,
1075 pfile_in_zip_read_info
->rest_read_uncompressed
-=uDoCopy
;
1076 pfile_in_zip_read_info
->stream
.avail_in
-= uDoCopy
;
1077 pfile_in_zip_read_info
->stream
.avail_out
-= uDoCopy
;
1078 pfile_in_zip_read_info
->stream
.next_out
+= uDoCopy
;
1079 pfile_in_zip_read_info
->stream
.next_in
+= uDoCopy
;
1080 pfile_in_zip_read_info
->stream
.total_out
+= uDoCopy
;
1085 uLong uTotalOutBefore
,uTotalOutAfter
;
1086 const Bytef
*bufBefore
;
1088 int flush
=Z_SYNC_FLUSH
;
1090 uTotalOutBefore
= pfile_in_zip_read_info
->stream
.total_out
;
1091 bufBefore
= pfile_in_zip_read_info
->stream
.next_out
;
1094 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1095 pfile_in_zip_read_info->stream.avail_out) &&
1096 (pfile_in_zip_read_info->rest_read_compressed == 0))
1099 err
=inflate(&pfile_in_zip_read_info
->stream
,flush
);
1101 uTotalOutAfter
= pfile_in_zip_read_info
->stream
.total_out
;
1102 uOutThis
= uTotalOutAfter
-uTotalOutBefore
;
1104 pfile_in_zip_read_info
->crc32
=
1105 crc32(pfile_in_zip_read_info
->crc32
,bufBefore
,
1108 pfile_in_zip_read_info
->rest_read_uncompressed
-=
1111 iRead
+= (uInt
)(uTotalOutAfter
- uTotalOutBefore
);
1113 if (err
==Z_STREAM_END
)
1114 return (iRead
==0) ? UNZ_EOF
: iRead
;
1127 Give the current position in uncompressed data
1129 extern z_off_t ZEXPORT
unztell (file
)
1133 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1135 return UNZ_PARAMERROR
;
1137 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1139 if (pfile_in_zip_read_info
==NULL
)
1140 return UNZ_PARAMERROR
;
1142 return (z_off_t
)pfile_in_zip_read_info
->stream
.total_out
;
1147 return 1 if the end of file was reached, 0 elsewhere
1149 extern int ZEXPORT
unzeof (file
)
1153 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1155 return UNZ_PARAMERROR
;
1157 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1159 if (pfile_in_zip_read_info
==NULL
)
1160 return UNZ_PARAMERROR
;
1162 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1171 Read extra field from the current file (opened by unzOpenCurrentFile)
1172 This is the local-header version of the extra field (sometimes, there is
1173 more info in the local-header version than in the central-header)
1175 if buf==NULL, it return the size of the local extra field that can be read
1177 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1179 the return value is the number of bytes copied in buf, or (if <0)
1182 extern int ZEXPORT
unzGetLocalExtrafield (file
,buf
,len
)
1188 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1193 return UNZ_PARAMERROR
;
1195 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1197 if (pfile_in_zip_read_info
==NULL
)
1198 return UNZ_PARAMERROR
;
1200 size_to_read
= (pfile_in_zip_read_info
->size_local_extrafield
-
1201 pfile_in_zip_read_info
->pos_local_extrafield
);
1204 return (int)size_to_read
;
1206 if (len
>size_to_read
)
1207 read_now
= (uInt
)size_to_read
;
1209 read_now
= (uInt
)len
;
1214 if (fseek(pfile_in_zip_read_info
->file
,
1215 pfile_in_zip_read_info
->offset_local_extrafield
+
1216 pfile_in_zip_read_info
->pos_local_extrafield
,SEEK_SET
)!=0)
1219 if (fread(buf
,(uInt
)size_to_read
,1,pfile_in_zip_read_info
->file
)!=1)
1222 return (int)read_now
;
1226 Close the file in zip opened with unzipOpenCurrentFile
1227 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1229 extern int ZEXPORT
unzCloseCurrentFile (file
)
1235 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1237 return UNZ_PARAMERROR
;
1239 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1241 if (pfile_in_zip_read_info
==NULL
)
1242 return UNZ_PARAMERROR
;
1245 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1247 if (pfile_in_zip_read_info
->crc32
!= pfile_in_zip_read_info
->crc32_wait
)
1252 TRYFREE(pfile_in_zip_read_info
->read_buffer
);
1253 pfile_in_zip_read_info
->read_buffer
= NULL
;
1254 if (pfile_in_zip_read_info
->stream_initialised
)
1255 inflateEnd(&pfile_in_zip_read_info
->stream
);
1257 pfile_in_zip_read_info
->stream_initialised
= 0;
1258 TRYFREE(pfile_in_zip_read_info
);
1260 s
->pfile_in_zip_read
=NULL
;
1267 Get the global comment string of the ZipFile, in the szComment buffer.
1268 uSizeBuf is the size of the szComment buffer.
1269 return the number of byte copied or an error code <0
1271 extern int ZEXPORT
unzGetGlobalComment (file
, szComment
, uSizeBuf
)
1280 return UNZ_PARAMERROR
;
1283 uReadThis
= uSizeBuf
;
1284 if (uReadThis
>s
->gi
.size_comment
)
1285 uReadThis
= s
->gi
.size_comment
;
1287 if (fseek(s
->file
,s
->central_pos
+22,SEEK_SET
)!=0)
1293 if (fread(szComment
,(uInt
)uReadThis
,1,s
->file
)!=1)
1297 if ((szComment
!= NULL
) && (uSizeBuf
> s
->gi
.size_comment
))
1298 *(szComment
+s
->gi
.size_comment
)='\0';
1299 return (int)uReadThis
;
1304 // the file shouldn't be empty, som compilers don't like it
1305 static const int dummyVariableInUnzip
= 17;
1307 #endif // wxUSE_ZLIB && wxUSE_ZIPSTREAM