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 wxUSE_ZLIB && wxUSE_ZIPSTREAM
16 /* Not the right solution (paths in makefiles) but... */
18 #include "../common/unzip.h"
38 /* compile with -Dlocal if your debugger can't find static symbols */
42 #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
43 !defined(CASESENSITIVITYDEFAULT_NO)
44 #define CASESENSITIVITYDEFAULT_NO
49 #define UNZ_BUFSIZE (16384)
52 #ifndef UNZ_MAXFILENAMEINZIP
53 #define UNZ_MAXFILENAMEINZIP (256)
57 # define ALLOC(size) (malloc(size))
60 # define TRYFREE(p) {if (p) free(p);}
63 #define SIZECENTRALDIRITEM (0x2e)
64 #define SIZEZIPLOCALHEADER (0x1e)
67 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
81 const char unz_copyright
[] =
82 " unzip 0.15 Copyright 1998 Gilles Vollant ";
84 /* unz_file_info_interntal contain internal info about a file in zipfile*/
85 typedef struct unz_file_info_internal_s
87 uLong offset_curfile
;/* relative offset of local header 4 bytes */
88 } unz_file_info_internal
;
91 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
92 when reading and decompress it */
95 char *read_buffer
; /* internal buffer for compressed data */
96 z_stream stream
; /* zLib stream structure for inflate */
98 uLong pos_in_zipfile
; /* position in byte on the zipfile, for fseek*/
99 uLong stream_initialised
; /* flag set if stream structure is initialised*/
101 uLong offset_local_extrafield
;/* offset of the local extra field */
102 uInt size_local_extrafield
;/* size of the local extra field */
103 uLong pos_local_extrafield
; /* position in the local extra field in read*/
105 uLong crc32
; /* crc32 of all data uncompressed */
106 uLong crc32_wait
; /* crc32 we must obtain after decompress all */
107 uLong rest_read_compressed
; /* number of byte to be decompressed */
108 uLong rest_read_uncompressed
;/*number of byte to be obtained after decomp*/
109 FILE* file
; /* io structore of the zipfile */
110 uLong compression_method
; /* compression method (0==store) */
111 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
112 } file_in_zip_read_info_s
;
115 /* unz_s contain internal information about the zipfile
119 FILE* file
; /* io structore of the zipfile */
120 unz_global_info gi
; /* public global information */
121 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
122 uLong num_file
; /* number of the current file in the zipfile*/
123 uLong pos_in_central_dir
; /* pos of the current file in the central dir*/
124 uLong current_file_ok
; /* flag about the usability of the current file*/
125 uLong central_pos
; /* position of the beginning of the central dir*/
127 uLong size_central_dir
; /* size of the central directory */
128 uLong offset_central_dir
; /* offset of start of central directory with
129 respect to the starting disk number */
131 unz_file_info cur_file_info
; /* public info about the current file in zip*/
132 unz_file_info_internal cur_file_info_internal
; /* private info about it*/
133 file_in_zip_read_info_s
* pfile_in_zip_read
; /* structure about the current
134 file if we are decompressing it */
137 #if defined (__VISAGECPP__)
138 // VA always requires prototypes
139 int unzlocal_CheckCurrentFileCoherencyHeader (unz_s
*, uInt
*, uLong
*, uInt
*);
142 /* ===========================================================================
143 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
145 IN assertion: the stream s has been sucessfully opened for reading.
149 local
int unzlocal_getByte(fin
,pi
)
154 int err
= fread(&c
, 1, 1, fin
);
170 /* ===========================================================================
171 Reads a long in LSB order from the given gz_stream. Sets
173 local
int unzlocal_getShort (fin
,pX
)
181 err
= unzlocal_getByte(fin
,&i
);
185 err
= unzlocal_getByte(fin
,&i
);
195 local
int unzlocal_getLong (fin
,pX
)
203 err
= unzlocal_getByte(fin
,&i
);
207 err
= unzlocal_getByte(fin
,&i
);
211 err
= unzlocal_getByte(fin
,&i
);
215 err
= unzlocal_getByte(fin
,&i
);
226 /* My own strcmpi / strcasecmp */
227 local
int strcmpcasenosensitive_internal (fileName1
,fileName2
)
228 const char* fileName1
;
229 const char* fileName2
;
233 char c1
=*(fileName1
++);
234 char c2
=*(fileName2
++);
235 if ((c1
>='a') && (c1
<='z'))
237 if ((c2
>='a') && (c2
<='z'))
240 return ((c2
=='\0') ? 0 : -1);
251 #ifdef CASESENSITIVITYDEFAULT_NO
252 #define CASESENSITIVITYDEFAULTVALUE 2
254 #define CASESENSITIVITYDEFAULTVALUE 1
257 #ifndef STRCMPCASENOSENTIVEFUNCTION
258 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
262 Compare two filename (fileName1,fileName2).
263 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
264 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
266 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
267 (like 1 on Unix, 2 on Windows)
270 extern int ZEXPORT
unzStringFileNameCompare (fileName1
,fileName2
,iCaseSensitivity
)
271 const char* fileName1
;
272 const char* fileName2
;
273 int iCaseSensitivity
;
275 if (iCaseSensitivity
==0)
276 iCaseSensitivity
=CASESENSITIVITYDEFAULTVALUE
;
278 if (iCaseSensitivity
==1)
279 return strcmp(fileName1
,fileName2
);
281 return STRCMPCASENOSENTIVEFUNCTION(fileName1
,fileName2
);
284 #define BUFREADCOMMENT (0x400)
287 Locate the Central directory of a zipfile (at the end, just before
290 local uLong
unzlocal_SearchCentralDir(fin
)
296 uLong uMaxBack
=0xffff; /* maximum size of global comment */
299 if (fseek(fin
,0,SEEK_END
) != 0)
303 uSizeFile
= ftell( fin
);
305 if (uMaxBack
>uSizeFile
)
306 uMaxBack
= uSizeFile
;
308 buf
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4);
313 while (uBackRead
<uMaxBack
)
315 uLong uReadSize
,uReadPos
;
317 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
)
318 uBackRead
= uMaxBack
;
320 uBackRead
+=BUFREADCOMMENT
;
321 uReadPos
= uSizeFile
-uBackRead
;
323 uReadSize
= ((BUFREADCOMMENT
+4) < (uSizeFile
-uReadPos
)) ?
324 (BUFREADCOMMENT
+4) : (uSizeFile
-uReadPos
);
325 if (fseek(fin
,uReadPos
,SEEK_SET
)!=0)
328 if (fread(buf
,(uInt
)uReadSize
,1,fin
)!=1)
331 for (i
=(int)uReadSize
-3; (i
--)>0;)
332 if (((*(buf
+i
))==0x50) && ((*(buf
+i
+1))==0x4b) &&
333 ((*(buf
+i
+2))==0x05) && ((*(buf
+i
+3))==0x06))
335 uPosFound
= uReadPos
+i
;
347 Open a Zip file. path contain the full pathname (by example,
348 on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
350 If the zipfile cannot be opened (file don't exist or in not valid), the
351 return value is NULL.
352 Else, the return value is a unzFile Handle, usable with other function
353 of this unzip package.
355 extern unzFile ZEXPORT
unzOpen (path
)
360 uLong central_pos
,uL
;
363 uLong number_disk
; /* number of the current dist, used for
364 spaning ZIP, unsupported, always 0*/
365 uLong number_disk_with_CD
; /* number the the disk with central dir, used
366 for spaning ZIP, unsupported, always 0*/
367 uLong number_entry_CD
; /* total number of entries in
369 (same than number_entry on nospan) */
373 if (unz_copyright
[0]!=' ')
376 fin
=fopen(path
,"rb");
380 central_pos
= unzlocal_SearchCentralDir(fin
);
384 if (fseek(fin
,central_pos
,SEEK_SET
)!=0)
387 /* the signature, already checked */
388 if (unzlocal_getLong(fin
,&uL
)!=UNZ_OK
)
391 /* number of this disk */
392 if (unzlocal_getShort(fin
,&number_disk
)!=UNZ_OK
)
395 /* number of the disk with the start of the central directory */
396 if (unzlocal_getShort(fin
,&number_disk_with_CD
)!=UNZ_OK
)
399 /* total number of entries in the central dir on this disk */
400 if (unzlocal_getShort(fin
,&us
.gi
.number_entry
)!=UNZ_OK
)
403 /* total number of entries in the central dir */
404 if (unzlocal_getShort(fin
,&number_entry_CD
)!=UNZ_OK
)
407 if ((number_entry_CD
!=us
.gi
.number_entry
) ||
408 (number_disk_with_CD
!=0) ||
412 /* size of the central directory */
413 if (unzlocal_getLong(fin
,&us
.size_central_dir
)!=UNZ_OK
)
416 /* offset of start of central directory with respect to the
417 starting disk number */
418 if (unzlocal_getLong(fin
,&us
.offset_central_dir
)!=UNZ_OK
)
421 /* zipfile comment length */
422 if (unzlocal_getShort(fin
,&us
.gi
.size_comment
)!=UNZ_OK
)
425 if ((central_pos
<us
.offset_central_dir
+us
.size_central_dir
) &&
435 us
.byte_before_the_zipfile
= central_pos
-
436 (us
.offset_central_dir
+us
.size_central_dir
);
437 us
.central_pos
= central_pos
;
438 us
.pfile_in_zip_read
= NULL
;
441 s
=(unz_s
*)ALLOC(sizeof(unz_s
));
443 unzGoToFirstFile((unzFile
)s
);
449 Close a ZipFile opened with unzipOpen.
450 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
451 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
452 return UNZ_OK if there is no problem. */
453 extern int ZEXPORT
unzClose (file
)
458 return UNZ_PARAMERROR
;
461 if (s
->pfile_in_zip_read
!=NULL
)
462 unzCloseCurrentFile(file
);
471 Write info about the ZipFile in the *pglobal_info structure.
472 No preparation of the structure is needed
473 return UNZ_OK if there is no problem. */
474 extern int ZEXPORT
unzGetGlobalInfo (file
,pglobal_info
)
476 unz_global_info
*pglobal_info
;
480 return UNZ_PARAMERROR
;
488 Translate date/time from Dos format to tm_unz (readable more easilty)
490 local
void unzlocal_DosDateToTmuDate (ulDosDate
, ptm
)
495 uDate
= (uLong
)(ulDosDate
>>16);
496 ptm
->tm_mday
= (uInt
)(uDate
&0x1f) ;
497 ptm
->tm_mon
= (uInt
)((((uDate
)&0x1E0)/0x20)-1) ;
498 ptm
->tm_year
= (uInt
)(((uDate
&0x0FE00)/0x0200)+1980) ;
500 ptm
->tm_hour
= (uInt
) ((ulDosDate
&0xF800)/0x800);
501 ptm
->tm_min
= (uInt
) ((ulDosDate
&0x7E0)/0x20) ;
502 ptm
->tm_sec
= (uInt
) (2*(ulDosDate
&0x1f)) ;
506 Get Info about the current file in the zipfile, with internal only info
508 local
int unzlocal_GetCurrentFileInfoInternal
OF((unzFile file
,
509 unz_file_info
*pfile_info
,
510 unz_file_info_internal
511 *pfile_info_internal
,
513 uLong fileNameBufferSize
,
515 uLong extraFieldBufferSize
,
517 uLong commentBufferSize
));
519 local
int unzlocal_GetCurrentFileInfoInternal (file
,
522 szFileName
, fileNameBufferSize
,
523 extraField
, extraFieldBufferSize
,
524 szComment
, commentBufferSize
)
526 unz_file_info
*pfile_info
;
527 unz_file_info_internal
*pfile_info_internal
;
529 uLong fileNameBufferSize
;
531 uLong extraFieldBufferSize
;
533 uLong commentBufferSize
;
536 unz_file_info file_info
;
537 unz_file_info_internal file_info_internal
;
543 return UNZ_PARAMERROR
;
545 if (fseek(s
->file
,s
->pos_in_central_dir
+s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
549 /* we check the magic */
551 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
553 else if (uMagic
!=0x02014b50)
556 if (unzlocal_getShort(s
->file
,&file_info
.version
) != UNZ_OK
)
559 if (unzlocal_getShort(s
->file
,&file_info
.version_needed
) != UNZ_OK
)
562 if (unzlocal_getShort(s
->file
,&file_info
.flag
) != UNZ_OK
)
565 if (unzlocal_getShort(s
->file
,&file_info
.compression_method
) != UNZ_OK
)
568 if (unzlocal_getLong(s
->file
,&file_info
.dosDate
) != UNZ_OK
)
571 unzlocal_DosDateToTmuDate(file_info
.dosDate
,&file_info
.tmu_date
);
573 if (unzlocal_getLong(s
->file
,&file_info
.crc
) != UNZ_OK
)
576 if (unzlocal_getLong(s
->file
,&file_info
.compressed_size
) != UNZ_OK
)
579 if (unzlocal_getLong(s
->file
,&file_info
.uncompressed_size
) != UNZ_OK
)
582 if (unzlocal_getShort(s
->file
,&file_info
.size_filename
) != UNZ_OK
)
585 if (unzlocal_getShort(s
->file
,&file_info
.size_file_extra
) != UNZ_OK
)
588 if (unzlocal_getShort(s
->file
,&file_info
.size_file_comment
) != UNZ_OK
)
591 if (unzlocal_getShort(s
->file
,&file_info
.disk_num_start
) != UNZ_OK
)
594 if (unzlocal_getShort(s
->file
,&file_info
.internal_fa
) != UNZ_OK
)
597 if (unzlocal_getLong(s
->file
,&file_info
.external_fa
) != UNZ_OK
)
600 if (unzlocal_getLong(s
->file
,&file_info_internal
.offset_curfile
) != UNZ_OK
)
603 lSeek
+=file_info
.size_filename
;
604 if ((err
==UNZ_OK
) && (szFileName
!=NULL
))
607 if (file_info
.size_filename
<fileNameBufferSize
)
609 *(szFileName
+file_info
.size_filename
)='\0';
610 uSizeRead
= file_info
.size_filename
;
613 uSizeRead
= fileNameBufferSize
;
615 if ((file_info
.size_filename
>0) && (fileNameBufferSize
>0))
616 if (fread(szFileName
,(uInt
)uSizeRead
,1,s
->file
)!=1)
622 if ((err
==UNZ_OK
) && (extraField
!=NULL
))
625 if (file_info
.size_file_extra
<extraFieldBufferSize
)
626 uSizeRead
= file_info
.size_file_extra
;
628 uSizeRead
= extraFieldBufferSize
;
631 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
635 if ((file_info
.size_file_extra
>0) && (extraFieldBufferSize
>0))
636 if (fread(extraField
,(uInt
)uSizeRead
,1,s
->file
)!=1)
638 lSeek
+= file_info
.size_file_extra
- uSizeRead
;
641 lSeek
+=file_info
.size_file_extra
;
644 if ((err
==UNZ_OK
) && (szComment
!=NULL
))
647 if (file_info
.size_file_comment
<commentBufferSize
)
649 *(szComment
+file_info
.size_file_comment
)='\0';
650 uSizeRead
= file_info
.size_file_comment
;
653 uSizeRead
= commentBufferSize
;
656 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
660 if ((file_info
.size_file_comment
>0) && (commentBufferSize
>0))
661 if (fread(szComment
,(uInt
)uSizeRead
,1,s
->file
)!=1)
663 lSeek
+=file_info
.size_file_comment
- uSizeRead
;
666 lSeek
+=file_info
.size_file_comment
;
668 if ((err
==UNZ_OK
) && (pfile_info
!=NULL
))
669 *pfile_info
=file_info
;
671 if ((err
==UNZ_OK
) && (pfile_info_internal
!=NULL
))
672 *pfile_info_internal
=file_info_internal
;
680 Write info about the ZipFile in the *pglobal_info structure.
681 No preparation of the structure is needed
682 return UNZ_OK if there is no problem.
684 extern int ZEXPORT
unzGetCurrentFileInfo (file
,
686 szFileName
, fileNameBufferSize
,
687 extraField
, extraFieldBufferSize
,
688 szComment
, commentBufferSize
)
690 unz_file_info
*pfile_info
;
692 uLong fileNameBufferSize
;
694 uLong extraFieldBufferSize
;
696 uLong commentBufferSize
;
698 return unzlocal_GetCurrentFileInfoInternal(file
,pfile_info
,NULL
,
699 szFileName
,fileNameBufferSize
,
700 extraField
,extraFieldBufferSize
,
701 szComment
,commentBufferSize
);
705 Set the current file of the zipfile to the first file.
706 return UNZ_OK if there is no problem
708 extern int ZEXPORT
unzGoToFirstFile (file
)
714 return UNZ_PARAMERROR
;
716 s
->pos_in_central_dir
=s
->offset_central_dir
;
718 err
=unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
719 &s
->cur_file_info_internal
,
720 NULL
,0,NULL
,0,NULL
,0);
721 s
->current_file_ok
= (err
== UNZ_OK
);
727 Set the current file of the zipfile to the next file.
728 return UNZ_OK if there is no problem
729 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
731 extern int ZEXPORT
unzGoToNextFile (file
)
738 return UNZ_PARAMERROR
;
740 if (!s
->current_file_ok
)
741 return UNZ_END_OF_LIST_OF_FILE
;
742 if (s
->num_file
+1==s
->gi
.number_entry
)
743 return UNZ_END_OF_LIST_OF_FILE
;
745 s
->pos_in_central_dir
+= SIZECENTRALDIRITEM
+ s
->cur_file_info
.size_filename
+
746 s
->cur_file_info
.size_file_extra
+ s
->cur_file_info
.size_file_comment
;
748 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
749 &s
->cur_file_info_internal
,
750 NULL
,0,NULL
,0,NULL
,0);
751 s
->current_file_ok
= (err
== UNZ_OK
);
757 Try locate the file szFileName in the zipfile.
758 For the iCaseSensitivity signification, see unzipStringFileNameCompare
761 UNZ_OK if the file is found. It becomes the current file.
762 UNZ_END_OF_LIST_OF_FILE if the file is not found
764 extern int ZEXPORT
unzLocateFile (file
, szFileName
, iCaseSensitivity
)
766 const char *szFileName
;
767 int iCaseSensitivity
;
774 uLong pos_in_central_dirSaved
;
778 return UNZ_PARAMERROR
;
780 if (strlen(szFileName
)>=UNZ_MAXFILENAMEINZIP
)
781 return UNZ_PARAMERROR
;
784 if (!s
->current_file_ok
)
785 return UNZ_END_OF_LIST_OF_FILE
;
787 num_fileSaved
= s
->num_file
;
788 pos_in_central_dirSaved
= s
->pos_in_central_dir
;
790 err
= unzGoToFirstFile(file
);
792 while (err
== UNZ_OK
)
794 char szCurrentFileName
[UNZ_MAXFILENAMEINZIP
+1];
795 unzGetCurrentFileInfo(file
,NULL
,
796 szCurrentFileName
,sizeof(szCurrentFileName
)-1,
798 if (unzStringFileNameCompare(szCurrentFileName
,
799 szFileName
,iCaseSensitivity
)==0)
801 err
= unzGoToNextFile(file
);
804 s
->num_file
= num_fileSaved
;
805 s
->pos_in_central_dir
= pos_in_central_dirSaved
;
811 Read the local header of the current zipfile
812 Check the coherency of the local header and info in the end of central
813 directory about this file
814 store in *piSizeVar the size of extra info in local header
815 (filename and size of extra field data)
817 local
int unzlocal_CheckCurrentFileCoherencyHeader (s
,piSizeVar
,
818 poffset_local_extrafield
,
819 psize_local_extrafield
)
822 uLong
*poffset_local_extrafield
;
823 uInt
*psize_local_extrafield
;
825 uLong uMagic
,uData
,uFlags
;
827 uLong size_extra_field
;
831 *poffset_local_extrafield
= 0;
832 *psize_local_extrafield
= 0;
834 if (fseek(s
->file
,s
->cur_file_info_internal
.offset_curfile
+
835 s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
840 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
842 else if (uMagic
!=0x04034b50)
845 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
848 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
851 if (unzlocal_getShort(s
->file
,&uFlags
) != UNZ_OK
)
854 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
856 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compression_method
))
859 if ((err
==UNZ_OK
) && (s
->cur_file_info
.compression_method
!=0) &&
860 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
863 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* date/time */
866 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* crc */
868 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.crc
) &&
872 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size compr */
874 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compressed_size
) &&
878 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size uncompr */
880 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.uncompressed_size
) &&
885 if (unzlocal_getShort(s
->file
,&size_filename
) != UNZ_OK
)
887 else if ((err
==UNZ_OK
) && (size_filename
!=s
->cur_file_info
.size_filename
))
890 *piSizeVar
+= (uInt
)size_filename
;
892 if (unzlocal_getShort(s
->file
,&size_extra_field
) != UNZ_OK
)
894 *poffset_local_extrafield
= s
->cur_file_info_internal
.offset_curfile
+
895 SIZEZIPLOCALHEADER
+ size_filename
;
896 *psize_local_extrafield
= (uInt
)size_extra_field
;
898 *piSizeVar
+= (uInt
)size_extra_field
;
904 Open for reading data the current file in the zipfile.
905 If there is no error and the file is opened, the return value is UNZ_OK.
907 extern int ZEXPORT
unzOpenCurrentFile (file
)
914 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
915 uLong offset_local_extrafield
; /* offset of the local extra field */
916 uInt size_local_extrafield
; /* size of the local extra field */
919 return UNZ_PARAMERROR
;
921 if (!s
->current_file_ok
)
922 return UNZ_PARAMERROR
;
924 if (s
->pfile_in_zip_read
!= NULL
)
925 unzCloseCurrentFile(file
);
927 if (unzlocal_CheckCurrentFileCoherencyHeader(s
,&iSizeVar
,
928 &offset_local_extrafield
,&size_local_extrafield
)!=UNZ_OK
)
929 return UNZ_BADZIPFILE
;
931 pfile_in_zip_read_info
= (file_in_zip_read_info_s
*)
932 ALLOC(sizeof(file_in_zip_read_info_s
));
933 if (pfile_in_zip_read_info
==NULL
)
934 return UNZ_INTERNALERROR
;
936 pfile_in_zip_read_info
->read_buffer
=(char*)ALLOC(UNZ_BUFSIZE
);
937 pfile_in_zip_read_info
->offset_local_extrafield
= offset_local_extrafield
;
938 pfile_in_zip_read_info
->size_local_extrafield
= size_local_extrafield
;
939 pfile_in_zip_read_info
->pos_local_extrafield
=0;
941 if (pfile_in_zip_read_info
->read_buffer
==NULL
)
943 TRYFREE(pfile_in_zip_read_info
);
944 return UNZ_INTERNALERROR
;
947 pfile_in_zip_read_info
->stream_initialised
=0;
949 if ((s
->cur_file_info
.compression_method
!=0) &&
950 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
952 Store
= s
->cur_file_info
.compression_method
==0;
954 pfile_in_zip_read_info
->crc32_wait
=s
->cur_file_info
.crc
;
955 pfile_in_zip_read_info
->crc32
=0;
956 pfile_in_zip_read_info
->compression_method
=
957 s
->cur_file_info
.compression_method
;
958 pfile_in_zip_read_info
->file
=s
->file
;
959 pfile_in_zip_read_info
->byte_before_the_zipfile
=s
->byte_before_the_zipfile
;
961 pfile_in_zip_read_info
->stream
.total_out
= 0;
965 pfile_in_zip_read_info
->stream
.zalloc
= (alloc_func
)0;
966 pfile_in_zip_read_info
->stream
.zfree
= (free_func
)0;
967 pfile_in_zip_read_info
->stream
.opaque
= (voidpf
)0;
969 err
=inflateInit2(&pfile_in_zip_read_info
->stream
, -MAX_WBITS
);
971 pfile_in_zip_read_info
->stream_initialised
=1;
972 /* windowBits is passed < 0 to tell that there is no zlib header.
973 * Note that in this case inflate *requires* an extra "dummy" byte
974 * after the compressed stream in order to complete decompression and
975 * return Z_STREAM_END.
976 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
977 * size of both compressed and uncompressed data
980 pfile_in_zip_read_info
->rest_read_compressed
=
981 s
->cur_file_info
.compressed_size
;
982 pfile_in_zip_read_info
->rest_read_uncompressed
=
983 s
->cur_file_info
.uncompressed_size
;
986 pfile_in_zip_read_info
->pos_in_zipfile
=
987 s
->cur_file_info_internal
.offset_curfile
+ SIZEZIPLOCALHEADER
+
990 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)0;
993 s
->pfile_in_zip_read
= pfile_in_zip_read_info
;
999 Read bytes from the current file.
1000 buf contain buffer where data must be copied
1001 len the size of buf.
1003 return the number of byte copied if somes bytes are copied
1004 return 0 if the end of file was reached
1005 return <0 with error code if there is an error
1006 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1008 extern int ZEXPORT
unzReadCurrentFile (file
, buf
, len
)
1016 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1018 return UNZ_PARAMERROR
;
1020 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1022 if (pfile_in_zip_read_info
==NULL
)
1023 return UNZ_PARAMERROR
;
1026 if ((pfile_in_zip_read_info
->read_buffer
== NULL
))
1027 return UNZ_END_OF_LIST_OF_FILE
;
1031 pfile_in_zip_read_info
->stream
.next_out
= (Bytef
*)buf
;
1033 pfile_in_zip_read_info
->stream
.avail_out
= (uInt
)len
;
1035 if (len
>pfile_in_zip_read_info
->rest_read_uncompressed
)
1036 pfile_in_zip_read_info
->stream
.avail_out
=
1037 (uInt
)pfile_in_zip_read_info
->rest_read_uncompressed
;
1039 while (pfile_in_zip_read_info
->stream
.avail_out
>0)
1041 if ((pfile_in_zip_read_info
->stream
.avail_in
==0) &&
1042 (pfile_in_zip_read_info
->rest_read_compressed
>0))
1044 uInt uReadThis
= UNZ_BUFSIZE
;
1045 if (pfile_in_zip_read_info
->rest_read_compressed
<uReadThis
)
1046 uReadThis
= (uInt
)pfile_in_zip_read_info
->rest_read_compressed
;
1049 if (fseek(pfile_in_zip_read_info
->file
,
1050 pfile_in_zip_read_info
->pos_in_zipfile
+
1051 pfile_in_zip_read_info
->byte_before_the_zipfile
,SEEK_SET
)!=0)
1053 if (fread(pfile_in_zip_read_info
->read_buffer
,uReadThis
,1,
1054 pfile_in_zip_read_info
->file
)!=1)
1056 pfile_in_zip_read_info
->pos_in_zipfile
+= uReadThis
;
1058 pfile_in_zip_read_info
->rest_read_compressed
-=uReadThis
;
1060 pfile_in_zip_read_info
->stream
.next_in
=
1061 (Bytef
*)pfile_in_zip_read_info
->read_buffer
;
1062 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)uReadThis
;
1065 if (pfile_in_zip_read_info
->compression_method
==0)
1068 if (pfile_in_zip_read_info
->stream
.avail_out
<
1069 pfile_in_zip_read_info
->stream
.avail_in
)
1070 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_out
;
1072 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_in
;
1074 for (i
=0;i
<uDoCopy
;i
++)
1075 *(pfile_in_zip_read_info
->stream
.next_out
+i
) =
1076 *(pfile_in_zip_read_info
->stream
.next_in
+i
);
1078 pfile_in_zip_read_info
->crc32
= crc32(pfile_in_zip_read_info
->crc32
,
1079 pfile_in_zip_read_info
->stream
.next_out
,
1081 pfile_in_zip_read_info
->rest_read_uncompressed
-=uDoCopy
;
1082 pfile_in_zip_read_info
->stream
.avail_in
-= uDoCopy
;
1083 pfile_in_zip_read_info
->stream
.avail_out
-= uDoCopy
;
1084 pfile_in_zip_read_info
->stream
.next_out
+= uDoCopy
;
1085 pfile_in_zip_read_info
->stream
.next_in
+= uDoCopy
;
1086 pfile_in_zip_read_info
->stream
.total_out
+= uDoCopy
;
1091 uLong uTotalOutBefore
,uTotalOutAfter
;
1092 const Bytef
*bufBefore
;
1094 int flush
=Z_SYNC_FLUSH
;
1096 uTotalOutBefore
= pfile_in_zip_read_info
->stream
.total_out
;
1097 bufBefore
= pfile_in_zip_read_info
->stream
.next_out
;
1100 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1101 pfile_in_zip_read_info->stream.avail_out) &&
1102 (pfile_in_zip_read_info->rest_read_compressed == 0))
1105 err
=inflate(&pfile_in_zip_read_info
->stream
,flush
);
1107 uTotalOutAfter
= pfile_in_zip_read_info
->stream
.total_out
;
1108 uOutThis
= uTotalOutAfter
-uTotalOutBefore
;
1110 pfile_in_zip_read_info
->crc32
=
1111 crc32(pfile_in_zip_read_info
->crc32
,bufBefore
,
1114 pfile_in_zip_read_info
->rest_read_uncompressed
-=
1117 iRead
+= (uInt
)(uTotalOutAfter
- uTotalOutBefore
);
1119 if (err
==Z_STREAM_END
)
1120 return (iRead
==0) ? UNZ_EOF
: iRead
;
1133 Give the current position in uncompressed data
1135 extern z_off_t ZEXPORT
unztell (file
)
1139 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1141 return UNZ_PARAMERROR
;
1143 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1145 if (pfile_in_zip_read_info
==NULL
)
1146 return UNZ_PARAMERROR
;
1148 return (z_off_t
)pfile_in_zip_read_info
->stream
.total_out
;
1153 return 1 if the end of file was reached, 0 elsewhere
1155 extern int ZEXPORT
unzeof (file
)
1159 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1161 return UNZ_PARAMERROR
;
1163 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1165 if (pfile_in_zip_read_info
==NULL
)
1166 return UNZ_PARAMERROR
;
1168 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1177 Read extra field from the current file (opened by unzOpenCurrentFile)
1178 This is the local-header version of the extra field (sometimes, there is
1179 more info in the local-header version than in the central-header)
1181 if buf==NULL, it return the size of the local extra field that can be read
1183 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1185 the return value is the number of bytes copied in buf, or (if <0)
1188 extern int ZEXPORT
unzGetLocalExtrafield (file
,buf
,len
)
1194 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1199 return UNZ_PARAMERROR
;
1201 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1203 if (pfile_in_zip_read_info
==NULL
)
1204 return UNZ_PARAMERROR
;
1206 size_to_read
= (pfile_in_zip_read_info
->size_local_extrafield
-
1207 pfile_in_zip_read_info
->pos_local_extrafield
);
1210 return (int)size_to_read
;
1212 if (len
>size_to_read
)
1213 read_now
= (uInt
)size_to_read
;
1215 read_now
= (uInt
)len
;
1220 if (fseek(pfile_in_zip_read_info
->file
,
1221 pfile_in_zip_read_info
->offset_local_extrafield
+
1222 pfile_in_zip_read_info
->pos_local_extrafield
,SEEK_SET
)!=0)
1225 if (fread(buf
,(uInt
)size_to_read
,1,pfile_in_zip_read_info
->file
)!=1)
1228 return (int)read_now
;
1232 Close the file in zip opened with unzipOpenCurrentFile
1233 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1235 extern int ZEXPORT
unzCloseCurrentFile (file
)
1241 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1243 return UNZ_PARAMERROR
;
1245 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1247 if (pfile_in_zip_read_info
==NULL
)
1248 return UNZ_PARAMERROR
;
1251 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1253 if (pfile_in_zip_read_info
->crc32
!= pfile_in_zip_read_info
->crc32_wait
)
1258 TRYFREE(pfile_in_zip_read_info
->read_buffer
);
1259 pfile_in_zip_read_info
->read_buffer
= NULL
;
1260 if (pfile_in_zip_read_info
->stream_initialised
)
1261 inflateEnd(&pfile_in_zip_read_info
->stream
);
1263 pfile_in_zip_read_info
->stream_initialised
= 0;
1264 TRYFREE(pfile_in_zip_read_info
);
1266 s
->pfile_in_zip_read
=NULL
;
1273 Get the global comment string of the ZipFile, in the szComment buffer.
1274 uSizeBuf is the size of the szComment buffer.
1275 return the number of byte copied or an error code <0
1277 extern int ZEXPORT
unzGetGlobalComment (file
, szComment
, uSizeBuf
)
1286 return UNZ_PARAMERROR
;
1289 uReadThis
= uSizeBuf
;
1290 if (uReadThis
>s
->gi
.size_comment
)
1291 uReadThis
= s
->gi
.size_comment
;
1293 if (fseek(s
->file
,s
->central_pos
+22,SEEK_SET
)!=0)
1299 if (fread(szComment
,(uInt
)uReadThis
,1,s
->file
)!=1)
1303 if ((szComment
!= NULL
) && (uSizeBuf
> s
->gi
.size_comment
))
1304 *(szComment
+s
->gi
.size_comment
)='\0';
1305 return (int)uReadThis
;
1310 // the file shouldn't be empty, som compilers don't like it
1311 static const int dummyVariableInUnzip
= 17;
1313 #endif // wxUSE_ZLIB && wxUSE_ZIPSTREAM