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 */
609 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
611 else if (uMagic
!=0x02014b50)
614 if (unzlocal_getShort(s
->file
,&file_info
.version
) != UNZ_OK
)
617 if (unzlocal_getShort(s
->file
,&file_info
.version_needed
) != UNZ_OK
)
620 if (unzlocal_getShort(s
->file
,&file_info
.flag
) != UNZ_OK
)
623 if (unzlocal_getShort(s
->file
,&file_info
.compression_method
) != UNZ_OK
)
626 if (unzlocal_getLong(s
->file
,&file_info
.dosDate
) != UNZ_OK
)
629 unzlocal_DosDateToTmuDate(file_info
.dosDate
,&file_info
.tmu_date
);
631 if (unzlocal_getLong(s
->file
,&file_info
.crc
) != UNZ_OK
)
634 if (unzlocal_getLong(s
->file
,&file_info
.compressed_size
) != UNZ_OK
)
637 if (unzlocal_getLong(s
->file
,&file_info
.uncompressed_size
) != UNZ_OK
)
640 if (unzlocal_getShort(s
->file
,&file_info
.size_filename
) != UNZ_OK
)
643 if (unzlocal_getShort(s
->file
,&file_info
.size_file_extra
) != UNZ_OK
)
646 if (unzlocal_getShort(s
->file
,&file_info
.size_file_comment
) != UNZ_OK
)
649 if (unzlocal_getShort(s
->file
,&file_info
.disk_num_start
) != UNZ_OK
)
652 if (unzlocal_getShort(s
->file
,&file_info
.internal_fa
) != UNZ_OK
)
655 if (unzlocal_getLong(s
->file
,&file_info
.external_fa
) != UNZ_OK
)
658 if (unzlocal_getLong(s
->file
,&file_info_internal
.offset_curfile
) != UNZ_OK
)
661 lSeek
+=file_info
.size_filename
;
662 if ((err
==UNZ_OK
) && (szFileName
!=NULL
))
665 if (file_info
.size_filename
<fileNameBufferSize
)
667 *(szFileName
+file_info
.size_filename
)='\0';
668 uSizeRead
= file_info
.size_filename
;
671 uSizeRead
= fileNameBufferSize
;
673 if ((file_info
.size_filename
>0) && (fileNameBufferSize
>0))
674 if (fread(szFileName
,(uInt
)uSizeRead
,1,s
->file
)!=1)
680 if ((err
==UNZ_OK
) && (extraField
!=NULL
))
683 if (file_info
.size_file_extra
<extraFieldBufferSize
)
684 uSizeRead
= file_info
.size_file_extra
;
686 uSizeRead
= extraFieldBufferSize
;
689 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
693 if ((file_info
.size_file_extra
>0) && (extraFieldBufferSize
>0))
694 if (fread(extraField
,(uInt
)uSizeRead
,1,s
->file
)!=1)
696 lSeek
+= file_info
.size_file_extra
- uSizeRead
;
699 lSeek
+=file_info
.size_file_extra
;
702 if ((err
==UNZ_OK
) && (szComment
!=NULL
))
705 if (file_info
.size_file_comment
<commentBufferSize
)
707 *(szComment
+file_info
.size_file_comment
)='\0';
708 uSizeRead
= file_info
.size_file_comment
;
711 uSizeRead
= commentBufferSize
;
714 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
718 if ((file_info
.size_file_comment
>0) && (commentBufferSize
>0))
719 if (fread(szComment
,(uInt
)uSizeRead
,1,s
->file
)!=1)
721 lSeek
+=file_info
.size_file_comment
- uSizeRead
;
724 lSeek
+=file_info
.size_file_comment
;
726 if ((err
==UNZ_OK
) && (pfile_info
!=NULL
))
727 *pfile_info
=file_info
;
729 if ((err
==UNZ_OK
) && (pfile_info_internal
!=NULL
))
730 *pfile_info_internal
=file_info_internal
;
738 Write info about the ZipFile in the *pglobal_info structure.
739 No preparation of the structure is needed
740 return UNZ_OK if there is no problem.
742 extern int ZEXPORT
unzGetCurrentFileInfo (file
,
744 szFileName
, fileNameBufferSize
,
745 extraField
, extraFieldBufferSize
,
746 szComment
, commentBufferSize
)
748 unz_file_info
*pfile_info
;
750 uLong fileNameBufferSize
;
752 uLong extraFieldBufferSize
;
754 uLong commentBufferSize
;
756 return unzlocal_GetCurrentFileInfoInternal(file
,pfile_info
,NULL
,
757 szFileName
,fileNameBufferSize
,
758 extraField
,extraFieldBufferSize
,
759 szComment
,commentBufferSize
);
763 Set the current file of the zipfile to the first file.
764 return UNZ_OK if there is no problem
766 extern int ZEXPORT
unzGoToFirstFile (file
)
772 return UNZ_PARAMERROR
;
774 s
->pos_in_central_dir
=s
->offset_central_dir
;
776 err
=unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
777 &s
->cur_file_info_internal
,
778 NULL
,0,NULL
,0,NULL
,0);
779 s
->current_file_ok
= (err
== UNZ_OK
);
785 Set the current file of the zipfile to the next file.
786 return UNZ_OK if there is no problem
787 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
789 extern int ZEXPORT
unzGoToNextFile (file
)
796 return UNZ_PARAMERROR
;
798 if (!s
->current_file_ok
)
799 return UNZ_END_OF_LIST_OF_FILE
;
800 if (s
->num_file
+1==s
->gi
.number_entry
)
801 return UNZ_END_OF_LIST_OF_FILE
;
803 s
->pos_in_central_dir
+= SIZECENTRALDIRITEM
+ s
->cur_file_info
.size_filename
+
804 s
->cur_file_info
.size_file_extra
+ s
->cur_file_info
.size_file_comment
;
806 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
807 &s
->cur_file_info_internal
,
808 NULL
,0,NULL
,0,NULL
,0);
809 s
->current_file_ok
= (err
== UNZ_OK
);
815 Try locate the file szFileName in the zipfile.
816 For the iCaseSensitivity signification, see unzipStringFileNameCompare
819 UNZ_OK if the file is found. It becomes the current file.
820 UNZ_END_OF_LIST_OF_FILE if the file is not found
822 extern int ZEXPORT
unzLocateFile (file
, szFileName
, iCaseSensitivity
)
824 const char *szFileName
;
825 int iCaseSensitivity
;
831 char szFileName2
[UNZ_MAXFILENAMEINZIP
+1];
834 uLong pos_in_central_dirSaved
;
836 for (c
= szFileName
, c2
= szFileName2
; *c
!= '\0'; c
++, c2
++)
837 if (*c
== '\\') *c2
= '/';
842 return UNZ_PARAMERROR
;
844 if (strlen(szFileName
)>=UNZ_MAXFILENAMEINZIP
)
845 return UNZ_PARAMERROR
;
848 if (!s
->current_file_ok
)
849 return UNZ_END_OF_LIST_OF_FILE
;
851 num_fileSaved
= s
->num_file
;
852 pos_in_central_dirSaved
= s
->pos_in_central_dir
;
854 err
= unzGoToFirstFile(file
);
856 while (err
== UNZ_OK
)
858 char szCurrentFileName
[UNZ_MAXFILENAMEINZIP
+1];
859 unzGetCurrentFileInfo(file
,NULL
,
860 szCurrentFileName
,sizeof(szCurrentFileName
)-1,
862 for (c2
= szCurrentFileName
; *c2
!= '\0'; c2
++) if (*c2
== '\\') *c2
= '/';
863 if (unzStringFileNameCompare(szCurrentFileName
,
864 szFileName2
,iCaseSensitivity
)==0)
866 err
= unzGoToNextFile(file
);
869 s
->num_file
= num_fileSaved
;
870 s
->pos_in_central_dir
= pos_in_central_dirSaved
;
876 Read the local header of the current zipfile
877 Check the coherency of the local header and info in the end of central
878 directory about this file
879 store in *piSizeVar the size of extra info in local header
880 (filename and size of extra field data)
882 local
int unzlocal_CheckCurrentFileCoherencyHeader (s
,piSizeVar
,
883 poffset_local_extrafield
,
884 psize_local_extrafield
)
887 uLong
*poffset_local_extrafield
;
888 uInt
*psize_local_extrafield
;
890 uLong uMagic
,uData
,uFlags
;
892 uLong size_extra_field
;
896 *poffset_local_extrafield
= 0;
897 *psize_local_extrafield
= 0;
899 if (fseek(s
->file
,s
->cur_file_info_internal
.offset_curfile
+
900 s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
905 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
907 else if (uMagic
!=0x04034b50)
910 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
913 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
916 if (unzlocal_getShort(s
->file
,&uFlags
) != UNZ_OK
)
919 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
921 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compression_method
))
924 if ((err
==UNZ_OK
) && (s
->cur_file_info
.compression_method
!=0) &&
925 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
928 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* date/time */
931 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* crc */
933 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.crc
) &&
937 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size compr */
939 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compressed_size
) &&
943 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size uncompr */
945 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.uncompressed_size
) &&
950 if (unzlocal_getShort(s
->file
,&size_filename
) != UNZ_OK
)
952 else if ((err
==UNZ_OK
) && (size_filename
!=s
->cur_file_info
.size_filename
))
955 *piSizeVar
+= (uInt
)size_filename
;
957 if (unzlocal_getShort(s
->file
,&size_extra_field
) != UNZ_OK
)
959 *poffset_local_extrafield
= s
->cur_file_info_internal
.offset_curfile
+
960 SIZEZIPLOCALHEADER
+ size_filename
;
961 *psize_local_extrafield
= (uInt
)size_extra_field
;
963 *piSizeVar
+= (uInt
)size_extra_field
;
969 Open for reading data the current file in the zipfile.
970 If there is no error and the file is opened, the return value is UNZ_OK.
972 extern int ZEXPORT
unzOpenCurrentFile (file
)
979 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
980 uLong offset_local_extrafield
; /* offset of the local extra field */
981 uInt size_local_extrafield
; /* size of the local extra field */
984 return UNZ_PARAMERROR
;
986 if (!s
->current_file_ok
)
987 return UNZ_PARAMERROR
;
989 if (s
->pfile_in_zip_read
!= NULL
)
990 unzCloseCurrentFile(file
);
992 if (unzlocal_CheckCurrentFileCoherencyHeader(s
,&iSizeVar
,
993 &offset_local_extrafield
,&size_local_extrafield
)!=UNZ_OK
)
994 return UNZ_BADZIPFILE
;
996 pfile_in_zip_read_info
= (file_in_zip_read_info_s
*)
997 ALLOC(sizeof(file_in_zip_read_info_s
));
998 if (pfile_in_zip_read_info
==NULL
)
999 return UNZ_INTERNALERROR
;
1001 pfile_in_zip_read_info
->read_buffer
=(char*)ALLOC(UNZ_BUFSIZE
);
1002 pfile_in_zip_read_info
->offset_local_extrafield
= offset_local_extrafield
;
1003 pfile_in_zip_read_info
->size_local_extrafield
= size_local_extrafield
;
1004 pfile_in_zip_read_info
->pos_local_extrafield
=0;
1006 if (pfile_in_zip_read_info
->read_buffer
==NULL
)
1008 TRYFREE(pfile_in_zip_read_info
);
1009 return UNZ_INTERNALERROR
;
1012 pfile_in_zip_read_info
->stream_initialised
=0;
1014 if ((s
->cur_file_info
.compression_method
!=0) &&
1015 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
1017 Store
= s
->cur_file_info
.compression_method
==0;
1019 pfile_in_zip_read_info
->crc32_wait
=s
->cur_file_info
.crc
;
1020 pfile_in_zip_read_info
->crc32
=0;
1021 pfile_in_zip_read_info
->compression_method
=
1022 s
->cur_file_info
.compression_method
;
1023 pfile_in_zip_read_info
->file
=s
->file
;
1024 pfile_in_zip_read_info
->byte_before_the_zipfile
=s
->byte_before_the_zipfile
;
1026 pfile_in_zip_read_info
->stream
.total_out
= 0;
1030 pfile_in_zip_read_info
->stream
.zalloc
= (alloc_func
)0;
1031 pfile_in_zip_read_info
->stream
.zfree
= (free_func
)0;
1032 pfile_in_zip_read_info
->stream
.opaque
= (voidpf
)0;
1034 err
=inflateInit2(&pfile_in_zip_read_info
->stream
, -MAX_WBITS
);
1036 pfile_in_zip_read_info
->stream_initialised
=1;
1037 /* windowBits is passed < 0 to tell that there is no zlib header.
1038 * Note that in this case inflate *requires* an extra "dummy" byte
1039 * after the compressed stream in order to complete decompression and
1040 * return Z_STREAM_END.
1041 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1042 * size of both compressed and uncompressed data
1045 pfile_in_zip_read_info
->rest_read_compressed
=
1046 s
->cur_file_info
.compressed_size
;
1047 pfile_in_zip_read_info
->rest_read_uncompressed
=
1048 s
->cur_file_info
.uncompressed_size
;
1051 pfile_in_zip_read_info
->pos_in_zipfile
=
1052 s
->cur_file_info_internal
.offset_curfile
+ SIZEZIPLOCALHEADER
+
1055 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)0;
1058 s
->pfile_in_zip_read
= pfile_in_zip_read_info
;
1064 Read bytes from the current file.
1065 buf contain buffer where data must be copied
1066 len the size of buf.
1068 return the number of byte copied if somes bytes are copied
1069 return 0 if the end of file was reached
1070 return <0 with error code if there is an error
1071 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1073 extern int ZEXPORT
unzReadCurrentFile (file
, buf
, len
)
1081 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1083 return UNZ_PARAMERROR
;
1085 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1087 if (pfile_in_zip_read_info
==NULL
)
1088 return UNZ_PARAMERROR
;
1091 if ((pfile_in_zip_read_info
->read_buffer
== NULL
))
1092 return UNZ_END_OF_LIST_OF_FILE
;
1096 pfile_in_zip_read_info
->stream
.next_out
= (Bytef
*)buf
;
1098 pfile_in_zip_read_info
->stream
.avail_out
= (uInt
)len
;
1100 if (len
>pfile_in_zip_read_info
->rest_read_uncompressed
)
1101 pfile_in_zip_read_info
->stream
.avail_out
=
1102 (uInt
)pfile_in_zip_read_info
->rest_read_uncompressed
;
1104 while (pfile_in_zip_read_info
->stream
.avail_out
>0)
1106 if ((pfile_in_zip_read_info
->stream
.avail_in
==0) &&
1107 (pfile_in_zip_read_info
->rest_read_compressed
>0))
1109 uInt uReadThis
= UNZ_BUFSIZE
;
1110 if (pfile_in_zip_read_info
->rest_read_compressed
<uReadThis
)
1111 uReadThis
= (uInt
)pfile_in_zip_read_info
->rest_read_compressed
;
1114 if (fseek(pfile_in_zip_read_info
->file
,
1115 pfile_in_zip_read_info
->pos_in_zipfile
+
1116 pfile_in_zip_read_info
->byte_before_the_zipfile
,SEEK_SET
)!=0)
1118 if (fread(pfile_in_zip_read_info
->read_buffer
,uReadThis
,1,
1119 pfile_in_zip_read_info
->file
)!=1)
1121 pfile_in_zip_read_info
->pos_in_zipfile
+= uReadThis
;
1123 pfile_in_zip_read_info
->rest_read_compressed
-=uReadThis
;
1125 pfile_in_zip_read_info
->stream
.next_in
=
1126 (Bytef
*)pfile_in_zip_read_info
->read_buffer
;
1127 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)uReadThis
;
1130 if (pfile_in_zip_read_info
->compression_method
==0)
1133 if (pfile_in_zip_read_info
->stream
.avail_out
<
1134 pfile_in_zip_read_info
->stream
.avail_in
)
1135 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_out
;
1137 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_in
;
1139 for (i
=0;i
<uDoCopy
;i
++)
1140 *(pfile_in_zip_read_info
->stream
.next_out
+i
) =
1141 *(pfile_in_zip_read_info
->stream
.next_in
+i
);
1143 pfile_in_zip_read_info
->crc32
= crc32(pfile_in_zip_read_info
->crc32
,
1144 pfile_in_zip_read_info
->stream
.next_out
,
1146 pfile_in_zip_read_info
->rest_read_uncompressed
-=uDoCopy
;
1147 pfile_in_zip_read_info
->stream
.avail_in
-= uDoCopy
;
1148 pfile_in_zip_read_info
->stream
.avail_out
-= uDoCopy
;
1149 pfile_in_zip_read_info
->stream
.next_out
+= uDoCopy
;
1150 pfile_in_zip_read_info
->stream
.next_in
+= uDoCopy
;
1151 pfile_in_zip_read_info
->stream
.total_out
+= uDoCopy
;
1156 uLong uTotalOutBefore
,uTotalOutAfter
;
1157 const Bytef
*bufBefore
;
1159 int flush
=Z_SYNC_FLUSH
;
1161 uTotalOutBefore
= pfile_in_zip_read_info
->stream
.total_out
;
1162 bufBefore
= pfile_in_zip_read_info
->stream
.next_out
;
1165 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1166 pfile_in_zip_read_info->stream.avail_out) &&
1167 (pfile_in_zip_read_info->rest_read_compressed == 0))
1170 err
=inflate(&pfile_in_zip_read_info
->stream
,flush
);
1172 uTotalOutAfter
= pfile_in_zip_read_info
->stream
.total_out
;
1173 uOutThis
= uTotalOutAfter
-uTotalOutBefore
;
1175 pfile_in_zip_read_info
->crc32
=
1176 crc32(pfile_in_zip_read_info
->crc32
,bufBefore
,
1179 pfile_in_zip_read_info
->rest_read_uncompressed
-=
1182 iRead
+= (uInt
)(uTotalOutAfter
- uTotalOutBefore
);
1184 if (err
==Z_STREAM_END
)
1185 return (iRead
==0) ? UNZ_EOF
: iRead
;
1198 Give the current position in uncompressed data
1200 extern z_off_t ZEXPORT
unztell (file
)
1204 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1206 return UNZ_PARAMERROR
;
1208 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1210 if (pfile_in_zip_read_info
==NULL
)
1211 return UNZ_PARAMERROR
;
1213 return (z_off_t
)pfile_in_zip_read_info
->stream
.total_out
;
1218 return 1 if the end of file was reached, 0 elsewhere
1220 extern int ZEXPORT
unzeof (file
)
1224 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1226 return UNZ_PARAMERROR
;
1228 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1230 if (pfile_in_zip_read_info
==NULL
)
1231 return UNZ_PARAMERROR
;
1233 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1242 Read extra field from the current file (opened by unzOpenCurrentFile)
1243 This is the local-header version of the extra field (sometimes, there is
1244 more info in the local-header version than in the central-header)
1246 if buf==NULL, it return the size of the local extra field that can be read
1248 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1250 the return value is the number of bytes copied in buf, or (if <0)
1253 extern int ZEXPORT
unzGetLocalExtrafield (file
,buf
,len
)
1259 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1264 return UNZ_PARAMERROR
;
1266 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1268 if (pfile_in_zip_read_info
==NULL
)
1269 return UNZ_PARAMERROR
;
1271 size_to_read
= (pfile_in_zip_read_info
->size_local_extrafield
-
1272 pfile_in_zip_read_info
->pos_local_extrafield
);
1275 return (int)size_to_read
;
1277 if (len
>size_to_read
)
1278 read_now
= (uInt
)size_to_read
;
1280 read_now
= (uInt
)len
;
1285 if (fseek(pfile_in_zip_read_info
->file
,
1286 pfile_in_zip_read_info
->offset_local_extrafield
+
1287 pfile_in_zip_read_info
->pos_local_extrafield
,SEEK_SET
)!=0)
1290 if (fread(buf
,(uInt
)size_to_read
,1,pfile_in_zip_read_info
->file
)!=1)
1293 return (int)read_now
;
1297 Close the file in zip opened with unzipOpenCurrentFile
1298 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1300 extern int ZEXPORT
unzCloseCurrentFile (file
)
1306 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1308 return UNZ_PARAMERROR
;
1310 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1312 if (pfile_in_zip_read_info
==NULL
)
1313 return UNZ_PARAMERROR
;
1316 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1318 if (pfile_in_zip_read_info
->crc32
!= pfile_in_zip_read_info
->crc32_wait
)
1323 TRYFREE(pfile_in_zip_read_info
->read_buffer
);
1324 pfile_in_zip_read_info
->read_buffer
= NULL
;
1325 if (pfile_in_zip_read_info
->stream_initialised
)
1326 inflateEnd(&pfile_in_zip_read_info
->stream
);
1328 pfile_in_zip_read_info
->stream_initialised
= 0;
1329 TRYFREE(pfile_in_zip_read_info
);
1331 s
->pfile_in_zip_read
=NULL
;
1338 Get the global comment string of the ZipFile, in the szComment buffer.
1339 uSizeBuf is the size of the szComment buffer.
1340 return the number of byte copied or an error code <0
1342 extern int ZEXPORT
unzGetGlobalComment (file
, szComment
, uSizeBuf
)
1351 return UNZ_PARAMERROR
;
1354 uReadThis
= uSizeBuf
;
1355 if (uReadThis
>s
->gi
.size_comment
)
1356 uReadThis
= s
->gi
.size_comment
;
1358 if (fseek(s
->file
,s
->central_pos
+22,SEEK_SET
)!=0)
1364 if (fread(szComment
,(uInt
)uReadThis
,1,s
->file
)!=1)
1368 if ((szComment
!= NULL
) && (uSizeBuf
> s
->gi
.size_comment
))
1369 *(szComment
+s
->gi
.size_comment
)='\0';
1370 return (int)uReadThis
;
1375 /* the file shouldn't be empty, som compilers don't like it */
1376 static const int dummyVariableInUnzip
= 17;
1378 #endif /* wxUSE_ZLIB && wxUSE_ZIPSTREAM */