3 This file was altered for needs of wxWindows.
8 /* unzip.c -- IO on .zip files using zlib
9 Version 0.15 beta, Mar 19th, 1998,
11 Read unzip.h for more info
21 #if wxUSE_ZLIB && wxUSE_ZIPSTREAM
28 normally, the compiler options should contain -I../zlib, but it is
29 apparently not the case for all MSW makefiles and so, unless we use
30 configure (which defines __WX_SETUP_H__) or it is explicitly overridden by
31 the user (who can define wxUSE_ZLIB_H_IN_PATH), we hardcode the path here
33 #if defined(__WXMSW__) && !defined(__WX_SETUP_H__) && !defined(wxUSE_ZLIB_H_IN_PATH)
34 #include "../zlib/zlib.h"
40 /* Not the right solution (paths in makefiles) but... */
42 #include "../common/unzip.h"
62 /* compile with -Dlocal if your debugger can't find static symbols */
66 #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
67 !defined(CASESENSITIVITYDEFAULT_NO)
68 #define CASESENSITIVITYDEFAULT_NO
73 #define UNZ_BUFSIZE (16384)
76 #ifndef UNZ_MAXFILENAMEINZIP
77 #define UNZ_MAXFILENAMEINZIP (256)
81 # define ALLOC(size) (malloc(size))
84 # define TRYFREE(p) {if (p) free(p);}
87 #define SIZECENTRALDIRITEM (0x2e)
88 #define SIZEZIPLOCALHEADER (0x1e)
91 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
105 const char unz_copyright
[] =
106 " unzip 0.15 Copyright 1998 Gilles Vollant ";
108 /* unz_file_info_interntal contain internal info about a file in zipfile*/
109 typedef struct unz_file_info_internal_s
111 uLong offset_curfile
;/* relative offset of local header 4 bytes */
112 } unz_file_info_internal
;
115 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
116 when reading and decompress it */
119 char *read_buffer
; /* internal buffer for compressed data */
120 z_stream stream
; /* zLib stream structure for inflate */
122 uLong pos_in_zipfile
; /* position in byte on the zipfile, for fseek*/
123 uLong stream_initialised
; /* flag set if stream structure is initialised*/
125 uLong offset_local_extrafield
;/* offset of the local extra field */
126 uInt size_local_extrafield
;/* size of the local extra field */
127 uLong pos_local_extrafield
; /* position in the local extra field in read*/
129 uLong crc32
; /* crc32 of all data uncompressed */
130 uLong crc32_wait
; /* crc32 we must obtain after decompress all */
131 uLong rest_read_compressed
; /* number of byte to be decompressed */
132 uLong rest_read_uncompressed
;/*number of byte to be obtained after decomp*/
133 FILE* file
; /* io structore of the zipfile */
134 uLong compression_method
; /* compression method (0==store) */
135 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
136 } file_in_zip_read_info_s
;
139 /* unz_s contain internal information about the zipfile
143 FILE* file
; /* io structore of the zipfile */
144 unz_global_info gi
; /* public global information */
145 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
146 uLong num_file
; /* number of the current file in the zipfile*/
147 uLong pos_in_central_dir
; /* pos of the current file in the central dir*/
148 uLong current_file_ok
; /* flag about the usability of the current file*/
149 uLong central_pos
; /* position of the beginning of the central dir*/
151 uLong size_central_dir
; /* size of the central directory */
152 uLong offset_central_dir
; /* offset of start of central directory with
153 respect to the starting disk number */
155 unz_file_info cur_file_info
; /* public info about the current file in zip*/
156 unz_file_info_internal cur_file_info_internal
; /* private info about it*/
157 file_in_zip_read_info_s
* pfile_in_zip_read
; /* structure about the current
158 file if we are decompressing it */
161 #if defined (__VISAGECPP__) || defined(__BORLANDC__)
162 /* VA always requires prototypes */
163 int unzlocal_CheckCurrentFileCoherencyHeader (unz_s
*, uInt
*, uLong
*, uInt
*);
166 /* disable warnings about K&R declarations until the end of file */
168 #pragma warning(disable:4131)
171 /* ===========================================================================
172 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
174 IN assertion: the stream s has been sucessfully opened for reading.
178 local
int unzlocal_getByte(fin
,pi
)
183 int err
= fread(&c
, 1, 1, fin
);
199 /* ===========================================================================
200 Reads a long in LSB order from the given gz_stream. Sets
202 local
int unzlocal_getShort (fin
,pX
)
210 err
= unzlocal_getByte(fin
,&i
);
214 err
= unzlocal_getByte(fin
,&i
);
224 local
int unzlocal_getLong (fin
,pX
)
232 err
= unzlocal_getByte(fin
,&i
);
236 err
= unzlocal_getByte(fin
,&i
);
240 err
= unzlocal_getByte(fin
,&i
);
244 err
= unzlocal_getByte(fin
,&i
);
255 /* My own strcmpi / strcasecmp */
256 local
int strcmpcasenosensitive_internal (fileName1
,fileName2
)
257 const char* fileName1
;
258 const char* fileName2
;
262 char c1
=*(fileName1
++);
263 char c2
=*(fileName2
++);
264 if ((c1
>='a') && (c1
<='z'))
266 if ((c2
>='a') && (c2
<='z'))
269 return ((c2
=='\0') ? 0 : -1);
280 #ifdef CASESENSITIVITYDEFAULT_NO
281 #define CASESENSITIVITYDEFAULTVALUE 2
283 #define CASESENSITIVITYDEFAULTVALUE 1
286 #ifndef STRCMPCASENOSENTIVEFUNCTION
287 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
291 Compare two filename (fileName1,fileName2).
292 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
293 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
295 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
296 (like 1 on Unix, 2 on Windows)
299 extern int ZEXPORT
unzStringFileNameCompare (fileName1
,fileName2
,iCaseSensitivity
)
300 const char* fileName1
;
301 const char* fileName2
;
302 int iCaseSensitivity
;
304 if (iCaseSensitivity
==0)
305 iCaseSensitivity
=CASESENSITIVITYDEFAULTVALUE
;
307 if (iCaseSensitivity
==1)
308 return strcmp(fileName1
,fileName2
);
310 return STRCMPCASENOSENTIVEFUNCTION(fileName1
,fileName2
);
313 #define BUFREADCOMMENT (0x400)
316 Locate the Central directory of a zipfile (at the end, just before
319 local uLong
unzlocal_SearchCentralDir(fin
)
325 uLong uMaxBack
=0xffff; /* maximum size of global comment */
328 if (fseek(fin
,0,SEEK_END
) != 0)
332 uSizeFile
= ftell( fin
);
334 if (uMaxBack
>uSizeFile
)
335 uMaxBack
= uSizeFile
;
337 buf
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4);
342 while (uBackRead
<uMaxBack
)
344 uLong uReadSize
,uReadPos
;
346 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
)
347 uBackRead
= uMaxBack
;
349 uBackRead
+=BUFREADCOMMENT
;
350 uReadPos
= uSizeFile
-uBackRead
;
352 uReadSize
= ((BUFREADCOMMENT
+4) < (uSizeFile
-uReadPos
)) ?
353 (BUFREADCOMMENT
+4) : (uSizeFile
-uReadPos
);
354 if (fseek(fin
,uReadPos
,SEEK_SET
)!=0)
357 if (fread(buf
,(uInt
)uReadSize
,1,fin
)!=1)
360 for (i
=(int)uReadSize
-3; (i
--)>0;)
361 if (((*(buf
+i
))==0x50) && ((*(buf
+i
+1))==0x4b) &&
362 ((*(buf
+i
+2))==0x05) && ((*(buf
+i
+3))==0x06))
364 uPosFound
= uReadPos
+i
;
375 #if defined(__WXMAC__) && !defined(__UNIX__)
376 void wxUnix2MacFilename (char *s
) ;
378 wxUnix2MacFilename (char *s
)
384 /* relative path , since it goes on with slash which is translated to a : */
385 memmove( s
, s
+1 ,strlen( s
) ) ;
387 else if ( *s
== '/' )
389 /* absolute path -> on mac just start with the drive name */
390 memmove( s
, s
+1 ,strlen( s
) ) ;
394 /* wxASSERT_MSG( 1 , "unkown path beginning" ) ; */
398 if (*s
== '/' || *s
== '\\')
400 /* convert any back-directory situations */
401 if ( *(s
+1) == '.' && *(s
+2) == '.' && ( (*(s
+3) == '/' || *(s
+3) == '\\') ) )
404 memmove( s
+1 , s
+3 ,strlen( s
+3 ) + 1 ) ;
414 extern char * wxBuffer
;
418 Open a Zip file. path contain the full pathname (by example,
419 on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
421 If the zipfile cannot be opened (file don't exist or in not valid), the
422 return value is NULL.
423 Else, the return value is a unzFile Handle, usable with other function
424 of this unzip package.
426 extern unzFile ZEXPORT
unzOpen (path
)
431 uLong central_pos
,uL
;
434 uLong number_disk
; /* number of the current dist, used for
435 spaning ZIP, unsupported, always 0*/
436 uLong number_disk_with_CD
; /* number the the disk with central dir, used
437 for spaning ZIP, unsupported, always 0*/
438 uLong number_entry_CD
; /* total number of entries in
440 (same than number_entry on nospan) */
444 if (unz_copyright
[0]!=' ')
447 #if defined(__WXMAC__) && !defined(__UNIX__)
448 strcpy( wxBuffer
, path
) ;
449 wxUnix2MacFilename( wxBuffer
) ;
450 fin
=fopen(wxBuffer
,"rb");
452 fin
=fopen(path
,"rb");
457 central_pos
= unzlocal_SearchCentralDir(fin
);
461 if (fseek(fin
,central_pos
,SEEK_SET
)!=0)
464 /* the signature, already checked */
465 if (unzlocal_getLong(fin
,&uL
)!=UNZ_OK
)
468 /* number of this disk */
469 if (unzlocal_getShort(fin
,&number_disk
)!=UNZ_OK
)
472 /* number of the disk with the start of the central directory */
473 if (unzlocal_getShort(fin
,&number_disk_with_CD
)!=UNZ_OK
)
476 /* total number of entries in the central dir on this disk */
477 if (unzlocal_getShort(fin
,&us
.gi
.number_entry
)!=UNZ_OK
)
480 /* total number of entries in the central dir */
481 if (unzlocal_getShort(fin
,&number_entry_CD
)!=UNZ_OK
)
484 if ((number_entry_CD
!=us
.gi
.number_entry
) ||
485 (number_disk_with_CD
!=0) ||
489 /* size of the central directory */
490 if (unzlocal_getLong(fin
,&us
.size_central_dir
)!=UNZ_OK
)
493 /* offset of start of central directory with respect to the
494 starting disk number */
495 if (unzlocal_getLong(fin
,&us
.offset_central_dir
)!=UNZ_OK
)
498 /* zipfile comment length */
499 if (unzlocal_getShort(fin
,&us
.gi
.size_comment
)!=UNZ_OK
)
502 if ((central_pos
<us
.offset_central_dir
+us
.size_central_dir
) &&
512 us
.byte_before_the_zipfile
= central_pos
-
513 (us
.offset_central_dir
+us
.size_central_dir
);
514 us
.central_pos
= central_pos
;
515 us
.pfile_in_zip_read
= NULL
;
518 s
=(unz_s
*)ALLOC(sizeof(unz_s
));
520 unzGoToFirstFile((unzFile
)s
);
526 Close a ZipFile opened with unzipOpen.
527 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
528 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
529 return UNZ_OK if there is no problem. */
530 extern int ZEXPORT
unzClose (file
)
535 return UNZ_PARAMERROR
;
538 if (s
->pfile_in_zip_read
!=NULL
)
539 unzCloseCurrentFile(file
);
548 Write info about the ZipFile in the *pglobal_info structure.
549 No preparation of the structure is needed
550 return UNZ_OK if there is no problem. */
551 extern int ZEXPORT
unzGetGlobalInfo (file
,pglobal_info
)
553 unz_global_info
*pglobal_info
;
557 return UNZ_PARAMERROR
;
565 Translate date/time from Dos format to tm_unz (readable more easilty)
567 local
void unzlocal_DosDateToTmuDate (ulDosDate
, ptm
)
572 uDate
= (uLong
)(ulDosDate
>>16);
573 ptm
->tm_mday
= (uInt
)(uDate
&0x1f) ;
574 ptm
->tm_mon
= (uInt
)((((uDate
)&0x1E0)/0x20)-1) ;
575 ptm
->tm_year
= (uInt
)(((uDate
&0x0FE00)/0x0200)+1980) ;
577 ptm
->tm_hour
= (uInt
) ((ulDosDate
&0xF800)/0x800);
578 ptm
->tm_min
= (uInt
) ((ulDosDate
&0x7E0)/0x20) ;
579 ptm
->tm_sec
= (uInt
) (2*(ulDosDate
&0x1f)) ;
583 Get Info about the current file in the zipfile, with internal only info
585 local
int unzlocal_GetCurrentFileInfoInternal
OF((unzFile file
,
586 unz_file_info
*pfile_info
,
587 unz_file_info_internal
588 *pfile_info_internal
,
590 uLong fileNameBufferSize
,
592 uLong extraFieldBufferSize
,
594 uLong commentBufferSize
));
596 local
int unzlocal_GetCurrentFileInfoInternal (file
,
599 szFileName
, fileNameBufferSize
,
600 extraField
, extraFieldBufferSize
,
601 szComment
, commentBufferSize
)
603 unz_file_info
*pfile_info
;
604 unz_file_info_internal
*pfile_info_internal
;
606 uLong fileNameBufferSize
;
608 uLong extraFieldBufferSize
;
610 uLong commentBufferSize
;
613 unz_file_info file_info
;
614 unz_file_info_internal file_info_internal
;
620 return UNZ_PARAMERROR
;
622 if (fseek(s
->file
,s
->pos_in_central_dir
+s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
626 /* we check the magic */
629 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
631 else if (uMagic
!=0x02014b50)
635 if (unzlocal_getShort(s
->file
,&file_info
.version
) != UNZ_OK
)
638 if (unzlocal_getShort(s
->file
,&file_info
.version_needed
) != UNZ_OK
)
641 if (unzlocal_getShort(s
->file
,&file_info
.flag
) != UNZ_OK
)
644 if (unzlocal_getShort(s
->file
,&file_info
.compression_method
) != UNZ_OK
)
647 if (unzlocal_getLong(s
->file
,&file_info
.dosDate
) != UNZ_OK
)
650 unzlocal_DosDateToTmuDate(file_info
.dosDate
,&file_info
.tmu_date
);
652 if (unzlocal_getLong(s
->file
,&file_info
.crc
) != UNZ_OK
)
655 if (unzlocal_getLong(s
->file
,&file_info
.compressed_size
) != UNZ_OK
)
658 if (unzlocal_getLong(s
->file
,&file_info
.uncompressed_size
) != UNZ_OK
)
661 if (unzlocal_getShort(s
->file
,&file_info
.size_filename
) != UNZ_OK
)
664 if (unzlocal_getShort(s
->file
,&file_info
.size_file_extra
) != UNZ_OK
)
667 if (unzlocal_getShort(s
->file
,&file_info
.size_file_comment
) != UNZ_OK
)
670 if (unzlocal_getShort(s
->file
,&file_info
.disk_num_start
) != UNZ_OK
)
673 if (unzlocal_getShort(s
->file
,&file_info
.internal_fa
) != UNZ_OK
)
676 if (unzlocal_getLong(s
->file
,&file_info
.external_fa
) != UNZ_OK
)
679 if (unzlocal_getLong(s
->file
,&file_info_internal
.offset_curfile
) != UNZ_OK
)
682 lSeek
+=file_info
.size_filename
;
683 if ((err
==UNZ_OK
) && (szFileName
!=NULL
))
686 if (file_info
.size_filename
<fileNameBufferSize
)
688 *(szFileName
+file_info
.size_filename
)='\0';
689 uSizeRead
= file_info
.size_filename
;
692 uSizeRead
= fileNameBufferSize
;
694 if ((file_info
.size_filename
>0) && (fileNameBufferSize
>0))
695 if (fread(szFileName
,(uInt
)uSizeRead
,1,s
->file
)!=1)
701 if ((err
==UNZ_OK
) && (extraField
!=NULL
))
704 if (file_info
.size_file_extra
<extraFieldBufferSize
)
705 uSizeRead
= file_info
.size_file_extra
;
707 uSizeRead
= extraFieldBufferSize
;
711 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
717 if ((file_info
.size_file_extra
>0) && (extraFieldBufferSize
>0))
718 if (fread(extraField
,(uInt
)uSizeRead
,1,s
->file
)!=1)
720 lSeek
+= file_info
.size_file_extra
- uSizeRead
;
723 lSeek
+=file_info
.size_file_extra
;
726 if ((err
==UNZ_OK
) && (szComment
!=NULL
))
729 if (file_info
.size_file_comment
<commentBufferSize
)
731 *(szComment
+file_info
.size_file_comment
)='\0';
732 uSizeRead
= file_info
.size_file_comment
;
735 uSizeRead
= commentBufferSize
;
739 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
745 if ((file_info
.size_file_comment
>0) && (commentBufferSize
>0))
746 if (fread(szComment
,(uInt
)uSizeRead
,1,s
->file
)!=1)
748 lSeek
+=file_info
.size_file_comment
- uSizeRead
;
751 lSeek
+=file_info
.size_file_comment
;
753 if ((err
==UNZ_OK
) && (pfile_info
!=NULL
))
754 *pfile_info
=file_info
;
756 if ((err
==UNZ_OK
) && (pfile_info_internal
!=NULL
))
757 *pfile_info_internal
=file_info_internal
;
765 Write info about the ZipFile in the *pglobal_info structure.
766 No preparation of the structure is needed
767 return UNZ_OK if there is no problem.
769 extern int ZEXPORT
unzGetCurrentFileInfo (file
,
771 szFileName
, fileNameBufferSize
,
772 extraField
, extraFieldBufferSize
,
773 szComment
, commentBufferSize
)
775 unz_file_info
*pfile_info
;
777 uLong fileNameBufferSize
;
779 uLong extraFieldBufferSize
;
781 uLong commentBufferSize
;
783 return unzlocal_GetCurrentFileInfoInternal(file
,pfile_info
,NULL
,
784 szFileName
,fileNameBufferSize
,
785 extraField
,extraFieldBufferSize
,
786 szComment
,commentBufferSize
);
790 Set the current file of the zipfile to the first file.
791 return UNZ_OK if there is no problem
793 extern int ZEXPORT
unzGoToFirstFile (file
)
799 return UNZ_PARAMERROR
;
801 s
->pos_in_central_dir
=s
->offset_central_dir
;
803 err
=unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
804 &s
->cur_file_info_internal
,
805 NULL
,0,NULL
,0,NULL
,0);
806 s
->current_file_ok
= (err
== UNZ_OK
);
812 Set the current file of the zipfile to the next file.
813 return UNZ_OK if there is no problem
814 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
816 extern int ZEXPORT
unzGoToNextFile (file
)
823 return UNZ_PARAMERROR
;
825 if (!s
->current_file_ok
)
826 return UNZ_END_OF_LIST_OF_FILE
;
827 if (s
->num_file
+1==s
->gi
.number_entry
)
828 return UNZ_END_OF_LIST_OF_FILE
;
830 s
->pos_in_central_dir
+= SIZECENTRALDIRITEM
+ s
->cur_file_info
.size_filename
+
831 s
->cur_file_info
.size_file_extra
+ s
->cur_file_info
.size_file_comment
;
833 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
834 &s
->cur_file_info_internal
,
835 NULL
,0,NULL
,0,NULL
,0);
836 s
->current_file_ok
= (err
== UNZ_OK
);
842 Try locate the file szFileName in the zipfile.
843 For the iCaseSensitivity signification, see unzipStringFileNameCompare
846 UNZ_OK if the file is found. It becomes the current file.
847 UNZ_END_OF_LIST_OF_FILE if the file is not found
849 extern int ZEXPORT
unzLocateFile (file
, szFileName
, iCaseSensitivity
)
851 const char *szFileName
;
852 int iCaseSensitivity
;
858 char szFileName2
[UNZ_MAXFILENAMEINZIP
+1];
861 uLong pos_in_central_dirSaved
;
863 for (c
= szFileName
, c2
= szFileName2
; *c
!= '\0'; c
++, c2
++)
864 if (*c
== '\\') *c2
= '/';
869 return UNZ_PARAMERROR
;
871 if (strlen(szFileName
)>=UNZ_MAXFILENAMEINZIP
)
872 return UNZ_PARAMERROR
;
875 if (!s
->current_file_ok
)
876 return UNZ_END_OF_LIST_OF_FILE
;
878 num_fileSaved
= s
->num_file
;
879 pos_in_central_dirSaved
= s
->pos_in_central_dir
;
881 err
= unzGoToFirstFile(file
);
883 while (err
== UNZ_OK
)
885 char szCurrentFileName
[UNZ_MAXFILENAMEINZIP
+1];
886 unzGetCurrentFileInfo(file
,NULL
,
887 szCurrentFileName
,sizeof(szCurrentFileName
)-1,
889 for (c2
= szCurrentFileName
; *c2
!= '\0'; c2
++) if (*c2
== '\\') *c2
= '/';
890 if (unzStringFileNameCompare(szCurrentFileName
,
891 szFileName2
,iCaseSensitivity
)==0)
893 err
= unzGoToNextFile(file
);
896 s
->num_file
= num_fileSaved
;
897 s
->pos_in_central_dir
= pos_in_central_dirSaved
;
903 Read the local header of the current zipfile
904 Check the coherency of the local header and info in the end of central
905 directory about this file
906 store in *piSizeVar the size of extra info in local header
907 (filename and size of extra field data)
909 local
int unzlocal_CheckCurrentFileCoherencyHeader (s
,piSizeVar
,
910 poffset_local_extrafield
,
911 psize_local_extrafield
)
914 uLong
*poffset_local_extrafield
;
915 uInt
*psize_local_extrafield
;
917 uLong uMagic
,uData
,uFlags
;
919 uLong size_extra_field
;
923 *poffset_local_extrafield
= 0;
924 *psize_local_extrafield
= 0;
926 if (fseek(s
->file
,s
->cur_file_info_internal
.offset_curfile
+
927 s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
933 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
935 else if (uMagic
!=0x04034b50)
939 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
942 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
945 if (unzlocal_getShort(s
->file
,&uFlags
) != UNZ_OK
)
948 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
950 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compression_method
))
953 if ((err
==UNZ_OK
) && (s
->cur_file_info
.compression_method
!=0) &&
954 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
957 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* date/time */
960 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* crc */
962 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.crc
) &&
966 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size compr */
968 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compressed_size
) &&
972 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size uncompr */
974 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.uncompressed_size
) &&
979 if (unzlocal_getShort(s
->file
,&size_filename
) != UNZ_OK
)
981 else if ((err
==UNZ_OK
) && (size_filename
!=s
->cur_file_info
.size_filename
))
984 *piSizeVar
+= (uInt
)size_filename
;
986 if (unzlocal_getShort(s
->file
,&size_extra_field
) != UNZ_OK
)
988 *poffset_local_extrafield
= s
->cur_file_info_internal
.offset_curfile
+
989 SIZEZIPLOCALHEADER
+ size_filename
;
990 *psize_local_extrafield
= (uInt
)size_extra_field
;
992 *piSizeVar
+= (uInt
)size_extra_field
;
998 Open for reading data the current file in the zipfile.
999 If there is no error and the file is opened, the return value is UNZ_OK.
1001 extern int ZEXPORT
unzOpenCurrentFile (file
)
1008 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1009 uLong offset_local_extrafield
; /* offset of the local extra field */
1010 uInt size_local_extrafield
; /* size of the local extra field */
1013 return UNZ_PARAMERROR
;
1015 if (!s
->current_file_ok
)
1016 return UNZ_PARAMERROR
;
1018 if (s
->pfile_in_zip_read
!= NULL
)
1019 unzCloseCurrentFile(file
);
1021 if (unzlocal_CheckCurrentFileCoherencyHeader(s
,&iSizeVar
,
1022 &offset_local_extrafield
,&size_local_extrafield
)!=UNZ_OK
)
1023 return UNZ_BADZIPFILE
;
1025 pfile_in_zip_read_info
= (file_in_zip_read_info_s
*)
1026 ALLOC(sizeof(file_in_zip_read_info_s
));
1027 if (pfile_in_zip_read_info
==NULL
)
1028 return UNZ_INTERNALERROR
;
1030 pfile_in_zip_read_info
->read_buffer
=(char*)ALLOC(UNZ_BUFSIZE
);
1031 pfile_in_zip_read_info
->offset_local_extrafield
= offset_local_extrafield
;
1032 pfile_in_zip_read_info
->size_local_extrafield
= size_local_extrafield
;
1033 pfile_in_zip_read_info
->pos_local_extrafield
=0;
1035 if (pfile_in_zip_read_info
->read_buffer
==NULL
)
1037 TRYFREE(pfile_in_zip_read_info
);
1038 return UNZ_INTERNALERROR
;
1041 pfile_in_zip_read_info
->stream_initialised
=0;
1043 if ((s
->cur_file_info
.compression_method
!=0) &&
1044 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
1046 Store
= s
->cur_file_info
.compression_method
==0;
1048 pfile_in_zip_read_info
->crc32_wait
=s
->cur_file_info
.crc
;
1049 pfile_in_zip_read_info
->crc32
=0;
1050 pfile_in_zip_read_info
->compression_method
=
1051 s
->cur_file_info
.compression_method
;
1052 pfile_in_zip_read_info
->file
=s
->file
;
1053 pfile_in_zip_read_info
->byte_before_the_zipfile
=s
->byte_before_the_zipfile
;
1055 pfile_in_zip_read_info
->stream
.total_out
= 0;
1059 pfile_in_zip_read_info
->stream
.zalloc
= (alloc_func
)0;
1060 pfile_in_zip_read_info
->stream
.zfree
= (free_func
)0;
1061 pfile_in_zip_read_info
->stream
.opaque
= (voidpf
)0;
1063 err
=inflateInit2(&pfile_in_zip_read_info
->stream
, -MAX_WBITS
);
1065 pfile_in_zip_read_info
->stream_initialised
=1;
1066 /* windowBits is passed < 0 to tell that there is no zlib header.
1067 * Note that in this case inflate *requires* an extra "dummy" byte
1068 * after the compressed stream in order to complete decompression and
1069 * return Z_STREAM_END.
1070 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1071 * size of both compressed and uncompressed data
1074 pfile_in_zip_read_info
->rest_read_compressed
=
1075 s
->cur_file_info
.compressed_size
;
1076 pfile_in_zip_read_info
->rest_read_uncompressed
=
1077 s
->cur_file_info
.uncompressed_size
;
1080 pfile_in_zip_read_info
->pos_in_zipfile
=
1081 s
->cur_file_info_internal
.offset_curfile
+ SIZEZIPLOCALHEADER
+
1084 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)0;
1087 s
->pfile_in_zip_read
= pfile_in_zip_read_info
;
1093 Read bytes from the current file.
1094 buf contain buffer where data must be copied
1095 len the size of buf.
1097 return the number of byte copied if somes bytes are copied
1098 return 0 if the end of file was reached
1099 return <0 with error code if there is an error
1100 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1102 extern int ZEXPORT
unzReadCurrentFile (file
, buf
, len
)
1110 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1112 return UNZ_PARAMERROR
;
1114 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1116 if (pfile_in_zip_read_info
==NULL
)
1117 return UNZ_PARAMERROR
;
1120 if ((pfile_in_zip_read_info
->read_buffer
== NULL
))
1121 return UNZ_END_OF_LIST_OF_FILE
;
1125 pfile_in_zip_read_info
->stream
.next_out
= (Bytef
*)buf
;
1127 pfile_in_zip_read_info
->stream
.avail_out
= (uInt
)len
;
1129 if (len
>pfile_in_zip_read_info
->rest_read_uncompressed
)
1130 pfile_in_zip_read_info
->stream
.avail_out
=
1131 (uInt
)pfile_in_zip_read_info
->rest_read_uncompressed
;
1133 while (pfile_in_zip_read_info
->stream
.avail_out
>0)
1135 if ((pfile_in_zip_read_info
->stream
.avail_in
==0) &&
1136 (pfile_in_zip_read_info
->rest_read_compressed
>0))
1138 uInt uReadThis
= UNZ_BUFSIZE
;
1139 if (pfile_in_zip_read_info
->rest_read_compressed
<uReadThis
)
1140 uReadThis
= (uInt
)pfile_in_zip_read_info
->rest_read_compressed
;
1143 if (fseek(pfile_in_zip_read_info
->file
,
1144 pfile_in_zip_read_info
->pos_in_zipfile
+
1145 pfile_in_zip_read_info
->byte_before_the_zipfile
,SEEK_SET
)!=0)
1147 if (fread(pfile_in_zip_read_info
->read_buffer
,uReadThis
,1,
1148 pfile_in_zip_read_info
->file
)!=1)
1150 pfile_in_zip_read_info
->pos_in_zipfile
+= uReadThis
;
1152 pfile_in_zip_read_info
->rest_read_compressed
-=uReadThis
;
1154 pfile_in_zip_read_info
->stream
.next_in
=
1155 (Bytef
*)pfile_in_zip_read_info
->read_buffer
;
1156 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)uReadThis
;
1159 if (pfile_in_zip_read_info
->compression_method
==0)
1162 if (pfile_in_zip_read_info
->stream
.avail_out
<
1163 pfile_in_zip_read_info
->stream
.avail_in
)
1164 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_out
;
1166 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_in
;
1168 for (i
=0;i
<uDoCopy
;i
++)
1169 *(pfile_in_zip_read_info
->stream
.next_out
+i
) =
1170 *(pfile_in_zip_read_info
->stream
.next_in
+i
);
1172 pfile_in_zip_read_info
->crc32
= crc32(pfile_in_zip_read_info
->crc32
,
1173 pfile_in_zip_read_info
->stream
.next_out
,
1175 pfile_in_zip_read_info
->rest_read_uncompressed
-=uDoCopy
;
1176 pfile_in_zip_read_info
->stream
.avail_in
-= uDoCopy
;
1177 pfile_in_zip_read_info
->stream
.avail_out
-= uDoCopy
;
1178 pfile_in_zip_read_info
->stream
.next_out
+= uDoCopy
;
1179 pfile_in_zip_read_info
->stream
.next_in
+= uDoCopy
;
1180 pfile_in_zip_read_info
->stream
.total_out
+= uDoCopy
;
1185 uLong uTotalOutBefore
,uTotalOutAfter
;
1186 const Bytef
*bufBefore
;
1188 int flush
=Z_SYNC_FLUSH
;
1190 uTotalOutBefore
= pfile_in_zip_read_info
->stream
.total_out
;
1191 bufBefore
= pfile_in_zip_read_info
->stream
.next_out
;
1194 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1195 pfile_in_zip_read_info->stream.avail_out) &&
1196 (pfile_in_zip_read_info->rest_read_compressed == 0))
1199 err
=inflate(&pfile_in_zip_read_info
->stream
,flush
);
1201 uTotalOutAfter
= pfile_in_zip_read_info
->stream
.total_out
;
1202 uOutThis
= uTotalOutAfter
-uTotalOutBefore
;
1204 pfile_in_zip_read_info
->crc32
=
1205 crc32(pfile_in_zip_read_info
->crc32
,bufBefore
,
1208 pfile_in_zip_read_info
->rest_read_uncompressed
-=
1211 iRead
+= (uInt
)(uTotalOutAfter
- uTotalOutBefore
);
1213 if (err
==Z_STREAM_END
)
1214 return (iRead
==0) ? UNZ_EOF
: iRead
;
1227 Give the current position in uncompressed data
1229 extern z_off_t ZEXPORT
unztell (file
)
1233 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1235 return UNZ_PARAMERROR
;
1237 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1239 if (pfile_in_zip_read_info
==NULL
)
1240 return UNZ_PARAMERROR
;
1242 return (z_off_t
)pfile_in_zip_read_info
->stream
.total_out
;
1247 return 1 if the end of file was reached, 0 elsewhere
1249 extern int ZEXPORT
unzeof (file
)
1253 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1255 return UNZ_PARAMERROR
;
1257 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1259 if (pfile_in_zip_read_info
==NULL
)
1260 return UNZ_PARAMERROR
;
1262 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1271 Read extra field from the current file (opened by unzOpenCurrentFile)
1272 This is the local-header version of the extra field (sometimes, there is
1273 more info in the local-header version than in the central-header)
1275 if buf==NULL, it return the size of the local extra field that can be read
1277 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1279 the return value is the number of bytes copied in buf, or (if <0)
1282 extern int ZEXPORT
unzGetLocalExtrafield (file
,buf
,len
)
1288 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1293 return UNZ_PARAMERROR
;
1295 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1297 if (pfile_in_zip_read_info
==NULL
)
1298 return UNZ_PARAMERROR
;
1300 size_to_read
= (pfile_in_zip_read_info
->size_local_extrafield
-
1301 pfile_in_zip_read_info
->pos_local_extrafield
);
1304 return (int)size_to_read
;
1306 if (len
>size_to_read
)
1307 read_now
= (uInt
)size_to_read
;
1309 read_now
= (uInt
)len
;
1314 if (fseek(pfile_in_zip_read_info
->file
,
1315 pfile_in_zip_read_info
->offset_local_extrafield
+
1316 pfile_in_zip_read_info
->pos_local_extrafield
,SEEK_SET
)!=0)
1319 if (fread(buf
,(uInt
)size_to_read
,1,pfile_in_zip_read_info
->file
)!=1)
1322 return (int)read_now
;
1326 Close the file in zip opened with unzipOpenCurrentFile
1327 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1329 extern int ZEXPORT
unzCloseCurrentFile (file
)
1335 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1337 return UNZ_PARAMERROR
;
1339 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1341 if (pfile_in_zip_read_info
==NULL
)
1342 return UNZ_PARAMERROR
;
1345 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1347 if (pfile_in_zip_read_info
->crc32
!= pfile_in_zip_read_info
->crc32_wait
)
1352 TRYFREE(pfile_in_zip_read_info
->read_buffer
);
1353 pfile_in_zip_read_info
->read_buffer
= NULL
;
1354 if (pfile_in_zip_read_info
->stream_initialised
)
1355 inflateEnd(&pfile_in_zip_read_info
->stream
);
1357 pfile_in_zip_read_info
->stream_initialised
= 0;
1358 TRYFREE(pfile_in_zip_read_info
);
1360 s
->pfile_in_zip_read
=NULL
;
1367 Get the global comment string of the ZipFile, in the szComment buffer.
1368 uSizeBuf is the size of the szComment buffer.
1369 return the number of byte copied or an error code <0
1371 extern int ZEXPORT
unzGetGlobalComment (file
, szComment
, uSizeBuf
)
1379 return UNZ_PARAMERROR
;
1382 uReadThis
= uSizeBuf
;
1383 if (uReadThis
>s
->gi
.size_comment
)
1384 uReadThis
= s
->gi
.size_comment
;
1386 if (fseek(s
->file
,s
->central_pos
+22,SEEK_SET
)!=0)
1392 if (fread(szComment
,(uInt
)uReadThis
,1,s
->file
)!=1)
1396 if ((szComment
!= NULL
) && (uSizeBuf
> s
->gi
.size_comment
))
1397 *(szComment
+s
->gi
.size_comment
)='\0';
1398 return (int)uReadThis
;
1403 /* the file shouldn't be empty, som compilers don't like it */
1404 static const int dummyVariableInUnzip
= 17;
1406 #endif /* wxUSE_ZLIB && wxUSE_ZIPSTREAM */