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 /* ===========================================================================
153 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
155 IN assertion: the stream s has been sucessfully opened for reading.
159 local
int unzlocal_getByte(fin
,pi
)
164 int err
= fread(&c
, 1, 1, fin
);
180 /* ===========================================================================
181 Reads a long in LSB order from the given gz_stream. Sets
183 local
int unzlocal_getShort (fin
,pX
)
191 err
= unzlocal_getByte(fin
,&i
);
195 err
= unzlocal_getByte(fin
,&i
);
205 local
int unzlocal_getLong (fin
,pX
)
213 err
= unzlocal_getByte(fin
,&i
);
217 err
= unzlocal_getByte(fin
,&i
);
221 err
= unzlocal_getByte(fin
,&i
);
225 err
= unzlocal_getByte(fin
,&i
);
236 /* My own strcmpi / strcasecmp */
237 local
int strcmpcasenosensitive_internal (fileName1
,fileName2
)
238 const char* fileName1
;
239 const char* fileName2
;
243 char c1
=*(fileName1
++);
244 char c2
=*(fileName2
++);
245 if ((c1
>='a') && (c1
<='z'))
247 if ((c2
>='a') && (c2
<='z'))
250 return ((c2
=='\0') ? 0 : -1);
261 #ifdef CASESENSITIVITYDEFAULT_NO
262 #define CASESENSITIVITYDEFAULTVALUE 2
264 #define CASESENSITIVITYDEFAULTVALUE 1
267 #ifndef STRCMPCASENOSENTIVEFUNCTION
268 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
272 Compare two filename (fileName1,fileName2).
273 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
274 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
276 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
277 (like 1 on Unix, 2 on Windows)
280 extern int ZEXPORT
unzStringFileNameCompare (fileName1
,fileName2
,iCaseSensitivity
)
281 const char* fileName1
;
282 const char* fileName2
;
283 int iCaseSensitivity
;
285 if (iCaseSensitivity
==0)
286 iCaseSensitivity
=CASESENSITIVITYDEFAULTVALUE
;
288 if (iCaseSensitivity
==1)
289 return strcmp(fileName1
,fileName2
);
291 return STRCMPCASENOSENTIVEFUNCTION(fileName1
,fileName2
);
294 #define BUFREADCOMMENT (0x400)
297 Locate the Central directory of a zipfile (at the end, just before
300 local uLong
unzlocal_SearchCentralDir(fin
)
306 uLong uMaxBack
=0xffff; /* maximum size of global comment */
309 if (fseek(fin
,0,SEEK_END
) != 0)
313 uSizeFile
= ftell( fin
);
315 if (uMaxBack
>uSizeFile
)
316 uMaxBack
= uSizeFile
;
318 buf
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4);
323 while (uBackRead
<uMaxBack
)
325 uLong uReadSize
,uReadPos
;
327 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
)
328 uBackRead
= uMaxBack
;
330 uBackRead
+=BUFREADCOMMENT
;
331 uReadPos
= uSizeFile
-uBackRead
;
333 uReadSize
= ((BUFREADCOMMENT
+4) < (uSizeFile
-uReadPos
)) ?
334 (BUFREADCOMMENT
+4) : (uSizeFile
-uReadPos
);
335 if (fseek(fin
,uReadPos
,SEEK_SET
)!=0)
338 if (fread(buf
,(uInt
)uReadSize
,1,fin
)!=1)
341 for (i
=(int)uReadSize
-3; (i
--)>0;)
342 if (((*(buf
+i
))==0x50) && ((*(buf
+i
+1))==0x4b) &&
343 ((*(buf
+i
+2))==0x05) && ((*(buf
+i
+3))==0x06))
345 uPosFound
= uReadPos
+i
;
357 void wxUnix2MacFilename (char *s
) ;
359 wxUnix2MacFilename (char *s
)
365 /* relative path , since it goes on with slash which is translated to a : */
366 memmove( s
, s
+1 ,strlen( s
) ) ;
368 else if ( *s
== '/' )
370 /* absolute path -> on mac just start with the drive name */
371 memmove( s
, s
+1 ,strlen( s
) ) ;
375 /* wxASSERT_MSG( 1 , "unkown path beginning" ) ; */
379 if (*s
== '/' || *s
== '\\')
381 /* convert any back-directory situations */
382 if ( *(s
+1) == '.' && *(s
+2) == '.' && ( (*(s
+3) == '/' || *(s
+3) == '\\') ) )
385 memmove( s
+1 , s
+3 ,strlen( s
+3 ) + 1 ) ;
395 extern char * wxBuffer
;
399 Open a Zip file. path contain the full pathname (by example,
400 on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
402 If the zipfile cannot be opened (file don't exist or in not valid), the
403 return value is NULL.
404 Else, the return value is a unzFile Handle, usable with other function
405 of this unzip package.
407 extern unzFile ZEXPORT
unzOpen (path
)
412 uLong central_pos
,uL
;
415 uLong number_disk
; /* number of the current dist, used for
416 spaning ZIP, unsupported, always 0*/
417 uLong number_disk_with_CD
; /* number the the disk with central dir, used
418 for spaning ZIP, unsupported, always 0*/
419 uLong number_entry_CD
; /* total number of entries in
421 (same than number_entry on nospan) */
425 if (unz_copyright
[0]!=' ')
429 strcpy( wxBuffer
, path
) ;
430 wxUnix2MacFilename( wxBuffer
) ;
431 fin
=fopen(wxBuffer
,"rb");
433 fin
=fopen(path
,"rb");
438 central_pos
= unzlocal_SearchCentralDir(fin
);
442 if (fseek(fin
,central_pos
,SEEK_SET
)!=0)
445 /* the signature, already checked */
446 if (unzlocal_getLong(fin
,&uL
)!=UNZ_OK
)
449 /* number of this disk */
450 if (unzlocal_getShort(fin
,&number_disk
)!=UNZ_OK
)
453 /* number of the disk with the start of the central directory */
454 if (unzlocal_getShort(fin
,&number_disk_with_CD
)!=UNZ_OK
)
457 /* total number of entries in the central dir on this disk */
458 if (unzlocal_getShort(fin
,&us
.gi
.number_entry
)!=UNZ_OK
)
461 /* total number of entries in the central dir */
462 if (unzlocal_getShort(fin
,&number_entry_CD
)!=UNZ_OK
)
465 if ((number_entry_CD
!=us
.gi
.number_entry
) ||
466 (number_disk_with_CD
!=0) ||
470 /* size of the central directory */
471 if (unzlocal_getLong(fin
,&us
.size_central_dir
)!=UNZ_OK
)
474 /* offset of start of central directory with respect to the
475 starting disk number */
476 if (unzlocal_getLong(fin
,&us
.offset_central_dir
)!=UNZ_OK
)
479 /* zipfile comment length */
480 if (unzlocal_getShort(fin
,&us
.gi
.size_comment
)!=UNZ_OK
)
483 if ((central_pos
<us
.offset_central_dir
+us
.size_central_dir
) &&
493 us
.byte_before_the_zipfile
= central_pos
-
494 (us
.offset_central_dir
+us
.size_central_dir
);
495 us
.central_pos
= central_pos
;
496 us
.pfile_in_zip_read
= NULL
;
499 s
=(unz_s
*)ALLOC(sizeof(unz_s
));
501 unzGoToFirstFile((unzFile
)s
);
507 Close a ZipFile opened with unzipOpen.
508 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
509 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
510 return UNZ_OK if there is no problem. */
511 extern int ZEXPORT
unzClose (file
)
516 return UNZ_PARAMERROR
;
519 if (s
->pfile_in_zip_read
!=NULL
)
520 unzCloseCurrentFile(file
);
529 Write info about the ZipFile in the *pglobal_info structure.
530 No preparation of the structure is needed
531 return UNZ_OK if there is no problem. */
532 extern int ZEXPORT
unzGetGlobalInfo (file
,pglobal_info
)
534 unz_global_info
*pglobal_info
;
538 return UNZ_PARAMERROR
;
546 Translate date/time from Dos format to tm_unz (readable more easilty)
548 local
void unzlocal_DosDateToTmuDate (ulDosDate
, ptm
)
553 uDate
= (uLong
)(ulDosDate
>>16);
554 ptm
->tm_mday
= (uInt
)(uDate
&0x1f) ;
555 ptm
->tm_mon
= (uInt
)((((uDate
)&0x1E0)/0x20)-1) ;
556 ptm
->tm_year
= (uInt
)(((uDate
&0x0FE00)/0x0200)+1980) ;
558 ptm
->tm_hour
= (uInt
) ((ulDosDate
&0xF800)/0x800);
559 ptm
->tm_min
= (uInt
) ((ulDosDate
&0x7E0)/0x20) ;
560 ptm
->tm_sec
= (uInt
) (2*(ulDosDate
&0x1f)) ;
564 Get Info about the current file in the zipfile, with internal only info
566 local
int unzlocal_GetCurrentFileInfoInternal
OF((unzFile file
,
567 unz_file_info
*pfile_info
,
568 unz_file_info_internal
569 *pfile_info_internal
,
571 uLong fileNameBufferSize
,
573 uLong extraFieldBufferSize
,
575 uLong commentBufferSize
));
577 local
int unzlocal_GetCurrentFileInfoInternal (file
,
580 szFileName
, fileNameBufferSize
,
581 extraField
, extraFieldBufferSize
,
582 szComment
, commentBufferSize
)
584 unz_file_info
*pfile_info
;
585 unz_file_info_internal
*pfile_info_internal
;
587 uLong fileNameBufferSize
;
589 uLong extraFieldBufferSize
;
591 uLong commentBufferSize
;
594 unz_file_info file_info
;
595 unz_file_info_internal file_info_internal
;
601 return UNZ_PARAMERROR
;
603 if (fseek(s
->file
,s
->pos_in_central_dir
+s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
607 /* we check the magic */
610 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
612 else if (uMagic
!=0x02014b50)
616 if (unzlocal_getShort(s
->file
,&file_info
.version
) != UNZ_OK
)
619 if (unzlocal_getShort(s
->file
,&file_info
.version_needed
) != UNZ_OK
)
622 if (unzlocal_getShort(s
->file
,&file_info
.flag
) != UNZ_OK
)
625 if (unzlocal_getShort(s
->file
,&file_info
.compression_method
) != UNZ_OK
)
628 if (unzlocal_getLong(s
->file
,&file_info
.dosDate
) != UNZ_OK
)
631 unzlocal_DosDateToTmuDate(file_info
.dosDate
,&file_info
.tmu_date
);
633 if (unzlocal_getLong(s
->file
,&file_info
.crc
) != UNZ_OK
)
636 if (unzlocal_getLong(s
->file
,&file_info
.compressed_size
) != UNZ_OK
)
639 if (unzlocal_getLong(s
->file
,&file_info
.uncompressed_size
) != UNZ_OK
)
642 if (unzlocal_getShort(s
->file
,&file_info
.size_filename
) != UNZ_OK
)
645 if (unzlocal_getShort(s
->file
,&file_info
.size_file_extra
) != UNZ_OK
)
648 if (unzlocal_getShort(s
->file
,&file_info
.size_file_comment
) != UNZ_OK
)
651 if (unzlocal_getShort(s
->file
,&file_info
.disk_num_start
) != UNZ_OK
)
654 if (unzlocal_getShort(s
->file
,&file_info
.internal_fa
) != UNZ_OK
)
657 if (unzlocal_getLong(s
->file
,&file_info
.external_fa
) != UNZ_OK
)
660 if (unzlocal_getLong(s
->file
,&file_info_internal
.offset_curfile
) != UNZ_OK
)
663 lSeek
+=file_info
.size_filename
;
664 if ((err
==UNZ_OK
) && (szFileName
!=NULL
))
667 if (file_info
.size_filename
<fileNameBufferSize
)
669 *(szFileName
+file_info
.size_filename
)='\0';
670 uSizeRead
= file_info
.size_filename
;
673 uSizeRead
= fileNameBufferSize
;
675 if ((file_info
.size_filename
>0) && (fileNameBufferSize
>0))
676 if (fread(szFileName
,(uInt
)uSizeRead
,1,s
->file
)!=1)
682 if ((err
==UNZ_OK
) && (extraField
!=NULL
))
685 if (file_info
.size_file_extra
<extraFieldBufferSize
)
686 uSizeRead
= file_info
.size_file_extra
;
688 uSizeRead
= extraFieldBufferSize
;
692 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
698 if ((file_info
.size_file_extra
>0) && (extraFieldBufferSize
>0))
699 if (fread(extraField
,(uInt
)uSizeRead
,1,s
->file
)!=1)
701 lSeek
+= file_info
.size_file_extra
- uSizeRead
;
704 lSeek
+=file_info
.size_file_extra
;
707 if ((err
==UNZ_OK
) && (szComment
!=NULL
))
710 if (file_info
.size_file_comment
<commentBufferSize
)
712 *(szComment
+file_info
.size_file_comment
)='\0';
713 uSizeRead
= file_info
.size_file_comment
;
716 uSizeRead
= commentBufferSize
;
720 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
726 if ((file_info
.size_file_comment
>0) && (commentBufferSize
>0))
727 if (fread(szComment
,(uInt
)uSizeRead
,1,s
->file
)!=1)
729 lSeek
+=file_info
.size_file_comment
- uSizeRead
;
732 lSeek
+=file_info
.size_file_comment
;
734 if ((err
==UNZ_OK
) && (pfile_info
!=NULL
))
735 *pfile_info
=file_info
;
737 if ((err
==UNZ_OK
) && (pfile_info_internal
!=NULL
))
738 *pfile_info_internal
=file_info_internal
;
746 Write info about the ZipFile in the *pglobal_info structure.
747 No preparation of the structure is needed
748 return UNZ_OK if there is no problem.
750 extern int ZEXPORT
unzGetCurrentFileInfo (file
,
752 szFileName
, fileNameBufferSize
,
753 extraField
, extraFieldBufferSize
,
754 szComment
, commentBufferSize
)
756 unz_file_info
*pfile_info
;
758 uLong fileNameBufferSize
;
760 uLong extraFieldBufferSize
;
762 uLong commentBufferSize
;
764 return unzlocal_GetCurrentFileInfoInternal(file
,pfile_info
,NULL
,
765 szFileName
,fileNameBufferSize
,
766 extraField
,extraFieldBufferSize
,
767 szComment
,commentBufferSize
);
771 Set the current file of the zipfile to the first file.
772 return UNZ_OK if there is no problem
774 extern int ZEXPORT
unzGoToFirstFile (file
)
780 return UNZ_PARAMERROR
;
782 s
->pos_in_central_dir
=s
->offset_central_dir
;
784 err
=unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
785 &s
->cur_file_info_internal
,
786 NULL
,0,NULL
,0,NULL
,0);
787 s
->current_file_ok
= (err
== UNZ_OK
);
793 Set the current file of the zipfile to the next file.
794 return UNZ_OK if there is no problem
795 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
797 extern int ZEXPORT
unzGoToNextFile (file
)
804 return UNZ_PARAMERROR
;
806 if (!s
->current_file_ok
)
807 return UNZ_END_OF_LIST_OF_FILE
;
808 if (s
->num_file
+1==s
->gi
.number_entry
)
809 return UNZ_END_OF_LIST_OF_FILE
;
811 s
->pos_in_central_dir
+= SIZECENTRALDIRITEM
+ s
->cur_file_info
.size_filename
+
812 s
->cur_file_info
.size_file_extra
+ s
->cur_file_info
.size_file_comment
;
814 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
815 &s
->cur_file_info_internal
,
816 NULL
,0,NULL
,0,NULL
,0);
817 s
->current_file_ok
= (err
== UNZ_OK
);
823 Try locate the file szFileName in the zipfile.
824 For the iCaseSensitivity signification, see unzipStringFileNameCompare
827 UNZ_OK if the file is found. It becomes the current file.
828 UNZ_END_OF_LIST_OF_FILE if the file is not found
830 extern int ZEXPORT
unzLocateFile (file
, szFileName
, iCaseSensitivity
)
832 const char *szFileName
;
833 int iCaseSensitivity
;
839 char szFileName2
[UNZ_MAXFILENAMEINZIP
+1];
842 uLong pos_in_central_dirSaved
;
844 for (c
= szFileName
, c2
= szFileName2
; *c
!= '\0'; c
++, c2
++)
845 if (*c
== '\\') *c2
= '/';
850 return UNZ_PARAMERROR
;
852 if (strlen(szFileName
)>=UNZ_MAXFILENAMEINZIP
)
853 return UNZ_PARAMERROR
;
856 if (!s
->current_file_ok
)
857 return UNZ_END_OF_LIST_OF_FILE
;
859 num_fileSaved
= s
->num_file
;
860 pos_in_central_dirSaved
= s
->pos_in_central_dir
;
862 err
= unzGoToFirstFile(file
);
864 while (err
== UNZ_OK
)
866 char szCurrentFileName
[UNZ_MAXFILENAMEINZIP
+1];
867 unzGetCurrentFileInfo(file
,NULL
,
868 szCurrentFileName
,sizeof(szCurrentFileName
)-1,
870 for (c2
= szCurrentFileName
; *c2
!= '\0'; c2
++) if (*c2
== '\\') *c2
= '/';
871 if (unzStringFileNameCompare(szCurrentFileName
,
872 szFileName2
,iCaseSensitivity
)==0)
874 err
= unzGoToNextFile(file
);
877 s
->num_file
= num_fileSaved
;
878 s
->pos_in_central_dir
= pos_in_central_dirSaved
;
884 Read the local header of the current zipfile
885 Check the coherency of the local header and info in the end of central
886 directory about this file
887 store in *piSizeVar the size of extra info in local header
888 (filename and size of extra field data)
890 local
int unzlocal_CheckCurrentFileCoherencyHeader (s
,piSizeVar
,
891 poffset_local_extrafield
,
892 psize_local_extrafield
)
895 uLong
*poffset_local_extrafield
;
896 uInt
*psize_local_extrafield
;
898 uLong uMagic
,uData
,uFlags
;
900 uLong size_extra_field
;
904 *poffset_local_extrafield
= 0;
905 *psize_local_extrafield
= 0;
907 if (fseek(s
->file
,s
->cur_file_info_internal
.offset_curfile
+
908 s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
914 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
916 else if (uMagic
!=0x04034b50)
920 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
923 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
926 if (unzlocal_getShort(s
->file
,&uFlags
) != UNZ_OK
)
929 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
931 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compression_method
))
934 if ((err
==UNZ_OK
) && (s
->cur_file_info
.compression_method
!=0) &&
935 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
938 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* date/time */
941 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* crc */
943 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.crc
) &&
947 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size compr */
949 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compressed_size
) &&
953 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size uncompr */
955 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.uncompressed_size
) &&
960 if (unzlocal_getShort(s
->file
,&size_filename
) != UNZ_OK
)
962 else if ((err
==UNZ_OK
) && (size_filename
!=s
->cur_file_info
.size_filename
))
965 *piSizeVar
+= (uInt
)size_filename
;
967 if (unzlocal_getShort(s
->file
,&size_extra_field
) != UNZ_OK
)
969 *poffset_local_extrafield
= s
->cur_file_info_internal
.offset_curfile
+
970 SIZEZIPLOCALHEADER
+ size_filename
;
971 *psize_local_extrafield
= (uInt
)size_extra_field
;
973 *piSizeVar
+= (uInt
)size_extra_field
;
979 Open for reading data the current file in the zipfile.
980 If there is no error and the file is opened, the return value is UNZ_OK.
982 extern int ZEXPORT
unzOpenCurrentFile (file
)
989 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
990 uLong offset_local_extrafield
; /* offset of the local extra field */
991 uInt size_local_extrafield
; /* size of the local extra field */
994 return UNZ_PARAMERROR
;
996 if (!s
->current_file_ok
)
997 return UNZ_PARAMERROR
;
999 if (s
->pfile_in_zip_read
!= NULL
)
1000 unzCloseCurrentFile(file
);
1002 if (unzlocal_CheckCurrentFileCoherencyHeader(s
,&iSizeVar
,
1003 &offset_local_extrafield
,&size_local_extrafield
)!=UNZ_OK
)
1004 return UNZ_BADZIPFILE
;
1006 pfile_in_zip_read_info
= (file_in_zip_read_info_s
*)
1007 ALLOC(sizeof(file_in_zip_read_info_s
));
1008 if (pfile_in_zip_read_info
==NULL
)
1009 return UNZ_INTERNALERROR
;
1011 pfile_in_zip_read_info
->read_buffer
=(char*)ALLOC(UNZ_BUFSIZE
);
1012 pfile_in_zip_read_info
->offset_local_extrafield
= offset_local_extrafield
;
1013 pfile_in_zip_read_info
->size_local_extrafield
= size_local_extrafield
;
1014 pfile_in_zip_read_info
->pos_local_extrafield
=0;
1016 if (pfile_in_zip_read_info
->read_buffer
==NULL
)
1018 TRYFREE(pfile_in_zip_read_info
);
1019 return UNZ_INTERNALERROR
;
1022 pfile_in_zip_read_info
->stream_initialised
=0;
1024 if ((s
->cur_file_info
.compression_method
!=0) &&
1025 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
1027 Store
= s
->cur_file_info
.compression_method
==0;
1029 pfile_in_zip_read_info
->crc32_wait
=s
->cur_file_info
.crc
;
1030 pfile_in_zip_read_info
->crc32
=0;
1031 pfile_in_zip_read_info
->compression_method
=
1032 s
->cur_file_info
.compression_method
;
1033 pfile_in_zip_read_info
->file
=s
->file
;
1034 pfile_in_zip_read_info
->byte_before_the_zipfile
=s
->byte_before_the_zipfile
;
1036 pfile_in_zip_read_info
->stream
.total_out
= 0;
1040 pfile_in_zip_read_info
->stream
.zalloc
= (alloc_func
)0;
1041 pfile_in_zip_read_info
->stream
.zfree
= (free_func
)0;
1042 pfile_in_zip_read_info
->stream
.opaque
= (voidpf
)0;
1044 err
=inflateInit2(&pfile_in_zip_read_info
->stream
, -MAX_WBITS
);
1046 pfile_in_zip_read_info
->stream_initialised
=1;
1047 /* windowBits is passed < 0 to tell that there is no zlib header.
1048 * Note that in this case inflate *requires* an extra "dummy" byte
1049 * after the compressed stream in order to complete decompression and
1050 * return Z_STREAM_END.
1051 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1052 * size of both compressed and uncompressed data
1055 pfile_in_zip_read_info
->rest_read_compressed
=
1056 s
->cur_file_info
.compressed_size
;
1057 pfile_in_zip_read_info
->rest_read_uncompressed
=
1058 s
->cur_file_info
.uncompressed_size
;
1061 pfile_in_zip_read_info
->pos_in_zipfile
=
1062 s
->cur_file_info_internal
.offset_curfile
+ SIZEZIPLOCALHEADER
+
1065 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)0;
1068 s
->pfile_in_zip_read
= pfile_in_zip_read_info
;
1074 Read bytes from the current file.
1075 buf contain buffer where data must be copied
1076 len the size of buf.
1078 return the number of byte copied if somes bytes are copied
1079 return 0 if the end of file was reached
1080 return <0 with error code if there is an error
1081 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1083 extern int ZEXPORT
unzReadCurrentFile (file
, buf
, len
)
1091 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1093 return UNZ_PARAMERROR
;
1095 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1097 if (pfile_in_zip_read_info
==NULL
)
1098 return UNZ_PARAMERROR
;
1101 if ((pfile_in_zip_read_info
->read_buffer
== NULL
))
1102 return UNZ_END_OF_LIST_OF_FILE
;
1106 pfile_in_zip_read_info
->stream
.next_out
= (Bytef
*)buf
;
1108 pfile_in_zip_read_info
->stream
.avail_out
= (uInt
)len
;
1110 if (len
>pfile_in_zip_read_info
->rest_read_uncompressed
)
1111 pfile_in_zip_read_info
->stream
.avail_out
=
1112 (uInt
)pfile_in_zip_read_info
->rest_read_uncompressed
;
1114 while (pfile_in_zip_read_info
->stream
.avail_out
>0)
1116 if ((pfile_in_zip_read_info
->stream
.avail_in
==0) &&
1117 (pfile_in_zip_read_info
->rest_read_compressed
>0))
1119 uInt uReadThis
= UNZ_BUFSIZE
;
1120 if (pfile_in_zip_read_info
->rest_read_compressed
<uReadThis
)
1121 uReadThis
= (uInt
)pfile_in_zip_read_info
->rest_read_compressed
;
1124 if (fseek(pfile_in_zip_read_info
->file
,
1125 pfile_in_zip_read_info
->pos_in_zipfile
+
1126 pfile_in_zip_read_info
->byte_before_the_zipfile
,SEEK_SET
)!=0)
1128 if (fread(pfile_in_zip_read_info
->read_buffer
,uReadThis
,1,
1129 pfile_in_zip_read_info
->file
)!=1)
1131 pfile_in_zip_read_info
->pos_in_zipfile
+= uReadThis
;
1133 pfile_in_zip_read_info
->rest_read_compressed
-=uReadThis
;
1135 pfile_in_zip_read_info
->stream
.next_in
=
1136 (Bytef
*)pfile_in_zip_read_info
->read_buffer
;
1137 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)uReadThis
;
1140 if (pfile_in_zip_read_info
->compression_method
==0)
1143 if (pfile_in_zip_read_info
->stream
.avail_out
<
1144 pfile_in_zip_read_info
->stream
.avail_in
)
1145 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_out
;
1147 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_in
;
1149 for (i
=0;i
<uDoCopy
;i
++)
1150 *(pfile_in_zip_read_info
->stream
.next_out
+i
) =
1151 *(pfile_in_zip_read_info
->stream
.next_in
+i
);
1153 pfile_in_zip_read_info
->crc32
= crc32(pfile_in_zip_read_info
->crc32
,
1154 pfile_in_zip_read_info
->stream
.next_out
,
1156 pfile_in_zip_read_info
->rest_read_uncompressed
-=uDoCopy
;
1157 pfile_in_zip_read_info
->stream
.avail_in
-= uDoCopy
;
1158 pfile_in_zip_read_info
->stream
.avail_out
-= uDoCopy
;
1159 pfile_in_zip_read_info
->stream
.next_out
+= uDoCopy
;
1160 pfile_in_zip_read_info
->stream
.next_in
+= uDoCopy
;
1161 pfile_in_zip_read_info
->stream
.total_out
+= uDoCopy
;
1166 uLong uTotalOutBefore
,uTotalOutAfter
;
1167 const Bytef
*bufBefore
;
1169 int flush
=Z_SYNC_FLUSH
;
1171 uTotalOutBefore
= pfile_in_zip_read_info
->stream
.total_out
;
1172 bufBefore
= pfile_in_zip_read_info
->stream
.next_out
;
1175 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1176 pfile_in_zip_read_info->stream.avail_out) &&
1177 (pfile_in_zip_read_info->rest_read_compressed == 0))
1180 err
=inflate(&pfile_in_zip_read_info
->stream
,flush
);
1182 uTotalOutAfter
= pfile_in_zip_read_info
->stream
.total_out
;
1183 uOutThis
= uTotalOutAfter
-uTotalOutBefore
;
1185 pfile_in_zip_read_info
->crc32
=
1186 crc32(pfile_in_zip_read_info
->crc32
,bufBefore
,
1189 pfile_in_zip_read_info
->rest_read_uncompressed
-=
1192 iRead
+= (uInt
)(uTotalOutAfter
- uTotalOutBefore
);
1194 if (err
==Z_STREAM_END
)
1195 return (iRead
==0) ? UNZ_EOF
: iRead
;
1208 Give the current position in uncompressed data
1210 extern z_off_t ZEXPORT
unztell (file
)
1214 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1216 return UNZ_PARAMERROR
;
1218 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1220 if (pfile_in_zip_read_info
==NULL
)
1221 return UNZ_PARAMERROR
;
1223 return (z_off_t
)pfile_in_zip_read_info
->stream
.total_out
;
1228 return 1 if the end of file was reached, 0 elsewhere
1230 extern int ZEXPORT
unzeof (file
)
1234 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1236 return UNZ_PARAMERROR
;
1238 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1240 if (pfile_in_zip_read_info
==NULL
)
1241 return UNZ_PARAMERROR
;
1243 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1252 Read extra field from the current file (opened by unzOpenCurrentFile)
1253 This is the local-header version of the extra field (sometimes, there is
1254 more info in the local-header version than in the central-header)
1256 if buf==NULL, it return the size of the local extra field that can be read
1258 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1260 the return value is the number of bytes copied in buf, or (if <0)
1263 extern int ZEXPORT
unzGetLocalExtrafield (file
,buf
,len
)
1269 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1274 return UNZ_PARAMERROR
;
1276 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1278 if (pfile_in_zip_read_info
==NULL
)
1279 return UNZ_PARAMERROR
;
1281 size_to_read
= (pfile_in_zip_read_info
->size_local_extrafield
-
1282 pfile_in_zip_read_info
->pos_local_extrafield
);
1285 return (int)size_to_read
;
1287 if (len
>size_to_read
)
1288 read_now
= (uInt
)size_to_read
;
1290 read_now
= (uInt
)len
;
1295 if (fseek(pfile_in_zip_read_info
->file
,
1296 pfile_in_zip_read_info
->offset_local_extrafield
+
1297 pfile_in_zip_read_info
->pos_local_extrafield
,SEEK_SET
)!=0)
1300 if (fread(buf
,(uInt
)size_to_read
,1,pfile_in_zip_read_info
->file
)!=1)
1303 return (int)read_now
;
1307 Close the file in zip opened with unzipOpenCurrentFile
1308 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1310 extern int ZEXPORT
unzCloseCurrentFile (file
)
1316 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1318 return UNZ_PARAMERROR
;
1320 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1322 if (pfile_in_zip_read_info
==NULL
)
1323 return UNZ_PARAMERROR
;
1326 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1328 if (pfile_in_zip_read_info
->crc32
!= pfile_in_zip_read_info
->crc32_wait
)
1333 TRYFREE(pfile_in_zip_read_info
->read_buffer
);
1334 pfile_in_zip_read_info
->read_buffer
= NULL
;
1335 if (pfile_in_zip_read_info
->stream_initialised
)
1336 inflateEnd(&pfile_in_zip_read_info
->stream
);
1338 pfile_in_zip_read_info
->stream_initialised
= 0;
1339 TRYFREE(pfile_in_zip_read_info
);
1341 s
->pfile_in_zip_read
=NULL
;
1348 Get the global comment string of the ZipFile, in the szComment buffer.
1349 uSizeBuf is the size of the szComment buffer.
1350 return the number of byte copied or an error code <0
1352 extern int ZEXPORT
unzGetGlobalComment (file
, szComment
, uSizeBuf
)
1360 return UNZ_PARAMERROR
;
1363 uReadThis
= uSizeBuf
;
1364 if (uReadThis
>s
->gi
.size_comment
)
1365 uReadThis
= s
->gi
.size_comment
;
1367 if (fseek(s
->file
,s
->central_pos
+22,SEEK_SET
)!=0)
1373 if (fread(szComment
,(uInt
)uReadThis
,1,s
->file
)!=1)
1377 if ((szComment
!= NULL
) && (uSizeBuf
> s
->gi
.size_comment
))
1378 *(szComment
+s
->gi
.size_comment
)='\0';
1379 return (int)uReadThis
;
1384 /* the file shouldn't be empty, som compilers don't like it */
1385 static const int dummyVariableInUnzip
= 17;
1387 #endif /* wxUSE_ZLIB && wxUSE_ZIPSTREAM */