1 /* unzip.c -- IO on .zip files using zlib
2 Version 0.15 beta, Mar 19th, 1998,
4 Read unzip.h for more info
9 #if !defined(__VISAGECPP__)
10 # pragma warning(disable:4001) /* non standard extension used: single line comment */
17 #if wxUSE_ZLIB && wxUSE_ZIPSTREAM
24 /* Not the right solution (paths in makefiles) but... */
26 #include "../common/unzip.h"
46 /* compile with -Dlocal if your debugger can't find static symbols */
50 #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
51 !defined(CASESENSITIVITYDEFAULT_NO)
52 #define CASESENSITIVITYDEFAULT_NO
57 #define UNZ_BUFSIZE (16384)
60 #ifndef UNZ_MAXFILENAMEINZIP
61 #define UNZ_MAXFILENAMEINZIP (256)
65 # define ALLOC(size) (malloc(size))
68 # define TRYFREE(p) {if (p) free(p);}
71 #define SIZECENTRALDIRITEM (0x2e)
72 #define SIZEZIPLOCALHEADER (0x1e)
75 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
89 const char unz_copyright
[] =
90 " unzip 0.15 Copyright 1998 Gilles Vollant ";
92 /* unz_file_info_interntal contain internal info about a file in zipfile*/
93 typedef struct unz_file_info_internal_s
95 uLong offset_curfile
;/* relative offset of local header 4 bytes */
96 } unz_file_info_internal
;
99 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
100 when reading and decompress it */
103 char *read_buffer
; /* internal buffer for compressed data */
104 z_stream stream
; /* zLib stream structure for inflate */
106 uLong pos_in_zipfile
; /* position in byte on the zipfile, for fseek*/
107 uLong stream_initialised
; /* flag set if stream structure is initialised*/
109 uLong offset_local_extrafield
;/* offset of the local extra field */
110 uInt size_local_extrafield
;/* size of the local extra field */
111 uLong pos_local_extrafield
; /* position in the local extra field in read*/
113 uLong crc32
; /* crc32 of all data uncompressed */
114 uLong crc32_wait
; /* crc32 we must obtain after decompress all */
115 uLong rest_read_compressed
; /* number of byte to be decompressed */
116 uLong rest_read_uncompressed
;/*number of byte to be obtained after decomp*/
117 FILE* file
; /* io structore of the zipfile */
118 uLong compression_method
; /* compression method (0==store) */
119 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
120 } file_in_zip_read_info_s
;
123 /* unz_s contain internal information about the zipfile
127 FILE* file
; /* io structore of the zipfile */
128 unz_global_info gi
; /* public global information */
129 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
130 uLong num_file
; /* number of the current file in the zipfile*/
131 uLong pos_in_central_dir
; /* pos of the current file in the central dir*/
132 uLong current_file_ok
; /* flag about the usability of the current file*/
133 uLong central_pos
; /* position of the beginning of the central dir*/
135 uLong size_central_dir
; /* size of the central directory */
136 uLong offset_central_dir
; /* offset of start of central directory with
137 respect to the starting disk number */
139 unz_file_info cur_file_info
; /* public info about the current file in zip*/
140 unz_file_info_internal cur_file_info_internal
; /* private info about it*/
141 file_in_zip_read_info_s
* pfile_in_zip_read
; /* structure about the current
142 file if we are decompressing it */
145 #if defined (__VISAGECPP__)
146 /* VA always requires prototypes */
147 int unzlocal_CheckCurrentFileCoherencyHeader (unz_s
*, uInt
*, uLong
*, uInt
*);
150 /* ===========================================================================
151 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
153 IN assertion: the stream s has been sucessfully opened for reading.
157 local
int unzlocal_getByte(fin
,pi
)
162 int err
= fread(&c
, 1, 1, fin
);
178 /* ===========================================================================
179 Reads a long in LSB order from the given gz_stream. Sets
181 local
int unzlocal_getShort (fin
,pX
)
189 err
= unzlocal_getByte(fin
,&i
);
193 err
= unzlocal_getByte(fin
,&i
);
203 local
int unzlocal_getLong (fin
,pX
)
211 err
= unzlocal_getByte(fin
,&i
);
215 err
= unzlocal_getByte(fin
,&i
);
219 err
= unzlocal_getByte(fin
,&i
);
223 err
= unzlocal_getByte(fin
,&i
);
234 /* My own strcmpi / strcasecmp */
235 local
int strcmpcasenosensitive_internal (fileName1
,fileName2
)
236 const char* fileName1
;
237 const char* fileName2
;
241 char c1
=*(fileName1
++);
242 char c2
=*(fileName2
++);
243 if ((c1
>='a') && (c1
<='z'))
245 if ((c2
>='a') && (c2
<='z'))
248 return ((c2
=='\0') ? 0 : -1);
259 #ifdef CASESENSITIVITYDEFAULT_NO
260 #define CASESENSITIVITYDEFAULTVALUE 2
262 #define CASESENSITIVITYDEFAULTVALUE 1
265 #ifndef STRCMPCASENOSENTIVEFUNCTION
266 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
270 Compare two filename (fileName1,fileName2).
271 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
272 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
274 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
275 (like 1 on Unix, 2 on Windows)
278 extern int ZEXPORT
unzStringFileNameCompare (fileName1
,fileName2
,iCaseSensitivity
)
279 const char* fileName1
;
280 const char* fileName2
;
281 int iCaseSensitivity
;
283 if (iCaseSensitivity
==0)
284 iCaseSensitivity
=CASESENSITIVITYDEFAULTVALUE
;
286 if (iCaseSensitivity
==1)
287 return strcmp(fileName1
,fileName2
);
289 return STRCMPCASENOSENTIVEFUNCTION(fileName1
,fileName2
);
292 #define BUFREADCOMMENT (0x400)
295 Locate the Central directory of a zipfile (at the end, just before
298 local uLong
unzlocal_SearchCentralDir(fin
)
304 uLong uMaxBack
=0xffff; /* maximum size of global comment */
307 if (fseek(fin
,0,SEEK_END
) != 0)
311 uSizeFile
= ftell( fin
);
313 if (uMaxBack
>uSizeFile
)
314 uMaxBack
= uSizeFile
;
316 buf
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4);
321 while (uBackRead
<uMaxBack
)
323 uLong uReadSize
,uReadPos
;
325 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
)
326 uBackRead
= uMaxBack
;
328 uBackRead
+=BUFREADCOMMENT
;
329 uReadPos
= uSizeFile
-uBackRead
;
331 uReadSize
= ((BUFREADCOMMENT
+4) < (uSizeFile
-uReadPos
)) ?
332 (BUFREADCOMMENT
+4) : (uSizeFile
-uReadPos
);
333 if (fseek(fin
,uReadPos
,SEEK_SET
)!=0)
336 if (fread(buf
,(uInt
)uReadSize
,1,fin
)!=1)
339 for (i
=(int)uReadSize
-3; (i
--)>0;)
340 if (((*(buf
+i
))==0x50) && ((*(buf
+i
+1))==0x4b) &&
341 ((*(buf
+i
+2))==0x05) && ((*(buf
+i
+3))==0x06))
343 uPosFound
= uReadPos
+i
;
355 void wxUnix2MacFilename (char *s
) ;
357 wxUnix2MacFilename (char *s
)
363 // relative path , since it goes on with slash which is translated to a :
364 memmove( s
, s
+1 ,strlen( s
) ) ;
366 else if ( *s
== '/' )
368 // absolute path -> on mac just start with the drive name
369 memmove( s
, s
+1 ,strlen( s
) ) ;
373 // wxASSERT_MSG( 1 , "unkown path beginning" ) ;
377 if (*s
== '/' || *s
== '\\')
379 // convert any back-directory situations
380 if ( *(s
+1) == '.' && *(s
+2) == '.' && ( (*(s
+3) == '/' || *(s
+3) == '\\') ) )
383 memmove( s
+1 , s
+3 ,strlen( s
+3 ) + 1 ) ;
393 extern char * wxBuffer
;
397 Open a Zip file. path contain the full pathname (by example,
398 on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
400 If the zipfile cannot be opened (file don't exist or in not valid), the
401 return value is NULL.
402 Else, the return value is a unzFile Handle, usable with other function
403 of this unzip package.
405 extern unzFile ZEXPORT
unzOpen (path
)
410 uLong central_pos
,uL
;
413 uLong number_disk
; /* number of the current dist, used for
414 spaning ZIP, unsupported, always 0*/
415 uLong number_disk_with_CD
; /* number the the disk with central dir, used
416 for spaning ZIP, unsupported, always 0*/
417 uLong number_entry_CD
; /* total number of entries in
419 (same than number_entry on nospan) */
423 if (unz_copyright
[0]!=' ')
427 strcpy( wxBuffer
, path
) ;
428 wxUnix2MacFilename( wxBuffer
) ;
429 fin
=fopen(wxBuffer
,"rb");
431 fin
=fopen(path
,"rb");
436 central_pos
= unzlocal_SearchCentralDir(fin
);
440 if (fseek(fin
,central_pos
,SEEK_SET
)!=0)
443 /* the signature, already checked */
444 if (unzlocal_getLong(fin
,&uL
)!=UNZ_OK
)
447 /* number of this disk */
448 if (unzlocal_getShort(fin
,&number_disk
)!=UNZ_OK
)
451 /* number of the disk with the start of the central directory */
452 if (unzlocal_getShort(fin
,&number_disk_with_CD
)!=UNZ_OK
)
455 /* total number of entries in the central dir on this disk */
456 if (unzlocal_getShort(fin
,&us
.gi
.number_entry
)!=UNZ_OK
)
459 /* total number of entries in the central dir */
460 if (unzlocal_getShort(fin
,&number_entry_CD
)!=UNZ_OK
)
463 if ((number_entry_CD
!=us
.gi
.number_entry
) ||
464 (number_disk_with_CD
!=0) ||
468 /* size of the central directory */
469 if (unzlocal_getLong(fin
,&us
.size_central_dir
)!=UNZ_OK
)
472 /* offset of start of central directory with respect to the
473 starting disk number */
474 if (unzlocal_getLong(fin
,&us
.offset_central_dir
)!=UNZ_OK
)
477 /* zipfile comment length */
478 if (unzlocal_getShort(fin
,&us
.gi
.size_comment
)!=UNZ_OK
)
481 if ((central_pos
<us
.offset_central_dir
+us
.size_central_dir
) &&
491 us
.byte_before_the_zipfile
= central_pos
-
492 (us
.offset_central_dir
+us
.size_central_dir
);
493 us
.central_pos
= central_pos
;
494 us
.pfile_in_zip_read
= NULL
;
497 s
=(unz_s
*)ALLOC(sizeof(unz_s
));
499 unzGoToFirstFile((unzFile
)s
);
505 Close a ZipFile opened with unzipOpen.
506 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
507 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
508 return UNZ_OK if there is no problem. */
509 extern int ZEXPORT
unzClose (file
)
514 return UNZ_PARAMERROR
;
517 if (s
->pfile_in_zip_read
!=NULL
)
518 unzCloseCurrentFile(file
);
527 Write info about the ZipFile in the *pglobal_info structure.
528 No preparation of the structure is needed
529 return UNZ_OK if there is no problem. */
530 extern int ZEXPORT
unzGetGlobalInfo (file
,pglobal_info
)
532 unz_global_info
*pglobal_info
;
536 return UNZ_PARAMERROR
;
544 Translate date/time from Dos format to tm_unz (readable more easilty)
546 local
void unzlocal_DosDateToTmuDate (ulDosDate
, ptm
)
551 uDate
= (uLong
)(ulDosDate
>>16);
552 ptm
->tm_mday
= (uInt
)(uDate
&0x1f) ;
553 ptm
->tm_mon
= (uInt
)((((uDate
)&0x1E0)/0x20)-1) ;
554 ptm
->tm_year
= (uInt
)(((uDate
&0x0FE00)/0x0200)+1980) ;
556 ptm
->tm_hour
= (uInt
) ((ulDosDate
&0xF800)/0x800);
557 ptm
->tm_min
= (uInt
) ((ulDosDate
&0x7E0)/0x20) ;
558 ptm
->tm_sec
= (uInt
) (2*(ulDosDate
&0x1f)) ;
562 Get Info about the current file in the zipfile, with internal only info
564 local
int unzlocal_GetCurrentFileInfoInternal
OF((unzFile file
,
565 unz_file_info
*pfile_info
,
566 unz_file_info_internal
567 *pfile_info_internal
,
569 uLong fileNameBufferSize
,
571 uLong extraFieldBufferSize
,
573 uLong commentBufferSize
));
575 local
int unzlocal_GetCurrentFileInfoInternal (file
,
578 szFileName
, fileNameBufferSize
,
579 extraField
, extraFieldBufferSize
,
580 szComment
, commentBufferSize
)
582 unz_file_info
*pfile_info
;
583 unz_file_info_internal
*pfile_info_internal
;
585 uLong fileNameBufferSize
;
587 uLong extraFieldBufferSize
;
589 uLong commentBufferSize
;
592 unz_file_info file_info
;
593 unz_file_info_internal file_info_internal
;
599 return UNZ_PARAMERROR
;
601 if (fseek(s
->file
,s
->pos_in_central_dir
+s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
605 /* we check the magic */
607 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
609 else if (uMagic
!=0x02014b50)
612 if (unzlocal_getShort(s
->file
,&file_info
.version
) != UNZ_OK
)
615 if (unzlocal_getShort(s
->file
,&file_info
.version_needed
) != UNZ_OK
)
618 if (unzlocal_getShort(s
->file
,&file_info
.flag
) != UNZ_OK
)
621 if (unzlocal_getShort(s
->file
,&file_info
.compression_method
) != UNZ_OK
)
624 if (unzlocal_getLong(s
->file
,&file_info
.dosDate
) != UNZ_OK
)
627 unzlocal_DosDateToTmuDate(file_info
.dosDate
,&file_info
.tmu_date
);
629 if (unzlocal_getLong(s
->file
,&file_info
.crc
) != UNZ_OK
)
632 if (unzlocal_getLong(s
->file
,&file_info
.compressed_size
) != UNZ_OK
)
635 if (unzlocal_getLong(s
->file
,&file_info
.uncompressed_size
) != UNZ_OK
)
638 if (unzlocal_getShort(s
->file
,&file_info
.size_filename
) != UNZ_OK
)
641 if (unzlocal_getShort(s
->file
,&file_info
.size_file_extra
) != UNZ_OK
)
644 if (unzlocal_getShort(s
->file
,&file_info
.size_file_comment
) != UNZ_OK
)
647 if (unzlocal_getShort(s
->file
,&file_info
.disk_num_start
) != UNZ_OK
)
650 if (unzlocal_getShort(s
->file
,&file_info
.internal_fa
) != UNZ_OK
)
653 if (unzlocal_getLong(s
->file
,&file_info
.external_fa
) != UNZ_OK
)
656 if (unzlocal_getLong(s
->file
,&file_info_internal
.offset_curfile
) != UNZ_OK
)
659 lSeek
+=file_info
.size_filename
;
660 if ((err
==UNZ_OK
) && (szFileName
!=NULL
))
663 if (file_info
.size_filename
<fileNameBufferSize
)
665 *(szFileName
+file_info
.size_filename
)='\0';
666 uSizeRead
= file_info
.size_filename
;
669 uSizeRead
= fileNameBufferSize
;
671 if ((file_info
.size_filename
>0) && (fileNameBufferSize
>0))
672 if (fread(szFileName
,(uInt
)uSizeRead
,1,s
->file
)!=1)
678 if ((err
==UNZ_OK
) && (extraField
!=NULL
))
681 if (file_info
.size_file_extra
<extraFieldBufferSize
)
682 uSizeRead
= file_info
.size_file_extra
;
684 uSizeRead
= extraFieldBufferSize
;
687 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
691 if ((file_info
.size_file_extra
>0) && (extraFieldBufferSize
>0))
692 if (fread(extraField
,(uInt
)uSizeRead
,1,s
->file
)!=1)
694 lSeek
+= file_info
.size_file_extra
- uSizeRead
;
697 lSeek
+=file_info
.size_file_extra
;
700 if ((err
==UNZ_OK
) && (szComment
!=NULL
))
703 if (file_info
.size_file_comment
<commentBufferSize
)
705 *(szComment
+file_info
.size_file_comment
)='\0';
706 uSizeRead
= file_info
.size_file_comment
;
709 uSizeRead
= commentBufferSize
;
712 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
716 if ((file_info
.size_file_comment
>0) && (commentBufferSize
>0))
717 if (fread(szComment
,(uInt
)uSizeRead
,1,s
->file
)!=1)
719 lSeek
+=file_info
.size_file_comment
- uSizeRead
;
722 lSeek
+=file_info
.size_file_comment
;
724 if ((err
==UNZ_OK
) && (pfile_info
!=NULL
))
725 *pfile_info
=file_info
;
727 if ((err
==UNZ_OK
) && (pfile_info_internal
!=NULL
))
728 *pfile_info_internal
=file_info_internal
;
736 Write info about the ZipFile in the *pglobal_info structure.
737 No preparation of the structure is needed
738 return UNZ_OK if there is no problem.
740 extern int ZEXPORT
unzGetCurrentFileInfo (file
,
742 szFileName
, fileNameBufferSize
,
743 extraField
, extraFieldBufferSize
,
744 szComment
, commentBufferSize
)
746 unz_file_info
*pfile_info
;
748 uLong fileNameBufferSize
;
750 uLong extraFieldBufferSize
;
752 uLong commentBufferSize
;
754 return unzlocal_GetCurrentFileInfoInternal(file
,pfile_info
,NULL
,
755 szFileName
,fileNameBufferSize
,
756 extraField
,extraFieldBufferSize
,
757 szComment
,commentBufferSize
);
761 Set the current file of the zipfile to the first file.
762 return UNZ_OK if there is no problem
764 extern int ZEXPORT
unzGoToFirstFile (file
)
770 return UNZ_PARAMERROR
;
772 s
->pos_in_central_dir
=s
->offset_central_dir
;
774 err
=unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
775 &s
->cur_file_info_internal
,
776 NULL
,0,NULL
,0,NULL
,0);
777 s
->current_file_ok
= (err
== UNZ_OK
);
783 Set the current file of the zipfile to the next file.
784 return UNZ_OK if there is no problem
785 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
787 extern int ZEXPORT
unzGoToNextFile (file
)
794 return UNZ_PARAMERROR
;
796 if (!s
->current_file_ok
)
797 return UNZ_END_OF_LIST_OF_FILE
;
798 if (s
->num_file
+1==s
->gi
.number_entry
)
799 return UNZ_END_OF_LIST_OF_FILE
;
801 s
->pos_in_central_dir
+= SIZECENTRALDIRITEM
+ s
->cur_file_info
.size_filename
+
802 s
->cur_file_info
.size_file_extra
+ s
->cur_file_info
.size_file_comment
;
804 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
805 &s
->cur_file_info_internal
,
806 NULL
,0,NULL
,0,NULL
,0);
807 s
->current_file_ok
= (err
== UNZ_OK
);
813 Try locate the file szFileName in the zipfile.
814 For the iCaseSensitivity signification, see unzipStringFileNameCompare
817 UNZ_OK if the file is found. It becomes the current file.
818 UNZ_END_OF_LIST_OF_FILE if the file is not found
820 extern int ZEXPORT
unzLocateFile (file
, szFileName
, iCaseSensitivity
)
822 const char *szFileName
;
823 int iCaseSensitivity
;
830 uLong pos_in_central_dirSaved
;
834 return UNZ_PARAMERROR
;
836 if (strlen(szFileName
)>=UNZ_MAXFILENAMEINZIP
)
837 return UNZ_PARAMERROR
;
840 if (!s
->current_file_ok
)
841 return UNZ_END_OF_LIST_OF_FILE
;
843 num_fileSaved
= s
->num_file
;
844 pos_in_central_dirSaved
= s
->pos_in_central_dir
;
846 err
= unzGoToFirstFile(file
);
848 while (err
== UNZ_OK
)
850 char szCurrentFileName
[UNZ_MAXFILENAMEINZIP
+1];
851 unzGetCurrentFileInfo(file
,NULL
,
852 szCurrentFileName
,sizeof(szCurrentFileName
)-1,
854 if (unzStringFileNameCompare(szCurrentFileName
,
855 szFileName
,iCaseSensitivity
)==0)
857 err
= unzGoToNextFile(file
);
860 s
->num_file
= num_fileSaved
;
861 s
->pos_in_central_dir
= pos_in_central_dirSaved
;
867 Read the local header of the current zipfile
868 Check the coherency of the local header and info in the end of central
869 directory about this file
870 store in *piSizeVar the size of extra info in local header
871 (filename and size of extra field data)
873 local
int unzlocal_CheckCurrentFileCoherencyHeader (s
,piSizeVar
,
874 poffset_local_extrafield
,
875 psize_local_extrafield
)
878 uLong
*poffset_local_extrafield
;
879 uInt
*psize_local_extrafield
;
881 uLong uMagic
,uData
,uFlags
;
883 uLong size_extra_field
;
887 *poffset_local_extrafield
= 0;
888 *psize_local_extrafield
= 0;
890 if (fseek(s
->file
,s
->cur_file_info_internal
.offset_curfile
+
891 s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
896 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
898 else if (uMagic
!=0x04034b50)
901 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
904 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
907 if (unzlocal_getShort(s
->file
,&uFlags
) != UNZ_OK
)
910 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
912 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compression_method
))
915 if ((err
==UNZ_OK
) && (s
->cur_file_info
.compression_method
!=0) &&
916 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
919 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* date/time */
922 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* crc */
924 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.crc
) &&
928 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size compr */
930 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compressed_size
) &&
934 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size uncompr */
936 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.uncompressed_size
) &&
941 if (unzlocal_getShort(s
->file
,&size_filename
) != UNZ_OK
)
943 else if ((err
==UNZ_OK
) && (size_filename
!=s
->cur_file_info
.size_filename
))
946 *piSizeVar
+= (uInt
)size_filename
;
948 if (unzlocal_getShort(s
->file
,&size_extra_field
) != UNZ_OK
)
950 *poffset_local_extrafield
= s
->cur_file_info_internal
.offset_curfile
+
951 SIZEZIPLOCALHEADER
+ size_filename
;
952 *psize_local_extrafield
= (uInt
)size_extra_field
;
954 *piSizeVar
+= (uInt
)size_extra_field
;
960 Open for reading data the current file in the zipfile.
961 If there is no error and the file is opened, the return value is UNZ_OK.
963 extern int ZEXPORT
unzOpenCurrentFile (file
)
970 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
971 uLong offset_local_extrafield
; /* offset of the local extra field */
972 uInt size_local_extrafield
; /* size of the local extra field */
975 return UNZ_PARAMERROR
;
977 if (!s
->current_file_ok
)
978 return UNZ_PARAMERROR
;
980 if (s
->pfile_in_zip_read
!= NULL
)
981 unzCloseCurrentFile(file
);
983 if (unzlocal_CheckCurrentFileCoherencyHeader(s
,&iSizeVar
,
984 &offset_local_extrafield
,&size_local_extrafield
)!=UNZ_OK
)
985 return UNZ_BADZIPFILE
;
987 pfile_in_zip_read_info
= (file_in_zip_read_info_s
*)
988 ALLOC(sizeof(file_in_zip_read_info_s
));
989 if (pfile_in_zip_read_info
==NULL
)
990 return UNZ_INTERNALERROR
;
992 pfile_in_zip_read_info
->read_buffer
=(char*)ALLOC(UNZ_BUFSIZE
);
993 pfile_in_zip_read_info
->offset_local_extrafield
= offset_local_extrafield
;
994 pfile_in_zip_read_info
->size_local_extrafield
= size_local_extrafield
;
995 pfile_in_zip_read_info
->pos_local_extrafield
=0;
997 if (pfile_in_zip_read_info
->read_buffer
==NULL
)
999 TRYFREE(pfile_in_zip_read_info
);
1000 return UNZ_INTERNALERROR
;
1003 pfile_in_zip_read_info
->stream_initialised
=0;
1005 if ((s
->cur_file_info
.compression_method
!=0) &&
1006 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
1008 Store
= s
->cur_file_info
.compression_method
==0;
1010 pfile_in_zip_read_info
->crc32_wait
=s
->cur_file_info
.crc
;
1011 pfile_in_zip_read_info
->crc32
=0;
1012 pfile_in_zip_read_info
->compression_method
=
1013 s
->cur_file_info
.compression_method
;
1014 pfile_in_zip_read_info
->file
=s
->file
;
1015 pfile_in_zip_read_info
->byte_before_the_zipfile
=s
->byte_before_the_zipfile
;
1017 pfile_in_zip_read_info
->stream
.total_out
= 0;
1021 pfile_in_zip_read_info
->stream
.zalloc
= (alloc_func
)0;
1022 pfile_in_zip_read_info
->stream
.zfree
= (free_func
)0;
1023 pfile_in_zip_read_info
->stream
.opaque
= (voidpf
)0;
1025 err
=inflateInit2(&pfile_in_zip_read_info
->stream
, -MAX_WBITS
);
1027 pfile_in_zip_read_info
->stream_initialised
=1;
1028 /* windowBits is passed < 0 to tell that there is no zlib header.
1029 * Note that in this case inflate *requires* an extra "dummy" byte
1030 * after the compressed stream in order to complete decompression and
1031 * return Z_STREAM_END.
1032 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1033 * size of both compressed and uncompressed data
1036 pfile_in_zip_read_info
->rest_read_compressed
=
1037 s
->cur_file_info
.compressed_size
;
1038 pfile_in_zip_read_info
->rest_read_uncompressed
=
1039 s
->cur_file_info
.uncompressed_size
;
1042 pfile_in_zip_read_info
->pos_in_zipfile
=
1043 s
->cur_file_info_internal
.offset_curfile
+ SIZEZIPLOCALHEADER
+
1046 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)0;
1049 s
->pfile_in_zip_read
= pfile_in_zip_read_info
;
1055 Read bytes from the current file.
1056 buf contain buffer where data must be copied
1057 len the size of buf.
1059 return the number of byte copied if somes bytes are copied
1060 return 0 if the end of file was reached
1061 return <0 with error code if there is an error
1062 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1064 extern int ZEXPORT
unzReadCurrentFile (file
, buf
, len
)
1072 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1074 return UNZ_PARAMERROR
;
1076 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1078 if (pfile_in_zip_read_info
==NULL
)
1079 return UNZ_PARAMERROR
;
1082 if ((pfile_in_zip_read_info
->read_buffer
== NULL
))
1083 return UNZ_END_OF_LIST_OF_FILE
;
1087 pfile_in_zip_read_info
->stream
.next_out
= (Bytef
*)buf
;
1089 pfile_in_zip_read_info
->stream
.avail_out
= (uInt
)len
;
1091 if (len
>pfile_in_zip_read_info
->rest_read_uncompressed
)
1092 pfile_in_zip_read_info
->stream
.avail_out
=
1093 (uInt
)pfile_in_zip_read_info
->rest_read_uncompressed
;
1095 while (pfile_in_zip_read_info
->stream
.avail_out
>0)
1097 if ((pfile_in_zip_read_info
->stream
.avail_in
==0) &&
1098 (pfile_in_zip_read_info
->rest_read_compressed
>0))
1100 uInt uReadThis
= UNZ_BUFSIZE
;
1101 if (pfile_in_zip_read_info
->rest_read_compressed
<uReadThis
)
1102 uReadThis
= (uInt
)pfile_in_zip_read_info
->rest_read_compressed
;
1105 if (fseek(pfile_in_zip_read_info
->file
,
1106 pfile_in_zip_read_info
->pos_in_zipfile
+
1107 pfile_in_zip_read_info
->byte_before_the_zipfile
,SEEK_SET
)!=0)
1109 if (fread(pfile_in_zip_read_info
->read_buffer
,uReadThis
,1,
1110 pfile_in_zip_read_info
->file
)!=1)
1112 pfile_in_zip_read_info
->pos_in_zipfile
+= uReadThis
;
1114 pfile_in_zip_read_info
->rest_read_compressed
-=uReadThis
;
1116 pfile_in_zip_read_info
->stream
.next_in
=
1117 (Bytef
*)pfile_in_zip_read_info
->read_buffer
;
1118 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)uReadThis
;
1121 if (pfile_in_zip_read_info
->compression_method
==0)
1124 if (pfile_in_zip_read_info
->stream
.avail_out
<
1125 pfile_in_zip_read_info
->stream
.avail_in
)
1126 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_out
;
1128 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_in
;
1130 for (i
=0;i
<uDoCopy
;i
++)
1131 *(pfile_in_zip_read_info
->stream
.next_out
+i
) =
1132 *(pfile_in_zip_read_info
->stream
.next_in
+i
);
1134 pfile_in_zip_read_info
->crc32
= crc32(pfile_in_zip_read_info
->crc32
,
1135 pfile_in_zip_read_info
->stream
.next_out
,
1137 pfile_in_zip_read_info
->rest_read_uncompressed
-=uDoCopy
;
1138 pfile_in_zip_read_info
->stream
.avail_in
-= uDoCopy
;
1139 pfile_in_zip_read_info
->stream
.avail_out
-= uDoCopy
;
1140 pfile_in_zip_read_info
->stream
.next_out
+= uDoCopy
;
1141 pfile_in_zip_read_info
->stream
.next_in
+= uDoCopy
;
1142 pfile_in_zip_read_info
->stream
.total_out
+= uDoCopy
;
1147 uLong uTotalOutBefore
,uTotalOutAfter
;
1148 const Bytef
*bufBefore
;
1150 int flush
=Z_SYNC_FLUSH
;
1152 uTotalOutBefore
= pfile_in_zip_read_info
->stream
.total_out
;
1153 bufBefore
= pfile_in_zip_read_info
->stream
.next_out
;
1156 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1157 pfile_in_zip_read_info->stream.avail_out) &&
1158 (pfile_in_zip_read_info->rest_read_compressed == 0))
1161 err
=inflate(&pfile_in_zip_read_info
->stream
,flush
);
1163 uTotalOutAfter
= pfile_in_zip_read_info
->stream
.total_out
;
1164 uOutThis
= uTotalOutAfter
-uTotalOutBefore
;
1166 pfile_in_zip_read_info
->crc32
=
1167 crc32(pfile_in_zip_read_info
->crc32
,bufBefore
,
1170 pfile_in_zip_read_info
->rest_read_uncompressed
-=
1173 iRead
+= (uInt
)(uTotalOutAfter
- uTotalOutBefore
);
1175 if (err
==Z_STREAM_END
)
1176 return (iRead
==0) ? UNZ_EOF
: iRead
;
1189 Give the current position in uncompressed data
1191 extern z_off_t ZEXPORT
unztell (file
)
1195 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1197 return UNZ_PARAMERROR
;
1199 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1201 if (pfile_in_zip_read_info
==NULL
)
1202 return UNZ_PARAMERROR
;
1204 return (z_off_t
)pfile_in_zip_read_info
->stream
.total_out
;
1209 return 1 if the end of file was reached, 0 elsewhere
1211 extern int ZEXPORT
unzeof (file
)
1215 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1217 return UNZ_PARAMERROR
;
1219 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1221 if (pfile_in_zip_read_info
==NULL
)
1222 return UNZ_PARAMERROR
;
1224 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1233 Read extra field from the current file (opened by unzOpenCurrentFile)
1234 This is the local-header version of the extra field (sometimes, there is
1235 more info in the local-header version than in the central-header)
1237 if buf==NULL, it return the size of the local extra field that can be read
1239 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1241 the return value is the number of bytes copied in buf, or (if <0)
1244 extern int ZEXPORT
unzGetLocalExtrafield (file
,buf
,len
)
1250 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1255 return UNZ_PARAMERROR
;
1257 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1259 if (pfile_in_zip_read_info
==NULL
)
1260 return UNZ_PARAMERROR
;
1262 size_to_read
= (pfile_in_zip_read_info
->size_local_extrafield
-
1263 pfile_in_zip_read_info
->pos_local_extrafield
);
1266 return (int)size_to_read
;
1268 if (len
>size_to_read
)
1269 read_now
= (uInt
)size_to_read
;
1271 read_now
= (uInt
)len
;
1276 if (fseek(pfile_in_zip_read_info
->file
,
1277 pfile_in_zip_read_info
->offset_local_extrafield
+
1278 pfile_in_zip_read_info
->pos_local_extrafield
,SEEK_SET
)!=0)
1281 if (fread(buf
,(uInt
)size_to_read
,1,pfile_in_zip_read_info
->file
)!=1)
1284 return (int)read_now
;
1288 Close the file in zip opened with unzipOpenCurrentFile
1289 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1291 extern int ZEXPORT
unzCloseCurrentFile (file
)
1297 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1299 return UNZ_PARAMERROR
;
1301 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1303 if (pfile_in_zip_read_info
==NULL
)
1304 return UNZ_PARAMERROR
;
1307 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1309 if (pfile_in_zip_read_info
->crc32
!= pfile_in_zip_read_info
->crc32_wait
)
1314 TRYFREE(pfile_in_zip_read_info
->read_buffer
);
1315 pfile_in_zip_read_info
->read_buffer
= NULL
;
1316 if (pfile_in_zip_read_info
->stream_initialised
)
1317 inflateEnd(&pfile_in_zip_read_info
->stream
);
1319 pfile_in_zip_read_info
->stream_initialised
= 0;
1320 TRYFREE(pfile_in_zip_read_info
);
1322 s
->pfile_in_zip_read
=NULL
;
1329 Get the global comment string of the ZipFile, in the szComment buffer.
1330 uSizeBuf is the size of the szComment buffer.
1331 return the number of byte copied or an error code <0
1333 extern int ZEXPORT
unzGetGlobalComment (file
, szComment
, uSizeBuf
)
1342 return UNZ_PARAMERROR
;
1345 uReadThis
= uSizeBuf
;
1346 if (uReadThis
>s
->gi
.size_comment
)
1347 uReadThis
= s
->gi
.size_comment
;
1349 if (fseek(s
->file
,s
->central_pos
+22,SEEK_SET
)!=0)
1355 if (fread(szComment
,(uInt
)uReadThis
,1,s
->file
)!=1)
1359 if ((szComment
!= NULL
) && (uSizeBuf
> s
->gi
.size_comment
))
1360 *(szComment
+s
->gi
.size_comment
)='\0';
1361 return (int)uReadThis
;
1366 /* the file shouldn't be empty, som compilers don't like it */
1367 static const int dummyVariableInUnzip
= 17;
1369 #endif /* wxUSE_ZLIB && wxUSE_ZIPSTREAM */