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 Open a Zip file. path contain the full pathname (by example,
356 on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
358 If the zipfile cannot be opened (file don't exist or in not valid), the
359 return value is NULL.
360 Else, the return value is a unzFile Handle, usable with other function
361 of this unzip package.
363 extern unzFile ZEXPORT
unzOpen (path
)
368 uLong central_pos
,uL
;
371 uLong number_disk
; /* number of the current dist, used for
372 spaning ZIP, unsupported, always 0*/
373 uLong number_disk_with_CD
; /* number the the disk with central dir, used
374 for spaning ZIP, unsupported, always 0*/
375 uLong number_entry_CD
; /* total number of entries in
377 (same than number_entry on nospan) */
381 if (unz_copyright
[0]!=' ')
384 fin
=fopen(path
,"rb");
388 central_pos
= unzlocal_SearchCentralDir(fin
);
392 if (fseek(fin
,central_pos
,SEEK_SET
)!=0)
395 /* the signature, already checked */
396 if (unzlocal_getLong(fin
,&uL
)!=UNZ_OK
)
399 /* number of this disk */
400 if (unzlocal_getShort(fin
,&number_disk
)!=UNZ_OK
)
403 /* number of the disk with the start of the central directory */
404 if (unzlocal_getShort(fin
,&number_disk_with_CD
)!=UNZ_OK
)
407 /* total number of entries in the central dir on this disk */
408 if (unzlocal_getShort(fin
,&us
.gi
.number_entry
)!=UNZ_OK
)
411 /* total number of entries in the central dir */
412 if (unzlocal_getShort(fin
,&number_entry_CD
)!=UNZ_OK
)
415 if ((number_entry_CD
!=us
.gi
.number_entry
) ||
416 (number_disk_with_CD
!=0) ||
420 /* size of the central directory */
421 if (unzlocal_getLong(fin
,&us
.size_central_dir
)!=UNZ_OK
)
424 /* offset of start of central directory with respect to the
425 starting disk number */
426 if (unzlocal_getLong(fin
,&us
.offset_central_dir
)!=UNZ_OK
)
429 /* zipfile comment length */
430 if (unzlocal_getShort(fin
,&us
.gi
.size_comment
)!=UNZ_OK
)
433 if ((central_pos
<us
.offset_central_dir
+us
.size_central_dir
) &&
443 us
.byte_before_the_zipfile
= central_pos
-
444 (us
.offset_central_dir
+us
.size_central_dir
);
445 us
.central_pos
= central_pos
;
446 us
.pfile_in_zip_read
= NULL
;
449 s
=(unz_s
*)ALLOC(sizeof(unz_s
));
451 unzGoToFirstFile((unzFile
)s
);
457 Close a ZipFile opened with unzipOpen.
458 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
459 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
460 return UNZ_OK if there is no problem. */
461 extern int ZEXPORT
unzClose (file
)
466 return UNZ_PARAMERROR
;
469 if (s
->pfile_in_zip_read
!=NULL
)
470 unzCloseCurrentFile(file
);
479 Write info about the ZipFile in the *pglobal_info structure.
480 No preparation of the structure is needed
481 return UNZ_OK if there is no problem. */
482 extern int ZEXPORT
unzGetGlobalInfo (file
,pglobal_info
)
484 unz_global_info
*pglobal_info
;
488 return UNZ_PARAMERROR
;
496 Translate date/time from Dos format to tm_unz (readable more easilty)
498 local
void unzlocal_DosDateToTmuDate (ulDosDate
, ptm
)
503 uDate
= (uLong
)(ulDosDate
>>16);
504 ptm
->tm_mday
= (uInt
)(uDate
&0x1f) ;
505 ptm
->tm_mon
= (uInt
)((((uDate
)&0x1E0)/0x20)-1) ;
506 ptm
->tm_year
= (uInt
)(((uDate
&0x0FE00)/0x0200)+1980) ;
508 ptm
->tm_hour
= (uInt
) ((ulDosDate
&0xF800)/0x800);
509 ptm
->tm_min
= (uInt
) ((ulDosDate
&0x7E0)/0x20) ;
510 ptm
->tm_sec
= (uInt
) (2*(ulDosDate
&0x1f)) ;
514 Get Info about the current file in the zipfile, with internal only info
516 local
int unzlocal_GetCurrentFileInfoInternal
OF((unzFile file
,
517 unz_file_info
*pfile_info
,
518 unz_file_info_internal
519 *pfile_info_internal
,
521 uLong fileNameBufferSize
,
523 uLong extraFieldBufferSize
,
525 uLong commentBufferSize
));
527 local
int unzlocal_GetCurrentFileInfoInternal (file
,
530 szFileName
, fileNameBufferSize
,
531 extraField
, extraFieldBufferSize
,
532 szComment
, commentBufferSize
)
534 unz_file_info
*pfile_info
;
535 unz_file_info_internal
*pfile_info_internal
;
537 uLong fileNameBufferSize
;
539 uLong extraFieldBufferSize
;
541 uLong commentBufferSize
;
544 unz_file_info file_info
;
545 unz_file_info_internal file_info_internal
;
551 return UNZ_PARAMERROR
;
553 if (fseek(s
->file
,s
->pos_in_central_dir
+s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
557 /* we check the magic */
559 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
561 else if (uMagic
!=0x02014b50)
564 if (unzlocal_getShort(s
->file
,&file_info
.version
) != UNZ_OK
)
567 if (unzlocal_getShort(s
->file
,&file_info
.version_needed
) != UNZ_OK
)
570 if (unzlocal_getShort(s
->file
,&file_info
.flag
) != UNZ_OK
)
573 if (unzlocal_getShort(s
->file
,&file_info
.compression_method
) != UNZ_OK
)
576 if (unzlocal_getLong(s
->file
,&file_info
.dosDate
) != UNZ_OK
)
579 unzlocal_DosDateToTmuDate(file_info
.dosDate
,&file_info
.tmu_date
);
581 if (unzlocal_getLong(s
->file
,&file_info
.crc
) != UNZ_OK
)
584 if (unzlocal_getLong(s
->file
,&file_info
.compressed_size
) != UNZ_OK
)
587 if (unzlocal_getLong(s
->file
,&file_info
.uncompressed_size
) != UNZ_OK
)
590 if (unzlocal_getShort(s
->file
,&file_info
.size_filename
) != UNZ_OK
)
593 if (unzlocal_getShort(s
->file
,&file_info
.size_file_extra
) != UNZ_OK
)
596 if (unzlocal_getShort(s
->file
,&file_info
.size_file_comment
) != UNZ_OK
)
599 if (unzlocal_getShort(s
->file
,&file_info
.disk_num_start
) != UNZ_OK
)
602 if (unzlocal_getShort(s
->file
,&file_info
.internal_fa
) != UNZ_OK
)
605 if (unzlocal_getLong(s
->file
,&file_info
.external_fa
) != UNZ_OK
)
608 if (unzlocal_getLong(s
->file
,&file_info_internal
.offset_curfile
) != UNZ_OK
)
611 lSeek
+=file_info
.size_filename
;
612 if ((err
==UNZ_OK
) && (szFileName
!=NULL
))
615 if (file_info
.size_filename
<fileNameBufferSize
)
617 *(szFileName
+file_info
.size_filename
)='\0';
618 uSizeRead
= file_info
.size_filename
;
621 uSizeRead
= fileNameBufferSize
;
623 if ((file_info
.size_filename
>0) && (fileNameBufferSize
>0))
624 if (fread(szFileName
,(uInt
)uSizeRead
,1,s
->file
)!=1)
630 if ((err
==UNZ_OK
) && (extraField
!=NULL
))
633 if (file_info
.size_file_extra
<extraFieldBufferSize
)
634 uSizeRead
= file_info
.size_file_extra
;
636 uSizeRead
= extraFieldBufferSize
;
639 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
643 if ((file_info
.size_file_extra
>0) && (extraFieldBufferSize
>0))
644 if (fread(extraField
,(uInt
)uSizeRead
,1,s
->file
)!=1)
646 lSeek
+= file_info
.size_file_extra
- uSizeRead
;
649 lSeek
+=file_info
.size_file_extra
;
652 if ((err
==UNZ_OK
) && (szComment
!=NULL
))
655 if (file_info
.size_file_comment
<commentBufferSize
)
657 *(szComment
+file_info
.size_file_comment
)='\0';
658 uSizeRead
= file_info
.size_file_comment
;
661 uSizeRead
= commentBufferSize
;
664 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
668 if ((file_info
.size_file_comment
>0) && (commentBufferSize
>0))
669 if (fread(szComment
,(uInt
)uSizeRead
,1,s
->file
)!=1)
671 lSeek
+=file_info
.size_file_comment
- uSizeRead
;
674 lSeek
+=file_info
.size_file_comment
;
676 if ((err
==UNZ_OK
) && (pfile_info
!=NULL
))
677 *pfile_info
=file_info
;
679 if ((err
==UNZ_OK
) && (pfile_info_internal
!=NULL
))
680 *pfile_info_internal
=file_info_internal
;
688 Write info about the ZipFile in the *pglobal_info structure.
689 No preparation of the structure is needed
690 return UNZ_OK if there is no problem.
692 extern int ZEXPORT
unzGetCurrentFileInfo (file
,
694 szFileName
, fileNameBufferSize
,
695 extraField
, extraFieldBufferSize
,
696 szComment
, commentBufferSize
)
698 unz_file_info
*pfile_info
;
700 uLong fileNameBufferSize
;
702 uLong extraFieldBufferSize
;
704 uLong commentBufferSize
;
706 return unzlocal_GetCurrentFileInfoInternal(file
,pfile_info
,NULL
,
707 szFileName
,fileNameBufferSize
,
708 extraField
,extraFieldBufferSize
,
709 szComment
,commentBufferSize
);
713 Set the current file of the zipfile to the first file.
714 return UNZ_OK if there is no problem
716 extern int ZEXPORT
unzGoToFirstFile (file
)
722 return UNZ_PARAMERROR
;
724 s
->pos_in_central_dir
=s
->offset_central_dir
;
726 err
=unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
727 &s
->cur_file_info_internal
,
728 NULL
,0,NULL
,0,NULL
,0);
729 s
->current_file_ok
= (err
== UNZ_OK
);
735 Set the current file of the zipfile to the next file.
736 return UNZ_OK if there is no problem
737 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
739 extern int ZEXPORT
unzGoToNextFile (file
)
746 return UNZ_PARAMERROR
;
748 if (!s
->current_file_ok
)
749 return UNZ_END_OF_LIST_OF_FILE
;
750 if (s
->num_file
+1==s
->gi
.number_entry
)
751 return UNZ_END_OF_LIST_OF_FILE
;
753 s
->pos_in_central_dir
+= SIZECENTRALDIRITEM
+ s
->cur_file_info
.size_filename
+
754 s
->cur_file_info
.size_file_extra
+ s
->cur_file_info
.size_file_comment
;
756 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
757 &s
->cur_file_info_internal
,
758 NULL
,0,NULL
,0,NULL
,0);
759 s
->current_file_ok
= (err
== UNZ_OK
);
765 Try locate the file szFileName in the zipfile.
766 For the iCaseSensitivity signification, see unzipStringFileNameCompare
769 UNZ_OK if the file is found. It becomes the current file.
770 UNZ_END_OF_LIST_OF_FILE if the file is not found
772 extern int ZEXPORT
unzLocateFile (file
, szFileName
, iCaseSensitivity
)
774 const char *szFileName
;
775 int iCaseSensitivity
;
782 uLong pos_in_central_dirSaved
;
786 return UNZ_PARAMERROR
;
788 if (strlen(szFileName
)>=UNZ_MAXFILENAMEINZIP
)
789 return UNZ_PARAMERROR
;
792 if (!s
->current_file_ok
)
793 return UNZ_END_OF_LIST_OF_FILE
;
795 num_fileSaved
= s
->num_file
;
796 pos_in_central_dirSaved
= s
->pos_in_central_dir
;
798 err
= unzGoToFirstFile(file
);
800 while (err
== UNZ_OK
)
802 char szCurrentFileName
[UNZ_MAXFILENAMEINZIP
+1];
803 unzGetCurrentFileInfo(file
,NULL
,
804 szCurrentFileName
,sizeof(szCurrentFileName
)-1,
806 if (unzStringFileNameCompare(szCurrentFileName
,
807 szFileName
,iCaseSensitivity
)==0)
809 err
= unzGoToNextFile(file
);
812 s
->num_file
= num_fileSaved
;
813 s
->pos_in_central_dir
= pos_in_central_dirSaved
;
819 Read the local header of the current zipfile
820 Check the coherency of the local header and info in the end of central
821 directory about this file
822 store in *piSizeVar the size of extra info in local header
823 (filename and size of extra field data)
825 local
int unzlocal_CheckCurrentFileCoherencyHeader (s
,piSizeVar
,
826 poffset_local_extrafield
,
827 psize_local_extrafield
)
830 uLong
*poffset_local_extrafield
;
831 uInt
*psize_local_extrafield
;
833 uLong uMagic
,uData
,uFlags
;
835 uLong size_extra_field
;
839 *poffset_local_extrafield
= 0;
840 *psize_local_extrafield
= 0;
842 if (fseek(s
->file
,s
->cur_file_info_internal
.offset_curfile
+
843 s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
848 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
850 else if (uMagic
!=0x04034b50)
853 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
856 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
859 if (unzlocal_getShort(s
->file
,&uFlags
) != UNZ_OK
)
862 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
864 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compression_method
))
867 if ((err
==UNZ_OK
) && (s
->cur_file_info
.compression_method
!=0) &&
868 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
871 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* date/time */
874 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* crc */
876 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.crc
) &&
880 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size compr */
882 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compressed_size
) &&
886 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size uncompr */
888 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.uncompressed_size
) &&
893 if (unzlocal_getShort(s
->file
,&size_filename
) != UNZ_OK
)
895 else if ((err
==UNZ_OK
) && (size_filename
!=s
->cur_file_info
.size_filename
))
898 *piSizeVar
+= (uInt
)size_filename
;
900 if (unzlocal_getShort(s
->file
,&size_extra_field
) != UNZ_OK
)
902 *poffset_local_extrafield
= s
->cur_file_info_internal
.offset_curfile
+
903 SIZEZIPLOCALHEADER
+ size_filename
;
904 *psize_local_extrafield
= (uInt
)size_extra_field
;
906 *piSizeVar
+= (uInt
)size_extra_field
;
912 Open for reading data the current file in the zipfile.
913 If there is no error and the file is opened, the return value is UNZ_OK.
915 extern int ZEXPORT
unzOpenCurrentFile (file
)
922 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
923 uLong offset_local_extrafield
; /* offset of the local extra field */
924 uInt size_local_extrafield
; /* size of the local extra field */
927 return UNZ_PARAMERROR
;
929 if (!s
->current_file_ok
)
930 return UNZ_PARAMERROR
;
932 if (s
->pfile_in_zip_read
!= NULL
)
933 unzCloseCurrentFile(file
);
935 if (unzlocal_CheckCurrentFileCoherencyHeader(s
,&iSizeVar
,
936 &offset_local_extrafield
,&size_local_extrafield
)!=UNZ_OK
)
937 return UNZ_BADZIPFILE
;
939 pfile_in_zip_read_info
= (file_in_zip_read_info_s
*)
940 ALLOC(sizeof(file_in_zip_read_info_s
));
941 if (pfile_in_zip_read_info
==NULL
)
942 return UNZ_INTERNALERROR
;
944 pfile_in_zip_read_info
->read_buffer
=(char*)ALLOC(UNZ_BUFSIZE
);
945 pfile_in_zip_read_info
->offset_local_extrafield
= offset_local_extrafield
;
946 pfile_in_zip_read_info
->size_local_extrafield
= size_local_extrafield
;
947 pfile_in_zip_read_info
->pos_local_extrafield
=0;
949 if (pfile_in_zip_read_info
->read_buffer
==NULL
)
951 TRYFREE(pfile_in_zip_read_info
);
952 return UNZ_INTERNALERROR
;
955 pfile_in_zip_read_info
->stream_initialised
=0;
957 if ((s
->cur_file_info
.compression_method
!=0) &&
958 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
960 Store
= s
->cur_file_info
.compression_method
==0;
962 pfile_in_zip_read_info
->crc32_wait
=s
->cur_file_info
.crc
;
963 pfile_in_zip_read_info
->crc32
=0;
964 pfile_in_zip_read_info
->compression_method
=
965 s
->cur_file_info
.compression_method
;
966 pfile_in_zip_read_info
->file
=s
->file
;
967 pfile_in_zip_read_info
->byte_before_the_zipfile
=s
->byte_before_the_zipfile
;
969 pfile_in_zip_read_info
->stream
.total_out
= 0;
973 pfile_in_zip_read_info
->stream
.zalloc
= (alloc_func
)0;
974 pfile_in_zip_read_info
->stream
.zfree
= (free_func
)0;
975 pfile_in_zip_read_info
->stream
.opaque
= (voidpf
)0;
977 err
=inflateInit2(&pfile_in_zip_read_info
->stream
, -MAX_WBITS
);
979 pfile_in_zip_read_info
->stream_initialised
=1;
980 /* windowBits is passed < 0 to tell that there is no zlib header.
981 * Note that in this case inflate *requires* an extra "dummy" byte
982 * after the compressed stream in order to complete decompression and
983 * return Z_STREAM_END.
984 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
985 * size of both compressed and uncompressed data
988 pfile_in_zip_read_info
->rest_read_compressed
=
989 s
->cur_file_info
.compressed_size
;
990 pfile_in_zip_read_info
->rest_read_uncompressed
=
991 s
->cur_file_info
.uncompressed_size
;
994 pfile_in_zip_read_info
->pos_in_zipfile
=
995 s
->cur_file_info_internal
.offset_curfile
+ SIZEZIPLOCALHEADER
+
998 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)0;
1001 s
->pfile_in_zip_read
= pfile_in_zip_read_info
;
1007 Read bytes from the current file.
1008 buf contain buffer where data must be copied
1009 len the size of buf.
1011 return the number of byte copied if somes bytes are copied
1012 return 0 if the end of file was reached
1013 return <0 with error code if there is an error
1014 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1016 extern int ZEXPORT
unzReadCurrentFile (file
, buf
, len
)
1024 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1026 return UNZ_PARAMERROR
;
1028 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1030 if (pfile_in_zip_read_info
==NULL
)
1031 return UNZ_PARAMERROR
;
1034 if ((pfile_in_zip_read_info
->read_buffer
== NULL
))
1035 return UNZ_END_OF_LIST_OF_FILE
;
1039 pfile_in_zip_read_info
->stream
.next_out
= (Bytef
*)buf
;
1041 pfile_in_zip_read_info
->stream
.avail_out
= (uInt
)len
;
1043 if (len
>pfile_in_zip_read_info
->rest_read_uncompressed
)
1044 pfile_in_zip_read_info
->stream
.avail_out
=
1045 (uInt
)pfile_in_zip_read_info
->rest_read_uncompressed
;
1047 while (pfile_in_zip_read_info
->stream
.avail_out
>0)
1049 if ((pfile_in_zip_read_info
->stream
.avail_in
==0) &&
1050 (pfile_in_zip_read_info
->rest_read_compressed
>0))
1052 uInt uReadThis
= UNZ_BUFSIZE
;
1053 if (pfile_in_zip_read_info
->rest_read_compressed
<uReadThis
)
1054 uReadThis
= (uInt
)pfile_in_zip_read_info
->rest_read_compressed
;
1057 if (fseek(pfile_in_zip_read_info
->file
,
1058 pfile_in_zip_read_info
->pos_in_zipfile
+
1059 pfile_in_zip_read_info
->byte_before_the_zipfile
,SEEK_SET
)!=0)
1061 if (fread(pfile_in_zip_read_info
->read_buffer
,uReadThis
,1,
1062 pfile_in_zip_read_info
->file
)!=1)
1064 pfile_in_zip_read_info
->pos_in_zipfile
+= uReadThis
;
1066 pfile_in_zip_read_info
->rest_read_compressed
-=uReadThis
;
1068 pfile_in_zip_read_info
->stream
.next_in
=
1069 (Bytef
*)pfile_in_zip_read_info
->read_buffer
;
1070 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)uReadThis
;
1073 if (pfile_in_zip_read_info
->compression_method
==0)
1076 if (pfile_in_zip_read_info
->stream
.avail_out
<
1077 pfile_in_zip_read_info
->stream
.avail_in
)
1078 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_out
;
1080 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_in
;
1082 for (i
=0;i
<uDoCopy
;i
++)
1083 *(pfile_in_zip_read_info
->stream
.next_out
+i
) =
1084 *(pfile_in_zip_read_info
->stream
.next_in
+i
);
1086 pfile_in_zip_read_info
->crc32
= crc32(pfile_in_zip_read_info
->crc32
,
1087 pfile_in_zip_read_info
->stream
.next_out
,
1089 pfile_in_zip_read_info
->rest_read_uncompressed
-=uDoCopy
;
1090 pfile_in_zip_read_info
->stream
.avail_in
-= uDoCopy
;
1091 pfile_in_zip_read_info
->stream
.avail_out
-= uDoCopy
;
1092 pfile_in_zip_read_info
->stream
.next_out
+= uDoCopy
;
1093 pfile_in_zip_read_info
->stream
.next_in
+= uDoCopy
;
1094 pfile_in_zip_read_info
->stream
.total_out
+= uDoCopy
;
1099 uLong uTotalOutBefore
,uTotalOutAfter
;
1100 const Bytef
*bufBefore
;
1102 int flush
=Z_SYNC_FLUSH
;
1104 uTotalOutBefore
= pfile_in_zip_read_info
->stream
.total_out
;
1105 bufBefore
= pfile_in_zip_read_info
->stream
.next_out
;
1108 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1109 pfile_in_zip_read_info->stream.avail_out) &&
1110 (pfile_in_zip_read_info->rest_read_compressed == 0))
1113 err
=inflate(&pfile_in_zip_read_info
->stream
,flush
);
1115 uTotalOutAfter
= pfile_in_zip_read_info
->stream
.total_out
;
1116 uOutThis
= uTotalOutAfter
-uTotalOutBefore
;
1118 pfile_in_zip_read_info
->crc32
=
1119 crc32(pfile_in_zip_read_info
->crc32
,bufBefore
,
1122 pfile_in_zip_read_info
->rest_read_uncompressed
-=
1125 iRead
+= (uInt
)(uTotalOutAfter
- uTotalOutBefore
);
1127 if (err
==Z_STREAM_END
)
1128 return (iRead
==0) ? UNZ_EOF
: iRead
;
1141 Give the current position in uncompressed data
1143 extern z_off_t ZEXPORT
unztell (file
)
1147 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1149 return UNZ_PARAMERROR
;
1151 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1153 if (pfile_in_zip_read_info
==NULL
)
1154 return UNZ_PARAMERROR
;
1156 return (z_off_t
)pfile_in_zip_read_info
->stream
.total_out
;
1161 return 1 if the end of file was reached, 0 elsewhere
1163 extern int ZEXPORT
unzeof (file
)
1167 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1169 return UNZ_PARAMERROR
;
1171 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1173 if (pfile_in_zip_read_info
==NULL
)
1174 return UNZ_PARAMERROR
;
1176 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1185 Read extra field from the current file (opened by unzOpenCurrentFile)
1186 This is the local-header version of the extra field (sometimes, there is
1187 more info in the local-header version than in the central-header)
1189 if buf==NULL, it return the size of the local extra field that can be read
1191 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1193 the return value is the number of bytes copied in buf, or (if <0)
1196 extern int ZEXPORT
unzGetLocalExtrafield (file
,buf
,len
)
1202 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1207 return UNZ_PARAMERROR
;
1209 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1211 if (pfile_in_zip_read_info
==NULL
)
1212 return UNZ_PARAMERROR
;
1214 size_to_read
= (pfile_in_zip_read_info
->size_local_extrafield
-
1215 pfile_in_zip_read_info
->pos_local_extrafield
);
1218 return (int)size_to_read
;
1220 if (len
>size_to_read
)
1221 read_now
= (uInt
)size_to_read
;
1223 read_now
= (uInt
)len
;
1228 if (fseek(pfile_in_zip_read_info
->file
,
1229 pfile_in_zip_read_info
->offset_local_extrafield
+
1230 pfile_in_zip_read_info
->pos_local_extrafield
,SEEK_SET
)!=0)
1233 if (fread(buf
,(uInt
)size_to_read
,1,pfile_in_zip_read_info
->file
)!=1)
1236 return (int)read_now
;
1240 Close the file in zip opened with unzipOpenCurrentFile
1241 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1243 extern int ZEXPORT
unzCloseCurrentFile (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
;
1259 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1261 if (pfile_in_zip_read_info
->crc32
!= pfile_in_zip_read_info
->crc32_wait
)
1266 TRYFREE(pfile_in_zip_read_info
->read_buffer
);
1267 pfile_in_zip_read_info
->read_buffer
= NULL
;
1268 if (pfile_in_zip_read_info
->stream_initialised
)
1269 inflateEnd(&pfile_in_zip_read_info
->stream
);
1271 pfile_in_zip_read_info
->stream_initialised
= 0;
1272 TRYFREE(pfile_in_zip_read_info
);
1274 s
->pfile_in_zip_read
=NULL
;
1281 Get the global comment string of the ZipFile, in the szComment buffer.
1282 uSizeBuf is the size of the szComment buffer.
1283 return the number of byte copied or an error code <0
1285 extern int ZEXPORT
unzGetGlobalComment (file
, szComment
, uSizeBuf
)
1294 return UNZ_PARAMERROR
;
1297 uReadThis
= uSizeBuf
;
1298 if (uReadThis
>s
->gi
.size_comment
)
1299 uReadThis
= s
->gi
.size_comment
;
1301 if (fseek(s
->file
,s
->central_pos
+22,SEEK_SET
)!=0)
1307 if (fread(szComment
,(uInt
)uReadThis
,1,s
->file
)!=1)
1311 if ((szComment
!= NULL
) && (uSizeBuf
> s
->gi
.size_comment
))
1312 *(szComment
+s
->gi
.size_comment
)='\0';
1313 return (int)uReadThis
;
1318 /* the file shouldn't be empty, som compilers don't like it */
1319 static const int dummyVariableInUnzip
= 17;
1321 #endif /* wxUSE_ZLIB && wxUSE_ZIPSTREAM */