3 This file was altered for needs of wxWidgets.
8 /* unzip.c -- IO on .zip files using zlib
9 Version 0.15 beta, Mar 19th, 1998,
11 Read unzip.h for more info
15 #include "wx/platform.h"
17 #if wxUSE_ZLIB && wxUSE_ZIPSTREAM
24 normally, the compiler options should contain -I../zlib, but it is
25 apparently not the case for all MSW makefiles and so, unless we use
26 configure (which defines __WX_SETUP_H__) or it is explicitly overridden by
27 the user (who can define wxUSE_ZLIB_H_IN_PATH), we hardcode the path here
29 #if defined(__WXMSW__) && !defined(__WX_SETUP_H__) && !defined(wxUSE_ZLIB_H_IN_PATH)
30 #include "../zlib/zlib.h"
36 /* Not the right solution (paths in makefiles) but... */
38 #include "../common/unzip.h"
58 /* compile with -Dlocal if your debugger can't find static symbols */
62 #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
63 !defined(CASESENSITIVITYDEFAULT_NO)
64 #define CASESENSITIVITYDEFAULT_NO
69 #define UNZ_BUFSIZE (16384)
72 #ifndef UNZ_MAXFILENAMEINZIP
73 #define UNZ_MAXFILENAMEINZIP (256)
77 # define ALLOC(size) (malloc(size))
80 # define TRYFREE(p) {if (p) free(p);}
83 #define SIZECENTRALDIRITEM (0x2e)
84 #define SIZEZIPLOCALHEADER (0x1e)
87 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
101 const char unz_copyright
[] =
102 " unzip 0.15 Copyright 1998 Gilles Vollant ";
104 /* unz_file_info_interntal contain internal info about a file in zipfile*/
105 typedef struct unz_file_info_internal_s
107 uLong offset_curfile
;/* relative offset of local header 4 bytes */
108 } unz_file_info_internal
;
111 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
112 when reading and decompress it */
115 char *read_buffer
; /* internal buffer for compressed data */
116 z_stream stream
; /* zLib stream structure for inflate */
118 uLong pos_in_zipfile
; /* position in byte on the zipfile, for fseek*/
119 uLong stream_initialised
; /* flag set if stream structure is initialised*/
121 uLong offset_local_extrafield
;/* offset of the local extra field */
122 uInt size_local_extrafield
;/* size of the local extra field */
123 uLong pos_local_extrafield
; /* position in the local extra field in read*/
125 uLong crc32
; /* crc32 of all data uncompressed */
126 uLong crc32_wait
; /* crc32 we must obtain after decompress all */
127 uLong rest_read_compressed
; /* number of byte to be decompressed */
128 uLong rest_read_uncompressed
;/*number of byte to be obtained after decomp*/
129 FILE* file
; /* io structore of the zipfile */
130 uLong compression_method
; /* compression method (0==store) */
131 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
132 } file_in_zip_read_info_s
;
135 /* unz_s contain internal information about the zipfile
139 FILE* file
; /* io structore of the zipfile */
140 unz_global_info gi
; /* public global information */
141 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
142 uLong num_file
; /* number of the current file in the zipfile*/
143 uLong pos_in_central_dir
; /* pos of the current file in the central dir*/
144 uLong current_file_ok
; /* flag about the usability of the current file*/
145 uLong central_pos
; /* position of the beginning of the central dir*/
147 uLong size_central_dir
; /* size of the central directory */
148 uLong offset_central_dir
; /* offset of start of central directory with
149 respect to the starting disk number */
151 unz_file_info cur_file_info
; /* public info about the current file in zip*/
152 unz_file_info_internal cur_file_info_internal
; /* private info about it*/
153 file_in_zip_read_info_s
* pfile_in_zip_read
; /* structure about the current
154 file if we are decompressing it */
157 #if defined (__VISAGECPP__) || defined(__BORLANDC__)
158 /* VA always requires prototypes */
159 int unzlocal_CheckCurrentFileCoherencyHeader (unz_s
*, uInt
*, uLong
*, uInt
*);
162 /* disable warnings about K&R declarations until the end of file */
164 #pragma warning(disable:4131)
167 /* ===========================================================================
168 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
170 IN assertion: the stream s has been sucessfully opened for reading.
174 local
int unzlocal_getByte(fin
,pi
)
179 int err
= fread(&c
, 1, 1, fin
);
195 /* ===========================================================================
196 Reads a long in LSB order from the given gz_stream. Sets
198 local
int unzlocal_getShort (fin
,pX
)
206 err
= unzlocal_getByte(fin
,&i
);
210 err
= unzlocal_getByte(fin
,&i
);
220 local
int unzlocal_getLong (fin
,pX
)
228 err
= unzlocal_getByte(fin
,&i
);
232 err
= unzlocal_getByte(fin
,&i
);
236 err
= unzlocal_getByte(fin
,&i
);
240 err
= unzlocal_getByte(fin
,&i
);
251 /* My own strcmpi / strcasecmp */
252 local
int strcmpcasenosensitive_internal (fileName1
,fileName2
)
253 const char* fileName1
;
254 const char* fileName2
;
258 char c1
=*(fileName1
++);
259 char c2
=*(fileName2
++);
260 if ((c1
>='a') && (c1
<='z'))
262 if ((c2
>='a') && (c2
<='z'))
265 return ((c2
=='\0') ? 0 : -1);
276 #ifdef CASESENSITIVITYDEFAULT_NO
277 #define CASESENSITIVITYDEFAULTVALUE 2
279 #define CASESENSITIVITYDEFAULTVALUE 1
282 #ifndef STRCMPCASENOSENTIVEFUNCTION
283 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
287 Compare two filename (fileName1,fileName2).
288 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
289 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
291 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
292 (like 1 on Unix, 2 on Windows)
295 extern int ZEXPORT
unzStringFileNameCompare (fileName1
,fileName2
,iCaseSensitivity
)
296 const char* fileName1
;
297 const char* fileName2
;
298 int iCaseSensitivity
;
300 if (iCaseSensitivity
==0)
301 iCaseSensitivity
=CASESENSITIVITYDEFAULTVALUE
;
303 if (iCaseSensitivity
==1)
304 return strcmp(fileName1
,fileName2
);
306 return STRCMPCASENOSENTIVEFUNCTION(fileName1
,fileName2
);
309 #define BUFREADCOMMENT (0x400)
312 Locate the Central directory of a zipfile (at the end, just before
315 local uLong
unzlocal_SearchCentralDir(fin
)
321 uLong uMaxBack
=0xffff; /* maximum size of global comment */
324 if (fseek(fin
,0,SEEK_END
) != 0)
328 uSizeFile
= ftell( fin
);
330 if (uMaxBack
>uSizeFile
)
331 uMaxBack
= uSizeFile
;
333 buf
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4);
338 while (uBackRead
<uMaxBack
)
340 uLong uReadSize
,uReadPos
;
342 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
)
343 uBackRead
= uMaxBack
;
345 uBackRead
+=BUFREADCOMMENT
;
346 uReadPos
= uSizeFile
-uBackRead
;
348 uReadSize
= ((BUFREADCOMMENT
+4) < (uSizeFile
-uReadPos
)) ?
349 (BUFREADCOMMENT
+4) : (uSizeFile
-uReadPos
);
350 if (fseek(fin
,uReadPos
,SEEK_SET
)!=0)
353 if (fread(buf
,(uInt
)uReadSize
,1,fin
)!=1)
356 for (i
=(int)uReadSize
-3; (i
--)>0;)
357 if (((*(buf
+i
))==0x50) && ((*(buf
+i
+1))==0x4b) &&
358 ((*(buf
+i
+2))==0x05) && ((*(buf
+i
+3))==0x06))
360 uPosFound
= uReadPos
+i
;
372 Open a Zip file. path contain the full pathname (by example,
373 on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
375 If the zipfile cannot be opened (file don't exist or in not valid), the
376 return value is NULL.
377 Else, the return value is a unzFile Handle, usable with other function
378 of this unzip package.
380 extern unzFile ZEXPORT
unzOpen (path
)
385 uLong central_pos
,uL
;
388 uLong number_disk
; /* number of the current dist, used for
389 spaning ZIP, unsupported, always 0*/
390 uLong number_disk_with_CD
; /* number the the disk with central dir, used
391 for spaning ZIP, unsupported, always 0*/
392 uLong number_entry_CD
; /* total number of entries in
394 (same than number_entry on nospan) */
398 if (unz_copyright
[0]!=' ')
401 fin
=fopen(path
,"rb");
406 central_pos
= unzlocal_SearchCentralDir(fin
);
410 if (fseek(fin
,central_pos
,SEEK_SET
)!=0)
413 /* the signature, already checked */
414 if (unzlocal_getLong(fin
,&uL
)!=UNZ_OK
)
417 /* number of this disk */
418 if (unzlocal_getShort(fin
,&number_disk
)!=UNZ_OK
)
421 /* number of the disk with the start of the central directory */
422 if (unzlocal_getShort(fin
,&number_disk_with_CD
)!=UNZ_OK
)
425 /* total number of entries in the central dir on this disk */
426 if (unzlocal_getShort(fin
,&us
.gi
.number_entry
)!=UNZ_OK
)
429 /* total number of entries in the central dir */
430 if (unzlocal_getShort(fin
,&number_entry_CD
)!=UNZ_OK
)
433 if ((number_entry_CD
!=us
.gi
.number_entry
) ||
434 (number_disk_with_CD
!=0) ||
438 /* size of the central directory */
439 if (unzlocal_getLong(fin
,&us
.size_central_dir
)!=UNZ_OK
)
442 /* offset of start of central directory with respect to the
443 starting disk number */
444 if (unzlocal_getLong(fin
,&us
.offset_central_dir
)!=UNZ_OK
)
447 /* zipfile comment length */
448 if (unzlocal_getShort(fin
,&us
.gi
.size_comment
)!=UNZ_OK
)
451 if ((central_pos
<us
.offset_central_dir
+us
.size_central_dir
) &&
461 us
.byte_before_the_zipfile
= central_pos
-
462 (us
.offset_central_dir
+us
.size_central_dir
);
463 us
.central_pos
= central_pos
;
464 us
.pfile_in_zip_read
= NULL
;
467 s
=(unz_s
*)ALLOC(sizeof(unz_s
));
469 unzGoToFirstFile((unzFile
)s
);
475 Close a ZipFile opened with unzipOpen.
476 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
477 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
478 return UNZ_OK if there is no problem. */
479 extern int ZEXPORT
unzClose (file
)
484 return UNZ_PARAMERROR
;
487 if (s
->pfile_in_zip_read
!=NULL
)
488 unzCloseCurrentFile(file
);
497 Write info about the ZipFile in the *pglobal_info structure.
498 No preparation of the structure is needed
499 return UNZ_OK if there is no problem. */
500 extern int ZEXPORT
unzGetGlobalInfo (file
,pglobal_info
)
502 unz_global_info
*pglobal_info
;
506 return UNZ_PARAMERROR
;
514 Translate date/time from Dos format to tm_unz (readable more easilty)
516 local
void unzlocal_DosDateToTmuDate (ulDosDate
, ptm
)
521 uDate
= (uLong
)(ulDosDate
>>16);
522 ptm
->tm_mday
= (uInt
)(uDate
&0x1f) ;
523 ptm
->tm_mon
= (uInt
)((((uDate
)&0x1E0)/0x20)-1) ;
524 ptm
->tm_year
= (uInt
)(((uDate
&0x0FE00)/0x0200)+1980) ;
526 ptm
->tm_hour
= (uInt
) ((ulDosDate
&0xF800)/0x800);
527 ptm
->tm_min
= (uInt
) ((ulDosDate
&0x7E0)/0x20) ;
528 ptm
->tm_sec
= (uInt
) (2*(ulDosDate
&0x1f)) ;
532 Get Info about the current file in the zipfile, with internal only info
534 local
int unzlocal_GetCurrentFileInfoInternal
OF((unzFile file
,
535 unz_file_info
*pfile_info
,
536 unz_file_info_internal
537 *pfile_info_internal
,
539 uLong fileNameBufferSize
,
541 uLong extraFieldBufferSize
,
543 uLong commentBufferSize
));
545 local
int unzlocal_GetCurrentFileInfoInternal (file
,
548 szFileName
, fileNameBufferSize
,
549 extraField
, extraFieldBufferSize
,
550 szComment
, commentBufferSize
)
552 unz_file_info
*pfile_info
;
553 unz_file_info_internal
*pfile_info_internal
;
555 uLong fileNameBufferSize
;
557 uLong extraFieldBufferSize
;
559 uLong commentBufferSize
;
562 unz_file_info file_info
;
563 unz_file_info_internal file_info_internal
;
569 return UNZ_PARAMERROR
;
571 if (fseek(s
->file
,s
->pos_in_central_dir
+s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
575 /* we check the magic */
578 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
580 else if (uMagic
!=0x02014b50)
584 if (unzlocal_getShort(s
->file
,&file_info
.version
) != UNZ_OK
)
587 if (unzlocal_getShort(s
->file
,&file_info
.version_needed
) != UNZ_OK
)
590 if (unzlocal_getShort(s
->file
,&file_info
.flag
) != UNZ_OK
)
593 if (unzlocal_getShort(s
->file
,&file_info
.compression_method
) != UNZ_OK
)
596 if (unzlocal_getLong(s
->file
,&file_info
.dosDate
) != UNZ_OK
)
599 unzlocal_DosDateToTmuDate(file_info
.dosDate
,&file_info
.tmu_date
);
601 if (unzlocal_getLong(s
->file
,&file_info
.crc
) != UNZ_OK
)
604 if (unzlocal_getLong(s
->file
,&file_info
.compressed_size
) != UNZ_OK
)
607 if (unzlocal_getLong(s
->file
,&file_info
.uncompressed_size
) != UNZ_OK
)
610 if (unzlocal_getShort(s
->file
,&file_info
.size_filename
) != UNZ_OK
)
613 if (unzlocal_getShort(s
->file
,&file_info
.size_file_extra
) != UNZ_OK
)
616 if (unzlocal_getShort(s
->file
,&file_info
.size_file_comment
) != UNZ_OK
)
619 if (unzlocal_getShort(s
->file
,&file_info
.disk_num_start
) != UNZ_OK
)
622 if (unzlocal_getShort(s
->file
,&file_info
.internal_fa
) != UNZ_OK
)
625 if (unzlocal_getLong(s
->file
,&file_info
.external_fa
) != UNZ_OK
)
628 if (unzlocal_getLong(s
->file
,&file_info_internal
.offset_curfile
) != UNZ_OK
)
631 lSeek
+=file_info
.size_filename
;
632 if ((err
==UNZ_OK
) && (szFileName
!=NULL
))
635 if (file_info
.size_filename
<fileNameBufferSize
)
637 *(szFileName
+file_info
.size_filename
)='\0';
638 uSizeRead
= file_info
.size_filename
;
641 uSizeRead
= fileNameBufferSize
;
643 if ((file_info
.size_filename
>0) && (fileNameBufferSize
>0))
644 if (fread(szFileName
,(uInt
)uSizeRead
,1,s
->file
)!=1)
650 if ((err
==UNZ_OK
) && (extraField
!=NULL
))
653 if (file_info
.size_file_extra
<extraFieldBufferSize
)
654 uSizeRead
= file_info
.size_file_extra
;
656 uSizeRead
= extraFieldBufferSize
;
660 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
666 if ((file_info
.size_file_extra
>0) && (extraFieldBufferSize
>0))
667 if (fread(extraField
,(uInt
)uSizeRead
,1,s
->file
)!=1)
669 lSeek
+= file_info
.size_file_extra
- uSizeRead
;
672 lSeek
+=file_info
.size_file_extra
;
675 if ((err
==UNZ_OK
) && (szComment
!=NULL
))
678 if (file_info
.size_file_comment
<commentBufferSize
)
680 *(szComment
+file_info
.size_file_comment
)='\0';
681 uSizeRead
= file_info
.size_file_comment
;
684 uSizeRead
= commentBufferSize
;
688 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
694 if ((file_info
.size_file_comment
>0) && (commentBufferSize
>0))
695 if (fread(szComment
,(uInt
)uSizeRead
,1,s
->file
)!=1)
697 lSeek
+=file_info
.size_file_comment
- uSizeRead
;
700 lSeek
+=file_info
.size_file_comment
;
702 if ((err
==UNZ_OK
) && (pfile_info
!=NULL
))
703 *pfile_info
=file_info
;
705 if ((err
==UNZ_OK
) && (pfile_info_internal
!=NULL
))
706 *pfile_info_internal
=file_info_internal
;
714 Write info about the ZipFile in the *pglobal_info structure.
715 No preparation of the structure is needed
716 return UNZ_OK if there is no problem.
718 extern int ZEXPORT
unzGetCurrentFileInfo (file
,
720 szFileName
, fileNameBufferSize
,
721 extraField
, extraFieldBufferSize
,
722 szComment
, commentBufferSize
)
724 unz_file_info
*pfile_info
;
726 uLong fileNameBufferSize
;
728 uLong extraFieldBufferSize
;
730 uLong commentBufferSize
;
732 return unzlocal_GetCurrentFileInfoInternal(file
,pfile_info
,NULL
,
733 szFileName
,fileNameBufferSize
,
734 extraField
,extraFieldBufferSize
,
735 szComment
,commentBufferSize
);
739 Set the current file of the zipfile to the first file.
740 return UNZ_OK if there is no problem
742 extern int ZEXPORT
unzGoToFirstFile (file
)
748 return UNZ_PARAMERROR
;
750 s
->pos_in_central_dir
=s
->offset_central_dir
;
752 err
=unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
753 &s
->cur_file_info_internal
,
754 NULL
,0,NULL
,0,NULL
,0);
755 s
->current_file_ok
= (err
== UNZ_OK
);
761 Set the current file of the zipfile to the next file.
762 return UNZ_OK if there is no problem
763 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
765 extern int ZEXPORT
unzGoToNextFile (file
)
772 return UNZ_PARAMERROR
;
774 if (!s
->current_file_ok
)
775 return UNZ_END_OF_LIST_OF_FILE
;
776 if (s
->num_file
+1==s
->gi
.number_entry
)
777 return UNZ_END_OF_LIST_OF_FILE
;
779 s
->pos_in_central_dir
+= SIZECENTRALDIRITEM
+ s
->cur_file_info
.size_filename
+
780 s
->cur_file_info
.size_file_extra
+ s
->cur_file_info
.size_file_comment
;
782 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
783 &s
->cur_file_info_internal
,
784 NULL
,0,NULL
,0,NULL
,0);
785 s
->current_file_ok
= (err
== UNZ_OK
);
791 Try locate the file szFileName in the zipfile.
792 For the iCaseSensitivity signification, see unzipStringFileNameCompare
795 UNZ_OK if the file is found. It becomes the current file.
796 UNZ_END_OF_LIST_OF_FILE if the file is not found
798 extern int ZEXPORT
unzLocateFile (file
, szFileName
, iCaseSensitivity
)
800 const char *szFileName
;
801 int iCaseSensitivity
;
807 char szFileName2
[UNZ_MAXFILENAMEINZIP
+1];
810 uLong pos_in_central_dirSaved
;
812 for (c
= szFileName
, c2
= szFileName2
; *c
!= '\0'; c
++, c2
++)
813 if (*c
== '\\') *c2
= '/';
818 return UNZ_PARAMERROR
;
820 if (strlen(szFileName
)>=UNZ_MAXFILENAMEINZIP
)
821 return UNZ_PARAMERROR
;
824 if (!s
->current_file_ok
)
825 return UNZ_END_OF_LIST_OF_FILE
;
827 num_fileSaved
= s
->num_file
;
828 pos_in_central_dirSaved
= s
->pos_in_central_dir
;
830 err
= unzGoToFirstFile(file
);
832 while (err
== UNZ_OK
)
834 char szCurrentFileName
[UNZ_MAXFILENAMEINZIP
+1];
835 unzGetCurrentFileInfo(file
,NULL
,
836 szCurrentFileName
,sizeof(szCurrentFileName
)-1,
838 for (c2
= szCurrentFileName
; *c2
!= '\0'; c2
++) if (*c2
== '\\') *c2
= '/';
839 if (unzStringFileNameCompare(szCurrentFileName
,
840 szFileName2
,iCaseSensitivity
)==0)
842 err
= unzGoToNextFile(file
);
845 s
->num_file
= num_fileSaved
;
846 s
->pos_in_central_dir
= pos_in_central_dirSaved
;
852 Read the local header of the current zipfile
853 Check the coherency of the local header and info in the end of central
854 directory about this file
855 store in *piSizeVar the size of extra info in local header
856 (filename and size of extra field data)
858 local
int unzlocal_CheckCurrentFileCoherencyHeader (s
,piSizeVar
,
859 poffset_local_extrafield
,
860 psize_local_extrafield
)
863 uLong
*poffset_local_extrafield
;
864 uInt
*psize_local_extrafield
;
866 uLong uMagic
,uData
,uFlags
;
868 uLong size_extra_field
;
872 *poffset_local_extrafield
= 0;
873 *psize_local_extrafield
= 0;
875 if (fseek(s
->file
,s
->cur_file_info_internal
.offset_curfile
+
876 s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
882 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
884 else if (uMagic
!=0x04034b50)
888 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
891 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
894 if (unzlocal_getShort(s
->file
,&uFlags
) != UNZ_OK
)
897 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
899 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compression_method
))
902 if ((err
==UNZ_OK
) && (s
->cur_file_info
.compression_method
!=0) &&
903 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
906 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* date/time */
909 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* crc */
911 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.crc
) &&
915 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size compr */
917 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compressed_size
) &&
921 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size uncompr */
923 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.uncompressed_size
) &&
928 if (unzlocal_getShort(s
->file
,&size_filename
) != UNZ_OK
)
930 else if ((err
==UNZ_OK
) && (size_filename
!=s
->cur_file_info
.size_filename
))
933 *piSizeVar
+= (uInt
)size_filename
;
935 if (unzlocal_getShort(s
->file
,&size_extra_field
) != UNZ_OK
)
937 *poffset_local_extrafield
= s
->cur_file_info_internal
.offset_curfile
+
938 SIZEZIPLOCALHEADER
+ size_filename
;
939 *psize_local_extrafield
= (uInt
)size_extra_field
;
941 *piSizeVar
+= (uInt
)size_extra_field
;
947 Open for reading data the current file in the zipfile.
948 If there is no error and the file is opened, the return value is UNZ_OK.
950 extern int ZEXPORT
unzOpenCurrentFile (file
)
957 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
958 uLong offset_local_extrafield
; /* offset of the local extra field */
959 uInt size_local_extrafield
; /* size of the local extra field */
962 return UNZ_PARAMERROR
;
964 if (!s
->current_file_ok
)
965 return UNZ_PARAMERROR
;
967 if (s
->pfile_in_zip_read
!= NULL
)
968 unzCloseCurrentFile(file
);
970 if (unzlocal_CheckCurrentFileCoherencyHeader(s
,&iSizeVar
,
971 &offset_local_extrafield
,&size_local_extrafield
)!=UNZ_OK
)
972 return UNZ_BADZIPFILE
;
974 pfile_in_zip_read_info
= (file_in_zip_read_info_s
*)
975 ALLOC(sizeof(file_in_zip_read_info_s
));
976 if (pfile_in_zip_read_info
==NULL
)
977 return UNZ_INTERNALERROR
;
979 pfile_in_zip_read_info
->read_buffer
=(char*)ALLOC(UNZ_BUFSIZE
);
980 pfile_in_zip_read_info
->offset_local_extrafield
= offset_local_extrafield
;
981 pfile_in_zip_read_info
->size_local_extrafield
= size_local_extrafield
;
982 pfile_in_zip_read_info
->pos_local_extrafield
=0;
984 if (pfile_in_zip_read_info
->read_buffer
==NULL
)
986 TRYFREE(pfile_in_zip_read_info
);
987 return UNZ_INTERNALERROR
;
990 pfile_in_zip_read_info
->stream_initialised
=0;
992 if ((s
->cur_file_info
.compression_method
!=0) &&
993 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
995 Store
= s
->cur_file_info
.compression_method
==0;
997 pfile_in_zip_read_info
->crc32_wait
=s
->cur_file_info
.crc
;
998 pfile_in_zip_read_info
->crc32
=0;
999 pfile_in_zip_read_info
->compression_method
=
1000 s
->cur_file_info
.compression_method
;
1001 pfile_in_zip_read_info
->file
=s
->file
;
1002 pfile_in_zip_read_info
->byte_before_the_zipfile
=s
->byte_before_the_zipfile
;
1004 pfile_in_zip_read_info
->stream
.total_out
= 0;
1008 pfile_in_zip_read_info
->stream
.zalloc
= (alloc_func
)0;
1009 pfile_in_zip_read_info
->stream
.zfree
= (free_func
)0;
1010 pfile_in_zip_read_info
->stream
.opaque
= (voidpf
)0;
1012 err
=inflateInit2(&pfile_in_zip_read_info
->stream
, -MAX_WBITS
);
1014 pfile_in_zip_read_info
->stream_initialised
=1;
1015 /* windowBits is passed < 0 to tell that there is no zlib header.
1016 * Note that in this case inflate *requires* an extra "dummy" byte
1017 * after the compressed stream in order to complete decompression and
1018 * return Z_STREAM_END.
1019 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1020 * size of both compressed and uncompressed data
1023 pfile_in_zip_read_info
->rest_read_compressed
=
1024 s
->cur_file_info
.compressed_size
;
1025 pfile_in_zip_read_info
->rest_read_uncompressed
=
1026 s
->cur_file_info
.uncompressed_size
;
1029 pfile_in_zip_read_info
->pos_in_zipfile
=
1030 s
->cur_file_info_internal
.offset_curfile
+ SIZEZIPLOCALHEADER
+
1033 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)0;
1036 s
->pfile_in_zip_read
= pfile_in_zip_read_info
;
1042 Read bytes from the current file.
1043 buf contain buffer where data must be copied
1044 len the size of buf.
1046 return the number of byte copied if somes bytes are copied
1047 return 0 if the end of file was reached
1048 return <0 with error code if there is an error
1049 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1051 extern int ZEXPORT
unzReadCurrentFile (file
, buf
, len
)
1059 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1061 return UNZ_PARAMERROR
;
1063 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1065 if (pfile_in_zip_read_info
==NULL
)
1066 return UNZ_PARAMERROR
;
1069 if ((pfile_in_zip_read_info
->read_buffer
== NULL
))
1070 return UNZ_END_OF_LIST_OF_FILE
;
1074 pfile_in_zip_read_info
->stream
.next_out
= (Bytef
*)buf
;
1076 pfile_in_zip_read_info
->stream
.avail_out
= (uInt
)len
;
1078 if (len
>pfile_in_zip_read_info
->rest_read_uncompressed
)
1079 pfile_in_zip_read_info
->stream
.avail_out
=
1080 (uInt
)pfile_in_zip_read_info
->rest_read_uncompressed
;
1082 while (pfile_in_zip_read_info
->stream
.avail_out
>0)
1084 if ((pfile_in_zip_read_info
->stream
.avail_in
==0) &&
1085 (pfile_in_zip_read_info
->rest_read_compressed
>0))
1087 uInt uReadThis
= UNZ_BUFSIZE
;
1088 if (pfile_in_zip_read_info
->rest_read_compressed
<uReadThis
)
1089 uReadThis
= (uInt
)pfile_in_zip_read_info
->rest_read_compressed
;
1092 if (fseek(pfile_in_zip_read_info
->file
,
1093 pfile_in_zip_read_info
->pos_in_zipfile
+
1094 pfile_in_zip_read_info
->byte_before_the_zipfile
,SEEK_SET
)!=0)
1096 if (fread(pfile_in_zip_read_info
->read_buffer
,uReadThis
,1,
1097 pfile_in_zip_read_info
->file
)!=1)
1099 pfile_in_zip_read_info
->pos_in_zipfile
+= uReadThis
;
1101 pfile_in_zip_read_info
->rest_read_compressed
-=uReadThis
;
1103 pfile_in_zip_read_info
->stream
.next_in
=
1104 (Bytef
*)pfile_in_zip_read_info
->read_buffer
;
1105 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)uReadThis
;
1108 if (pfile_in_zip_read_info
->compression_method
==0)
1111 if (pfile_in_zip_read_info
->stream
.avail_out
<
1112 pfile_in_zip_read_info
->stream
.avail_in
)
1113 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_out
;
1115 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_in
;
1117 for (i
=0;i
<uDoCopy
;i
++)
1118 *(pfile_in_zip_read_info
->stream
.next_out
+i
) =
1119 *(pfile_in_zip_read_info
->stream
.next_in
+i
);
1121 pfile_in_zip_read_info
->crc32
= crc32(pfile_in_zip_read_info
->crc32
,
1122 pfile_in_zip_read_info
->stream
.next_out
,
1124 pfile_in_zip_read_info
->rest_read_uncompressed
-=uDoCopy
;
1125 pfile_in_zip_read_info
->stream
.avail_in
-= uDoCopy
;
1126 pfile_in_zip_read_info
->stream
.avail_out
-= uDoCopy
;
1127 pfile_in_zip_read_info
->stream
.next_out
+= uDoCopy
;
1128 pfile_in_zip_read_info
->stream
.next_in
+= uDoCopy
;
1129 pfile_in_zip_read_info
->stream
.total_out
+= uDoCopy
;
1134 uLong uTotalOutBefore
,uTotalOutAfter
;
1135 const Bytef
*bufBefore
;
1137 int flush
=Z_SYNC_FLUSH
;
1139 uTotalOutBefore
= pfile_in_zip_read_info
->stream
.total_out
;
1140 bufBefore
= pfile_in_zip_read_info
->stream
.next_out
;
1143 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1144 pfile_in_zip_read_info->stream.avail_out) &&
1145 (pfile_in_zip_read_info->rest_read_compressed == 0))
1148 err
=inflate(&pfile_in_zip_read_info
->stream
,flush
);
1150 uTotalOutAfter
= pfile_in_zip_read_info
->stream
.total_out
;
1151 uOutThis
= uTotalOutAfter
-uTotalOutBefore
;
1153 pfile_in_zip_read_info
->crc32
=
1154 crc32(pfile_in_zip_read_info
->crc32
,bufBefore
,
1157 pfile_in_zip_read_info
->rest_read_uncompressed
-=
1160 iRead
+= (uInt
)(uTotalOutAfter
- uTotalOutBefore
);
1162 if (err
==Z_STREAM_END
)
1163 return (iRead
==0) ? UNZ_EOF
: iRead
;
1176 Give the current position in uncompressed data
1178 extern z_off_t ZEXPORT
unztell (file
)
1182 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1184 return UNZ_PARAMERROR
;
1186 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1188 if (pfile_in_zip_read_info
==NULL
)
1189 return UNZ_PARAMERROR
;
1191 return (z_off_t
)pfile_in_zip_read_info
->stream
.total_out
;
1196 return 1 if the end of file was reached, 0 elsewhere
1198 extern int ZEXPORT
unzeof (file
)
1202 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1204 return UNZ_PARAMERROR
;
1206 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1208 if (pfile_in_zip_read_info
==NULL
)
1209 return UNZ_PARAMERROR
;
1211 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1220 Read extra field from the current file (opened by unzOpenCurrentFile)
1221 This is the local-header version of the extra field (sometimes, there is
1222 more info in the local-header version than in the central-header)
1224 if buf==NULL, it return the size of the local extra field that can be read
1226 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1228 the return value is the number of bytes copied in buf, or (if <0)
1231 extern int ZEXPORT
unzGetLocalExtrafield (file
,buf
,len
)
1237 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1242 return UNZ_PARAMERROR
;
1244 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1246 if (pfile_in_zip_read_info
==NULL
)
1247 return UNZ_PARAMERROR
;
1249 size_to_read
= (pfile_in_zip_read_info
->size_local_extrafield
-
1250 pfile_in_zip_read_info
->pos_local_extrafield
);
1253 return (int)size_to_read
;
1255 if (len
>size_to_read
)
1256 read_now
= (uInt
)size_to_read
;
1258 read_now
= (uInt
)len
;
1263 if (fseek(pfile_in_zip_read_info
->file
,
1264 pfile_in_zip_read_info
->offset_local_extrafield
+
1265 pfile_in_zip_read_info
->pos_local_extrafield
,SEEK_SET
)!=0)
1268 if (fread(buf
,(uInt
)size_to_read
,1,pfile_in_zip_read_info
->file
)!=1)
1271 return (int)read_now
;
1275 Close the file in zip opened with unzipOpenCurrentFile
1276 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1278 extern int ZEXPORT
unzCloseCurrentFile (file
)
1284 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1286 return UNZ_PARAMERROR
;
1288 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1290 if (pfile_in_zip_read_info
==NULL
)
1291 return UNZ_PARAMERROR
;
1294 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1296 if (pfile_in_zip_read_info
->crc32
!= pfile_in_zip_read_info
->crc32_wait
)
1301 TRYFREE(pfile_in_zip_read_info
->read_buffer
);
1302 pfile_in_zip_read_info
->read_buffer
= NULL
;
1303 if (pfile_in_zip_read_info
->stream_initialised
)
1304 inflateEnd(&pfile_in_zip_read_info
->stream
);
1306 pfile_in_zip_read_info
->stream_initialised
= 0;
1307 TRYFREE(pfile_in_zip_read_info
);
1309 s
->pfile_in_zip_read
=NULL
;
1316 Get the global comment string of the ZipFile, in the szComment buffer.
1317 uSizeBuf is the size of the szComment buffer.
1318 return the number of byte copied or an error code <0
1320 extern int ZEXPORT
unzGetGlobalComment (file
, szComment
, uSizeBuf
)
1328 return UNZ_PARAMERROR
;
1331 uReadThis
= uSizeBuf
;
1332 if (uReadThis
>s
->gi
.size_comment
)
1333 uReadThis
= s
->gi
.size_comment
;
1335 if (fseek(s
->file
,s
->central_pos
+22,SEEK_SET
)!=0)
1341 if (fread(szComment
,(uInt
)uReadThis
,1,s
->file
)!=1)
1345 if ((szComment
!= NULL
) && (uSizeBuf
> s
->gi
.size_comment
))
1346 *(szComment
+s
->gi
.size_comment
)='\0';
1347 return (int)uReadThis
;
1352 /* the file shouldn't be empty, som compilers don't like it */
1353 static const int dummyVariableInUnzip
= 17;
1355 #endif /* wxUSE_ZLIB && wxUSE_ZIPSTREAM */