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
15 #include "wx/platform.h"
17 #if wxUSE_ZLIB && wxUSE_ZIPSTREAM
24 normally, the compiler options should contain -I../zlib, but it is
25 apparently not the case for all MSW makefiles and so, unless we use
26 configure (which defines __WX_SETUP_H__) or it is explicitly overridden by
27 the user (who can define wxUSE_ZLIB_H_IN_PATH), we hardcode the path here
29 #if defined(__WXMSW__) && !defined(__WX_SETUP_H__) && !defined(wxUSE_ZLIB_H_IN_PATH)
30 #include "../zlib/zlib.h"
36 /* Not the right solution (paths in makefiles) but... */
38 #include "../common/unzip.h"
58 /* compile with -Dlocal if your debugger can't find static symbols */
62 #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
63 !defined(CASESENSITIVITYDEFAULT_NO)
64 #define CASESENSITIVITYDEFAULT_NO
69 #define UNZ_BUFSIZE (16384)
72 #ifndef UNZ_MAXFILENAMEINZIP
73 #define UNZ_MAXFILENAMEINZIP (256)
77 # define ALLOC(size) (malloc(size))
80 # define TRYFREE(p) {if (p) free(p);}
83 #define SIZECENTRALDIRITEM (0x2e)
84 #define SIZEZIPLOCALHEADER (0x1e)
87 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
101 const char unz_copyright
[] =
102 " unzip 0.15 Copyright 1998 Gilles Vollant ";
104 /* unz_file_info_interntal contain internal info about a file in zipfile*/
105 typedef struct unz_file_info_internal_s
107 uLong offset_curfile
;/* relative offset of local header 4 bytes */
108 } unz_file_info_internal
;
111 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
112 when reading and decompress it */
115 char *read_buffer
; /* internal buffer for compressed data */
116 z_stream stream
; /* zLib stream structure for inflate */
118 uLong pos_in_zipfile
; /* position in byte on the zipfile, for fseek*/
119 uLong stream_initialised
; /* flag set if stream structure is initialised*/
121 uLong offset_local_extrafield
;/* offset of the local extra field */
122 uInt size_local_extrafield
;/* size of the local extra field */
123 uLong pos_local_extrafield
; /* position in the local extra field in read*/
125 uLong crc32
; /* crc32 of all data uncompressed */
126 uLong crc32_wait
; /* crc32 we must obtain after decompress all */
127 uLong rest_read_compressed
; /* number of byte to be decompressed */
128 uLong rest_read_uncompressed
;/*number of byte to be obtained after decomp*/
129 FILE* file
; /* io structore of the zipfile */
130 uLong compression_method
; /* compression method (0==store) */
131 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
132 } file_in_zip_read_info_s
;
135 /* unz_s contain internal information about the zipfile
139 FILE* file
; /* io structore of the zipfile */
140 unz_global_info gi
; /* public global information */
141 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
142 uLong num_file
; /* number of the current file in the zipfile*/
143 uLong pos_in_central_dir
; /* pos of the current file in the central dir*/
144 uLong current_file_ok
; /* flag about the usability of the current file*/
145 uLong central_pos
; /* position of the beginning of the central dir*/
147 uLong size_central_dir
; /* size of the central directory */
148 uLong offset_central_dir
; /* offset of start of central directory with
149 respect to the starting disk number */
151 unz_file_info cur_file_info
; /* public info about the current file in zip*/
152 unz_file_info_internal cur_file_info_internal
; /* private info about it*/
153 file_in_zip_read_info_s
* pfile_in_zip_read
; /* structure about the current
154 file if we are decompressing it */
157 #if defined (__VISAGECPP__) || defined(__BORLANDC__)
158 /* VA always requires prototypes */
159 int unzlocal_CheckCurrentFileCoherencyHeader (unz_s
*, uInt
*, uLong
*, uInt
*);
162 /* disable warnings about K&R declarations until the end of file */
164 #pragma warning(disable:4131)
167 /* ===========================================================================
168 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
170 IN assertion: the stream s has been sucessfully opened for reading.
174 local
int unzlocal_getByte(fin
,pi
)
179 int err
= fread(&c
, 1, 1, fin
);
195 /* ===========================================================================
196 Reads a long in LSB order from the given gz_stream. Sets
198 local
int unzlocal_getShort (fin
,pX
)
206 err
= unzlocal_getByte(fin
,&i
);
210 err
= unzlocal_getByte(fin
,&i
);
220 local
int unzlocal_getLong (fin
,pX
)
228 err
= unzlocal_getByte(fin
,&i
);
232 err
= unzlocal_getByte(fin
,&i
);
236 err
= unzlocal_getByte(fin
,&i
);
240 err
= unzlocal_getByte(fin
,&i
);
251 /* My own strcmpi / strcasecmp */
252 local
int strcmpcasenosensitive_internal (fileName1
,fileName2
)
253 const char* fileName1
;
254 const char* fileName2
;
258 char c1
=*(fileName1
++);
259 char c2
=*(fileName2
++);
260 if ((c1
>='a') && (c1
<='z'))
262 if ((c2
>='a') && (c2
<='z'))
265 return ((c2
=='\0') ? 0 : -1);
276 #ifdef CASESENSITIVITYDEFAULT_NO
277 #define CASESENSITIVITYDEFAULTVALUE 2
279 #define CASESENSITIVITYDEFAULTVALUE 1
282 #ifndef STRCMPCASENOSENTIVEFUNCTION
283 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
287 Compare two filename (fileName1,fileName2).
288 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
289 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
291 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
292 (like 1 on Unix, 2 on Windows)
295 extern int ZEXPORT
unzStringFileNameCompare (fileName1
,fileName2
,iCaseSensitivity
)
296 const char* fileName1
;
297 const char* fileName2
;
298 int iCaseSensitivity
;
300 if (iCaseSensitivity
==0)
301 iCaseSensitivity
=CASESENSITIVITYDEFAULTVALUE
;
303 if (iCaseSensitivity
==1)
304 return strcmp(fileName1
,fileName2
);
306 return STRCMPCASENOSENTIVEFUNCTION(fileName1
,fileName2
);
309 #define BUFREADCOMMENT (0x400)
312 Locate the Central directory of a zipfile (at the end, just before
315 local uLong
unzlocal_SearchCentralDir(fin
)
321 uLong uMaxBack
=0xffff; /* maximum size of global comment */
324 if (fseek(fin
,0,SEEK_END
) != 0)
328 uSizeFile
= ftell( fin
);
330 if (uMaxBack
>uSizeFile
)
331 uMaxBack
= uSizeFile
;
333 buf
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4);
338 while (uBackRead
<uMaxBack
)
340 uLong uReadSize
,uReadPos
;
342 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
)
343 uBackRead
= uMaxBack
;
345 uBackRead
+=BUFREADCOMMENT
;
346 uReadPos
= uSizeFile
-uBackRead
;
348 uReadSize
= ((BUFREADCOMMENT
+4) < (uSizeFile
-uReadPos
)) ?
349 (BUFREADCOMMENT
+4) : (uSizeFile
-uReadPos
);
350 if (fseek(fin
,uReadPos
,SEEK_SET
)!=0)
353 if (fread(buf
,(uInt
)uReadSize
,1,fin
)!=1)
356 for (i
=(int)uReadSize
-3; (i
--)>0;)
357 if (((*(buf
+i
))==0x50) && ((*(buf
+i
+1))==0x4b) &&
358 ((*(buf
+i
+2))==0x05) && ((*(buf
+i
+3))==0x06))
360 uPosFound
= uReadPos
+i
;
371 #if defined(__WXMAC__) && !defined(__UNIX__)
372 void wxUnix2MacFilename (char *s
) ;
374 wxUnix2MacFilename (char *s
)
380 /* relative path , since it goes on with slash which is translated to a : */
381 memmove( s
, s
+1 ,strlen( s
) ) ;
383 else if ( *s
== '/' )
385 /* absolute path -> on mac just start with the drive name */
386 memmove( s
, s
+1 ,strlen( s
) ) ;
390 /* wxASSERT_MSG( 1 , "unkown path beginning" ) ; */
394 if (*s
== '/' || *s
== '\\')
396 /* convert any back-directory situations */
397 if ( *(s
+1) == '.' && *(s
+2) == '.' && ( (*(s
+3) == '/' || *(s
+3) == '\\') ) )
400 memmove( s
+1 , s
+3 ,strlen( s
+3 ) + 1 ) ;
410 extern char * wxBuffer
;
414 Open a Zip file. path contain the full pathname (by example,
415 on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
417 If the zipfile cannot be opened (file don't exist or in not valid), the
418 return value is NULL.
419 Else, the return value is a unzFile Handle, usable with other function
420 of this unzip package.
422 extern unzFile ZEXPORT
unzOpen (path
)
427 uLong central_pos
,uL
;
430 uLong number_disk
; /* number of the current dist, used for
431 spaning ZIP, unsupported, always 0*/
432 uLong number_disk_with_CD
; /* number the the disk with central dir, used
433 for spaning ZIP, unsupported, always 0*/
434 uLong number_entry_CD
; /* total number of entries in
436 (same than number_entry on nospan) */
440 if (unz_copyright
[0]!=' ')
443 #if defined(__WXMAC__) && !defined(__UNIX__)
444 strcpy( wxBuffer
, path
) ;
445 wxUnix2MacFilename( wxBuffer
) ;
446 fin
=fopen(wxBuffer
,"rb");
448 fin
=fopen(path
,"rb");
453 central_pos
= unzlocal_SearchCentralDir(fin
);
457 if (fseek(fin
,central_pos
,SEEK_SET
)!=0)
460 /* the signature, already checked */
461 if (unzlocal_getLong(fin
,&uL
)!=UNZ_OK
)
464 /* number of this disk */
465 if (unzlocal_getShort(fin
,&number_disk
)!=UNZ_OK
)
468 /* number of the disk with the start of the central directory */
469 if (unzlocal_getShort(fin
,&number_disk_with_CD
)!=UNZ_OK
)
472 /* total number of entries in the central dir on this disk */
473 if (unzlocal_getShort(fin
,&us
.gi
.number_entry
)!=UNZ_OK
)
476 /* total number of entries in the central dir */
477 if (unzlocal_getShort(fin
,&number_entry_CD
)!=UNZ_OK
)
480 if ((number_entry_CD
!=us
.gi
.number_entry
) ||
481 (number_disk_with_CD
!=0) ||
485 /* size of the central directory */
486 if (unzlocal_getLong(fin
,&us
.size_central_dir
)!=UNZ_OK
)
489 /* offset of start of central directory with respect to the
490 starting disk number */
491 if (unzlocal_getLong(fin
,&us
.offset_central_dir
)!=UNZ_OK
)
494 /* zipfile comment length */
495 if (unzlocal_getShort(fin
,&us
.gi
.size_comment
)!=UNZ_OK
)
498 if ((central_pos
<us
.offset_central_dir
+us
.size_central_dir
) &&
508 us
.byte_before_the_zipfile
= central_pos
-
509 (us
.offset_central_dir
+us
.size_central_dir
);
510 us
.central_pos
= central_pos
;
511 us
.pfile_in_zip_read
= NULL
;
514 s
=(unz_s
*)ALLOC(sizeof(unz_s
));
516 unzGoToFirstFile((unzFile
)s
);
522 Close a ZipFile opened with unzipOpen.
523 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
524 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
525 return UNZ_OK if there is no problem. */
526 extern int ZEXPORT
unzClose (file
)
531 return UNZ_PARAMERROR
;
534 if (s
->pfile_in_zip_read
!=NULL
)
535 unzCloseCurrentFile(file
);
544 Write info about the ZipFile in the *pglobal_info structure.
545 No preparation of the structure is needed
546 return UNZ_OK if there is no problem. */
547 extern int ZEXPORT
unzGetGlobalInfo (file
,pglobal_info
)
549 unz_global_info
*pglobal_info
;
553 return UNZ_PARAMERROR
;
561 Translate date/time from Dos format to tm_unz (readable more easilty)
563 local
void unzlocal_DosDateToTmuDate (ulDosDate
, ptm
)
568 uDate
= (uLong
)(ulDosDate
>>16);
569 ptm
->tm_mday
= (uInt
)(uDate
&0x1f) ;
570 ptm
->tm_mon
= (uInt
)((((uDate
)&0x1E0)/0x20)-1) ;
571 ptm
->tm_year
= (uInt
)(((uDate
&0x0FE00)/0x0200)+1980) ;
573 ptm
->tm_hour
= (uInt
) ((ulDosDate
&0xF800)/0x800);
574 ptm
->tm_min
= (uInt
) ((ulDosDate
&0x7E0)/0x20) ;
575 ptm
->tm_sec
= (uInt
) (2*(ulDosDate
&0x1f)) ;
579 Get Info about the current file in the zipfile, with internal only info
581 local
int unzlocal_GetCurrentFileInfoInternal
OF((unzFile file
,
582 unz_file_info
*pfile_info
,
583 unz_file_info_internal
584 *pfile_info_internal
,
586 uLong fileNameBufferSize
,
588 uLong extraFieldBufferSize
,
590 uLong commentBufferSize
));
592 local
int unzlocal_GetCurrentFileInfoInternal (file
,
595 szFileName
, fileNameBufferSize
,
596 extraField
, extraFieldBufferSize
,
597 szComment
, commentBufferSize
)
599 unz_file_info
*pfile_info
;
600 unz_file_info_internal
*pfile_info_internal
;
602 uLong fileNameBufferSize
;
604 uLong extraFieldBufferSize
;
606 uLong commentBufferSize
;
609 unz_file_info file_info
;
610 unz_file_info_internal file_info_internal
;
616 return UNZ_PARAMERROR
;
618 if (fseek(s
->file
,s
->pos_in_central_dir
+s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
622 /* we check the magic */
625 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
627 else if (uMagic
!=0x02014b50)
631 if (unzlocal_getShort(s
->file
,&file_info
.version
) != UNZ_OK
)
634 if (unzlocal_getShort(s
->file
,&file_info
.version_needed
) != UNZ_OK
)
637 if (unzlocal_getShort(s
->file
,&file_info
.flag
) != UNZ_OK
)
640 if (unzlocal_getShort(s
->file
,&file_info
.compression_method
) != UNZ_OK
)
643 if (unzlocal_getLong(s
->file
,&file_info
.dosDate
) != UNZ_OK
)
646 unzlocal_DosDateToTmuDate(file_info
.dosDate
,&file_info
.tmu_date
);
648 if (unzlocal_getLong(s
->file
,&file_info
.crc
) != UNZ_OK
)
651 if (unzlocal_getLong(s
->file
,&file_info
.compressed_size
) != UNZ_OK
)
654 if (unzlocal_getLong(s
->file
,&file_info
.uncompressed_size
) != UNZ_OK
)
657 if (unzlocal_getShort(s
->file
,&file_info
.size_filename
) != UNZ_OK
)
660 if (unzlocal_getShort(s
->file
,&file_info
.size_file_extra
) != UNZ_OK
)
663 if (unzlocal_getShort(s
->file
,&file_info
.size_file_comment
) != UNZ_OK
)
666 if (unzlocal_getShort(s
->file
,&file_info
.disk_num_start
) != UNZ_OK
)
669 if (unzlocal_getShort(s
->file
,&file_info
.internal_fa
) != UNZ_OK
)
672 if (unzlocal_getLong(s
->file
,&file_info
.external_fa
) != UNZ_OK
)
675 if (unzlocal_getLong(s
->file
,&file_info_internal
.offset_curfile
) != UNZ_OK
)
678 lSeek
+=file_info
.size_filename
;
679 if ((err
==UNZ_OK
) && (szFileName
!=NULL
))
682 if (file_info
.size_filename
<fileNameBufferSize
)
684 *(szFileName
+file_info
.size_filename
)='\0';
685 uSizeRead
= file_info
.size_filename
;
688 uSizeRead
= fileNameBufferSize
;
690 if ((file_info
.size_filename
>0) && (fileNameBufferSize
>0))
691 if (fread(szFileName
,(uInt
)uSizeRead
,1,s
->file
)!=1)
697 if ((err
==UNZ_OK
) && (extraField
!=NULL
))
700 if (file_info
.size_file_extra
<extraFieldBufferSize
)
701 uSizeRead
= file_info
.size_file_extra
;
703 uSizeRead
= extraFieldBufferSize
;
707 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
713 if ((file_info
.size_file_extra
>0) && (extraFieldBufferSize
>0))
714 if (fread(extraField
,(uInt
)uSizeRead
,1,s
->file
)!=1)
716 lSeek
+= file_info
.size_file_extra
- uSizeRead
;
719 lSeek
+=file_info
.size_file_extra
;
722 if ((err
==UNZ_OK
) && (szComment
!=NULL
))
725 if (file_info
.size_file_comment
<commentBufferSize
)
727 *(szComment
+file_info
.size_file_comment
)='\0';
728 uSizeRead
= file_info
.size_file_comment
;
731 uSizeRead
= commentBufferSize
;
735 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
741 if ((file_info
.size_file_comment
>0) && (commentBufferSize
>0))
742 if (fread(szComment
,(uInt
)uSizeRead
,1,s
->file
)!=1)
744 lSeek
+=file_info
.size_file_comment
- uSizeRead
;
747 lSeek
+=file_info
.size_file_comment
;
749 if ((err
==UNZ_OK
) && (pfile_info
!=NULL
))
750 *pfile_info
=file_info
;
752 if ((err
==UNZ_OK
) && (pfile_info_internal
!=NULL
))
753 *pfile_info_internal
=file_info_internal
;
761 Write info about the ZipFile in the *pglobal_info structure.
762 No preparation of the structure is needed
763 return UNZ_OK if there is no problem.
765 extern int ZEXPORT
unzGetCurrentFileInfo (file
,
767 szFileName
, fileNameBufferSize
,
768 extraField
, extraFieldBufferSize
,
769 szComment
, commentBufferSize
)
771 unz_file_info
*pfile_info
;
773 uLong fileNameBufferSize
;
775 uLong extraFieldBufferSize
;
777 uLong commentBufferSize
;
779 return unzlocal_GetCurrentFileInfoInternal(file
,pfile_info
,NULL
,
780 szFileName
,fileNameBufferSize
,
781 extraField
,extraFieldBufferSize
,
782 szComment
,commentBufferSize
);
786 Set the current file of the zipfile to the first file.
787 return UNZ_OK if there is no problem
789 extern int ZEXPORT
unzGoToFirstFile (file
)
795 return UNZ_PARAMERROR
;
797 s
->pos_in_central_dir
=s
->offset_central_dir
;
799 err
=unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
800 &s
->cur_file_info_internal
,
801 NULL
,0,NULL
,0,NULL
,0);
802 s
->current_file_ok
= (err
== UNZ_OK
);
808 Set the current file of the zipfile to the next file.
809 return UNZ_OK if there is no problem
810 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
812 extern int ZEXPORT
unzGoToNextFile (file
)
819 return UNZ_PARAMERROR
;
821 if (!s
->current_file_ok
)
822 return UNZ_END_OF_LIST_OF_FILE
;
823 if (s
->num_file
+1==s
->gi
.number_entry
)
824 return UNZ_END_OF_LIST_OF_FILE
;
826 s
->pos_in_central_dir
+= SIZECENTRALDIRITEM
+ s
->cur_file_info
.size_filename
+
827 s
->cur_file_info
.size_file_extra
+ s
->cur_file_info
.size_file_comment
;
829 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
830 &s
->cur_file_info_internal
,
831 NULL
,0,NULL
,0,NULL
,0);
832 s
->current_file_ok
= (err
== UNZ_OK
);
838 Try locate the file szFileName in the zipfile.
839 For the iCaseSensitivity signification, see unzipStringFileNameCompare
842 UNZ_OK if the file is found. It becomes the current file.
843 UNZ_END_OF_LIST_OF_FILE if the file is not found
845 extern int ZEXPORT
unzLocateFile (file
, szFileName
, iCaseSensitivity
)
847 const char *szFileName
;
848 int iCaseSensitivity
;
854 char szFileName2
[UNZ_MAXFILENAMEINZIP
+1];
857 uLong pos_in_central_dirSaved
;
859 for (c
= szFileName
, c2
= szFileName2
; *c
!= '\0'; c
++, c2
++)
860 if (*c
== '\\') *c2
= '/';
865 return UNZ_PARAMERROR
;
867 if (strlen(szFileName
)>=UNZ_MAXFILENAMEINZIP
)
868 return UNZ_PARAMERROR
;
871 if (!s
->current_file_ok
)
872 return UNZ_END_OF_LIST_OF_FILE
;
874 num_fileSaved
= s
->num_file
;
875 pos_in_central_dirSaved
= s
->pos_in_central_dir
;
877 err
= unzGoToFirstFile(file
);
879 while (err
== UNZ_OK
)
881 char szCurrentFileName
[UNZ_MAXFILENAMEINZIP
+1];
882 unzGetCurrentFileInfo(file
,NULL
,
883 szCurrentFileName
,sizeof(szCurrentFileName
)-1,
885 for (c2
= szCurrentFileName
; *c2
!= '\0'; c2
++) if (*c2
== '\\') *c2
= '/';
886 if (unzStringFileNameCompare(szCurrentFileName
,
887 szFileName2
,iCaseSensitivity
)==0)
889 err
= unzGoToNextFile(file
);
892 s
->num_file
= num_fileSaved
;
893 s
->pos_in_central_dir
= pos_in_central_dirSaved
;
899 Read the local header of the current zipfile
900 Check the coherency of the local header and info in the end of central
901 directory about this file
902 store in *piSizeVar the size of extra info in local header
903 (filename and size of extra field data)
905 local
int unzlocal_CheckCurrentFileCoherencyHeader (s
,piSizeVar
,
906 poffset_local_extrafield
,
907 psize_local_extrafield
)
910 uLong
*poffset_local_extrafield
;
911 uInt
*psize_local_extrafield
;
913 uLong uMagic
,uData
,uFlags
;
915 uLong size_extra_field
;
919 *poffset_local_extrafield
= 0;
920 *psize_local_extrafield
= 0;
922 if (fseek(s
->file
,s
->cur_file_info_internal
.offset_curfile
+
923 s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
929 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
931 else if (uMagic
!=0x04034b50)
935 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
938 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
941 if (unzlocal_getShort(s
->file
,&uFlags
) != UNZ_OK
)
944 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
946 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compression_method
))
949 if ((err
==UNZ_OK
) && (s
->cur_file_info
.compression_method
!=0) &&
950 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
953 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* date/time */
956 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* crc */
958 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.crc
) &&
962 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size compr */
964 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compressed_size
) &&
968 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size uncompr */
970 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.uncompressed_size
) &&
975 if (unzlocal_getShort(s
->file
,&size_filename
) != UNZ_OK
)
977 else if ((err
==UNZ_OK
) && (size_filename
!=s
->cur_file_info
.size_filename
))
980 *piSizeVar
+= (uInt
)size_filename
;
982 if (unzlocal_getShort(s
->file
,&size_extra_field
) != UNZ_OK
)
984 *poffset_local_extrafield
= s
->cur_file_info_internal
.offset_curfile
+
985 SIZEZIPLOCALHEADER
+ size_filename
;
986 *psize_local_extrafield
= (uInt
)size_extra_field
;
988 *piSizeVar
+= (uInt
)size_extra_field
;
994 Open for reading data the current file in the zipfile.
995 If there is no error and the file is opened, the return value is UNZ_OK.
997 extern int ZEXPORT
unzOpenCurrentFile (file
)
1004 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1005 uLong offset_local_extrafield
; /* offset of the local extra field */
1006 uInt size_local_extrafield
; /* size of the local extra field */
1009 return UNZ_PARAMERROR
;
1011 if (!s
->current_file_ok
)
1012 return UNZ_PARAMERROR
;
1014 if (s
->pfile_in_zip_read
!= NULL
)
1015 unzCloseCurrentFile(file
);
1017 if (unzlocal_CheckCurrentFileCoherencyHeader(s
,&iSizeVar
,
1018 &offset_local_extrafield
,&size_local_extrafield
)!=UNZ_OK
)
1019 return UNZ_BADZIPFILE
;
1021 pfile_in_zip_read_info
= (file_in_zip_read_info_s
*)
1022 ALLOC(sizeof(file_in_zip_read_info_s
));
1023 if (pfile_in_zip_read_info
==NULL
)
1024 return UNZ_INTERNALERROR
;
1026 pfile_in_zip_read_info
->read_buffer
=(char*)ALLOC(UNZ_BUFSIZE
);
1027 pfile_in_zip_read_info
->offset_local_extrafield
= offset_local_extrafield
;
1028 pfile_in_zip_read_info
->size_local_extrafield
= size_local_extrafield
;
1029 pfile_in_zip_read_info
->pos_local_extrafield
=0;
1031 if (pfile_in_zip_read_info
->read_buffer
==NULL
)
1033 TRYFREE(pfile_in_zip_read_info
);
1034 return UNZ_INTERNALERROR
;
1037 pfile_in_zip_read_info
->stream_initialised
=0;
1039 if ((s
->cur_file_info
.compression_method
!=0) &&
1040 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
1042 Store
= s
->cur_file_info
.compression_method
==0;
1044 pfile_in_zip_read_info
->crc32_wait
=s
->cur_file_info
.crc
;
1045 pfile_in_zip_read_info
->crc32
=0;
1046 pfile_in_zip_read_info
->compression_method
=
1047 s
->cur_file_info
.compression_method
;
1048 pfile_in_zip_read_info
->file
=s
->file
;
1049 pfile_in_zip_read_info
->byte_before_the_zipfile
=s
->byte_before_the_zipfile
;
1051 pfile_in_zip_read_info
->stream
.total_out
= 0;
1055 pfile_in_zip_read_info
->stream
.zalloc
= (alloc_func
)0;
1056 pfile_in_zip_read_info
->stream
.zfree
= (free_func
)0;
1057 pfile_in_zip_read_info
->stream
.opaque
= (voidpf
)0;
1059 err
=inflateInit2(&pfile_in_zip_read_info
->stream
, -MAX_WBITS
);
1061 pfile_in_zip_read_info
->stream_initialised
=1;
1062 /* windowBits is passed < 0 to tell that there is no zlib header.
1063 * Note that in this case inflate *requires* an extra "dummy" byte
1064 * after the compressed stream in order to complete decompression and
1065 * return Z_STREAM_END.
1066 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1067 * size of both compressed and uncompressed data
1070 pfile_in_zip_read_info
->rest_read_compressed
=
1071 s
->cur_file_info
.compressed_size
;
1072 pfile_in_zip_read_info
->rest_read_uncompressed
=
1073 s
->cur_file_info
.uncompressed_size
;
1076 pfile_in_zip_read_info
->pos_in_zipfile
=
1077 s
->cur_file_info_internal
.offset_curfile
+ SIZEZIPLOCALHEADER
+
1080 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)0;
1083 s
->pfile_in_zip_read
= pfile_in_zip_read_info
;
1089 Read bytes from the current file.
1090 buf contain buffer where data must be copied
1091 len the size of buf.
1093 return the number of byte copied if somes bytes are copied
1094 return 0 if the end of file was reached
1095 return <0 with error code if there is an error
1096 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1098 extern int ZEXPORT
unzReadCurrentFile (file
, buf
, len
)
1106 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1108 return UNZ_PARAMERROR
;
1110 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1112 if (pfile_in_zip_read_info
==NULL
)
1113 return UNZ_PARAMERROR
;
1116 if ((pfile_in_zip_read_info
->read_buffer
== NULL
))
1117 return UNZ_END_OF_LIST_OF_FILE
;
1121 pfile_in_zip_read_info
->stream
.next_out
= (Bytef
*)buf
;
1123 pfile_in_zip_read_info
->stream
.avail_out
= (uInt
)len
;
1125 if (len
>pfile_in_zip_read_info
->rest_read_uncompressed
)
1126 pfile_in_zip_read_info
->stream
.avail_out
=
1127 (uInt
)pfile_in_zip_read_info
->rest_read_uncompressed
;
1129 while (pfile_in_zip_read_info
->stream
.avail_out
>0)
1131 if ((pfile_in_zip_read_info
->stream
.avail_in
==0) &&
1132 (pfile_in_zip_read_info
->rest_read_compressed
>0))
1134 uInt uReadThis
= UNZ_BUFSIZE
;
1135 if (pfile_in_zip_read_info
->rest_read_compressed
<uReadThis
)
1136 uReadThis
= (uInt
)pfile_in_zip_read_info
->rest_read_compressed
;
1139 if (fseek(pfile_in_zip_read_info
->file
,
1140 pfile_in_zip_read_info
->pos_in_zipfile
+
1141 pfile_in_zip_read_info
->byte_before_the_zipfile
,SEEK_SET
)!=0)
1143 if (fread(pfile_in_zip_read_info
->read_buffer
,uReadThis
,1,
1144 pfile_in_zip_read_info
->file
)!=1)
1146 pfile_in_zip_read_info
->pos_in_zipfile
+= uReadThis
;
1148 pfile_in_zip_read_info
->rest_read_compressed
-=uReadThis
;
1150 pfile_in_zip_read_info
->stream
.next_in
=
1151 (Bytef
*)pfile_in_zip_read_info
->read_buffer
;
1152 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)uReadThis
;
1155 if (pfile_in_zip_read_info
->compression_method
==0)
1158 if (pfile_in_zip_read_info
->stream
.avail_out
<
1159 pfile_in_zip_read_info
->stream
.avail_in
)
1160 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_out
;
1162 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_in
;
1164 for (i
=0;i
<uDoCopy
;i
++)
1165 *(pfile_in_zip_read_info
->stream
.next_out
+i
) =
1166 *(pfile_in_zip_read_info
->stream
.next_in
+i
);
1168 pfile_in_zip_read_info
->crc32
= crc32(pfile_in_zip_read_info
->crc32
,
1169 pfile_in_zip_read_info
->stream
.next_out
,
1171 pfile_in_zip_read_info
->rest_read_uncompressed
-=uDoCopy
;
1172 pfile_in_zip_read_info
->stream
.avail_in
-= uDoCopy
;
1173 pfile_in_zip_read_info
->stream
.avail_out
-= uDoCopy
;
1174 pfile_in_zip_read_info
->stream
.next_out
+= uDoCopy
;
1175 pfile_in_zip_read_info
->stream
.next_in
+= uDoCopy
;
1176 pfile_in_zip_read_info
->stream
.total_out
+= uDoCopy
;
1181 uLong uTotalOutBefore
,uTotalOutAfter
;
1182 const Bytef
*bufBefore
;
1184 int flush
=Z_SYNC_FLUSH
;
1186 uTotalOutBefore
= pfile_in_zip_read_info
->stream
.total_out
;
1187 bufBefore
= pfile_in_zip_read_info
->stream
.next_out
;
1190 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1191 pfile_in_zip_read_info->stream.avail_out) &&
1192 (pfile_in_zip_read_info->rest_read_compressed == 0))
1195 err
=inflate(&pfile_in_zip_read_info
->stream
,flush
);
1197 uTotalOutAfter
= pfile_in_zip_read_info
->stream
.total_out
;
1198 uOutThis
= uTotalOutAfter
-uTotalOutBefore
;
1200 pfile_in_zip_read_info
->crc32
=
1201 crc32(pfile_in_zip_read_info
->crc32
,bufBefore
,
1204 pfile_in_zip_read_info
->rest_read_uncompressed
-=
1207 iRead
+= (uInt
)(uTotalOutAfter
- uTotalOutBefore
);
1209 if (err
==Z_STREAM_END
)
1210 return (iRead
==0) ? UNZ_EOF
: iRead
;
1223 Give the current position in uncompressed data
1225 extern z_off_t ZEXPORT
unztell (file
)
1229 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1231 return UNZ_PARAMERROR
;
1233 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1235 if (pfile_in_zip_read_info
==NULL
)
1236 return UNZ_PARAMERROR
;
1238 return (z_off_t
)pfile_in_zip_read_info
->stream
.total_out
;
1243 return 1 if the end of file was reached, 0 elsewhere
1245 extern int ZEXPORT
unzeof (file
)
1249 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1251 return UNZ_PARAMERROR
;
1253 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1255 if (pfile_in_zip_read_info
==NULL
)
1256 return UNZ_PARAMERROR
;
1258 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1267 Read extra field from the current file (opened by unzOpenCurrentFile)
1268 This is the local-header version of the extra field (sometimes, there is
1269 more info in the local-header version than in the central-header)
1271 if buf==NULL, it return the size of the local extra field that can be read
1273 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1275 the return value is the number of bytes copied in buf, or (if <0)
1278 extern int ZEXPORT
unzGetLocalExtrafield (file
,buf
,len
)
1284 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1289 return UNZ_PARAMERROR
;
1291 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1293 if (pfile_in_zip_read_info
==NULL
)
1294 return UNZ_PARAMERROR
;
1296 size_to_read
= (pfile_in_zip_read_info
->size_local_extrafield
-
1297 pfile_in_zip_read_info
->pos_local_extrafield
);
1300 return (int)size_to_read
;
1302 if (len
>size_to_read
)
1303 read_now
= (uInt
)size_to_read
;
1305 read_now
= (uInt
)len
;
1310 if (fseek(pfile_in_zip_read_info
->file
,
1311 pfile_in_zip_read_info
->offset_local_extrafield
+
1312 pfile_in_zip_read_info
->pos_local_extrafield
,SEEK_SET
)!=0)
1315 if (fread(buf
,(uInt
)size_to_read
,1,pfile_in_zip_read_info
->file
)!=1)
1318 return (int)read_now
;
1322 Close the file in zip opened with unzipOpenCurrentFile
1323 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1325 extern int ZEXPORT
unzCloseCurrentFile (file
)
1331 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1333 return UNZ_PARAMERROR
;
1335 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1337 if (pfile_in_zip_read_info
==NULL
)
1338 return UNZ_PARAMERROR
;
1341 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1343 if (pfile_in_zip_read_info
->crc32
!= pfile_in_zip_read_info
->crc32_wait
)
1348 TRYFREE(pfile_in_zip_read_info
->read_buffer
);
1349 pfile_in_zip_read_info
->read_buffer
= NULL
;
1350 if (pfile_in_zip_read_info
->stream_initialised
)
1351 inflateEnd(&pfile_in_zip_read_info
->stream
);
1353 pfile_in_zip_read_info
->stream_initialised
= 0;
1354 TRYFREE(pfile_in_zip_read_info
);
1356 s
->pfile_in_zip_read
=NULL
;
1363 Get the global comment string of the ZipFile, in the szComment buffer.
1364 uSizeBuf is the size of the szComment buffer.
1365 return the number of byte copied or an error code <0
1367 extern int ZEXPORT
unzGetGlobalComment (file
, szComment
, uSizeBuf
)
1375 return UNZ_PARAMERROR
;
1378 uReadThis
= uSizeBuf
;
1379 if (uReadThis
>s
->gi
.size_comment
)
1380 uReadThis
= s
->gi
.size_comment
;
1382 if (fseek(s
->file
,s
->central_pos
+22,SEEK_SET
)!=0)
1388 if (fread(szComment
,(uInt
)uReadThis
,1,s
->file
)!=1)
1392 if ((szComment
!= NULL
) && (uSizeBuf
> s
->gi
.size_comment
))
1393 *(szComment
+s
->gi
.size_comment
)='\0';
1394 return (int)uReadThis
;
1399 /* the file shouldn't be empty, som compilers don't like it */
1400 static const int dummyVariableInUnzip
= 17;
1402 #endif /* wxUSE_ZLIB && wxUSE_ZIPSTREAM */