1 /* unzip.c -- IO on .zip files using zlib
2 Version 0.15 beta, Mar 19th, 1998,
4 Read unzip.h for more info
7 # pragma warning(disable:4001) /* non standard extension used: single line comment */
10 #if wxUSE_ZLIB && wxUSE_ZIPSTREAM
17 /* Not the right solution (paths in makefiles) but... */
19 #include "../common/unzip.h"
39 /* compile with -Dlocal if your debugger can't find static symbols */
43 #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
44 !defined(CASESENSITIVITYDEFAULT_NO)
45 #define CASESENSITIVITYDEFAULT_NO
50 #define UNZ_BUFSIZE (16384)
53 #ifndef UNZ_MAXFILENAMEINZIP
54 #define UNZ_MAXFILENAMEINZIP (256)
58 # define ALLOC(size) (malloc(size))
61 # define TRYFREE(p) {if (p) free(p);}
64 #define SIZECENTRALDIRITEM (0x2e)
65 #define SIZEZIPLOCALHEADER (0x1e)
68 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
82 const char unz_copyright
[] =
83 " unzip 0.15 Copyright 1998 Gilles Vollant ";
85 /* unz_file_info_interntal contain internal info about a file in zipfile*/
86 typedef struct unz_file_info_internal_s
88 uLong offset_curfile
;/* relative offset of local header 4 bytes */
89 } unz_file_info_internal
;
92 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
93 when reading and decompress it */
96 char *read_buffer
; /* internal buffer for compressed data */
97 z_stream stream
; /* zLib stream structure for inflate */
99 uLong pos_in_zipfile
; /* position in byte on the zipfile, for fseek*/
100 uLong stream_initialised
; /* flag set if stream structure is initialised*/
102 uLong offset_local_extrafield
;/* offset of the local extra field */
103 uInt size_local_extrafield
;/* size of the local extra field */
104 uLong pos_local_extrafield
; /* position in the local extra field in read*/
106 uLong crc32
; /* crc32 of all data uncompressed */
107 uLong crc32_wait
; /* crc32 we must obtain after decompress all */
108 uLong rest_read_compressed
; /* number of byte to be decompressed */
109 uLong rest_read_uncompressed
;/*number of byte to be obtained after decomp*/
110 FILE* file
; /* io structore of the zipfile */
111 uLong compression_method
; /* compression method (0==store) */
112 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
113 } file_in_zip_read_info_s
;
116 /* unz_s contain internal information about the zipfile
120 FILE* file
; /* io structore of the zipfile */
121 unz_global_info gi
; /* public global information */
122 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
123 uLong num_file
; /* number of the current file in the zipfile*/
124 uLong pos_in_central_dir
; /* pos of the current file in the central dir*/
125 uLong current_file_ok
; /* flag about the usability of the current file*/
126 uLong central_pos
; /* position of the beginning of the central dir*/
128 uLong size_central_dir
; /* size of the central directory */
129 uLong offset_central_dir
; /* offset of start of central directory with
130 respect to the starting disk number */
132 unz_file_info cur_file_info
; /* public info about the current file in zip*/
133 unz_file_info_internal cur_file_info_internal
; /* private info about it*/
134 file_in_zip_read_info_s
* pfile_in_zip_read
; /* structure about the current
135 file if we are decompressing it */
138 #if defined (__VISAGECPP__)
139 // VA always requires prototypes
140 int unzlocal_CheckCurrentFileCoherencyHeader (unz_s
*, uInt
*, uLong
*, uInt
*);
143 /* ===========================================================================
144 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
146 IN assertion: the stream s has been sucessfully opened for reading.
150 local
int unzlocal_getByte(fin
,pi
)
155 int err
= fread(&c
, 1, 1, fin
);
171 /* ===========================================================================
172 Reads a long in LSB order from the given gz_stream. Sets
174 local
int unzlocal_getShort (fin
,pX
)
182 err
= unzlocal_getByte(fin
,&i
);
186 err
= unzlocal_getByte(fin
,&i
);
196 local
int unzlocal_getLong (fin
,pX
)
204 err
= unzlocal_getByte(fin
,&i
);
208 err
= unzlocal_getByte(fin
,&i
);
212 err
= unzlocal_getByte(fin
,&i
);
216 err
= unzlocal_getByte(fin
,&i
);
227 /* My own strcmpi / strcasecmp */
228 local
int strcmpcasenosensitive_internal (fileName1
,fileName2
)
229 const char* fileName1
;
230 const char* fileName2
;
234 char c1
=*(fileName1
++);
235 char c2
=*(fileName2
++);
236 if ((c1
>='a') && (c1
<='z'))
238 if ((c2
>='a') && (c2
<='z'))
241 return ((c2
=='\0') ? 0 : -1);
252 #ifdef CASESENSITIVITYDEFAULT_NO
253 #define CASESENSITIVITYDEFAULTVALUE 2
255 #define CASESENSITIVITYDEFAULTVALUE 1
258 #ifndef STRCMPCASENOSENTIVEFUNCTION
259 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
263 Compare two filename (fileName1,fileName2).
264 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
265 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
267 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
268 (like 1 on Unix, 2 on Windows)
271 extern int ZEXPORT
unzStringFileNameCompare (fileName1
,fileName2
,iCaseSensitivity
)
272 const char* fileName1
;
273 const char* fileName2
;
274 int iCaseSensitivity
;
276 if (iCaseSensitivity
==0)
277 iCaseSensitivity
=CASESENSITIVITYDEFAULTVALUE
;
279 if (iCaseSensitivity
==1)
280 return strcmp(fileName1
,fileName2
);
282 return STRCMPCASENOSENTIVEFUNCTION(fileName1
,fileName2
);
285 #define BUFREADCOMMENT (0x400)
288 Locate the Central directory of a zipfile (at the end, just before
291 local uLong
unzlocal_SearchCentralDir(fin
)
297 uLong uMaxBack
=0xffff; /* maximum size of global comment */
300 if (fseek(fin
,0,SEEK_END
) != 0)
304 uSizeFile
= ftell( fin
);
306 if (uMaxBack
>uSizeFile
)
307 uMaxBack
= uSizeFile
;
309 buf
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4);
314 while (uBackRead
<uMaxBack
)
316 uLong uReadSize
,uReadPos
;
318 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
)
319 uBackRead
= uMaxBack
;
321 uBackRead
+=BUFREADCOMMENT
;
322 uReadPos
= uSizeFile
-uBackRead
;
324 uReadSize
= ((BUFREADCOMMENT
+4) < (uSizeFile
-uReadPos
)) ?
325 (BUFREADCOMMENT
+4) : (uSizeFile
-uReadPos
);
326 if (fseek(fin
,uReadPos
,SEEK_SET
)!=0)
329 if (fread(buf
,(uInt
)uReadSize
,1,fin
)!=1)
332 for (i
=(int)uReadSize
-3; (i
--)>0;)
333 if (((*(buf
+i
))==0x50) && ((*(buf
+i
+1))==0x4b) &&
334 ((*(buf
+i
+2))==0x05) && ((*(buf
+i
+3))==0x06))
336 uPosFound
= uReadPos
+i
;
348 Open a Zip file. path contain the full pathname (by example,
349 on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
351 If the zipfile cannot be opened (file don't exist or in not valid), the
352 return value is NULL.
353 Else, the return value is a unzFile Handle, usable with other function
354 of this unzip package.
356 extern unzFile ZEXPORT
unzOpen (path
)
361 uLong central_pos
,uL
;
364 uLong number_disk
; /* number of the current dist, used for
365 spaning ZIP, unsupported, always 0*/
366 uLong number_disk_with_CD
; /* number the the disk with central dir, used
367 for spaning ZIP, unsupported, always 0*/
368 uLong number_entry_CD
; /* total number of entries in
370 (same than number_entry on nospan) */
374 if (unz_copyright
[0]!=' ')
377 fin
=fopen(path
,"rb");
381 central_pos
= unzlocal_SearchCentralDir(fin
);
385 if (fseek(fin
,central_pos
,SEEK_SET
)!=0)
388 /* the signature, already checked */
389 if (unzlocal_getLong(fin
,&uL
)!=UNZ_OK
)
392 /* number of this disk */
393 if (unzlocal_getShort(fin
,&number_disk
)!=UNZ_OK
)
396 /* number of the disk with the start of the central directory */
397 if (unzlocal_getShort(fin
,&number_disk_with_CD
)!=UNZ_OK
)
400 /* total number of entries in the central dir on this disk */
401 if (unzlocal_getShort(fin
,&us
.gi
.number_entry
)!=UNZ_OK
)
404 /* total number of entries in the central dir */
405 if (unzlocal_getShort(fin
,&number_entry_CD
)!=UNZ_OK
)
408 if ((number_entry_CD
!=us
.gi
.number_entry
) ||
409 (number_disk_with_CD
!=0) ||
413 /* size of the central directory */
414 if (unzlocal_getLong(fin
,&us
.size_central_dir
)!=UNZ_OK
)
417 /* offset of start of central directory with respect to the
418 starting disk number */
419 if (unzlocal_getLong(fin
,&us
.offset_central_dir
)!=UNZ_OK
)
422 /* zipfile comment length */
423 if (unzlocal_getShort(fin
,&us
.gi
.size_comment
)!=UNZ_OK
)
426 if ((central_pos
<us
.offset_central_dir
+us
.size_central_dir
) &&
436 us
.byte_before_the_zipfile
= central_pos
-
437 (us
.offset_central_dir
+us
.size_central_dir
);
438 us
.central_pos
= central_pos
;
439 us
.pfile_in_zip_read
= NULL
;
442 s
=(unz_s
*)ALLOC(sizeof(unz_s
));
444 unzGoToFirstFile((unzFile
)s
);
450 Close a ZipFile opened with unzipOpen.
451 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
452 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
453 return UNZ_OK if there is no problem. */
454 extern int ZEXPORT
unzClose (file
)
459 return UNZ_PARAMERROR
;
462 if (s
->pfile_in_zip_read
!=NULL
)
463 unzCloseCurrentFile(file
);
472 Write info about the ZipFile in the *pglobal_info structure.
473 No preparation of the structure is needed
474 return UNZ_OK if there is no problem. */
475 extern int ZEXPORT
unzGetGlobalInfo (file
,pglobal_info
)
477 unz_global_info
*pglobal_info
;
481 return UNZ_PARAMERROR
;
489 Translate date/time from Dos format to tm_unz (readable more easilty)
491 local
void unzlocal_DosDateToTmuDate (ulDosDate
, ptm
)
496 uDate
= (uLong
)(ulDosDate
>>16);
497 ptm
->tm_mday
= (uInt
)(uDate
&0x1f) ;
498 ptm
->tm_mon
= (uInt
)((((uDate
)&0x1E0)/0x20)-1) ;
499 ptm
->tm_year
= (uInt
)(((uDate
&0x0FE00)/0x0200)+1980) ;
501 ptm
->tm_hour
= (uInt
) ((ulDosDate
&0xF800)/0x800);
502 ptm
->tm_min
= (uInt
) ((ulDosDate
&0x7E0)/0x20) ;
503 ptm
->tm_sec
= (uInt
) (2*(ulDosDate
&0x1f)) ;
507 Get Info about the current file in the zipfile, with internal only info
509 local
int unzlocal_GetCurrentFileInfoInternal
OF((unzFile file
,
510 unz_file_info
*pfile_info
,
511 unz_file_info_internal
512 *pfile_info_internal
,
514 uLong fileNameBufferSize
,
516 uLong extraFieldBufferSize
,
518 uLong commentBufferSize
));
520 local
int unzlocal_GetCurrentFileInfoInternal (file
,
523 szFileName
, fileNameBufferSize
,
524 extraField
, extraFieldBufferSize
,
525 szComment
, commentBufferSize
)
527 unz_file_info
*pfile_info
;
528 unz_file_info_internal
*pfile_info_internal
;
530 uLong fileNameBufferSize
;
532 uLong extraFieldBufferSize
;
534 uLong commentBufferSize
;
537 unz_file_info file_info
;
538 unz_file_info_internal file_info_internal
;
544 return UNZ_PARAMERROR
;
546 if (fseek(s
->file
,s
->pos_in_central_dir
+s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
550 /* we check the magic */
552 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
554 else if (uMagic
!=0x02014b50)
557 if (unzlocal_getShort(s
->file
,&file_info
.version
) != UNZ_OK
)
560 if (unzlocal_getShort(s
->file
,&file_info
.version_needed
) != UNZ_OK
)
563 if (unzlocal_getShort(s
->file
,&file_info
.flag
) != UNZ_OK
)
566 if (unzlocal_getShort(s
->file
,&file_info
.compression_method
) != UNZ_OK
)
569 if (unzlocal_getLong(s
->file
,&file_info
.dosDate
) != UNZ_OK
)
572 unzlocal_DosDateToTmuDate(file_info
.dosDate
,&file_info
.tmu_date
);
574 if (unzlocal_getLong(s
->file
,&file_info
.crc
) != UNZ_OK
)
577 if (unzlocal_getLong(s
->file
,&file_info
.compressed_size
) != UNZ_OK
)
580 if (unzlocal_getLong(s
->file
,&file_info
.uncompressed_size
) != UNZ_OK
)
583 if (unzlocal_getShort(s
->file
,&file_info
.size_filename
) != UNZ_OK
)
586 if (unzlocal_getShort(s
->file
,&file_info
.size_file_extra
) != UNZ_OK
)
589 if (unzlocal_getShort(s
->file
,&file_info
.size_file_comment
) != UNZ_OK
)
592 if (unzlocal_getShort(s
->file
,&file_info
.disk_num_start
) != UNZ_OK
)
595 if (unzlocal_getShort(s
->file
,&file_info
.internal_fa
) != UNZ_OK
)
598 if (unzlocal_getLong(s
->file
,&file_info
.external_fa
) != UNZ_OK
)
601 if (unzlocal_getLong(s
->file
,&file_info_internal
.offset_curfile
) != UNZ_OK
)
604 lSeek
+=file_info
.size_filename
;
605 if ((err
==UNZ_OK
) && (szFileName
!=NULL
))
608 if (file_info
.size_filename
<fileNameBufferSize
)
610 *(szFileName
+file_info
.size_filename
)='\0';
611 uSizeRead
= file_info
.size_filename
;
614 uSizeRead
= fileNameBufferSize
;
616 if ((file_info
.size_filename
>0) && (fileNameBufferSize
>0))
617 if (fread(szFileName
,(uInt
)uSizeRead
,1,s
->file
)!=1)
623 if ((err
==UNZ_OK
) && (extraField
!=NULL
))
626 if (file_info
.size_file_extra
<extraFieldBufferSize
)
627 uSizeRead
= file_info
.size_file_extra
;
629 uSizeRead
= extraFieldBufferSize
;
632 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
636 if ((file_info
.size_file_extra
>0) && (extraFieldBufferSize
>0))
637 if (fread(extraField
,(uInt
)uSizeRead
,1,s
->file
)!=1)
639 lSeek
+= file_info
.size_file_extra
- uSizeRead
;
642 lSeek
+=file_info
.size_file_extra
;
645 if ((err
==UNZ_OK
) && (szComment
!=NULL
))
648 if (file_info
.size_file_comment
<commentBufferSize
)
650 *(szComment
+file_info
.size_file_comment
)='\0';
651 uSizeRead
= file_info
.size_file_comment
;
654 uSizeRead
= commentBufferSize
;
657 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
661 if ((file_info
.size_file_comment
>0) && (commentBufferSize
>0))
662 if (fread(szComment
,(uInt
)uSizeRead
,1,s
->file
)!=1)
664 lSeek
+=file_info
.size_file_comment
- uSizeRead
;
667 lSeek
+=file_info
.size_file_comment
;
669 if ((err
==UNZ_OK
) && (pfile_info
!=NULL
))
670 *pfile_info
=file_info
;
672 if ((err
==UNZ_OK
) && (pfile_info_internal
!=NULL
))
673 *pfile_info_internal
=file_info_internal
;
681 Write info about the ZipFile in the *pglobal_info structure.
682 No preparation of the structure is needed
683 return UNZ_OK if there is no problem.
685 extern int ZEXPORT
unzGetCurrentFileInfo (file
,
687 szFileName
, fileNameBufferSize
,
688 extraField
, extraFieldBufferSize
,
689 szComment
, commentBufferSize
)
691 unz_file_info
*pfile_info
;
693 uLong fileNameBufferSize
;
695 uLong extraFieldBufferSize
;
697 uLong commentBufferSize
;
699 return unzlocal_GetCurrentFileInfoInternal(file
,pfile_info
,NULL
,
700 szFileName
,fileNameBufferSize
,
701 extraField
,extraFieldBufferSize
,
702 szComment
,commentBufferSize
);
706 Set the current file of the zipfile to the first file.
707 return UNZ_OK if there is no problem
709 extern int ZEXPORT
unzGoToFirstFile (file
)
715 return UNZ_PARAMERROR
;
717 s
->pos_in_central_dir
=s
->offset_central_dir
;
719 err
=unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
720 &s
->cur_file_info_internal
,
721 NULL
,0,NULL
,0,NULL
,0);
722 s
->current_file_ok
= (err
== UNZ_OK
);
728 Set the current file of the zipfile to the next file.
729 return UNZ_OK if there is no problem
730 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
732 extern int ZEXPORT
unzGoToNextFile (file
)
739 return UNZ_PARAMERROR
;
741 if (!s
->current_file_ok
)
742 return UNZ_END_OF_LIST_OF_FILE
;
743 if (s
->num_file
+1==s
->gi
.number_entry
)
744 return UNZ_END_OF_LIST_OF_FILE
;
746 s
->pos_in_central_dir
+= SIZECENTRALDIRITEM
+ s
->cur_file_info
.size_filename
+
747 s
->cur_file_info
.size_file_extra
+ s
->cur_file_info
.size_file_comment
;
749 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
750 &s
->cur_file_info_internal
,
751 NULL
,0,NULL
,0,NULL
,0);
752 s
->current_file_ok
= (err
== UNZ_OK
);
758 Try locate the file szFileName in the zipfile.
759 For the iCaseSensitivity signification, see unzipStringFileNameCompare
762 UNZ_OK if the file is found. It becomes the current file.
763 UNZ_END_OF_LIST_OF_FILE if the file is not found
765 extern int ZEXPORT
unzLocateFile (file
, szFileName
, iCaseSensitivity
)
767 const char *szFileName
;
768 int iCaseSensitivity
;
775 uLong pos_in_central_dirSaved
;
779 return UNZ_PARAMERROR
;
781 if (strlen(szFileName
)>=UNZ_MAXFILENAMEINZIP
)
782 return UNZ_PARAMERROR
;
785 if (!s
->current_file_ok
)
786 return UNZ_END_OF_LIST_OF_FILE
;
788 num_fileSaved
= s
->num_file
;
789 pos_in_central_dirSaved
= s
->pos_in_central_dir
;
791 err
= unzGoToFirstFile(file
);
793 while (err
== UNZ_OK
)
795 char szCurrentFileName
[UNZ_MAXFILENAMEINZIP
+1];
796 unzGetCurrentFileInfo(file
,NULL
,
797 szCurrentFileName
,sizeof(szCurrentFileName
)-1,
799 if (unzStringFileNameCompare(szCurrentFileName
,
800 szFileName
,iCaseSensitivity
)==0)
802 err
= unzGoToNextFile(file
);
805 s
->num_file
= num_fileSaved
;
806 s
->pos_in_central_dir
= pos_in_central_dirSaved
;
812 Read the local header of the current zipfile
813 Check the coherency of the local header and info in the end of central
814 directory about this file
815 store in *piSizeVar the size of extra info in local header
816 (filename and size of extra field data)
818 local
int unzlocal_CheckCurrentFileCoherencyHeader (s
,piSizeVar
,
819 poffset_local_extrafield
,
820 psize_local_extrafield
)
823 uLong
*poffset_local_extrafield
;
824 uInt
*psize_local_extrafield
;
826 uLong uMagic
,uData
,uFlags
;
828 uLong size_extra_field
;
832 *poffset_local_extrafield
= 0;
833 *psize_local_extrafield
= 0;
835 if (fseek(s
->file
,s
->cur_file_info_internal
.offset_curfile
+
836 s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
841 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
843 else if (uMagic
!=0x04034b50)
846 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
849 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
852 if (unzlocal_getShort(s
->file
,&uFlags
) != UNZ_OK
)
855 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
857 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compression_method
))
860 if ((err
==UNZ_OK
) && (s
->cur_file_info
.compression_method
!=0) &&
861 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
864 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* date/time */
867 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* crc */
869 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.crc
) &&
873 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size compr */
875 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compressed_size
) &&
879 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size uncompr */
881 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.uncompressed_size
) &&
886 if (unzlocal_getShort(s
->file
,&size_filename
) != UNZ_OK
)
888 else if ((err
==UNZ_OK
) && (size_filename
!=s
->cur_file_info
.size_filename
))
891 *piSizeVar
+= (uInt
)size_filename
;
893 if (unzlocal_getShort(s
->file
,&size_extra_field
) != UNZ_OK
)
895 *poffset_local_extrafield
= s
->cur_file_info_internal
.offset_curfile
+
896 SIZEZIPLOCALHEADER
+ size_filename
;
897 *psize_local_extrafield
= (uInt
)size_extra_field
;
899 *piSizeVar
+= (uInt
)size_extra_field
;
905 Open for reading data the current file in the zipfile.
906 If there is no error and the file is opened, the return value is UNZ_OK.
908 extern int ZEXPORT
unzOpenCurrentFile (file
)
915 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
916 uLong offset_local_extrafield
; /* offset of the local extra field */
917 uInt size_local_extrafield
; /* size of the local extra field */
920 return UNZ_PARAMERROR
;
922 if (!s
->current_file_ok
)
923 return UNZ_PARAMERROR
;
925 if (s
->pfile_in_zip_read
!= NULL
)
926 unzCloseCurrentFile(file
);
928 if (unzlocal_CheckCurrentFileCoherencyHeader(s
,&iSizeVar
,
929 &offset_local_extrafield
,&size_local_extrafield
)!=UNZ_OK
)
930 return UNZ_BADZIPFILE
;
932 pfile_in_zip_read_info
= (file_in_zip_read_info_s
*)
933 ALLOC(sizeof(file_in_zip_read_info_s
));
934 if (pfile_in_zip_read_info
==NULL
)
935 return UNZ_INTERNALERROR
;
937 pfile_in_zip_read_info
->read_buffer
=(char*)ALLOC(UNZ_BUFSIZE
);
938 pfile_in_zip_read_info
->offset_local_extrafield
= offset_local_extrafield
;
939 pfile_in_zip_read_info
->size_local_extrafield
= size_local_extrafield
;
940 pfile_in_zip_read_info
->pos_local_extrafield
=0;
942 if (pfile_in_zip_read_info
->read_buffer
==NULL
)
944 TRYFREE(pfile_in_zip_read_info
);
945 return UNZ_INTERNALERROR
;
948 pfile_in_zip_read_info
->stream_initialised
=0;
950 if ((s
->cur_file_info
.compression_method
!=0) &&
951 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
953 Store
= s
->cur_file_info
.compression_method
==0;
955 pfile_in_zip_read_info
->crc32_wait
=s
->cur_file_info
.crc
;
956 pfile_in_zip_read_info
->crc32
=0;
957 pfile_in_zip_read_info
->compression_method
=
958 s
->cur_file_info
.compression_method
;
959 pfile_in_zip_read_info
->file
=s
->file
;
960 pfile_in_zip_read_info
->byte_before_the_zipfile
=s
->byte_before_the_zipfile
;
962 pfile_in_zip_read_info
->stream
.total_out
= 0;
966 pfile_in_zip_read_info
->stream
.zalloc
= (alloc_func
)0;
967 pfile_in_zip_read_info
->stream
.zfree
= (free_func
)0;
968 pfile_in_zip_read_info
->stream
.opaque
= (voidpf
)0;
970 err
=inflateInit2(&pfile_in_zip_read_info
->stream
, -MAX_WBITS
);
972 pfile_in_zip_read_info
->stream_initialised
=1;
973 /* windowBits is passed < 0 to tell that there is no zlib header.
974 * Note that in this case inflate *requires* an extra "dummy" byte
975 * after the compressed stream in order to complete decompression and
976 * return Z_STREAM_END.
977 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
978 * size of both compressed and uncompressed data
981 pfile_in_zip_read_info
->rest_read_compressed
=
982 s
->cur_file_info
.compressed_size
;
983 pfile_in_zip_read_info
->rest_read_uncompressed
=
984 s
->cur_file_info
.uncompressed_size
;
987 pfile_in_zip_read_info
->pos_in_zipfile
=
988 s
->cur_file_info_internal
.offset_curfile
+ SIZEZIPLOCALHEADER
+
991 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)0;
994 s
->pfile_in_zip_read
= pfile_in_zip_read_info
;
1000 Read bytes from the current file.
1001 buf contain buffer where data must be copied
1002 len the size of buf.
1004 return the number of byte copied if somes bytes are copied
1005 return 0 if the end of file was reached
1006 return <0 with error code if there is an error
1007 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1009 extern int ZEXPORT
unzReadCurrentFile (file
, buf
, len
)
1017 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1019 return UNZ_PARAMERROR
;
1021 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1023 if (pfile_in_zip_read_info
==NULL
)
1024 return UNZ_PARAMERROR
;
1027 if ((pfile_in_zip_read_info
->read_buffer
== NULL
))
1028 return UNZ_END_OF_LIST_OF_FILE
;
1032 pfile_in_zip_read_info
->stream
.next_out
= (Bytef
*)buf
;
1034 pfile_in_zip_read_info
->stream
.avail_out
= (uInt
)len
;
1036 if (len
>pfile_in_zip_read_info
->rest_read_uncompressed
)
1037 pfile_in_zip_read_info
->stream
.avail_out
=
1038 (uInt
)pfile_in_zip_read_info
->rest_read_uncompressed
;
1040 while (pfile_in_zip_read_info
->stream
.avail_out
>0)
1042 if ((pfile_in_zip_read_info
->stream
.avail_in
==0) &&
1043 (pfile_in_zip_read_info
->rest_read_compressed
>0))
1045 uInt uReadThis
= UNZ_BUFSIZE
;
1046 if (pfile_in_zip_read_info
->rest_read_compressed
<uReadThis
)
1047 uReadThis
= (uInt
)pfile_in_zip_read_info
->rest_read_compressed
;
1050 if (fseek(pfile_in_zip_read_info
->file
,
1051 pfile_in_zip_read_info
->pos_in_zipfile
+
1052 pfile_in_zip_read_info
->byte_before_the_zipfile
,SEEK_SET
)!=0)
1054 if (fread(pfile_in_zip_read_info
->read_buffer
,uReadThis
,1,
1055 pfile_in_zip_read_info
->file
)!=1)
1057 pfile_in_zip_read_info
->pos_in_zipfile
+= uReadThis
;
1059 pfile_in_zip_read_info
->rest_read_compressed
-=uReadThis
;
1061 pfile_in_zip_read_info
->stream
.next_in
=
1062 (Bytef
*)pfile_in_zip_read_info
->read_buffer
;
1063 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)uReadThis
;
1066 if (pfile_in_zip_read_info
->compression_method
==0)
1069 if (pfile_in_zip_read_info
->stream
.avail_out
<
1070 pfile_in_zip_read_info
->stream
.avail_in
)
1071 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_out
;
1073 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_in
;
1075 for (i
=0;i
<uDoCopy
;i
++)
1076 *(pfile_in_zip_read_info
->stream
.next_out
+i
) =
1077 *(pfile_in_zip_read_info
->stream
.next_in
+i
);
1079 pfile_in_zip_read_info
->crc32
= crc32(pfile_in_zip_read_info
->crc32
,
1080 pfile_in_zip_read_info
->stream
.next_out
,
1082 pfile_in_zip_read_info
->rest_read_uncompressed
-=uDoCopy
;
1083 pfile_in_zip_read_info
->stream
.avail_in
-= uDoCopy
;
1084 pfile_in_zip_read_info
->stream
.avail_out
-= uDoCopy
;
1085 pfile_in_zip_read_info
->stream
.next_out
+= uDoCopy
;
1086 pfile_in_zip_read_info
->stream
.next_in
+= uDoCopy
;
1087 pfile_in_zip_read_info
->stream
.total_out
+= uDoCopy
;
1092 uLong uTotalOutBefore
,uTotalOutAfter
;
1093 const Bytef
*bufBefore
;
1095 int flush
=Z_SYNC_FLUSH
;
1097 uTotalOutBefore
= pfile_in_zip_read_info
->stream
.total_out
;
1098 bufBefore
= pfile_in_zip_read_info
->stream
.next_out
;
1101 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1102 pfile_in_zip_read_info->stream.avail_out) &&
1103 (pfile_in_zip_read_info->rest_read_compressed == 0))
1106 err
=inflate(&pfile_in_zip_read_info
->stream
,flush
);
1108 uTotalOutAfter
= pfile_in_zip_read_info
->stream
.total_out
;
1109 uOutThis
= uTotalOutAfter
-uTotalOutBefore
;
1111 pfile_in_zip_read_info
->crc32
=
1112 crc32(pfile_in_zip_read_info
->crc32
,bufBefore
,
1115 pfile_in_zip_read_info
->rest_read_uncompressed
-=
1118 iRead
+= (uInt
)(uTotalOutAfter
- uTotalOutBefore
);
1120 if (err
==Z_STREAM_END
)
1121 return (iRead
==0) ? UNZ_EOF
: iRead
;
1134 Give the current position in uncompressed data
1136 extern z_off_t ZEXPORT
unztell (file
)
1140 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1142 return UNZ_PARAMERROR
;
1144 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1146 if (pfile_in_zip_read_info
==NULL
)
1147 return UNZ_PARAMERROR
;
1149 return (z_off_t
)pfile_in_zip_read_info
->stream
.total_out
;
1154 return 1 if the end of file was reached, 0 elsewhere
1156 extern int ZEXPORT
unzeof (file
)
1160 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1162 return UNZ_PARAMERROR
;
1164 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1166 if (pfile_in_zip_read_info
==NULL
)
1167 return UNZ_PARAMERROR
;
1169 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1178 Read extra field from the current file (opened by unzOpenCurrentFile)
1179 This is the local-header version of the extra field (sometimes, there is
1180 more info in the local-header version than in the central-header)
1182 if buf==NULL, it return the size of the local extra field that can be read
1184 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1186 the return value is the number of bytes copied in buf, or (if <0)
1189 extern int ZEXPORT
unzGetLocalExtrafield (file
,buf
,len
)
1195 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1200 return UNZ_PARAMERROR
;
1202 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1204 if (pfile_in_zip_read_info
==NULL
)
1205 return UNZ_PARAMERROR
;
1207 size_to_read
= (pfile_in_zip_read_info
->size_local_extrafield
-
1208 pfile_in_zip_read_info
->pos_local_extrafield
);
1211 return (int)size_to_read
;
1213 if (len
>size_to_read
)
1214 read_now
= (uInt
)size_to_read
;
1216 read_now
= (uInt
)len
;
1221 if (fseek(pfile_in_zip_read_info
->file
,
1222 pfile_in_zip_read_info
->offset_local_extrafield
+
1223 pfile_in_zip_read_info
->pos_local_extrafield
,SEEK_SET
)!=0)
1226 if (fread(buf
,(uInt
)size_to_read
,1,pfile_in_zip_read_info
->file
)!=1)
1229 return (int)read_now
;
1233 Close the file in zip opened with unzipOpenCurrentFile
1234 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1236 extern int ZEXPORT
unzCloseCurrentFile (file
)
1242 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1244 return UNZ_PARAMERROR
;
1246 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1248 if (pfile_in_zip_read_info
==NULL
)
1249 return UNZ_PARAMERROR
;
1252 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1254 if (pfile_in_zip_read_info
->crc32
!= pfile_in_zip_read_info
->crc32_wait
)
1259 TRYFREE(pfile_in_zip_read_info
->read_buffer
);
1260 pfile_in_zip_read_info
->read_buffer
= NULL
;
1261 if (pfile_in_zip_read_info
->stream_initialised
)
1262 inflateEnd(&pfile_in_zip_read_info
->stream
);
1264 pfile_in_zip_read_info
->stream_initialised
= 0;
1265 TRYFREE(pfile_in_zip_read_info
);
1267 s
->pfile_in_zip_read
=NULL
;
1274 Get the global comment string of the ZipFile, in the szComment buffer.
1275 uSizeBuf is the size of the szComment buffer.
1276 return the number of byte copied or an error code <0
1278 extern int ZEXPORT
unzGetGlobalComment (file
, szComment
, uSizeBuf
)
1287 return UNZ_PARAMERROR
;
1290 uReadThis
= uSizeBuf
;
1291 if (uReadThis
>s
->gi
.size_comment
)
1292 uReadThis
= s
->gi
.size_comment
;
1294 if (fseek(s
->file
,s
->central_pos
+22,SEEK_SET
)!=0)
1300 if (fread(szComment
,(uInt
)uReadThis
,1,s
->file
)!=1)
1304 if ((szComment
!= NULL
) && (uSizeBuf
> s
->gi
.size_comment
))
1305 *(szComment
+s
->gi
.size_comment
)='\0';
1306 return (int)uReadThis
;
1311 // the file shouldn't be empty, som compilers don't like it
1312 static const int dummyVariableInUnzip
= 17;
1314 #endif // wxUSE_ZLIB && wxUSE_ZIPSTREAM