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 /* Not the right solution (paths in makefiles) but... */
28 #include "../common/unzip.h"
48 /* compile with -Dlocal if your debugger can't find static symbols */
52 #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
53 !defined(CASESENSITIVITYDEFAULT_NO)
54 #define CASESENSITIVITYDEFAULT_NO
59 #define UNZ_BUFSIZE (16384)
62 #ifndef UNZ_MAXFILENAMEINZIP
63 #define UNZ_MAXFILENAMEINZIP (256)
67 # define ALLOC(size) (malloc(size))
70 # define TRYFREE(p) {if (p) free(p);}
73 #define SIZECENTRALDIRITEM (0x2e)
74 #define SIZEZIPLOCALHEADER (0x1e)
77 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
91 const char unz_copyright
[] =
92 " unzip 0.15 Copyright 1998 Gilles Vollant ";
94 /* unz_file_info_interntal contain internal info about a file in zipfile*/
95 typedef struct unz_file_info_internal_s
97 uLong offset_curfile
;/* relative offset of local header 4 bytes */
98 } unz_file_info_internal
;
101 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
102 when reading and decompress it */
105 char *read_buffer
; /* internal buffer for compressed data */
106 z_stream stream
; /* zLib stream structure for inflate */
108 uLong pos_in_zipfile
; /* position in byte on the zipfile, for fseek*/
109 uLong stream_initialised
; /* flag set if stream structure is initialised*/
111 uLong offset_local_extrafield
;/* offset of the local extra field */
112 uInt size_local_extrafield
;/* size of the local extra field */
113 uLong pos_local_extrafield
; /* position in the local extra field in read*/
115 uLong crc32
; /* crc32 of all data uncompressed */
116 uLong crc32_wait
; /* crc32 we must obtain after decompress all */
117 uLong rest_read_compressed
; /* number of byte to be decompressed */
118 uLong rest_read_uncompressed
;/*number of byte to be obtained after decomp*/
119 FILE* file
; /* io structore of the zipfile */
120 uLong compression_method
; /* compression method (0==store) */
121 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
122 } file_in_zip_read_info_s
;
125 /* unz_s contain internal information about the zipfile
129 FILE* file
; /* io structore of the zipfile */
130 unz_global_info gi
; /* public global information */
131 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
132 uLong num_file
; /* number of the current file in the zipfile*/
133 uLong pos_in_central_dir
; /* pos of the current file in the central dir*/
134 uLong current_file_ok
; /* flag about the usability of the current file*/
135 uLong central_pos
; /* position of the beginning of the central dir*/
137 uLong size_central_dir
; /* size of the central directory */
138 uLong offset_central_dir
; /* offset of start of central directory with
139 respect to the starting disk number */
141 unz_file_info cur_file_info
; /* public info about the current file in zip*/
142 unz_file_info_internal cur_file_info_internal
; /* private info about it*/
143 file_in_zip_read_info_s
* pfile_in_zip_read
; /* structure about the current
144 file if we are decompressing it */
147 #if defined (__VISAGECPP__) || defined(__BORLANDC__)
148 /* VA always requires prototypes */
149 int unzlocal_CheckCurrentFileCoherencyHeader (unz_s
*, uInt
*, uLong
*, uInt
*);
152 /* disable warnings about K&R declarations until the end of file */
154 #pragma warning(disable:4131)
157 /* ===========================================================================
158 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
160 IN assertion: the stream s has been sucessfully opened for reading.
164 local
int unzlocal_getByte(fin
,pi
)
169 int err
= fread(&c
, 1, 1, fin
);
185 /* ===========================================================================
186 Reads a long in LSB order from the given gz_stream. Sets
188 local
int unzlocal_getShort (fin
,pX
)
196 err
= unzlocal_getByte(fin
,&i
);
200 err
= unzlocal_getByte(fin
,&i
);
210 local
int unzlocal_getLong (fin
,pX
)
218 err
= unzlocal_getByte(fin
,&i
);
222 err
= unzlocal_getByte(fin
,&i
);
226 err
= unzlocal_getByte(fin
,&i
);
230 err
= unzlocal_getByte(fin
,&i
);
241 /* My own strcmpi / strcasecmp */
242 local
int strcmpcasenosensitive_internal (fileName1
,fileName2
)
243 const char* fileName1
;
244 const char* fileName2
;
248 char c1
=*(fileName1
++);
249 char c2
=*(fileName2
++);
250 if ((c1
>='a') && (c1
<='z'))
252 if ((c2
>='a') && (c2
<='z'))
255 return ((c2
=='\0') ? 0 : -1);
266 #ifdef CASESENSITIVITYDEFAULT_NO
267 #define CASESENSITIVITYDEFAULTVALUE 2
269 #define CASESENSITIVITYDEFAULTVALUE 1
272 #ifndef STRCMPCASENOSENTIVEFUNCTION
273 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
277 Compare two filename (fileName1,fileName2).
278 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
279 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
281 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
282 (like 1 on Unix, 2 on Windows)
285 extern int ZEXPORT
unzStringFileNameCompare (fileName1
,fileName2
,iCaseSensitivity
)
286 const char* fileName1
;
287 const char* fileName2
;
288 int iCaseSensitivity
;
290 if (iCaseSensitivity
==0)
291 iCaseSensitivity
=CASESENSITIVITYDEFAULTVALUE
;
293 if (iCaseSensitivity
==1)
294 return strcmp(fileName1
,fileName2
);
296 return STRCMPCASENOSENTIVEFUNCTION(fileName1
,fileName2
);
299 #define BUFREADCOMMENT (0x400)
302 Locate the Central directory of a zipfile (at the end, just before
305 local uLong
unzlocal_SearchCentralDir(fin
)
311 uLong uMaxBack
=0xffff; /* maximum size of global comment */
314 if (fseek(fin
,0,SEEK_END
) != 0)
318 uSizeFile
= ftell( fin
);
320 if (uMaxBack
>uSizeFile
)
321 uMaxBack
= uSizeFile
;
323 buf
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4);
328 while (uBackRead
<uMaxBack
)
330 uLong uReadSize
,uReadPos
;
332 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
)
333 uBackRead
= uMaxBack
;
335 uBackRead
+=BUFREADCOMMENT
;
336 uReadPos
= uSizeFile
-uBackRead
;
338 uReadSize
= ((BUFREADCOMMENT
+4) < (uSizeFile
-uReadPos
)) ?
339 (BUFREADCOMMENT
+4) : (uSizeFile
-uReadPos
);
340 if (fseek(fin
,uReadPos
,SEEK_SET
)!=0)
343 if (fread(buf
,(uInt
)uReadSize
,1,fin
)!=1)
346 for (i
=(int)uReadSize
-3; (i
--)>0;)
347 if (((*(buf
+i
))==0x50) && ((*(buf
+i
+1))==0x4b) &&
348 ((*(buf
+i
+2))==0x05) && ((*(buf
+i
+3))==0x06))
350 uPosFound
= uReadPos
+i
;
361 #if defined(__WXMAC__) && !defined(__UNIX__)
362 void wxUnix2MacFilename (char *s
) ;
364 wxUnix2MacFilename (char *s
)
370 /* relative path , since it goes on with slash which is translated to a : */
371 memmove( s
, s
+1 ,strlen( s
) ) ;
373 else if ( *s
== '/' )
375 /* absolute path -> on mac just start with the drive name */
376 memmove( s
, s
+1 ,strlen( s
) ) ;
380 /* wxASSERT_MSG( 1 , "unkown path beginning" ) ; */
384 if (*s
== '/' || *s
== '\\')
386 /* convert any back-directory situations */
387 if ( *(s
+1) == '.' && *(s
+2) == '.' && ( (*(s
+3) == '/' || *(s
+3) == '\\') ) )
390 memmove( s
+1 , s
+3 ,strlen( s
+3 ) + 1 ) ;
400 extern char * wxBuffer
;
404 Open a Zip file. path contain the full pathname (by example,
405 on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
407 If the zipfile cannot be opened (file don't exist or in not valid), the
408 return value is NULL.
409 Else, the return value is a unzFile Handle, usable with other function
410 of this unzip package.
412 extern unzFile ZEXPORT
unzOpen (path
)
417 uLong central_pos
,uL
;
420 uLong number_disk
; /* number of the current dist, used for
421 spaning ZIP, unsupported, always 0*/
422 uLong number_disk_with_CD
; /* number the the disk with central dir, used
423 for spaning ZIP, unsupported, always 0*/
424 uLong number_entry_CD
; /* total number of entries in
426 (same than number_entry on nospan) */
430 if (unz_copyright
[0]!=' ')
433 #if defined(__WXMAC__) && !defined(__UNIX__)
434 strcpy( wxBuffer
, path
) ;
435 wxUnix2MacFilename( wxBuffer
) ;
436 fin
=fopen(wxBuffer
,"rb");
438 fin
=fopen(path
,"rb");
443 central_pos
= unzlocal_SearchCentralDir(fin
);
447 if (fseek(fin
,central_pos
,SEEK_SET
)!=0)
450 /* the signature, already checked */
451 if (unzlocal_getLong(fin
,&uL
)!=UNZ_OK
)
454 /* number of this disk */
455 if (unzlocal_getShort(fin
,&number_disk
)!=UNZ_OK
)
458 /* number of the disk with the start of the central directory */
459 if (unzlocal_getShort(fin
,&number_disk_with_CD
)!=UNZ_OK
)
462 /* total number of entries in the central dir on this disk */
463 if (unzlocal_getShort(fin
,&us
.gi
.number_entry
)!=UNZ_OK
)
466 /* total number of entries in the central dir */
467 if (unzlocal_getShort(fin
,&number_entry_CD
)!=UNZ_OK
)
470 if ((number_entry_CD
!=us
.gi
.number_entry
) ||
471 (number_disk_with_CD
!=0) ||
475 /* size of the central directory */
476 if (unzlocal_getLong(fin
,&us
.size_central_dir
)!=UNZ_OK
)
479 /* offset of start of central directory with respect to the
480 starting disk number */
481 if (unzlocal_getLong(fin
,&us
.offset_central_dir
)!=UNZ_OK
)
484 /* zipfile comment length */
485 if (unzlocal_getShort(fin
,&us
.gi
.size_comment
)!=UNZ_OK
)
488 if ((central_pos
<us
.offset_central_dir
+us
.size_central_dir
) &&
498 us
.byte_before_the_zipfile
= central_pos
-
499 (us
.offset_central_dir
+us
.size_central_dir
);
500 us
.central_pos
= central_pos
;
501 us
.pfile_in_zip_read
= NULL
;
504 s
=(unz_s
*)ALLOC(sizeof(unz_s
));
506 unzGoToFirstFile((unzFile
)s
);
512 Close a ZipFile opened with unzipOpen.
513 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
514 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
515 return UNZ_OK if there is no problem. */
516 extern int ZEXPORT
unzClose (file
)
521 return UNZ_PARAMERROR
;
524 if (s
->pfile_in_zip_read
!=NULL
)
525 unzCloseCurrentFile(file
);
534 Write info about the ZipFile in the *pglobal_info structure.
535 No preparation of the structure is needed
536 return UNZ_OK if there is no problem. */
537 extern int ZEXPORT
unzGetGlobalInfo (file
,pglobal_info
)
539 unz_global_info
*pglobal_info
;
543 return UNZ_PARAMERROR
;
551 Translate date/time from Dos format to tm_unz (readable more easilty)
553 local
void unzlocal_DosDateToTmuDate (ulDosDate
, ptm
)
558 uDate
= (uLong
)(ulDosDate
>>16);
559 ptm
->tm_mday
= (uInt
)(uDate
&0x1f) ;
560 ptm
->tm_mon
= (uInt
)((((uDate
)&0x1E0)/0x20)-1) ;
561 ptm
->tm_year
= (uInt
)(((uDate
&0x0FE00)/0x0200)+1980) ;
563 ptm
->tm_hour
= (uInt
) ((ulDosDate
&0xF800)/0x800);
564 ptm
->tm_min
= (uInt
) ((ulDosDate
&0x7E0)/0x20) ;
565 ptm
->tm_sec
= (uInt
) (2*(ulDosDate
&0x1f)) ;
569 Get Info about the current file in the zipfile, with internal only info
571 local
int unzlocal_GetCurrentFileInfoInternal
OF((unzFile file
,
572 unz_file_info
*pfile_info
,
573 unz_file_info_internal
574 *pfile_info_internal
,
576 uLong fileNameBufferSize
,
578 uLong extraFieldBufferSize
,
580 uLong commentBufferSize
));
582 local
int unzlocal_GetCurrentFileInfoInternal (file
,
585 szFileName
, fileNameBufferSize
,
586 extraField
, extraFieldBufferSize
,
587 szComment
, commentBufferSize
)
589 unz_file_info
*pfile_info
;
590 unz_file_info_internal
*pfile_info_internal
;
592 uLong fileNameBufferSize
;
594 uLong extraFieldBufferSize
;
596 uLong commentBufferSize
;
599 unz_file_info file_info
;
600 unz_file_info_internal file_info_internal
;
606 return UNZ_PARAMERROR
;
608 if (fseek(s
->file
,s
->pos_in_central_dir
+s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
612 /* we check the magic */
615 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
617 else if (uMagic
!=0x02014b50)
621 if (unzlocal_getShort(s
->file
,&file_info
.version
) != UNZ_OK
)
624 if (unzlocal_getShort(s
->file
,&file_info
.version_needed
) != UNZ_OK
)
627 if (unzlocal_getShort(s
->file
,&file_info
.flag
) != UNZ_OK
)
630 if (unzlocal_getShort(s
->file
,&file_info
.compression_method
) != UNZ_OK
)
633 if (unzlocal_getLong(s
->file
,&file_info
.dosDate
) != UNZ_OK
)
636 unzlocal_DosDateToTmuDate(file_info
.dosDate
,&file_info
.tmu_date
);
638 if (unzlocal_getLong(s
->file
,&file_info
.crc
) != UNZ_OK
)
641 if (unzlocal_getLong(s
->file
,&file_info
.compressed_size
) != UNZ_OK
)
644 if (unzlocal_getLong(s
->file
,&file_info
.uncompressed_size
) != UNZ_OK
)
647 if (unzlocal_getShort(s
->file
,&file_info
.size_filename
) != UNZ_OK
)
650 if (unzlocal_getShort(s
->file
,&file_info
.size_file_extra
) != UNZ_OK
)
653 if (unzlocal_getShort(s
->file
,&file_info
.size_file_comment
) != UNZ_OK
)
656 if (unzlocal_getShort(s
->file
,&file_info
.disk_num_start
) != UNZ_OK
)
659 if (unzlocal_getShort(s
->file
,&file_info
.internal_fa
) != UNZ_OK
)
662 if (unzlocal_getLong(s
->file
,&file_info
.external_fa
) != UNZ_OK
)
665 if (unzlocal_getLong(s
->file
,&file_info_internal
.offset_curfile
) != UNZ_OK
)
668 lSeek
+=file_info
.size_filename
;
669 if ((err
==UNZ_OK
) && (szFileName
!=NULL
))
672 if (file_info
.size_filename
<fileNameBufferSize
)
674 *(szFileName
+file_info
.size_filename
)='\0';
675 uSizeRead
= file_info
.size_filename
;
678 uSizeRead
= fileNameBufferSize
;
680 if ((file_info
.size_filename
>0) && (fileNameBufferSize
>0))
681 if (fread(szFileName
,(uInt
)uSizeRead
,1,s
->file
)!=1)
687 if ((err
==UNZ_OK
) && (extraField
!=NULL
))
690 if (file_info
.size_file_extra
<extraFieldBufferSize
)
691 uSizeRead
= file_info
.size_file_extra
;
693 uSizeRead
= extraFieldBufferSize
;
697 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
703 if ((file_info
.size_file_extra
>0) && (extraFieldBufferSize
>0))
704 if (fread(extraField
,(uInt
)uSizeRead
,1,s
->file
)!=1)
706 lSeek
+= file_info
.size_file_extra
- uSizeRead
;
709 lSeek
+=file_info
.size_file_extra
;
712 if ((err
==UNZ_OK
) && (szComment
!=NULL
))
715 if (file_info
.size_file_comment
<commentBufferSize
)
717 *(szComment
+file_info
.size_file_comment
)='\0';
718 uSizeRead
= file_info
.size_file_comment
;
721 uSizeRead
= commentBufferSize
;
725 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
731 if ((file_info
.size_file_comment
>0) && (commentBufferSize
>0))
732 if (fread(szComment
,(uInt
)uSizeRead
,1,s
->file
)!=1)
734 lSeek
+=file_info
.size_file_comment
- uSizeRead
;
737 lSeek
+=file_info
.size_file_comment
;
739 if ((err
==UNZ_OK
) && (pfile_info
!=NULL
))
740 *pfile_info
=file_info
;
742 if ((err
==UNZ_OK
) && (pfile_info_internal
!=NULL
))
743 *pfile_info_internal
=file_info_internal
;
751 Write info about the ZipFile in the *pglobal_info structure.
752 No preparation of the structure is needed
753 return UNZ_OK if there is no problem.
755 extern int ZEXPORT
unzGetCurrentFileInfo (file
,
757 szFileName
, fileNameBufferSize
,
758 extraField
, extraFieldBufferSize
,
759 szComment
, commentBufferSize
)
761 unz_file_info
*pfile_info
;
763 uLong fileNameBufferSize
;
765 uLong extraFieldBufferSize
;
767 uLong commentBufferSize
;
769 return unzlocal_GetCurrentFileInfoInternal(file
,pfile_info
,NULL
,
770 szFileName
,fileNameBufferSize
,
771 extraField
,extraFieldBufferSize
,
772 szComment
,commentBufferSize
);
776 Set the current file of the zipfile to the first file.
777 return UNZ_OK if there is no problem
779 extern int ZEXPORT
unzGoToFirstFile (file
)
785 return UNZ_PARAMERROR
;
787 s
->pos_in_central_dir
=s
->offset_central_dir
;
789 err
=unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
790 &s
->cur_file_info_internal
,
791 NULL
,0,NULL
,0,NULL
,0);
792 s
->current_file_ok
= (err
== UNZ_OK
);
798 Set the current file of the zipfile to the next file.
799 return UNZ_OK if there is no problem
800 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
802 extern int ZEXPORT
unzGoToNextFile (file
)
809 return UNZ_PARAMERROR
;
811 if (!s
->current_file_ok
)
812 return UNZ_END_OF_LIST_OF_FILE
;
813 if (s
->num_file
+1==s
->gi
.number_entry
)
814 return UNZ_END_OF_LIST_OF_FILE
;
816 s
->pos_in_central_dir
+= SIZECENTRALDIRITEM
+ s
->cur_file_info
.size_filename
+
817 s
->cur_file_info
.size_file_extra
+ s
->cur_file_info
.size_file_comment
;
819 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
820 &s
->cur_file_info_internal
,
821 NULL
,0,NULL
,0,NULL
,0);
822 s
->current_file_ok
= (err
== UNZ_OK
);
828 Try locate the file szFileName in the zipfile.
829 For the iCaseSensitivity signification, see unzipStringFileNameCompare
832 UNZ_OK if the file is found. It becomes the current file.
833 UNZ_END_OF_LIST_OF_FILE if the file is not found
835 extern int ZEXPORT
unzLocateFile (file
, szFileName
, iCaseSensitivity
)
837 const char *szFileName
;
838 int iCaseSensitivity
;
844 char szFileName2
[UNZ_MAXFILENAMEINZIP
+1];
847 uLong pos_in_central_dirSaved
;
849 for (c
= szFileName
, c2
= szFileName2
; *c
!= '\0'; c
++, c2
++)
850 if (*c
== '\\') *c2
= '/';
855 return UNZ_PARAMERROR
;
857 if (strlen(szFileName
)>=UNZ_MAXFILENAMEINZIP
)
858 return UNZ_PARAMERROR
;
861 if (!s
->current_file_ok
)
862 return UNZ_END_OF_LIST_OF_FILE
;
864 num_fileSaved
= s
->num_file
;
865 pos_in_central_dirSaved
= s
->pos_in_central_dir
;
867 err
= unzGoToFirstFile(file
);
869 while (err
== UNZ_OK
)
871 char szCurrentFileName
[UNZ_MAXFILENAMEINZIP
+1];
872 unzGetCurrentFileInfo(file
,NULL
,
873 szCurrentFileName
,sizeof(szCurrentFileName
)-1,
875 for (c2
= szCurrentFileName
; *c2
!= '\0'; c2
++) if (*c2
== '\\') *c2
= '/';
876 if (unzStringFileNameCompare(szCurrentFileName
,
877 szFileName2
,iCaseSensitivity
)==0)
879 err
= unzGoToNextFile(file
);
882 s
->num_file
= num_fileSaved
;
883 s
->pos_in_central_dir
= pos_in_central_dirSaved
;
889 Read the local header of the current zipfile
890 Check the coherency of the local header and info in the end of central
891 directory about this file
892 store in *piSizeVar the size of extra info in local header
893 (filename and size of extra field data)
895 local
int unzlocal_CheckCurrentFileCoherencyHeader (s
,piSizeVar
,
896 poffset_local_extrafield
,
897 psize_local_extrafield
)
900 uLong
*poffset_local_extrafield
;
901 uInt
*psize_local_extrafield
;
903 uLong uMagic
,uData
,uFlags
;
905 uLong size_extra_field
;
909 *poffset_local_extrafield
= 0;
910 *psize_local_extrafield
= 0;
912 if (fseek(s
->file
,s
->cur_file_info_internal
.offset_curfile
+
913 s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
919 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
921 else if (uMagic
!=0x04034b50)
925 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
928 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
931 if (unzlocal_getShort(s
->file
,&uFlags
) != UNZ_OK
)
934 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
936 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compression_method
))
939 if ((err
==UNZ_OK
) && (s
->cur_file_info
.compression_method
!=0) &&
940 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
943 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* date/time */
946 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* crc */
948 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.crc
) &&
952 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size compr */
954 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compressed_size
) &&
958 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size uncompr */
960 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.uncompressed_size
) &&
965 if (unzlocal_getShort(s
->file
,&size_filename
) != UNZ_OK
)
967 else if ((err
==UNZ_OK
) && (size_filename
!=s
->cur_file_info
.size_filename
))
970 *piSizeVar
+= (uInt
)size_filename
;
972 if (unzlocal_getShort(s
->file
,&size_extra_field
) != UNZ_OK
)
974 *poffset_local_extrafield
= s
->cur_file_info_internal
.offset_curfile
+
975 SIZEZIPLOCALHEADER
+ size_filename
;
976 *psize_local_extrafield
= (uInt
)size_extra_field
;
978 *piSizeVar
+= (uInt
)size_extra_field
;
984 Open for reading data the current file in the zipfile.
985 If there is no error and the file is opened, the return value is UNZ_OK.
987 extern int ZEXPORT
unzOpenCurrentFile (file
)
994 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
995 uLong offset_local_extrafield
; /* offset of the local extra field */
996 uInt size_local_extrafield
; /* size of the local extra field */
999 return UNZ_PARAMERROR
;
1001 if (!s
->current_file_ok
)
1002 return UNZ_PARAMERROR
;
1004 if (s
->pfile_in_zip_read
!= NULL
)
1005 unzCloseCurrentFile(file
);
1007 if (unzlocal_CheckCurrentFileCoherencyHeader(s
,&iSizeVar
,
1008 &offset_local_extrafield
,&size_local_extrafield
)!=UNZ_OK
)
1009 return UNZ_BADZIPFILE
;
1011 pfile_in_zip_read_info
= (file_in_zip_read_info_s
*)
1012 ALLOC(sizeof(file_in_zip_read_info_s
));
1013 if (pfile_in_zip_read_info
==NULL
)
1014 return UNZ_INTERNALERROR
;
1016 pfile_in_zip_read_info
->read_buffer
=(char*)ALLOC(UNZ_BUFSIZE
);
1017 pfile_in_zip_read_info
->offset_local_extrafield
= offset_local_extrafield
;
1018 pfile_in_zip_read_info
->size_local_extrafield
= size_local_extrafield
;
1019 pfile_in_zip_read_info
->pos_local_extrafield
=0;
1021 if (pfile_in_zip_read_info
->read_buffer
==NULL
)
1023 TRYFREE(pfile_in_zip_read_info
);
1024 return UNZ_INTERNALERROR
;
1027 pfile_in_zip_read_info
->stream_initialised
=0;
1029 if ((s
->cur_file_info
.compression_method
!=0) &&
1030 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
1032 Store
= s
->cur_file_info
.compression_method
==0;
1034 pfile_in_zip_read_info
->crc32_wait
=s
->cur_file_info
.crc
;
1035 pfile_in_zip_read_info
->crc32
=0;
1036 pfile_in_zip_read_info
->compression_method
=
1037 s
->cur_file_info
.compression_method
;
1038 pfile_in_zip_read_info
->file
=s
->file
;
1039 pfile_in_zip_read_info
->byte_before_the_zipfile
=s
->byte_before_the_zipfile
;
1041 pfile_in_zip_read_info
->stream
.total_out
= 0;
1045 pfile_in_zip_read_info
->stream
.zalloc
= (alloc_func
)0;
1046 pfile_in_zip_read_info
->stream
.zfree
= (free_func
)0;
1047 pfile_in_zip_read_info
->stream
.opaque
= (voidpf
)0;
1049 err
=inflateInit2(&pfile_in_zip_read_info
->stream
, -MAX_WBITS
);
1051 pfile_in_zip_read_info
->stream_initialised
=1;
1052 /* windowBits is passed < 0 to tell that there is no zlib header.
1053 * Note that in this case inflate *requires* an extra "dummy" byte
1054 * after the compressed stream in order to complete decompression and
1055 * return Z_STREAM_END.
1056 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1057 * size of both compressed and uncompressed data
1060 pfile_in_zip_read_info
->rest_read_compressed
=
1061 s
->cur_file_info
.compressed_size
;
1062 pfile_in_zip_read_info
->rest_read_uncompressed
=
1063 s
->cur_file_info
.uncompressed_size
;
1066 pfile_in_zip_read_info
->pos_in_zipfile
=
1067 s
->cur_file_info_internal
.offset_curfile
+ SIZEZIPLOCALHEADER
+
1070 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)0;
1073 s
->pfile_in_zip_read
= pfile_in_zip_read_info
;
1079 Read bytes from the current file.
1080 buf contain buffer where data must be copied
1081 len the size of buf.
1083 return the number of byte copied if somes bytes are copied
1084 return 0 if the end of file was reached
1085 return <0 with error code if there is an error
1086 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1088 extern int ZEXPORT
unzReadCurrentFile (file
, buf
, len
)
1096 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1098 return UNZ_PARAMERROR
;
1100 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1102 if (pfile_in_zip_read_info
==NULL
)
1103 return UNZ_PARAMERROR
;
1106 if ((pfile_in_zip_read_info
->read_buffer
== NULL
))
1107 return UNZ_END_OF_LIST_OF_FILE
;
1111 pfile_in_zip_read_info
->stream
.next_out
= (Bytef
*)buf
;
1113 pfile_in_zip_read_info
->stream
.avail_out
= (uInt
)len
;
1115 if (len
>pfile_in_zip_read_info
->rest_read_uncompressed
)
1116 pfile_in_zip_read_info
->stream
.avail_out
=
1117 (uInt
)pfile_in_zip_read_info
->rest_read_uncompressed
;
1119 while (pfile_in_zip_read_info
->stream
.avail_out
>0)
1121 if ((pfile_in_zip_read_info
->stream
.avail_in
==0) &&
1122 (pfile_in_zip_read_info
->rest_read_compressed
>0))
1124 uInt uReadThis
= UNZ_BUFSIZE
;
1125 if (pfile_in_zip_read_info
->rest_read_compressed
<uReadThis
)
1126 uReadThis
= (uInt
)pfile_in_zip_read_info
->rest_read_compressed
;
1129 if (fseek(pfile_in_zip_read_info
->file
,
1130 pfile_in_zip_read_info
->pos_in_zipfile
+
1131 pfile_in_zip_read_info
->byte_before_the_zipfile
,SEEK_SET
)!=0)
1133 if (fread(pfile_in_zip_read_info
->read_buffer
,uReadThis
,1,
1134 pfile_in_zip_read_info
->file
)!=1)
1136 pfile_in_zip_read_info
->pos_in_zipfile
+= uReadThis
;
1138 pfile_in_zip_read_info
->rest_read_compressed
-=uReadThis
;
1140 pfile_in_zip_read_info
->stream
.next_in
=
1141 (Bytef
*)pfile_in_zip_read_info
->read_buffer
;
1142 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)uReadThis
;
1145 if (pfile_in_zip_read_info
->compression_method
==0)
1148 if (pfile_in_zip_read_info
->stream
.avail_out
<
1149 pfile_in_zip_read_info
->stream
.avail_in
)
1150 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_out
;
1152 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_in
;
1154 for (i
=0;i
<uDoCopy
;i
++)
1155 *(pfile_in_zip_read_info
->stream
.next_out
+i
) =
1156 *(pfile_in_zip_read_info
->stream
.next_in
+i
);
1158 pfile_in_zip_read_info
->crc32
= crc32(pfile_in_zip_read_info
->crc32
,
1159 pfile_in_zip_read_info
->stream
.next_out
,
1161 pfile_in_zip_read_info
->rest_read_uncompressed
-=uDoCopy
;
1162 pfile_in_zip_read_info
->stream
.avail_in
-= uDoCopy
;
1163 pfile_in_zip_read_info
->stream
.avail_out
-= uDoCopy
;
1164 pfile_in_zip_read_info
->stream
.next_out
+= uDoCopy
;
1165 pfile_in_zip_read_info
->stream
.next_in
+= uDoCopy
;
1166 pfile_in_zip_read_info
->stream
.total_out
+= uDoCopy
;
1171 uLong uTotalOutBefore
,uTotalOutAfter
;
1172 const Bytef
*bufBefore
;
1174 int flush
=Z_SYNC_FLUSH
;
1176 uTotalOutBefore
= pfile_in_zip_read_info
->stream
.total_out
;
1177 bufBefore
= pfile_in_zip_read_info
->stream
.next_out
;
1180 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1181 pfile_in_zip_read_info->stream.avail_out) &&
1182 (pfile_in_zip_read_info->rest_read_compressed == 0))
1185 err
=inflate(&pfile_in_zip_read_info
->stream
,flush
);
1187 uTotalOutAfter
= pfile_in_zip_read_info
->stream
.total_out
;
1188 uOutThis
= uTotalOutAfter
-uTotalOutBefore
;
1190 pfile_in_zip_read_info
->crc32
=
1191 crc32(pfile_in_zip_read_info
->crc32
,bufBefore
,
1194 pfile_in_zip_read_info
->rest_read_uncompressed
-=
1197 iRead
+= (uInt
)(uTotalOutAfter
- uTotalOutBefore
);
1199 if (err
==Z_STREAM_END
)
1200 return (iRead
==0) ? UNZ_EOF
: iRead
;
1213 Give the current position in uncompressed data
1215 extern z_off_t ZEXPORT
unztell (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 return (z_off_t
)pfile_in_zip_read_info
->stream
.total_out
;
1233 return 1 if the end of file was reached, 0 elsewhere
1235 extern int ZEXPORT
unzeof (file
)
1239 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1241 return UNZ_PARAMERROR
;
1243 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1245 if (pfile_in_zip_read_info
==NULL
)
1246 return UNZ_PARAMERROR
;
1248 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1257 Read extra field from the current file (opened by unzOpenCurrentFile)
1258 This is the local-header version of the extra field (sometimes, there is
1259 more info in the local-header version than in the central-header)
1261 if buf==NULL, it return the size of the local extra field that can be read
1263 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1265 the return value is the number of bytes copied in buf, or (if <0)
1268 extern int ZEXPORT
unzGetLocalExtrafield (file
,buf
,len
)
1274 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1279 return UNZ_PARAMERROR
;
1281 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1283 if (pfile_in_zip_read_info
==NULL
)
1284 return UNZ_PARAMERROR
;
1286 size_to_read
= (pfile_in_zip_read_info
->size_local_extrafield
-
1287 pfile_in_zip_read_info
->pos_local_extrafield
);
1290 return (int)size_to_read
;
1292 if (len
>size_to_read
)
1293 read_now
= (uInt
)size_to_read
;
1295 read_now
= (uInt
)len
;
1300 if (fseek(pfile_in_zip_read_info
->file
,
1301 pfile_in_zip_read_info
->offset_local_extrafield
+
1302 pfile_in_zip_read_info
->pos_local_extrafield
,SEEK_SET
)!=0)
1305 if (fread(buf
,(uInt
)size_to_read
,1,pfile_in_zip_read_info
->file
)!=1)
1308 return (int)read_now
;
1312 Close the file in zip opened with unzipOpenCurrentFile
1313 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1315 extern int ZEXPORT
unzCloseCurrentFile (file
)
1321 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1323 return UNZ_PARAMERROR
;
1325 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1327 if (pfile_in_zip_read_info
==NULL
)
1328 return UNZ_PARAMERROR
;
1331 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1333 if (pfile_in_zip_read_info
->crc32
!= pfile_in_zip_read_info
->crc32_wait
)
1338 TRYFREE(pfile_in_zip_read_info
->read_buffer
);
1339 pfile_in_zip_read_info
->read_buffer
= NULL
;
1340 if (pfile_in_zip_read_info
->stream_initialised
)
1341 inflateEnd(&pfile_in_zip_read_info
->stream
);
1343 pfile_in_zip_read_info
->stream_initialised
= 0;
1344 TRYFREE(pfile_in_zip_read_info
);
1346 s
->pfile_in_zip_read
=NULL
;
1353 Get the global comment string of the ZipFile, in the szComment buffer.
1354 uSizeBuf is the size of the szComment buffer.
1355 return the number of byte copied or an error code <0
1357 extern int ZEXPORT
unzGetGlobalComment (file
, szComment
, uSizeBuf
)
1365 return UNZ_PARAMERROR
;
1368 uReadThis
= uSizeBuf
;
1369 if (uReadThis
>s
->gi
.size_comment
)
1370 uReadThis
= s
->gi
.size_comment
;
1372 if (fseek(s
->file
,s
->central_pos
+22,SEEK_SET
)!=0)
1378 if (fread(szComment
,(uInt
)uReadThis
,1,s
->file
)!=1)
1382 if ((szComment
!= NULL
) && (uSizeBuf
> s
->gi
.size_comment
))
1383 *(szComment
+s
->gi
.size_comment
)='\0';
1384 return (int)uReadThis
;
1389 /* the file shouldn't be empty, som compilers don't like it */
1390 static const int dummyVariableInUnzip
= 17;
1392 #endif /* wxUSE_ZLIB && wxUSE_ZIPSTREAM */