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 #if !defined(__VISAGECPP__)
8 # pragma warning(disable:4001) /* non standard extension used: single line comment */
12 #if wxUSE_ZLIB && wxUSE_ZIPSTREAM
19 /* Not the right solution (paths in makefiles) but... */
21 #include "../common/unzip.h"
41 /* compile with -Dlocal if your debugger can't find static symbols */
45 #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
46 !defined(CASESENSITIVITYDEFAULT_NO)
47 #define CASESENSITIVITYDEFAULT_NO
52 #define UNZ_BUFSIZE (16384)
55 #ifndef UNZ_MAXFILENAMEINZIP
56 #define UNZ_MAXFILENAMEINZIP (256)
60 # define ALLOC(size) (malloc(size))
63 # define TRYFREE(p) {if (p) free(p);}
66 #define SIZECENTRALDIRITEM (0x2e)
67 #define SIZEZIPLOCALHEADER (0x1e)
70 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
84 const char unz_copyright
[] =
85 " unzip 0.15 Copyright 1998 Gilles Vollant ";
87 /* unz_file_info_interntal contain internal info about a file in zipfile*/
88 typedef struct unz_file_info_internal_s
90 uLong offset_curfile
;/* relative offset of local header 4 bytes */
91 } unz_file_info_internal
;
94 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
95 when reading and decompress it */
98 char *read_buffer
; /* internal buffer for compressed data */
99 z_stream stream
; /* zLib stream structure for inflate */
101 uLong pos_in_zipfile
; /* position in byte on the zipfile, for fseek*/
102 uLong stream_initialised
; /* flag set if stream structure is initialised*/
104 uLong offset_local_extrafield
;/* offset of the local extra field */
105 uInt size_local_extrafield
;/* size of the local extra field */
106 uLong pos_local_extrafield
; /* position in the local extra field in read*/
108 uLong crc32
; /* crc32 of all data uncompressed */
109 uLong crc32_wait
; /* crc32 we must obtain after decompress all */
110 uLong rest_read_compressed
; /* number of byte to be decompressed */
111 uLong rest_read_uncompressed
;/*number of byte to be obtained after decomp*/
112 FILE* file
; /* io structore of the zipfile */
113 uLong compression_method
; /* compression method (0==store) */
114 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
115 } file_in_zip_read_info_s
;
118 /* unz_s contain internal information about the zipfile
122 FILE* file
; /* io structore of the zipfile */
123 unz_global_info gi
; /* public global information */
124 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
125 uLong num_file
; /* number of the current file in the zipfile*/
126 uLong pos_in_central_dir
; /* pos of the current file in the central dir*/
127 uLong current_file_ok
; /* flag about the usability of the current file*/
128 uLong central_pos
; /* position of the beginning of the central dir*/
130 uLong size_central_dir
; /* size of the central directory */
131 uLong offset_central_dir
; /* offset of start of central directory with
132 respect to the starting disk number */
134 unz_file_info cur_file_info
; /* public info about the current file in zip*/
135 unz_file_info_internal cur_file_info_internal
; /* private info about it*/
136 file_in_zip_read_info_s
* pfile_in_zip_read
; /* structure about the current
137 file if we are decompressing it */
140 #if defined (__VISAGECPP__)
141 /* VA always requires prototypes */
142 int unzlocal_CheckCurrentFileCoherencyHeader (unz_s
*, uInt
*, uLong
*, uInt
*);
145 /* ===========================================================================
146 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
148 IN assertion: the stream s has been sucessfully opened for reading.
152 local
int unzlocal_getByte(fin
,pi
)
157 int err
= fread(&c
, 1, 1, fin
);
173 /* ===========================================================================
174 Reads a long in LSB order from the given gz_stream. Sets
176 local
int unzlocal_getShort (fin
,pX
)
184 err
= unzlocal_getByte(fin
,&i
);
188 err
= unzlocal_getByte(fin
,&i
);
198 local
int unzlocal_getLong (fin
,pX
)
206 err
= unzlocal_getByte(fin
,&i
);
210 err
= unzlocal_getByte(fin
,&i
);
214 err
= unzlocal_getByte(fin
,&i
);
218 err
= unzlocal_getByte(fin
,&i
);
229 /* My own strcmpi / strcasecmp */
230 local
int strcmpcasenosensitive_internal (fileName1
,fileName2
)
231 const char* fileName1
;
232 const char* fileName2
;
236 char c1
=*(fileName1
++);
237 char c2
=*(fileName2
++);
238 if ((c1
>='a') && (c1
<='z'))
240 if ((c2
>='a') && (c2
<='z'))
243 return ((c2
=='\0') ? 0 : -1);
254 #ifdef CASESENSITIVITYDEFAULT_NO
255 #define CASESENSITIVITYDEFAULTVALUE 2
257 #define CASESENSITIVITYDEFAULTVALUE 1
260 #ifndef STRCMPCASENOSENTIVEFUNCTION
261 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
265 Compare two filename (fileName1,fileName2).
266 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
267 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
269 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
270 (like 1 on Unix, 2 on Windows)
273 extern int ZEXPORT
unzStringFileNameCompare (fileName1
,fileName2
,iCaseSensitivity
)
274 const char* fileName1
;
275 const char* fileName2
;
276 int iCaseSensitivity
;
278 if (iCaseSensitivity
==0)
279 iCaseSensitivity
=CASESENSITIVITYDEFAULTVALUE
;
281 if (iCaseSensitivity
==1)
282 return strcmp(fileName1
,fileName2
);
284 return STRCMPCASENOSENTIVEFUNCTION(fileName1
,fileName2
);
287 #define BUFREADCOMMENT (0x400)
290 Locate the Central directory of a zipfile (at the end, just before
293 local uLong
unzlocal_SearchCentralDir(fin
)
299 uLong uMaxBack
=0xffff; /* maximum size of global comment */
302 if (fseek(fin
,0,SEEK_END
) != 0)
306 uSizeFile
= ftell( fin
);
308 if (uMaxBack
>uSizeFile
)
309 uMaxBack
= uSizeFile
;
311 buf
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4);
316 while (uBackRead
<uMaxBack
)
318 uLong uReadSize
,uReadPos
;
320 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
)
321 uBackRead
= uMaxBack
;
323 uBackRead
+=BUFREADCOMMENT
;
324 uReadPos
= uSizeFile
-uBackRead
;
326 uReadSize
= ((BUFREADCOMMENT
+4) < (uSizeFile
-uReadPos
)) ?
327 (BUFREADCOMMENT
+4) : (uSizeFile
-uReadPos
);
328 if (fseek(fin
,uReadPos
,SEEK_SET
)!=0)
331 if (fread(buf
,(uInt
)uReadSize
,1,fin
)!=1)
334 for (i
=(int)uReadSize
-3; (i
--)>0;)
335 if (((*(buf
+i
))==0x50) && ((*(buf
+i
+1))==0x4b) &&
336 ((*(buf
+i
+2))==0x05) && ((*(buf
+i
+3))==0x06))
338 uPosFound
= uReadPos
+i
;
350 Open a Zip file. path contain the full pathname (by example,
351 on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
353 If the zipfile cannot be opened (file don't exist or in not valid), the
354 return value is NULL.
355 Else, the return value is a unzFile Handle, usable with other function
356 of this unzip package.
358 extern unzFile ZEXPORT
unzOpen (path
)
363 uLong central_pos
,uL
;
366 uLong number_disk
; /* number of the current dist, used for
367 spaning ZIP, unsupported, always 0*/
368 uLong number_disk_with_CD
; /* number the the disk with central dir, used
369 for spaning ZIP, unsupported, always 0*/
370 uLong number_entry_CD
; /* total number of entries in
372 (same than number_entry on nospan) */
376 if (unz_copyright
[0]!=' ')
379 fin
=fopen(path
,"rb");
383 central_pos
= unzlocal_SearchCentralDir(fin
);
387 if (fseek(fin
,central_pos
,SEEK_SET
)!=0)
390 /* the signature, already checked */
391 if (unzlocal_getLong(fin
,&uL
)!=UNZ_OK
)
394 /* number of this disk */
395 if (unzlocal_getShort(fin
,&number_disk
)!=UNZ_OK
)
398 /* number of the disk with the start of the central directory */
399 if (unzlocal_getShort(fin
,&number_disk_with_CD
)!=UNZ_OK
)
402 /* total number of entries in the central dir on this disk */
403 if (unzlocal_getShort(fin
,&us
.gi
.number_entry
)!=UNZ_OK
)
406 /* total number of entries in the central dir */
407 if (unzlocal_getShort(fin
,&number_entry_CD
)!=UNZ_OK
)
410 if ((number_entry_CD
!=us
.gi
.number_entry
) ||
411 (number_disk_with_CD
!=0) ||
415 /* size of the central directory */
416 if (unzlocal_getLong(fin
,&us
.size_central_dir
)!=UNZ_OK
)
419 /* offset of start of central directory with respect to the
420 starting disk number */
421 if (unzlocal_getLong(fin
,&us
.offset_central_dir
)!=UNZ_OK
)
424 /* zipfile comment length */
425 if (unzlocal_getShort(fin
,&us
.gi
.size_comment
)!=UNZ_OK
)
428 if ((central_pos
<us
.offset_central_dir
+us
.size_central_dir
) &&
438 us
.byte_before_the_zipfile
= central_pos
-
439 (us
.offset_central_dir
+us
.size_central_dir
);
440 us
.central_pos
= central_pos
;
441 us
.pfile_in_zip_read
= NULL
;
444 s
=(unz_s
*)ALLOC(sizeof(unz_s
));
446 unzGoToFirstFile((unzFile
)s
);
452 Close a ZipFile opened with unzipOpen.
453 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
454 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
455 return UNZ_OK if there is no problem. */
456 extern int ZEXPORT
unzClose (file
)
461 return UNZ_PARAMERROR
;
464 if (s
->pfile_in_zip_read
!=NULL
)
465 unzCloseCurrentFile(file
);
474 Write info about the ZipFile in the *pglobal_info structure.
475 No preparation of the structure is needed
476 return UNZ_OK if there is no problem. */
477 extern int ZEXPORT
unzGetGlobalInfo (file
,pglobal_info
)
479 unz_global_info
*pglobal_info
;
483 return UNZ_PARAMERROR
;
491 Translate date/time from Dos format to tm_unz (readable more easilty)
493 local
void unzlocal_DosDateToTmuDate (ulDosDate
, ptm
)
498 uDate
= (uLong
)(ulDosDate
>>16);
499 ptm
->tm_mday
= (uInt
)(uDate
&0x1f) ;
500 ptm
->tm_mon
= (uInt
)((((uDate
)&0x1E0)/0x20)-1) ;
501 ptm
->tm_year
= (uInt
)(((uDate
&0x0FE00)/0x0200)+1980) ;
503 ptm
->tm_hour
= (uInt
) ((ulDosDate
&0xF800)/0x800);
504 ptm
->tm_min
= (uInt
) ((ulDosDate
&0x7E0)/0x20) ;
505 ptm
->tm_sec
= (uInt
) (2*(ulDosDate
&0x1f)) ;
509 Get Info about the current file in the zipfile, with internal only info
511 local
int unzlocal_GetCurrentFileInfoInternal
OF((unzFile file
,
512 unz_file_info
*pfile_info
,
513 unz_file_info_internal
514 *pfile_info_internal
,
516 uLong fileNameBufferSize
,
518 uLong extraFieldBufferSize
,
520 uLong commentBufferSize
));
522 local
int unzlocal_GetCurrentFileInfoInternal (file
,
525 szFileName
, fileNameBufferSize
,
526 extraField
, extraFieldBufferSize
,
527 szComment
, commentBufferSize
)
529 unz_file_info
*pfile_info
;
530 unz_file_info_internal
*pfile_info_internal
;
532 uLong fileNameBufferSize
;
534 uLong extraFieldBufferSize
;
536 uLong commentBufferSize
;
539 unz_file_info file_info
;
540 unz_file_info_internal file_info_internal
;
546 return UNZ_PARAMERROR
;
548 if (fseek(s
->file
,s
->pos_in_central_dir
+s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
552 /* we check the magic */
554 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
556 else if (uMagic
!=0x02014b50)
559 if (unzlocal_getShort(s
->file
,&file_info
.version
) != UNZ_OK
)
562 if (unzlocal_getShort(s
->file
,&file_info
.version_needed
) != UNZ_OK
)
565 if (unzlocal_getShort(s
->file
,&file_info
.flag
) != UNZ_OK
)
568 if (unzlocal_getShort(s
->file
,&file_info
.compression_method
) != UNZ_OK
)
571 if (unzlocal_getLong(s
->file
,&file_info
.dosDate
) != UNZ_OK
)
574 unzlocal_DosDateToTmuDate(file_info
.dosDate
,&file_info
.tmu_date
);
576 if (unzlocal_getLong(s
->file
,&file_info
.crc
) != UNZ_OK
)
579 if (unzlocal_getLong(s
->file
,&file_info
.compressed_size
) != UNZ_OK
)
582 if (unzlocal_getLong(s
->file
,&file_info
.uncompressed_size
) != UNZ_OK
)
585 if (unzlocal_getShort(s
->file
,&file_info
.size_filename
) != UNZ_OK
)
588 if (unzlocal_getShort(s
->file
,&file_info
.size_file_extra
) != UNZ_OK
)
591 if (unzlocal_getShort(s
->file
,&file_info
.size_file_comment
) != UNZ_OK
)
594 if (unzlocal_getShort(s
->file
,&file_info
.disk_num_start
) != UNZ_OK
)
597 if (unzlocal_getShort(s
->file
,&file_info
.internal_fa
) != UNZ_OK
)
600 if (unzlocal_getLong(s
->file
,&file_info
.external_fa
) != UNZ_OK
)
603 if (unzlocal_getLong(s
->file
,&file_info_internal
.offset_curfile
) != UNZ_OK
)
606 lSeek
+=file_info
.size_filename
;
607 if ((err
==UNZ_OK
) && (szFileName
!=NULL
))
610 if (file_info
.size_filename
<fileNameBufferSize
)
612 *(szFileName
+file_info
.size_filename
)='\0';
613 uSizeRead
= file_info
.size_filename
;
616 uSizeRead
= fileNameBufferSize
;
618 if ((file_info
.size_filename
>0) && (fileNameBufferSize
>0))
619 if (fread(szFileName
,(uInt
)uSizeRead
,1,s
->file
)!=1)
625 if ((err
==UNZ_OK
) && (extraField
!=NULL
))
628 if (file_info
.size_file_extra
<extraFieldBufferSize
)
629 uSizeRead
= file_info
.size_file_extra
;
631 uSizeRead
= extraFieldBufferSize
;
634 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
638 if ((file_info
.size_file_extra
>0) && (extraFieldBufferSize
>0))
639 if (fread(extraField
,(uInt
)uSizeRead
,1,s
->file
)!=1)
641 lSeek
+= file_info
.size_file_extra
- uSizeRead
;
644 lSeek
+=file_info
.size_file_extra
;
647 if ((err
==UNZ_OK
) && (szComment
!=NULL
))
650 if (file_info
.size_file_comment
<commentBufferSize
)
652 *(szComment
+file_info
.size_file_comment
)='\0';
653 uSizeRead
= file_info
.size_file_comment
;
656 uSizeRead
= commentBufferSize
;
659 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
663 if ((file_info
.size_file_comment
>0) && (commentBufferSize
>0))
664 if (fread(szComment
,(uInt
)uSizeRead
,1,s
->file
)!=1)
666 lSeek
+=file_info
.size_file_comment
- uSizeRead
;
669 lSeek
+=file_info
.size_file_comment
;
671 if ((err
==UNZ_OK
) && (pfile_info
!=NULL
))
672 *pfile_info
=file_info
;
674 if ((err
==UNZ_OK
) && (pfile_info_internal
!=NULL
))
675 *pfile_info_internal
=file_info_internal
;
683 Write info about the ZipFile in the *pglobal_info structure.
684 No preparation of the structure is needed
685 return UNZ_OK if there is no problem.
687 extern int ZEXPORT
unzGetCurrentFileInfo (file
,
689 szFileName
, fileNameBufferSize
,
690 extraField
, extraFieldBufferSize
,
691 szComment
, commentBufferSize
)
693 unz_file_info
*pfile_info
;
695 uLong fileNameBufferSize
;
697 uLong extraFieldBufferSize
;
699 uLong commentBufferSize
;
701 return unzlocal_GetCurrentFileInfoInternal(file
,pfile_info
,NULL
,
702 szFileName
,fileNameBufferSize
,
703 extraField
,extraFieldBufferSize
,
704 szComment
,commentBufferSize
);
708 Set the current file of the zipfile to the first file.
709 return UNZ_OK if there is no problem
711 extern int ZEXPORT
unzGoToFirstFile (file
)
717 return UNZ_PARAMERROR
;
719 s
->pos_in_central_dir
=s
->offset_central_dir
;
721 err
=unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
722 &s
->cur_file_info_internal
,
723 NULL
,0,NULL
,0,NULL
,0);
724 s
->current_file_ok
= (err
== UNZ_OK
);
730 Set the current file of the zipfile to the next file.
731 return UNZ_OK if there is no problem
732 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
734 extern int ZEXPORT
unzGoToNextFile (file
)
741 return UNZ_PARAMERROR
;
743 if (!s
->current_file_ok
)
744 return UNZ_END_OF_LIST_OF_FILE
;
745 if (s
->num_file
+1==s
->gi
.number_entry
)
746 return UNZ_END_OF_LIST_OF_FILE
;
748 s
->pos_in_central_dir
+= SIZECENTRALDIRITEM
+ s
->cur_file_info
.size_filename
+
749 s
->cur_file_info
.size_file_extra
+ s
->cur_file_info
.size_file_comment
;
751 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
752 &s
->cur_file_info_internal
,
753 NULL
,0,NULL
,0,NULL
,0);
754 s
->current_file_ok
= (err
== UNZ_OK
);
760 Try locate the file szFileName in the zipfile.
761 For the iCaseSensitivity signification, see unzipStringFileNameCompare
764 UNZ_OK if the file is found. It becomes the current file.
765 UNZ_END_OF_LIST_OF_FILE if the file is not found
767 extern int ZEXPORT
unzLocateFile (file
, szFileName
, iCaseSensitivity
)
769 const char *szFileName
;
770 int iCaseSensitivity
;
777 uLong pos_in_central_dirSaved
;
781 return UNZ_PARAMERROR
;
783 if (strlen(szFileName
)>=UNZ_MAXFILENAMEINZIP
)
784 return UNZ_PARAMERROR
;
787 if (!s
->current_file_ok
)
788 return UNZ_END_OF_LIST_OF_FILE
;
790 num_fileSaved
= s
->num_file
;
791 pos_in_central_dirSaved
= s
->pos_in_central_dir
;
793 err
= unzGoToFirstFile(file
);
795 while (err
== UNZ_OK
)
797 char szCurrentFileName
[UNZ_MAXFILENAMEINZIP
+1];
798 unzGetCurrentFileInfo(file
,NULL
,
799 szCurrentFileName
,sizeof(szCurrentFileName
)-1,
801 if (unzStringFileNameCompare(szCurrentFileName
,
802 szFileName
,iCaseSensitivity
)==0)
804 err
= unzGoToNextFile(file
);
807 s
->num_file
= num_fileSaved
;
808 s
->pos_in_central_dir
= pos_in_central_dirSaved
;
814 Read the local header of the current zipfile
815 Check the coherency of the local header and info in the end of central
816 directory about this file
817 store in *piSizeVar the size of extra info in local header
818 (filename and size of extra field data)
820 local
int unzlocal_CheckCurrentFileCoherencyHeader (s
,piSizeVar
,
821 poffset_local_extrafield
,
822 psize_local_extrafield
)
825 uLong
*poffset_local_extrafield
;
826 uInt
*psize_local_extrafield
;
828 uLong uMagic
,uData
,uFlags
;
830 uLong size_extra_field
;
834 *poffset_local_extrafield
= 0;
835 *psize_local_extrafield
= 0;
837 if (fseek(s
->file
,s
->cur_file_info_internal
.offset_curfile
+
838 s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
843 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
845 else if (uMagic
!=0x04034b50)
848 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
851 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
854 if (unzlocal_getShort(s
->file
,&uFlags
) != UNZ_OK
)
857 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
859 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compression_method
))
862 if ((err
==UNZ_OK
) && (s
->cur_file_info
.compression_method
!=0) &&
863 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
866 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* date/time */
869 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* crc */
871 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.crc
) &&
875 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size compr */
877 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compressed_size
) &&
881 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size uncompr */
883 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.uncompressed_size
) &&
888 if (unzlocal_getShort(s
->file
,&size_filename
) != UNZ_OK
)
890 else if ((err
==UNZ_OK
) && (size_filename
!=s
->cur_file_info
.size_filename
))
893 *piSizeVar
+= (uInt
)size_filename
;
895 if (unzlocal_getShort(s
->file
,&size_extra_field
) != UNZ_OK
)
897 *poffset_local_extrafield
= s
->cur_file_info_internal
.offset_curfile
+
898 SIZEZIPLOCALHEADER
+ size_filename
;
899 *psize_local_extrafield
= (uInt
)size_extra_field
;
901 *piSizeVar
+= (uInt
)size_extra_field
;
907 Open for reading data the current file in the zipfile.
908 If there is no error and the file is opened, the return value is UNZ_OK.
910 extern int ZEXPORT
unzOpenCurrentFile (file
)
917 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
918 uLong offset_local_extrafield
; /* offset of the local extra field */
919 uInt size_local_extrafield
; /* size of the local extra field */
922 return UNZ_PARAMERROR
;
924 if (!s
->current_file_ok
)
925 return UNZ_PARAMERROR
;
927 if (s
->pfile_in_zip_read
!= NULL
)
928 unzCloseCurrentFile(file
);
930 if (unzlocal_CheckCurrentFileCoherencyHeader(s
,&iSizeVar
,
931 &offset_local_extrafield
,&size_local_extrafield
)!=UNZ_OK
)
932 return UNZ_BADZIPFILE
;
934 pfile_in_zip_read_info
= (file_in_zip_read_info_s
*)
935 ALLOC(sizeof(file_in_zip_read_info_s
));
936 if (pfile_in_zip_read_info
==NULL
)
937 return UNZ_INTERNALERROR
;
939 pfile_in_zip_read_info
->read_buffer
=(char*)ALLOC(UNZ_BUFSIZE
);
940 pfile_in_zip_read_info
->offset_local_extrafield
= offset_local_extrafield
;
941 pfile_in_zip_read_info
->size_local_extrafield
= size_local_extrafield
;
942 pfile_in_zip_read_info
->pos_local_extrafield
=0;
944 if (pfile_in_zip_read_info
->read_buffer
==NULL
)
946 TRYFREE(pfile_in_zip_read_info
);
947 return UNZ_INTERNALERROR
;
950 pfile_in_zip_read_info
->stream_initialised
=0;
952 if ((s
->cur_file_info
.compression_method
!=0) &&
953 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
955 Store
= s
->cur_file_info
.compression_method
==0;
957 pfile_in_zip_read_info
->crc32_wait
=s
->cur_file_info
.crc
;
958 pfile_in_zip_read_info
->crc32
=0;
959 pfile_in_zip_read_info
->compression_method
=
960 s
->cur_file_info
.compression_method
;
961 pfile_in_zip_read_info
->file
=s
->file
;
962 pfile_in_zip_read_info
->byte_before_the_zipfile
=s
->byte_before_the_zipfile
;
964 pfile_in_zip_read_info
->stream
.total_out
= 0;
968 pfile_in_zip_read_info
->stream
.zalloc
= (alloc_func
)0;
969 pfile_in_zip_read_info
->stream
.zfree
= (free_func
)0;
970 pfile_in_zip_read_info
->stream
.opaque
= (voidpf
)0;
972 err
=inflateInit2(&pfile_in_zip_read_info
->stream
, -MAX_WBITS
);
974 pfile_in_zip_read_info
->stream_initialised
=1;
975 /* windowBits is passed < 0 to tell that there is no zlib header.
976 * Note that in this case inflate *requires* an extra "dummy" byte
977 * after the compressed stream in order to complete decompression and
978 * return Z_STREAM_END.
979 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
980 * size of both compressed and uncompressed data
983 pfile_in_zip_read_info
->rest_read_compressed
=
984 s
->cur_file_info
.compressed_size
;
985 pfile_in_zip_read_info
->rest_read_uncompressed
=
986 s
->cur_file_info
.uncompressed_size
;
989 pfile_in_zip_read_info
->pos_in_zipfile
=
990 s
->cur_file_info_internal
.offset_curfile
+ SIZEZIPLOCALHEADER
+
993 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)0;
996 s
->pfile_in_zip_read
= pfile_in_zip_read_info
;
1002 Read bytes from the current file.
1003 buf contain buffer where data must be copied
1004 len the size of buf.
1006 return the number of byte copied if somes bytes are copied
1007 return 0 if the end of file was reached
1008 return <0 with error code if there is an error
1009 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1011 extern int ZEXPORT
unzReadCurrentFile (file
, buf
, len
)
1019 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1021 return UNZ_PARAMERROR
;
1023 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1025 if (pfile_in_zip_read_info
==NULL
)
1026 return UNZ_PARAMERROR
;
1029 if ((pfile_in_zip_read_info
->read_buffer
== NULL
))
1030 return UNZ_END_OF_LIST_OF_FILE
;
1034 pfile_in_zip_read_info
->stream
.next_out
= (Bytef
*)buf
;
1036 pfile_in_zip_read_info
->stream
.avail_out
= (uInt
)len
;
1038 if (len
>pfile_in_zip_read_info
->rest_read_uncompressed
)
1039 pfile_in_zip_read_info
->stream
.avail_out
=
1040 (uInt
)pfile_in_zip_read_info
->rest_read_uncompressed
;
1042 while (pfile_in_zip_read_info
->stream
.avail_out
>0)
1044 if ((pfile_in_zip_read_info
->stream
.avail_in
==0) &&
1045 (pfile_in_zip_read_info
->rest_read_compressed
>0))
1047 uInt uReadThis
= UNZ_BUFSIZE
;
1048 if (pfile_in_zip_read_info
->rest_read_compressed
<uReadThis
)
1049 uReadThis
= (uInt
)pfile_in_zip_read_info
->rest_read_compressed
;
1052 if (fseek(pfile_in_zip_read_info
->file
,
1053 pfile_in_zip_read_info
->pos_in_zipfile
+
1054 pfile_in_zip_read_info
->byte_before_the_zipfile
,SEEK_SET
)!=0)
1056 if (fread(pfile_in_zip_read_info
->read_buffer
,uReadThis
,1,
1057 pfile_in_zip_read_info
->file
)!=1)
1059 pfile_in_zip_read_info
->pos_in_zipfile
+= uReadThis
;
1061 pfile_in_zip_read_info
->rest_read_compressed
-=uReadThis
;
1063 pfile_in_zip_read_info
->stream
.next_in
=
1064 (Bytef
*)pfile_in_zip_read_info
->read_buffer
;
1065 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)uReadThis
;
1068 if (pfile_in_zip_read_info
->compression_method
==0)
1071 if (pfile_in_zip_read_info
->stream
.avail_out
<
1072 pfile_in_zip_read_info
->stream
.avail_in
)
1073 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_out
;
1075 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_in
;
1077 for (i
=0;i
<uDoCopy
;i
++)
1078 *(pfile_in_zip_read_info
->stream
.next_out
+i
) =
1079 *(pfile_in_zip_read_info
->stream
.next_in
+i
);
1081 pfile_in_zip_read_info
->crc32
= crc32(pfile_in_zip_read_info
->crc32
,
1082 pfile_in_zip_read_info
->stream
.next_out
,
1084 pfile_in_zip_read_info
->rest_read_uncompressed
-=uDoCopy
;
1085 pfile_in_zip_read_info
->stream
.avail_in
-= uDoCopy
;
1086 pfile_in_zip_read_info
->stream
.avail_out
-= uDoCopy
;
1087 pfile_in_zip_read_info
->stream
.next_out
+= uDoCopy
;
1088 pfile_in_zip_read_info
->stream
.next_in
+= uDoCopy
;
1089 pfile_in_zip_read_info
->stream
.total_out
+= uDoCopy
;
1094 uLong uTotalOutBefore
,uTotalOutAfter
;
1095 const Bytef
*bufBefore
;
1097 int flush
=Z_SYNC_FLUSH
;
1099 uTotalOutBefore
= pfile_in_zip_read_info
->stream
.total_out
;
1100 bufBefore
= pfile_in_zip_read_info
->stream
.next_out
;
1103 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1104 pfile_in_zip_read_info->stream.avail_out) &&
1105 (pfile_in_zip_read_info->rest_read_compressed == 0))
1108 err
=inflate(&pfile_in_zip_read_info
->stream
,flush
);
1110 uTotalOutAfter
= pfile_in_zip_read_info
->stream
.total_out
;
1111 uOutThis
= uTotalOutAfter
-uTotalOutBefore
;
1113 pfile_in_zip_read_info
->crc32
=
1114 crc32(pfile_in_zip_read_info
->crc32
,bufBefore
,
1117 pfile_in_zip_read_info
->rest_read_uncompressed
-=
1120 iRead
+= (uInt
)(uTotalOutAfter
- uTotalOutBefore
);
1122 if (err
==Z_STREAM_END
)
1123 return (iRead
==0) ? UNZ_EOF
: iRead
;
1136 Give the current position in uncompressed data
1138 extern z_off_t ZEXPORT
unztell (file
)
1142 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1144 return UNZ_PARAMERROR
;
1146 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1148 if (pfile_in_zip_read_info
==NULL
)
1149 return UNZ_PARAMERROR
;
1151 return (z_off_t
)pfile_in_zip_read_info
->stream
.total_out
;
1156 return 1 if the end of file was reached, 0 elsewhere
1158 extern int ZEXPORT
unzeof (file
)
1162 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1164 return UNZ_PARAMERROR
;
1166 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1168 if (pfile_in_zip_read_info
==NULL
)
1169 return UNZ_PARAMERROR
;
1171 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1180 Read extra field from the current file (opened by unzOpenCurrentFile)
1181 This is the local-header version of the extra field (sometimes, there is
1182 more info in the local-header version than in the central-header)
1184 if buf==NULL, it return the size of the local extra field that can be read
1186 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1188 the return value is the number of bytes copied in buf, or (if <0)
1191 extern int ZEXPORT
unzGetLocalExtrafield (file
,buf
,len
)
1197 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1202 return UNZ_PARAMERROR
;
1204 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1206 if (pfile_in_zip_read_info
==NULL
)
1207 return UNZ_PARAMERROR
;
1209 size_to_read
= (pfile_in_zip_read_info
->size_local_extrafield
-
1210 pfile_in_zip_read_info
->pos_local_extrafield
);
1213 return (int)size_to_read
;
1215 if (len
>size_to_read
)
1216 read_now
= (uInt
)size_to_read
;
1218 read_now
= (uInt
)len
;
1223 if (fseek(pfile_in_zip_read_info
->file
,
1224 pfile_in_zip_read_info
->offset_local_extrafield
+
1225 pfile_in_zip_read_info
->pos_local_extrafield
,SEEK_SET
)!=0)
1228 if (fread(buf
,(uInt
)size_to_read
,1,pfile_in_zip_read_info
->file
)!=1)
1231 return (int)read_now
;
1235 Close the file in zip opened with unzipOpenCurrentFile
1236 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1238 extern int ZEXPORT
unzCloseCurrentFile (file
)
1244 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1246 return UNZ_PARAMERROR
;
1248 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1250 if (pfile_in_zip_read_info
==NULL
)
1251 return UNZ_PARAMERROR
;
1254 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1256 if (pfile_in_zip_read_info
->crc32
!= pfile_in_zip_read_info
->crc32_wait
)
1261 TRYFREE(pfile_in_zip_read_info
->read_buffer
);
1262 pfile_in_zip_read_info
->read_buffer
= NULL
;
1263 if (pfile_in_zip_read_info
->stream_initialised
)
1264 inflateEnd(&pfile_in_zip_read_info
->stream
);
1266 pfile_in_zip_read_info
->stream_initialised
= 0;
1267 TRYFREE(pfile_in_zip_read_info
);
1269 s
->pfile_in_zip_read
=NULL
;
1276 Get the global comment string of the ZipFile, in the szComment buffer.
1277 uSizeBuf is the size of the szComment buffer.
1278 return the number of byte copied or an error code <0
1280 extern int ZEXPORT
unzGetGlobalComment (file
, szComment
, uSizeBuf
)
1289 return UNZ_PARAMERROR
;
1292 uReadThis
= uSizeBuf
;
1293 if (uReadThis
>s
->gi
.size_comment
)
1294 uReadThis
= s
->gi
.size_comment
;
1296 if (fseek(s
->file
,s
->central_pos
+22,SEEK_SET
)!=0)
1302 if (fread(szComment
,(uInt
)uReadThis
,1,s
->file
)!=1)
1306 if ((szComment
!= NULL
) && (uSizeBuf
> s
->gi
.size_comment
))
1307 *(szComment
+s
->gi
.size_comment
)='\0';
1308 return (int)uReadThis
;
1313 /* the file shouldn't be empty, som compilers don't like it */
1314 static const int dummyVariableInUnzip
= 17;
1316 #endif /* wxUSE_ZLIB && wxUSE_ZIPSTREAM */