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
19 #if wxUSE_ZLIB && wxUSE_ZIPSTREAM
26 normally, the compiler options should contain -I../zlib, but it is
27 apparently not the case for all MSW makefiles and so, unless we use
28 configure (which defines __WX_SETUP_H__) or it is explicitly overridden by
29 the user (who can define wxUSE_ZLIB_H_IN_PATH), we hardcode the path here
31 #if defined(__WXMSW__) && !defined(__WX_SETUP_H__) && !defined(wxUSE_ZLIB_H_IN_PATH)
32 #include "../zlib/zlib.h"
38 /* Not the right solution (paths in makefiles) but... */
40 #include "../common/unzip.h"
60 /* compile with -Dlocal if your debugger can't find static symbols */
64 #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
65 !defined(CASESENSITIVITYDEFAULT_NO)
66 #define CASESENSITIVITYDEFAULT_NO
71 #define UNZ_BUFSIZE (16384)
74 #ifndef UNZ_MAXFILENAMEINZIP
75 #define UNZ_MAXFILENAMEINZIP (256)
79 # define ALLOC(size) (malloc(size))
82 # define TRYFREE(p) {if (p) free(p);}
85 #define SIZECENTRALDIRITEM (0x2e)
86 #define SIZEZIPLOCALHEADER (0x1e)
89 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
103 const char unz_copyright
[] =
104 " unzip 0.15 Copyright 1998 Gilles Vollant ";
106 /* unz_file_info_interntal contain internal info about a file in zipfile*/
107 typedef struct unz_file_info_internal_s
109 uLong offset_curfile
;/* relative offset of local header 4 bytes */
110 } unz_file_info_internal
;
113 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
114 when reading and decompress it */
117 char *read_buffer
; /* internal buffer for compressed data */
118 z_stream stream
; /* zLib stream structure for inflate */
120 uLong pos_in_zipfile
; /* position in byte on the zipfile, for fseek*/
121 uLong stream_initialised
; /* flag set if stream structure is initialised*/
123 uLong offset_local_extrafield
;/* offset of the local extra field */
124 uInt size_local_extrafield
;/* size of the local extra field */
125 uLong pos_local_extrafield
; /* position in the local extra field in read*/
127 uLong crc32
; /* crc32 of all data uncompressed */
128 uLong crc32_wait
; /* crc32 we must obtain after decompress all */
129 uLong rest_read_compressed
; /* number of byte to be decompressed */
130 uLong rest_read_uncompressed
;/*number of byte to be obtained after decomp*/
131 FILE* file
; /* io structore of the zipfile */
132 uLong compression_method
; /* compression method (0==store) */
133 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
134 } file_in_zip_read_info_s
;
137 /* unz_s contain internal information about the zipfile
141 FILE* file
; /* io structore of the zipfile */
142 unz_global_info gi
; /* public global information */
143 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
144 uLong num_file
; /* number of the current file in the zipfile*/
145 uLong pos_in_central_dir
; /* pos of the current file in the central dir*/
146 uLong current_file_ok
; /* flag about the usability of the current file*/
147 uLong central_pos
; /* position of the beginning of the central dir*/
149 uLong size_central_dir
; /* size of the central directory */
150 uLong offset_central_dir
; /* offset of start of central directory with
151 respect to the starting disk number */
153 unz_file_info cur_file_info
; /* public info about the current file in zip*/
154 unz_file_info_internal cur_file_info_internal
; /* private info about it*/
155 file_in_zip_read_info_s
* pfile_in_zip_read
; /* structure about the current
156 file if we are decompressing it */
159 #if defined (__VISAGECPP__) || defined(__BORLANDC__)
160 /* VA always requires prototypes */
161 int unzlocal_CheckCurrentFileCoherencyHeader (unz_s
*, uInt
*, uLong
*, uInt
*);
164 /* disable warnings about K&R declarations until the end of file */
166 #pragma warning(disable:4131)
169 /* ===========================================================================
170 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
172 IN assertion: the stream s has been sucessfully opened for reading.
176 local
int unzlocal_getByte(fin
,pi
)
181 int err
= fread(&c
, 1, 1, fin
);
197 /* ===========================================================================
198 Reads a long in LSB order from the given gz_stream. Sets
200 local
int unzlocal_getShort (fin
,pX
)
208 err
= unzlocal_getByte(fin
,&i
);
212 err
= unzlocal_getByte(fin
,&i
);
222 local
int unzlocal_getLong (fin
,pX
)
230 err
= unzlocal_getByte(fin
,&i
);
234 err
= unzlocal_getByte(fin
,&i
);
238 err
= unzlocal_getByte(fin
,&i
);
242 err
= unzlocal_getByte(fin
,&i
);
253 /* My own strcmpi / strcasecmp */
254 local
int strcmpcasenosensitive_internal (fileName1
,fileName2
)
255 const char* fileName1
;
256 const char* fileName2
;
260 char c1
=*(fileName1
++);
261 char c2
=*(fileName2
++);
262 if ((c1
>='a') && (c1
<='z'))
264 if ((c2
>='a') && (c2
<='z'))
267 return ((c2
=='\0') ? 0 : -1);
278 #ifdef CASESENSITIVITYDEFAULT_NO
279 #define CASESENSITIVITYDEFAULTVALUE 2
281 #define CASESENSITIVITYDEFAULTVALUE 1
284 #ifndef STRCMPCASENOSENTIVEFUNCTION
285 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
289 Compare two filename (fileName1,fileName2).
290 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
291 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
293 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
294 (like 1 on Unix, 2 on Windows)
297 extern int ZEXPORT
unzStringFileNameCompare (fileName1
,fileName2
,iCaseSensitivity
)
298 const char* fileName1
;
299 const char* fileName2
;
300 int iCaseSensitivity
;
302 if (iCaseSensitivity
==0)
303 iCaseSensitivity
=CASESENSITIVITYDEFAULTVALUE
;
305 if (iCaseSensitivity
==1)
306 return strcmp(fileName1
,fileName2
);
308 return STRCMPCASENOSENTIVEFUNCTION(fileName1
,fileName2
);
311 #define BUFREADCOMMENT (0x400)
314 Locate the Central directory of a zipfile (at the end, just before
317 local uLong
unzlocal_SearchCentralDir(fin
)
323 uLong uMaxBack
=0xffff; /* maximum size of global comment */
326 if (fseek(fin
,0,SEEK_END
) != 0)
330 uSizeFile
= ftell( fin
);
332 if (uMaxBack
>uSizeFile
)
333 uMaxBack
= uSizeFile
;
335 buf
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4);
340 while (uBackRead
<uMaxBack
)
342 uLong uReadSize
,uReadPos
;
344 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
)
345 uBackRead
= uMaxBack
;
347 uBackRead
+=BUFREADCOMMENT
;
348 uReadPos
= uSizeFile
-uBackRead
;
350 uReadSize
= ((BUFREADCOMMENT
+4) < (uSizeFile
-uReadPos
)) ?
351 (BUFREADCOMMENT
+4) : (uSizeFile
-uReadPos
);
352 if (fseek(fin
,uReadPos
,SEEK_SET
)!=0)
355 if (fread(buf
,(uInt
)uReadSize
,1,fin
)!=1)
358 for (i
=(int)uReadSize
-3; (i
--)>0;)
359 if (((*(buf
+i
))==0x50) && ((*(buf
+i
+1))==0x4b) &&
360 ((*(buf
+i
+2))==0x05) && ((*(buf
+i
+3))==0x06))
362 uPosFound
= uReadPos
+i
;
373 #if defined(__WXMAC__) && !defined(__UNIX__)
374 void wxUnix2MacFilename (char *s
) ;
376 wxUnix2MacFilename (char *s
)
382 /* relative path , since it goes on with slash which is translated to a : */
383 memmove( s
, s
+1 ,strlen( s
) ) ;
385 else if ( *s
== '/' )
387 /* absolute path -> on mac just start with the drive name */
388 memmove( s
, s
+1 ,strlen( s
) ) ;
392 /* wxASSERT_MSG( 1 , "unkown path beginning" ) ; */
396 if (*s
== '/' || *s
== '\\')
398 /* convert any back-directory situations */
399 if ( *(s
+1) == '.' && *(s
+2) == '.' && ( (*(s
+3) == '/' || *(s
+3) == '\\') ) )
402 memmove( s
+1 , s
+3 ,strlen( s
+3 ) + 1 ) ;
412 extern char * wxBuffer
;
416 Open a Zip file. path contain the full pathname (by example,
417 on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
419 If the zipfile cannot be opened (file don't exist or in not valid), the
420 return value is NULL.
421 Else, the return value is a unzFile Handle, usable with other function
422 of this unzip package.
424 extern unzFile ZEXPORT
unzOpen (path
)
429 uLong central_pos
,uL
;
432 uLong number_disk
; /* number of the current dist, used for
433 spaning ZIP, unsupported, always 0*/
434 uLong number_disk_with_CD
; /* number the the disk with central dir, used
435 for spaning ZIP, unsupported, always 0*/
436 uLong number_entry_CD
; /* total number of entries in
438 (same than number_entry on nospan) */
442 if (unz_copyright
[0]!=' ')
445 #if defined(__WXMAC__) && !defined(__UNIX__)
446 strcpy( wxBuffer
, path
) ;
447 wxUnix2MacFilename( wxBuffer
) ;
448 fin
=fopen(wxBuffer
,"rb");
450 fin
=fopen(path
,"rb");
455 central_pos
= unzlocal_SearchCentralDir(fin
);
459 if (fseek(fin
,central_pos
,SEEK_SET
)!=0)
462 /* the signature, already checked */
463 if (unzlocal_getLong(fin
,&uL
)!=UNZ_OK
)
466 /* number of this disk */
467 if (unzlocal_getShort(fin
,&number_disk
)!=UNZ_OK
)
470 /* number of the disk with the start of the central directory */
471 if (unzlocal_getShort(fin
,&number_disk_with_CD
)!=UNZ_OK
)
474 /* total number of entries in the central dir on this disk */
475 if (unzlocal_getShort(fin
,&us
.gi
.number_entry
)!=UNZ_OK
)
478 /* total number of entries in the central dir */
479 if (unzlocal_getShort(fin
,&number_entry_CD
)!=UNZ_OK
)
482 if ((number_entry_CD
!=us
.gi
.number_entry
) ||
483 (number_disk_with_CD
!=0) ||
487 /* size of the central directory */
488 if (unzlocal_getLong(fin
,&us
.size_central_dir
)!=UNZ_OK
)
491 /* offset of start of central directory with respect to the
492 starting disk number */
493 if (unzlocal_getLong(fin
,&us
.offset_central_dir
)!=UNZ_OK
)
496 /* zipfile comment length */
497 if (unzlocal_getShort(fin
,&us
.gi
.size_comment
)!=UNZ_OK
)
500 if ((central_pos
<us
.offset_central_dir
+us
.size_central_dir
) &&
510 us
.byte_before_the_zipfile
= central_pos
-
511 (us
.offset_central_dir
+us
.size_central_dir
);
512 us
.central_pos
= central_pos
;
513 us
.pfile_in_zip_read
= NULL
;
516 s
=(unz_s
*)ALLOC(sizeof(unz_s
));
518 unzGoToFirstFile((unzFile
)s
);
524 Close a ZipFile opened with unzipOpen.
525 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
526 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
527 return UNZ_OK if there is no problem. */
528 extern int ZEXPORT
unzClose (file
)
533 return UNZ_PARAMERROR
;
536 if (s
->pfile_in_zip_read
!=NULL
)
537 unzCloseCurrentFile(file
);
546 Write info about the ZipFile in the *pglobal_info structure.
547 No preparation of the structure is needed
548 return UNZ_OK if there is no problem. */
549 extern int ZEXPORT
unzGetGlobalInfo (file
,pglobal_info
)
551 unz_global_info
*pglobal_info
;
555 return UNZ_PARAMERROR
;
563 Translate date/time from Dos format to tm_unz (readable more easilty)
565 local
void unzlocal_DosDateToTmuDate (ulDosDate
, ptm
)
570 uDate
= (uLong
)(ulDosDate
>>16);
571 ptm
->tm_mday
= (uInt
)(uDate
&0x1f) ;
572 ptm
->tm_mon
= (uInt
)((((uDate
)&0x1E0)/0x20)-1) ;
573 ptm
->tm_year
= (uInt
)(((uDate
&0x0FE00)/0x0200)+1980) ;
575 ptm
->tm_hour
= (uInt
) ((ulDosDate
&0xF800)/0x800);
576 ptm
->tm_min
= (uInt
) ((ulDosDate
&0x7E0)/0x20) ;
577 ptm
->tm_sec
= (uInt
) (2*(ulDosDate
&0x1f)) ;
581 Get Info about the current file in the zipfile, with internal only info
583 local
int unzlocal_GetCurrentFileInfoInternal
OF((unzFile file
,
584 unz_file_info
*pfile_info
,
585 unz_file_info_internal
586 *pfile_info_internal
,
588 uLong fileNameBufferSize
,
590 uLong extraFieldBufferSize
,
592 uLong commentBufferSize
));
594 local
int unzlocal_GetCurrentFileInfoInternal (file
,
597 szFileName
, fileNameBufferSize
,
598 extraField
, extraFieldBufferSize
,
599 szComment
, commentBufferSize
)
601 unz_file_info
*pfile_info
;
602 unz_file_info_internal
*pfile_info_internal
;
604 uLong fileNameBufferSize
;
606 uLong extraFieldBufferSize
;
608 uLong commentBufferSize
;
611 unz_file_info file_info
;
612 unz_file_info_internal file_info_internal
;
618 return UNZ_PARAMERROR
;
620 if (fseek(s
->file
,s
->pos_in_central_dir
+s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
624 /* we check the magic */
627 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
629 else if (uMagic
!=0x02014b50)
633 if (unzlocal_getShort(s
->file
,&file_info
.version
) != UNZ_OK
)
636 if (unzlocal_getShort(s
->file
,&file_info
.version_needed
) != UNZ_OK
)
639 if (unzlocal_getShort(s
->file
,&file_info
.flag
) != UNZ_OK
)
642 if (unzlocal_getShort(s
->file
,&file_info
.compression_method
) != UNZ_OK
)
645 if (unzlocal_getLong(s
->file
,&file_info
.dosDate
) != UNZ_OK
)
648 unzlocal_DosDateToTmuDate(file_info
.dosDate
,&file_info
.tmu_date
);
650 if (unzlocal_getLong(s
->file
,&file_info
.crc
) != UNZ_OK
)
653 if (unzlocal_getLong(s
->file
,&file_info
.compressed_size
) != UNZ_OK
)
656 if (unzlocal_getLong(s
->file
,&file_info
.uncompressed_size
) != UNZ_OK
)
659 if (unzlocal_getShort(s
->file
,&file_info
.size_filename
) != UNZ_OK
)
662 if (unzlocal_getShort(s
->file
,&file_info
.size_file_extra
) != UNZ_OK
)
665 if (unzlocal_getShort(s
->file
,&file_info
.size_file_comment
) != UNZ_OK
)
668 if (unzlocal_getShort(s
->file
,&file_info
.disk_num_start
) != UNZ_OK
)
671 if (unzlocal_getShort(s
->file
,&file_info
.internal_fa
) != UNZ_OK
)
674 if (unzlocal_getLong(s
->file
,&file_info
.external_fa
) != UNZ_OK
)
677 if (unzlocal_getLong(s
->file
,&file_info_internal
.offset_curfile
) != UNZ_OK
)
680 lSeek
+=file_info
.size_filename
;
681 if ((err
==UNZ_OK
) && (szFileName
!=NULL
))
684 if (file_info
.size_filename
<fileNameBufferSize
)
686 *(szFileName
+file_info
.size_filename
)='\0';
687 uSizeRead
= file_info
.size_filename
;
690 uSizeRead
= fileNameBufferSize
;
692 if ((file_info
.size_filename
>0) && (fileNameBufferSize
>0))
693 if (fread(szFileName
,(uInt
)uSizeRead
,1,s
->file
)!=1)
699 if ((err
==UNZ_OK
) && (extraField
!=NULL
))
702 if (file_info
.size_file_extra
<extraFieldBufferSize
)
703 uSizeRead
= file_info
.size_file_extra
;
705 uSizeRead
= extraFieldBufferSize
;
709 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
715 if ((file_info
.size_file_extra
>0) && (extraFieldBufferSize
>0))
716 if (fread(extraField
,(uInt
)uSizeRead
,1,s
->file
)!=1)
718 lSeek
+= file_info
.size_file_extra
- uSizeRead
;
721 lSeek
+=file_info
.size_file_extra
;
724 if ((err
==UNZ_OK
) && (szComment
!=NULL
))
727 if (file_info
.size_file_comment
<commentBufferSize
)
729 *(szComment
+file_info
.size_file_comment
)='\0';
730 uSizeRead
= file_info
.size_file_comment
;
733 uSizeRead
= commentBufferSize
;
737 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
743 if ((file_info
.size_file_comment
>0) && (commentBufferSize
>0))
744 if (fread(szComment
,(uInt
)uSizeRead
,1,s
->file
)!=1)
746 lSeek
+=file_info
.size_file_comment
- uSizeRead
;
749 lSeek
+=file_info
.size_file_comment
;
751 if ((err
==UNZ_OK
) && (pfile_info
!=NULL
))
752 *pfile_info
=file_info
;
754 if ((err
==UNZ_OK
) && (pfile_info_internal
!=NULL
))
755 *pfile_info_internal
=file_info_internal
;
763 Write info about the ZipFile in the *pglobal_info structure.
764 No preparation of the structure is needed
765 return UNZ_OK if there is no problem.
767 extern int ZEXPORT
unzGetCurrentFileInfo (file
,
769 szFileName
, fileNameBufferSize
,
770 extraField
, extraFieldBufferSize
,
771 szComment
, commentBufferSize
)
773 unz_file_info
*pfile_info
;
775 uLong fileNameBufferSize
;
777 uLong extraFieldBufferSize
;
779 uLong commentBufferSize
;
781 return unzlocal_GetCurrentFileInfoInternal(file
,pfile_info
,NULL
,
782 szFileName
,fileNameBufferSize
,
783 extraField
,extraFieldBufferSize
,
784 szComment
,commentBufferSize
);
788 Set the current file of the zipfile to the first file.
789 return UNZ_OK if there is no problem
791 extern int ZEXPORT
unzGoToFirstFile (file
)
797 return UNZ_PARAMERROR
;
799 s
->pos_in_central_dir
=s
->offset_central_dir
;
801 err
=unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
802 &s
->cur_file_info_internal
,
803 NULL
,0,NULL
,0,NULL
,0);
804 s
->current_file_ok
= (err
== UNZ_OK
);
810 Set the current file of the zipfile to the next file.
811 return UNZ_OK if there is no problem
812 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
814 extern int ZEXPORT
unzGoToNextFile (file
)
821 return UNZ_PARAMERROR
;
823 if (!s
->current_file_ok
)
824 return UNZ_END_OF_LIST_OF_FILE
;
825 if (s
->num_file
+1==s
->gi
.number_entry
)
826 return UNZ_END_OF_LIST_OF_FILE
;
828 s
->pos_in_central_dir
+= SIZECENTRALDIRITEM
+ s
->cur_file_info
.size_filename
+
829 s
->cur_file_info
.size_file_extra
+ s
->cur_file_info
.size_file_comment
;
831 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
832 &s
->cur_file_info_internal
,
833 NULL
,0,NULL
,0,NULL
,0);
834 s
->current_file_ok
= (err
== UNZ_OK
);
840 Try locate the file szFileName in the zipfile.
841 For the iCaseSensitivity signification, see unzipStringFileNameCompare
844 UNZ_OK if the file is found. It becomes the current file.
845 UNZ_END_OF_LIST_OF_FILE if the file is not found
847 extern int ZEXPORT
unzLocateFile (file
, szFileName
, iCaseSensitivity
)
849 const char *szFileName
;
850 int iCaseSensitivity
;
856 char szFileName2
[UNZ_MAXFILENAMEINZIP
+1];
859 uLong pos_in_central_dirSaved
;
861 for (c
= szFileName
, c2
= szFileName2
; *c
!= '\0'; c
++, c2
++)
862 if (*c
== '\\') *c2
= '/';
867 return UNZ_PARAMERROR
;
869 if (strlen(szFileName
)>=UNZ_MAXFILENAMEINZIP
)
870 return UNZ_PARAMERROR
;
873 if (!s
->current_file_ok
)
874 return UNZ_END_OF_LIST_OF_FILE
;
876 num_fileSaved
= s
->num_file
;
877 pos_in_central_dirSaved
= s
->pos_in_central_dir
;
879 err
= unzGoToFirstFile(file
);
881 while (err
== UNZ_OK
)
883 char szCurrentFileName
[UNZ_MAXFILENAMEINZIP
+1];
884 unzGetCurrentFileInfo(file
,NULL
,
885 szCurrentFileName
,sizeof(szCurrentFileName
)-1,
887 for (c2
= szCurrentFileName
; *c2
!= '\0'; c2
++) if (*c2
== '\\') *c2
= '/';
888 if (unzStringFileNameCompare(szCurrentFileName
,
889 szFileName2
,iCaseSensitivity
)==0)
891 err
= unzGoToNextFile(file
);
894 s
->num_file
= num_fileSaved
;
895 s
->pos_in_central_dir
= pos_in_central_dirSaved
;
901 Read the local header of the current zipfile
902 Check the coherency of the local header and info in the end of central
903 directory about this file
904 store in *piSizeVar the size of extra info in local header
905 (filename and size of extra field data)
907 local
int unzlocal_CheckCurrentFileCoherencyHeader (s
,piSizeVar
,
908 poffset_local_extrafield
,
909 psize_local_extrafield
)
912 uLong
*poffset_local_extrafield
;
913 uInt
*psize_local_extrafield
;
915 uLong uMagic
,uData
,uFlags
;
917 uLong size_extra_field
;
921 *poffset_local_extrafield
= 0;
922 *psize_local_extrafield
= 0;
924 if (fseek(s
->file
,s
->cur_file_info_internal
.offset_curfile
+
925 s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
931 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
933 else if (uMagic
!=0x04034b50)
937 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
940 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
943 if (unzlocal_getShort(s
->file
,&uFlags
) != UNZ_OK
)
946 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
948 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compression_method
))
951 if ((err
==UNZ_OK
) && (s
->cur_file_info
.compression_method
!=0) &&
952 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
955 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* date/time */
958 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* crc */
960 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.crc
) &&
964 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size compr */
966 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compressed_size
) &&
970 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size uncompr */
972 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.uncompressed_size
) &&
977 if (unzlocal_getShort(s
->file
,&size_filename
) != UNZ_OK
)
979 else if ((err
==UNZ_OK
) && (size_filename
!=s
->cur_file_info
.size_filename
))
982 *piSizeVar
+= (uInt
)size_filename
;
984 if (unzlocal_getShort(s
->file
,&size_extra_field
) != UNZ_OK
)
986 *poffset_local_extrafield
= s
->cur_file_info_internal
.offset_curfile
+
987 SIZEZIPLOCALHEADER
+ size_filename
;
988 *psize_local_extrafield
= (uInt
)size_extra_field
;
990 *piSizeVar
+= (uInt
)size_extra_field
;
996 Open for reading data the current file in the zipfile.
997 If there is no error and the file is opened, the return value is UNZ_OK.
999 extern int ZEXPORT
unzOpenCurrentFile (file
)
1006 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1007 uLong offset_local_extrafield
; /* offset of the local extra field */
1008 uInt size_local_extrafield
; /* size of the local extra field */
1011 return UNZ_PARAMERROR
;
1013 if (!s
->current_file_ok
)
1014 return UNZ_PARAMERROR
;
1016 if (s
->pfile_in_zip_read
!= NULL
)
1017 unzCloseCurrentFile(file
);
1019 if (unzlocal_CheckCurrentFileCoherencyHeader(s
,&iSizeVar
,
1020 &offset_local_extrafield
,&size_local_extrafield
)!=UNZ_OK
)
1021 return UNZ_BADZIPFILE
;
1023 pfile_in_zip_read_info
= (file_in_zip_read_info_s
*)
1024 ALLOC(sizeof(file_in_zip_read_info_s
));
1025 if (pfile_in_zip_read_info
==NULL
)
1026 return UNZ_INTERNALERROR
;
1028 pfile_in_zip_read_info
->read_buffer
=(char*)ALLOC(UNZ_BUFSIZE
);
1029 pfile_in_zip_read_info
->offset_local_extrafield
= offset_local_extrafield
;
1030 pfile_in_zip_read_info
->size_local_extrafield
= size_local_extrafield
;
1031 pfile_in_zip_read_info
->pos_local_extrafield
=0;
1033 if (pfile_in_zip_read_info
->read_buffer
==NULL
)
1035 TRYFREE(pfile_in_zip_read_info
);
1036 return UNZ_INTERNALERROR
;
1039 pfile_in_zip_read_info
->stream_initialised
=0;
1041 if ((s
->cur_file_info
.compression_method
!=0) &&
1042 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
1044 Store
= s
->cur_file_info
.compression_method
==0;
1046 pfile_in_zip_read_info
->crc32_wait
=s
->cur_file_info
.crc
;
1047 pfile_in_zip_read_info
->crc32
=0;
1048 pfile_in_zip_read_info
->compression_method
=
1049 s
->cur_file_info
.compression_method
;
1050 pfile_in_zip_read_info
->file
=s
->file
;
1051 pfile_in_zip_read_info
->byte_before_the_zipfile
=s
->byte_before_the_zipfile
;
1053 pfile_in_zip_read_info
->stream
.total_out
= 0;
1057 pfile_in_zip_read_info
->stream
.zalloc
= (alloc_func
)0;
1058 pfile_in_zip_read_info
->stream
.zfree
= (free_func
)0;
1059 pfile_in_zip_read_info
->stream
.opaque
= (voidpf
)0;
1061 err
=inflateInit2(&pfile_in_zip_read_info
->stream
, -MAX_WBITS
);
1063 pfile_in_zip_read_info
->stream_initialised
=1;
1064 /* windowBits is passed < 0 to tell that there is no zlib header.
1065 * Note that in this case inflate *requires* an extra "dummy" byte
1066 * after the compressed stream in order to complete decompression and
1067 * return Z_STREAM_END.
1068 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1069 * size of both compressed and uncompressed data
1072 pfile_in_zip_read_info
->rest_read_compressed
=
1073 s
->cur_file_info
.compressed_size
;
1074 pfile_in_zip_read_info
->rest_read_uncompressed
=
1075 s
->cur_file_info
.uncompressed_size
;
1078 pfile_in_zip_read_info
->pos_in_zipfile
=
1079 s
->cur_file_info_internal
.offset_curfile
+ SIZEZIPLOCALHEADER
+
1082 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)0;
1085 s
->pfile_in_zip_read
= pfile_in_zip_read_info
;
1091 Read bytes from the current file.
1092 buf contain buffer where data must be copied
1093 len the size of buf.
1095 return the number of byte copied if somes bytes are copied
1096 return 0 if the end of file was reached
1097 return <0 with error code if there is an error
1098 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1100 extern int ZEXPORT
unzReadCurrentFile (file
, buf
, len
)
1108 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1110 return UNZ_PARAMERROR
;
1112 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1114 if (pfile_in_zip_read_info
==NULL
)
1115 return UNZ_PARAMERROR
;
1118 if ((pfile_in_zip_read_info
->read_buffer
== NULL
))
1119 return UNZ_END_OF_LIST_OF_FILE
;
1123 pfile_in_zip_read_info
->stream
.next_out
= (Bytef
*)buf
;
1125 pfile_in_zip_read_info
->stream
.avail_out
= (uInt
)len
;
1127 if (len
>pfile_in_zip_read_info
->rest_read_uncompressed
)
1128 pfile_in_zip_read_info
->stream
.avail_out
=
1129 (uInt
)pfile_in_zip_read_info
->rest_read_uncompressed
;
1131 while (pfile_in_zip_read_info
->stream
.avail_out
>0)
1133 if ((pfile_in_zip_read_info
->stream
.avail_in
==0) &&
1134 (pfile_in_zip_read_info
->rest_read_compressed
>0))
1136 uInt uReadThis
= UNZ_BUFSIZE
;
1137 if (pfile_in_zip_read_info
->rest_read_compressed
<uReadThis
)
1138 uReadThis
= (uInt
)pfile_in_zip_read_info
->rest_read_compressed
;
1141 if (fseek(pfile_in_zip_read_info
->file
,
1142 pfile_in_zip_read_info
->pos_in_zipfile
+
1143 pfile_in_zip_read_info
->byte_before_the_zipfile
,SEEK_SET
)!=0)
1145 if (fread(pfile_in_zip_read_info
->read_buffer
,uReadThis
,1,
1146 pfile_in_zip_read_info
->file
)!=1)
1148 pfile_in_zip_read_info
->pos_in_zipfile
+= uReadThis
;
1150 pfile_in_zip_read_info
->rest_read_compressed
-=uReadThis
;
1152 pfile_in_zip_read_info
->stream
.next_in
=
1153 (Bytef
*)pfile_in_zip_read_info
->read_buffer
;
1154 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)uReadThis
;
1157 if (pfile_in_zip_read_info
->compression_method
==0)
1160 if (pfile_in_zip_read_info
->stream
.avail_out
<
1161 pfile_in_zip_read_info
->stream
.avail_in
)
1162 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_out
;
1164 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_in
;
1166 for (i
=0;i
<uDoCopy
;i
++)
1167 *(pfile_in_zip_read_info
->stream
.next_out
+i
) =
1168 *(pfile_in_zip_read_info
->stream
.next_in
+i
);
1170 pfile_in_zip_read_info
->crc32
= crc32(pfile_in_zip_read_info
->crc32
,
1171 pfile_in_zip_read_info
->stream
.next_out
,
1173 pfile_in_zip_read_info
->rest_read_uncompressed
-=uDoCopy
;
1174 pfile_in_zip_read_info
->stream
.avail_in
-= uDoCopy
;
1175 pfile_in_zip_read_info
->stream
.avail_out
-= uDoCopy
;
1176 pfile_in_zip_read_info
->stream
.next_out
+= uDoCopy
;
1177 pfile_in_zip_read_info
->stream
.next_in
+= uDoCopy
;
1178 pfile_in_zip_read_info
->stream
.total_out
+= uDoCopy
;
1183 uLong uTotalOutBefore
,uTotalOutAfter
;
1184 const Bytef
*bufBefore
;
1186 int flush
=Z_SYNC_FLUSH
;
1188 uTotalOutBefore
= pfile_in_zip_read_info
->stream
.total_out
;
1189 bufBefore
= pfile_in_zip_read_info
->stream
.next_out
;
1192 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1193 pfile_in_zip_read_info->stream.avail_out) &&
1194 (pfile_in_zip_read_info->rest_read_compressed == 0))
1197 err
=inflate(&pfile_in_zip_read_info
->stream
,flush
);
1199 uTotalOutAfter
= pfile_in_zip_read_info
->stream
.total_out
;
1200 uOutThis
= uTotalOutAfter
-uTotalOutBefore
;
1202 pfile_in_zip_read_info
->crc32
=
1203 crc32(pfile_in_zip_read_info
->crc32
,bufBefore
,
1206 pfile_in_zip_read_info
->rest_read_uncompressed
-=
1209 iRead
+= (uInt
)(uTotalOutAfter
- uTotalOutBefore
);
1211 if (err
==Z_STREAM_END
)
1212 return (iRead
==0) ? UNZ_EOF
: iRead
;
1225 Give the current position in uncompressed data
1227 extern z_off_t ZEXPORT
unztell (file
)
1231 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1233 return UNZ_PARAMERROR
;
1235 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1237 if (pfile_in_zip_read_info
==NULL
)
1238 return UNZ_PARAMERROR
;
1240 return (z_off_t
)pfile_in_zip_read_info
->stream
.total_out
;
1245 return 1 if the end of file was reached, 0 elsewhere
1247 extern int ZEXPORT
unzeof (file
)
1251 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1253 return UNZ_PARAMERROR
;
1255 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1257 if (pfile_in_zip_read_info
==NULL
)
1258 return UNZ_PARAMERROR
;
1260 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1269 Read extra field from the current file (opened by unzOpenCurrentFile)
1270 This is the local-header version of the extra field (sometimes, there is
1271 more info in the local-header version than in the central-header)
1273 if buf==NULL, it return the size of the local extra field that can be read
1275 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1277 the return value is the number of bytes copied in buf, or (if <0)
1280 extern int ZEXPORT
unzGetLocalExtrafield (file
,buf
,len
)
1286 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1291 return UNZ_PARAMERROR
;
1293 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1295 if (pfile_in_zip_read_info
==NULL
)
1296 return UNZ_PARAMERROR
;
1298 size_to_read
= (pfile_in_zip_read_info
->size_local_extrafield
-
1299 pfile_in_zip_read_info
->pos_local_extrafield
);
1302 return (int)size_to_read
;
1304 if (len
>size_to_read
)
1305 read_now
= (uInt
)size_to_read
;
1307 read_now
= (uInt
)len
;
1312 if (fseek(pfile_in_zip_read_info
->file
,
1313 pfile_in_zip_read_info
->offset_local_extrafield
+
1314 pfile_in_zip_read_info
->pos_local_extrafield
,SEEK_SET
)!=0)
1317 if (fread(buf
,(uInt
)size_to_read
,1,pfile_in_zip_read_info
->file
)!=1)
1320 return (int)read_now
;
1324 Close the file in zip opened with unzipOpenCurrentFile
1325 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1327 extern int ZEXPORT
unzCloseCurrentFile (file
)
1333 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1335 return UNZ_PARAMERROR
;
1337 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1339 if (pfile_in_zip_read_info
==NULL
)
1340 return UNZ_PARAMERROR
;
1343 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1345 if (pfile_in_zip_read_info
->crc32
!= pfile_in_zip_read_info
->crc32_wait
)
1350 TRYFREE(pfile_in_zip_read_info
->read_buffer
);
1351 pfile_in_zip_read_info
->read_buffer
= NULL
;
1352 if (pfile_in_zip_read_info
->stream_initialised
)
1353 inflateEnd(&pfile_in_zip_read_info
->stream
);
1355 pfile_in_zip_read_info
->stream_initialised
= 0;
1356 TRYFREE(pfile_in_zip_read_info
);
1358 s
->pfile_in_zip_read
=NULL
;
1365 Get the global comment string of the ZipFile, in the szComment buffer.
1366 uSizeBuf is the size of the szComment buffer.
1367 return the number of byte copied or an error code <0
1369 extern int ZEXPORT
unzGetGlobalComment (file
, szComment
, uSizeBuf
)
1377 return UNZ_PARAMERROR
;
1380 uReadThis
= uSizeBuf
;
1381 if (uReadThis
>s
->gi
.size_comment
)
1382 uReadThis
= s
->gi
.size_comment
;
1384 if (fseek(s
->file
,s
->central_pos
+22,SEEK_SET
)!=0)
1390 if (fread(szComment
,(uInt
)uReadThis
,1,s
->file
)!=1)
1394 if ((szComment
!= NULL
) && (uSizeBuf
> s
->gi
.size_comment
))
1395 *(szComment
+s
->gi
.size_comment
)='\0';
1396 return (int)uReadThis
;
1401 /* the file shouldn't be empty, som compilers don't like it */
1402 static const int dummyVariableInUnzip
= 17;
1404 #endif /* wxUSE_ZLIB && wxUSE_ZIPSTREAM */