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)
691 // lSeek is not used later in the code so update it only for debug purposes
697 if ((file_info
.size_file_comment
>0) && (commentBufferSize
>0))
698 if (fread(szComment
,(uInt
)uSizeRead
,1,s
->file
)!=1)
701 // lSeek is not used later in the code so update it only for debug purposes
702 lSeek
+=file_info
.size_file_comment
- uSizeRead
;
708 // lSeek is not used later in the code so update it only for debug purposes
709 lSeek
+=file_info
.size_file_comment
;
713 if ((err
==UNZ_OK
) && (pfile_info
!=NULL
))
714 *pfile_info
=file_info
;
716 if ((err
==UNZ_OK
) && (pfile_info_internal
!=NULL
))
717 *pfile_info_internal
=file_info_internal
;
725 Write info about the ZipFile in the *pglobal_info structure.
726 No preparation of the structure is needed
727 return UNZ_OK if there is no problem.
729 extern int ZEXPORT
unzGetCurrentFileInfo (file
,
731 szFileName
, fileNameBufferSize
,
732 extraField
, extraFieldBufferSize
,
733 szComment
, commentBufferSize
)
735 unz_file_info
*pfile_info
;
737 uLong fileNameBufferSize
;
739 uLong extraFieldBufferSize
;
741 uLong commentBufferSize
;
743 return unzlocal_GetCurrentFileInfoInternal(file
,pfile_info
,NULL
,
744 szFileName
,fileNameBufferSize
,
745 extraField
,extraFieldBufferSize
,
746 szComment
,commentBufferSize
);
750 Set the current file of the zipfile to the first file.
751 return UNZ_OK if there is no problem
753 extern int ZEXPORT
unzGoToFirstFile (file
)
759 return UNZ_PARAMERROR
;
761 s
->pos_in_central_dir
=s
->offset_central_dir
;
763 err
=unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
764 &s
->cur_file_info_internal
,
765 NULL
,0,NULL
,0,NULL
,0);
766 s
->current_file_ok
= (err
== UNZ_OK
);
772 Set the current file of the zipfile to the next file.
773 return UNZ_OK if there is no problem
774 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
776 extern int ZEXPORT
unzGoToNextFile (file
)
783 return UNZ_PARAMERROR
;
785 if (!s
->current_file_ok
)
786 return UNZ_END_OF_LIST_OF_FILE
;
787 if (s
->num_file
+1==s
->gi
.number_entry
)
788 return UNZ_END_OF_LIST_OF_FILE
;
790 s
->pos_in_central_dir
+= SIZECENTRALDIRITEM
+ s
->cur_file_info
.size_filename
+
791 s
->cur_file_info
.size_file_extra
+ s
->cur_file_info
.size_file_comment
;
793 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
794 &s
->cur_file_info_internal
,
795 NULL
,0,NULL
,0,NULL
,0);
796 s
->current_file_ok
= (err
== UNZ_OK
);
802 Try locate the file szFileName in the zipfile.
803 For the iCaseSensitivity signification, see unzipStringFileNameCompare
806 UNZ_OK if the file is found. It becomes the current file.
807 UNZ_END_OF_LIST_OF_FILE if the file is not found
809 extern int ZEXPORT
unzLocateFile (file
, szFileName
, iCaseSensitivity
)
811 const char *szFileName
;
812 int iCaseSensitivity
;
818 char szFileName2
[UNZ_MAXFILENAMEINZIP
+1];
821 uLong pos_in_central_dirSaved
;
823 for (c
= szFileName
, c2
= szFileName2
; *c
!= '\0'; c
++, c2
++)
824 if (*c
== '\\') *c2
= '/';
829 return UNZ_PARAMERROR
;
831 if (strlen(szFileName
)>=UNZ_MAXFILENAMEINZIP
)
832 return UNZ_PARAMERROR
;
835 if (!s
->current_file_ok
)
836 return UNZ_END_OF_LIST_OF_FILE
;
838 num_fileSaved
= s
->num_file
;
839 pos_in_central_dirSaved
= s
->pos_in_central_dir
;
841 err
= unzGoToFirstFile(file
);
843 while (err
== UNZ_OK
)
845 char szCurrentFileName
[UNZ_MAXFILENAMEINZIP
+1];
846 unzGetCurrentFileInfo(file
,NULL
,
847 szCurrentFileName
,sizeof(szCurrentFileName
)-1,
849 for (c2
= szCurrentFileName
; *c2
!= '\0'; c2
++) if (*c2
== '\\') *c2
= '/';
850 if (unzStringFileNameCompare(szCurrentFileName
,
851 szFileName2
,iCaseSensitivity
)==0)
853 err
= unzGoToNextFile(file
);
856 s
->num_file
= num_fileSaved
;
857 s
->pos_in_central_dir
= pos_in_central_dirSaved
;
863 Read the local header of the current zipfile
864 Check the coherency of the local header and info in the end of central
865 directory about this file
866 store in *piSizeVar the size of extra info in local header
867 (filename and size of extra field data)
869 local
int unzlocal_CheckCurrentFileCoherencyHeader (s
,piSizeVar
,
870 poffset_local_extrafield
,
871 psize_local_extrafield
)
874 uLong
*poffset_local_extrafield
;
875 uInt
*psize_local_extrafield
;
877 uLong uMagic
,uData
,uFlags
;
879 uLong size_extra_field
;
883 *poffset_local_extrafield
= 0;
884 *psize_local_extrafield
= 0;
886 if (fseek(s
->file
,s
->cur_file_info_internal
.offset_curfile
+
887 s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
893 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
895 else if (uMagic
!=0x04034b50)
899 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
902 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
905 if (unzlocal_getShort(s
->file
,&uFlags
) != UNZ_OK
)
908 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
910 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compression_method
))
913 if ((err
==UNZ_OK
) && (s
->cur_file_info
.compression_method
!=0) &&
914 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
917 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* date/time */
920 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* crc */
922 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.crc
) &&
926 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size compr */
928 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compressed_size
) &&
932 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size uncompr */
934 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.uncompressed_size
) &&
939 if (unzlocal_getShort(s
->file
,&size_filename
) != UNZ_OK
)
941 else if ((err
==UNZ_OK
) && (size_filename
!=s
->cur_file_info
.size_filename
))
944 *piSizeVar
+= (uInt
)size_filename
;
946 if (unzlocal_getShort(s
->file
,&size_extra_field
) != UNZ_OK
)
948 *poffset_local_extrafield
= s
->cur_file_info_internal
.offset_curfile
+
949 SIZEZIPLOCALHEADER
+ size_filename
;
950 *psize_local_extrafield
= (uInt
)size_extra_field
;
952 *piSizeVar
+= (uInt
)size_extra_field
;
958 Open for reading data the current file in the zipfile.
959 If there is no error and the file is opened, the return value is UNZ_OK.
961 extern int ZEXPORT
unzOpenCurrentFile (file
)
972 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
973 uLong offset_local_extrafield
; /* offset of the local extra field */
974 uInt size_local_extrafield
; /* size of the local extra field */
977 return UNZ_PARAMERROR
;
979 if (!s
->current_file_ok
)
980 return UNZ_PARAMERROR
;
982 if (s
->pfile_in_zip_read
!= NULL
)
983 unzCloseCurrentFile(file
);
985 if (unzlocal_CheckCurrentFileCoherencyHeader(s
,&iSizeVar
,
986 &offset_local_extrafield
,&size_local_extrafield
)!=UNZ_OK
)
987 return UNZ_BADZIPFILE
;
989 pfile_in_zip_read_info
= (file_in_zip_read_info_s
*)
990 ALLOC(sizeof(file_in_zip_read_info_s
));
991 if (pfile_in_zip_read_info
==NULL
)
992 return UNZ_INTERNALERROR
;
994 pfile_in_zip_read_info
->read_buffer
=(char*)ALLOC(UNZ_BUFSIZE
);
995 pfile_in_zip_read_info
->offset_local_extrafield
= offset_local_extrafield
;
996 pfile_in_zip_read_info
->size_local_extrafield
= size_local_extrafield
;
997 pfile_in_zip_read_info
->pos_local_extrafield
=0;
999 if (pfile_in_zip_read_info
->read_buffer
==NULL
)
1001 TRYFREE(pfile_in_zip_read_info
);
1002 return UNZ_INTERNALERROR
;
1005 pfile_in_zip_read_info
->stream_initialised
=0;
1008 if ((s
->cur_file_info
.compression_method
!=0) &&
1009 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
1012 Store
= s
->cur_file_info
.compression_method
==0;
1014 pfile_in_zip_read_info
->crc32_wait
=s
->cur_file_info
.crc
;
1015 pfile_in_zip_read_info
->crc32
=0;
1016 pfile_in_zip_read_info
->compression_method
=
1017 s
->cur_file_info
.compression_method
;
1018 pfile_in_zip_read_info
->file
=s
->file
;
1019 pfile_in_zip_read_info
->byte_before_the_zipfile
=s
->byte_before_the_zipfile
;
1021 pfile_in_zip_read_info
->stream
.total_out
= 0;
1025 pfile_in_zip_read_info
->stream
.zalloc
= (alloc_func
)0;
1026 pfile_in_zip_read_info
->stream
.zfree
= (free_func
)0;
1027 pfile_in_zip_read_info
->stream
.opaque
= (voidpf
)0;
1029 err
=inflateInit2(&pfile_in_zip_read_info
->stream
, -MAX_WBITS
);
1031 pfile_in_zip_read_info
->stream_initialised
=1;
1032 /* windowBits is passed < 0 to tell that there is no zlib header.
1033 * Note that in this case inflate *requires* an extra "dummy" byte
1034 * after the compressed stream in order to complete decompression and
1035 * return Z_STREAM_END.
1036 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1037 * size of both compressed and uncompressed data
1040 pfile_in_zip_read_info
->rest_read_compressed
=
1041 s
->cur_file_info
.compressed_size
;
1042 pfile_in_zip_read_info
->rest_read_uncompressed
=
1043 s
->cur_file_info
.uncompressed_size
;
1046 pfile_in_zip_read_info
->pos_in_zipfile
=
1047 s
->cur_file_info_internal
.offset_curfile
+ SIZEZIPLOCALHEADER
+
1050 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)0;
1053 s
->pfile_in_zip_read
= pfile_in_zip_read_info
;
1059 Read bytes from the current file.
1060 buf contain buffer where data must be copied
1061 len the size of buf.
1063 return the number of byte copied if somes bytes are copied
1064 return 0 if the end of file was reached
1065 return <0 with error code if there is an error
1066 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1068 extern int ZEXPORT
unzReadCurrentFile (file
, buf
, len
)
1076 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1078 return UNZ_PARAMERROR
;
1080 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1082 if (pfile_in_zip_read_info
==NULL
)
1083 return UNZ_PARAMERROR
;
1086 if ((pfile_in_zip_read_info
->read_buffer
== NULL
))
1087 return UNZ_END_OF_LIST_OF_FILE
;
1091 pfile_in_zip_read_info
->stream
.next_out
= (Bytef
*)buf
;
1093 pfile_in_zip_read_info
->stream
.avail_out
= (uInt
)len
;
1095 if (len
>pfile_in_zip_read_info
->rest_read_uncompressed
)
1096 pfile_in_zip_read_info
->stream
.avail_out
=
1097 (uInt
)pfile_in_zip_read_info
->rest_read_uncompressed
;
1099 while (pfile_in_zip_read_info
->stream
.avail_out
>0)
1101 if ((pfile_in_zip_read_info
->stream
.avail_in
==0) &&
1102 (pfile_in_zip_read_info
->rest_read_compressed
>0))
1104 uInt uReadThis
= UNZ_BUFSIZE
;
1105 if (pfile_in_zip_read_info
->rest_read_compressed
<uReadThis
)
1106 uReadThis
= (uInt
)pfile_in_zip_read_info
->rest_read_compressed
;
1109 if (fseek(pfile_in_zip_read_info
->file
,
1110 pfile_in_zip_read_info
->pos_in_zipfile
+
1111 pfile_in_zip_read_info
->byte_before_the_zipfile
,SEEK_SET
)!=0)
1113 if (fread(pfile_in_zip_read_info
->read_buffer
,uReadThis
,1,
1114 pfile_in_zip_read_info
->file
)!=1)
1116 pfile_in_zip_read_info
->pos_in_zipfile
+= uReadThis
;
1118 pfile_in_zip_read_info
->rest_read_compressed
-=uReadThis
;
1120 pfile_in_zip_read_info
->stream
.next_in
=
1121 (Bytef
*)pfile_in_zip_read_info
->read_buffer
;
1122 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)uReadThis
;
1125 if (pfile_in_zip_read_info
->compression_method
==0)
1128 if (pfile_in_zip_read_info
->stream
.avail_out
<
1129 pfile_in_zip_read_info
->stream
.avail_in
)
1130 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_out
;
1132 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_in
;
1134 for (i
=0;i
<uDoCopy
;i
++)
1135 *(pfile_in_zip_read_info
->stream
.next_out
+i
) =
1136 *(pfile_in_zip_read_info
->stream
.next_in
+i
);
1138 pfile_in_zip_read_info
->crc32
= crc32(pfile_in_zip_read_info
->crc32
,
1139 pfile_in_zip_read_info
->stream
.next_out
,
1141 pfile_in_zip_read_info
->rest_read_uncompressed
-=uDoCopy
;
1142 pfile_in_zip_read_info
->stream
.avail_in
-= uDoCopy
;
1143 pfile_in_zip_read_info
->stream
.avail_out
-= uDoCopy
;
1144 pfile_in_zip_read_info
->stream
.next_out
+= uDoCopy
;
1145 pfile_in_zip_read_info
->stream
.next_in
+= uDoCopy
;
1146 pfile_in_zip_read_info
->stream
.total_out
+= uDoCopy
;
1151 uLong uTotalOutBefore
,uTotalOutAfter
;
1152 const Bytef
*bufBefore
;
1154 int flush
=Z_SYNC_FLUSH
;
1156 uTotalOutBefore
= pfile_in_zip_read_info
->stream
.total_out
;
1157 bufBefore
= pfile_in_zip_read_info
->stream
.next_out
;
1160 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1161 pfile_in_zip_read_info->stream.avail_out) &&
1162 (pfile_in_zip_read_info->rest_read_compressed == 0))
1165 err
=inflate(&pfile_in_zip_read_info
->stream
,flush
);
1167 uTotalOutAfter
= pfile_in_zip_read_info
->stream
.total_out
;
1168 uOutThis
= uTotalOutAfter
-uTotalOutBefore
;
1170 pfile_in_zip_read_info
->crc32
=
1171 crc32(pfile_in_zip_read_info
->crc32
,bufBefore
,
1174 pfile_in_zip_read_info
->rest_read_uncompressed
-=
1177 iRead
+= (uInt
)(uTotalOutAfter
- uTotalOutBefore
);
1179 if (err
==Z_STREAM_END
)
1180 return (iRead
==0) ? UNZ_EOF
: iRead
;
1193 Give the current position in uncompressed data
1195 extern z_off_t ZEXPORT
unztell (file
)
1199 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1201 return UNZ_PARAMERROR
;
1203 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1205 if (pfile_in_zip_read_info
==NULL
)
1206 return UNZ_PARAMERROR
;
1208 return (z_off_t
)pfile_in_zip_read_info
->stream
.total_out
;
1213 return 1 if the end of file was reached, 0 elsewhere
1215 extern int ZEXPORT
unzeof (file
)
1219 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1221 return UNZ_PARAMERROR
;
1223 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1225 if (pfile_in_zip_read_info
==NULL
)
1226 return UNZ_PARAMERROR
;
1228 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1237 Read extra field from the current file (opened by unzOpenCurrentFile)
1238 This is the local-header version of the extra field (sometimes, there is
1239 more info in the local-header version than in the central-header)
1241 if buf==NULL, it return the size of the local extra field that can be read
1243 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1245 the return value is the number of bytes copied in buf, or (if <0)
1248 extern int ZEXPORT
unzGetLocalExtrafield (file
,buf
,len
)
1254 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1259 return UNZ_PARAMERROR
;
1261 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1263 if (pfile_in_zip_read_info
==NULL
)
1264 return UNZ_PARAMERROR
;
1266 size_to_read
= (pfile_in_zip_read_info
->size_local_extrafield
-
1267 pfile_in_zip_read_info
->pos_local_extrafield
);
1270 return (int)size_to_read
;
1272 if (len
>size_to_read
)
1273 read_now
= (uInt
)size_to_read
;
1275 read_now
= (uInt
)len
;
1280 if (fseek(pfile_in_zip_read_info
->file
,
1281 pfile_in_zip_read_info
->offset_local_extrafield
+
1282 pfile_in_zip_read_info
->pos_local_extrafield
,SEEK_SET
)!=0)
1285 if (fread(buf
,(uInt
)size_to_read
,1,pfile_in_zip_read_info
->file
)!=1)
1288 return (int)read_now
;
1292 Close the file in zip opened with unzipOpenCurrentFile
1293 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1295 extern int ZEXPORT
unzCloseCurrentFile (file
)
1301 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1303 return UNZ_PARAMERROR
;
1305 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1307 if (pfile_in_zip_read_info
==NULL
)
1308 return UNZ_PARAMERROR
;
1311 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1313 if (pfile_in_zip_read_info
->crc32
!= pfile_in_zip_read_info
->crc32_wait
)
1318 TRYFREE(pfile_in_zip_read_info
->read_buffer
);
1319 pfile_in_zip_read_info
->read_buffer
= NULL
;
1320 if (pfile_in_zip_read_info
->stream_initialised
)
1321 inflateEnd(&pfile_in_zip_read_info
->stream
);
1323 pfile_in_zip_read_info
->stream_initialised
= 0;
1324 TRYFREE(pfile_in_zip_read_info
);
1326 s
->pfile_in_zip_read
=NULL
;
1333 Get the global comment string of the ZipFile, in the szComment buffer.
1334 uSizeBuf is the size of the szComment buffer.
1335 return the number of byte copied or an error code <0
1337 extern int ZEXPORT
unzGetGlobalComment (file
, szComment
, uSizeBuf
)
1345 return UNZ_PARAMERROR
;
1348 uReadThis
= uSizeBuf
;
1349 if (uReadThis
>s
->gi
.size_comment
)
1350 uReadThis
= s
->gi
.size_comment
;
1352 if (fseek(s
->file
,s
->central_pos
+22,SEEK_SET
)!=0)
1358 if (fread(szComment
,(uInt
)uReadThis
,1,s
->file
)!=1)
1362 if ((szComment
!= NULL
) && (uSizeBuf
> s
->gi
.size_comment
))
1363 *(szComment
+s
->gi
.size_comment
)='\0';
1364 return (int)uReadThis
;
1369 /* the file shouldn't be empty, som compilers don't like it */
1370 static const int dummyVariableInUnzip
= 17;
1372 #endif /* wxUSE_ZLIB && wxUSE_ZIPSTREAM */