3 This file was altered for needs of wxWindows.
8 /* unzip.c -- IO on .zip files using zlib
9 Version 0.15 beta, Mar 19th, 1998,
11 Read unzip.h for more info
19 #if wxUSE_ZLIB && wxUSE_ZIPSTREAM
26 /* Not the right solution (paths in makefiles) but... */
28 #include "../common/unzip.h"
48 /* compile with -Dlocal if your debugger can't find static symbols */
52 #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
53 !defined(CASESENSITIVITYDEFAULT_NO)
54 #define CASESENSITIVITYDEFAULT_NO
59 #define UNZ_BUFSIZE (16384)
62 #ifndef UNZ_MAXFILENAMEINZIP
63 #define UNZ_MAXFILENAMEINZIP (256)
67 # define ALLOC(size) (malloc(size))
70 # define TRYFREE(p) {if (p) free(p);}
73 #define SIZECENTRALDIRITEM (0x2e)
74 #define SIZEZIPLOCALHEADER (0x1e)
77 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
91 const char unz_copyright
[] =
92 " unzip 0.15 Copyright 1998 Gilles Vollant ";
94 /* unz_file_info_interntal contain internal info about a file in zipfile*/
95 typedef struct unz_file_info_internal_s
97 uLong offset_curfile
;/* relative offset of local header 4 bytes */
98 } unz_file_info_internal
;
101 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
102 when reading and decompress it */
105 char *read_buffer
; /* internal buffer for compressed data */
106 z_stream stream
; /* zLib stream structure for inflate */
108 uLong pos_in_zipfile
; /* position in byte on the zipfile, for fseek*/
109 uLong stream_initialised
; /* flag set if stream structure is initialised*/
111 uLong offset_local_extrafield
;/* offset of the local extra field */
112 uInt size_local_extrafield
;/* size of the local extra field */
113 uLong pos_local_extrafield
; /* position in the local extra field in read*/
115 uLong crc32
; /* crc32 of all data uncompressed */
116 uLong crc32_wait
; /* crc32 we must obtain after decompress all */
117 uLong rest_read_compressed
; /* number of byte to be decompressed */
118 uLong rest_read_uncompressed
;/*number of byte to be obtained after decomp*/
119 FILE* file
; /* io structore of the zipfile */
120 uLong compression_method
; /* compression method (0==store) */
121 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
122 } file_in_zip_read_info_s
;
125 /* unz_s contain internal information about the zipfile
129 FILE* file
; /* io structore of the zipfile */
130 unz_global_info gi
; /* public global information */
131 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
132 uLong num_file
; /* number of the current file in the zipfile*/
133 uLong pos_in_central_dir
; /* pos of the current file in the central dir*/
134 uLong current_file_ok
; /* flag about the usability of the current file*/
135 uLong central_pos
; /* position of the beginning of the central dir*/
137 uLong size_central_dir
; /* size of the central directory */
138 uLong offset_central_dir
; /* offset of start of central directory with
139 respect to the starting disk number */
141 unz_file_info cur_file_info
; /* public info about the current file in zip*/
142 unz_file_info_internal cur_file_info_internal
; /* private info about it*/
143 file_in_zip_read_info_s
* pfile_in_zip_read
; /* structure about the current
144 file if we are decompressing it */
147 #if defined (__VISAGECPP__)
148 /* VA always requires prototypes */
149 int unzlocal_CheckCurrentFileCoherencyHeader (unz_s
*, uInt
*, uLong
*, uInt
*);
152 /* ===========================================================================
153 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
155 IN assertion: the stream s has been sucessfully opened for reading.
159 local
int unzlocal_getByte(fin
,pi
)
164 int err
= fread(&c
, 1, 1, fin
);
180 /* ===========================================================================
181 Reads a long in LSB order from the given gz_stream. Sets
183 local
int unzlocal_getShort (fin
,pX
)
191 err
= unzlocal_getByte(fin
,&i
);
195 err
= unzlocal_getByte(fin
,&i
);
205 local
int unzlocal_getLong (fin
,pX
)
213 err
= unzlocal_getByte(fin
,&i
);
217 err
= unzlocal_getByte(fin
,&i
);
221 err
= unzlocal_getByte(fin
,&i
);
225 err
= unzlocal_getByte(fin
,&i
);
236 /* My own strcmpi / strcasecmp */
237 local
int strcmpcasenosensitive_internal (fileName1
,fileName2
)
238 const char* fileName1
;
239 const char* fileName2
;
243 char c1
=*(fileName1
++);
244 char c2
=*(fileName2
++);
245 if ((c1
>='a') && (c1
<='z'))
247 if ((c2
>='a') && (c2
<='z'))
250 return ((c2
=='\0') ? 0 : -1);
261 #ifdef CASESENSITIVITYDEFAULT_NO
262 #define CASESENSITIVITYDEFAULTVALUE 2
264 #define CASESENSITIVITYDEFAULTVALUE 1
267 #ifndef STRCMPCASENOSENTIVEFUNCTION
268 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
272 Compare two filename (fileName1,fileName2).
273 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
274 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
276 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
277 (like 1 on Unix, 2 on Windows)
280 extern int ZEXPORT
unzStringFileNameCompare (fileName1
,fileName2
,iCaseSensitivity
)
281 const char* fileName1
;
282 const char* fileName2
;
283 int iCaseSensitivity
;
285 if (iCaseSensitivity
==0)
286 iCaseSensitivity
=CASESENSITIVITYDEFAULTVALUE
;
288 if (iCaseSensitivity
==1)
289 return strcmp(fileName1
,fileName2
);
291 return STRCMPCASENOSENTIVEFUNCTION(fileName1
,fileName2
);
294 #define BUFREADCOMMENT (0x400)
297 Locate the Central directory of a zipfile (at the end, just before
300 local uLong
unzlocal_SearchCentralDir(fin
)
306 uLong uMaxBack
=0xffff; /* maximum size of global comment */
309 if (fseek(fin
,0,SEEK_END
) != 0)
313 uSizeFile
= ftell( fin
);
315 if (uMaxBack
>uSizeFile
)
316 uMaxBack
= uSizeFile
;
318 buf
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4);
323 while (uBackRead
<uMaxBack
)
325 uLong uReadSize
,uReadPos
;
327 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
)
328 uBackRead
= uMaxBack
;
330 uBackRead
+=BUFREADCOMMENT
;
331 uReadPos
= uSizeFile
-uBackRead
;
333 uReadSize
= ((BUFREADCOMMENT
+4) < (uSizeFile
-uReadPos
)) ?
334 (BUFREADCOMMENT
+4) : (uSizeFile
-uReadPos
);
335 if (fseek(fin
,uReadPos
,SEEK_SET
)!=0)
338 if (fread(buf
,(uInt
)uReadSize
,1,fin
)!=1)
341 for (i
=(int)uReadSize
-3; (i
--)>0;)
342 if (((*(buf
+i
))==0x50) && ((*(buf
+i
+1))==0x4b) &&
343 ((*(buf
+i
+2))==0x05) && ((*(buf
+i
+3))==0x06))
345 uPosFound
= uReadPos
+i
;
357 void wxUnix2MacFilename (char *s
) ;
359 wxUnix2MacFilename (char *s
)
365 /* relative path , since it goes on with slash which is translated to a : */
366 memmove( s
, s
+1 ,strlen( s
) ) ;
368 else if ( *s
== '/' )
370 /* absolute path -> on mac just start with the drive name */
371 memmove( s
, s
+1 ,strlen( s
) ) ;
375 /* wxASSERT_MSG( 1 , "unkown path beginning" ) ; */
379 if (*s
== '/' || *s
== '\\')
381 /* convert any back-directory situations */
382 if ( *(s
+1) == '.' && *(s
+2) == '.' && ( (*(s
+3) == '/' || *(s
+3) == '\\') ) )
385 memmove( s
+1 , s
+3 ,strlen( s
+3 ) + 1 ) ;
395 extern char * wxBuffer
;
399 Open a Zip file. path contain the full pathname (by example,
400 on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
402 If the zipfile cannot be opened (file don't exist or in not valid), the
403 return value is NULL.
404 Else, the return value is a unzFile Handle, usable with other function
405 of this unzip package.
407 extern unzFile ZEXPORT
unzOpen (path
)
412 uLong central_pos
,uL
;
415 uLong number_disk
; /* number of the current dist, used for
416 spaning ZIP, unsupported, always 0*/
417 uLong number_disk_with_CD
; /* number the the disk with central dir, used
418 for spaning ZIP, unsupported, always 0*/
419 uLong number_entry_CD
; /* total number of entries in
421 (same than number_entry on nospan) */
425 if (unz_copyright
[0]!=' ')
429 strcpy( wxBuffer
, path
) ;
430 wxUnix2MacFilename( wxBuffer
) ;
431 fin
=fopen(wxBuffer
,"rb");
433 fin
=fopen(path
,"rb");
438 central_pos
= unzlocal_SearchCentralDir(fin
);
442 if (fseek(fin
,central_pos
,SEEK_SET
)!=0)
445 /* the signature, already checked */
446 if (unzlocal_getLong(fin
,&uL
)!=UNZ_OK
)
449 /* number of this disk */
450 if (unzlocal_getShort(fin
,&number_disk
)!=UNZ_OK
)
453 /* number of the disk with the start of the central directory */
454 if (unzlocal_getShort(fin
,&number_disk_with_CD
)!=UNZ_OK
)
457 /* total number of entries in the central dir on this disk */
458 if (unzlocal_getShort(fin
,&us
.gi
.number_entry
)!=UNZ_OK
)
461 /* total number of entries in the central dir */
462 if (unzlocal_getShort(fin
,&number_entry_CD
)!=UNZ_OK
)
465 if ((number_entry_CD
!=us
.gi
.number_entry
) ||
466 (number_disk_with_CD
!=0) ||
470 /* size of the central directory */
471 if (unzlocal_getLong(fin
,&us
.size_central_dir
)!=UNZ_OK
)
474 /* offset of start of central directory with respect to the
475 starting disk number */
476 if (unzlocal_getLong(fin
,&us
.offset_central_dir
)!=UNZ_OK
)
479 /* zipfile comment length */
480 if (unzlocal_getShort(fin
,&us
.gi
.size_comment
)!=UNZ_OK
)
483 if ((central_pos
<us
.offset_central_dir
+us
.size_central_dir
) &&
493 us
.byte_before_the_zipfile
= central_pos
-
494 (us
.offset_central_dir
+us
.size_central_dir
);
495 us
.central_pos
= central_pos
;
496 us
.pfile_in_zip_read
= NULL
;
499 s
=(unz_s
*)ALLOC(sizeof(unz_s
));
501 unzGoToFirstFile((unzFile
)s
);
507 Close a ZipFile opened with unzipOpen.
508 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
509 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
510 return UNZ_OK if there is no problem. */
511 extern int ZEXPORT
unzClose (file
)
516 return UNZ_PARAMERROR
;
519 if (s
->pfile_in_zip_read
!=NULL
)
520 unzCloseCurrentFile(file
);
529 Write info about the ZipFile in the *pglobal_info structure.
530 No preparation of the structure is needed
531 return UNZ_OK if there is no problem. */
532 extern int ZEXPORT
unzGetGlobalInfo (file
,pglobal_info
)
534 unz_global_info
*pglobal_info
;
538 return UNZ_PARAMERROR
;
546 Translate date/time from Dos format to tm_unz (readable more easilty)
548 local
void unzlocal_DosDateToTmuDate (ulDosDate
, ptm
)
553 uDate
= (uLong
)(ulDosDate
>>16);
554 ptm
->tm_mday
= (uInt
)(uDate
&0x1f) ;
555 ptm
->tm_mon
= (uInt
)((((uDate
)&0x1E0)/0x20)-1) ;
556 ptm
->tm_year
= (uInt
)(((uDate
&0x0FE00)/0x0200)+1980) ;
558 ptm
->tm_hour
= (uInt
) ((ulDosDate
&0xF800)/0x800);
559 ptm
->tm_min
= (uInt
) ((ulDosDate
&0x7E0)/0x20) ;
560 ptm
->tm_sec
= (uInt
) (2*(ulDosDate
&0x1f)) ;
564 Get Info about the current file in the zipfile, with internal only info
566 local
int unzlocal_GetCurrentFileInfoInternal
OF((unzFile file
,
567 unz_file_info
*pfile_info
,
568 unz_file_info_internal
569 *pfile_info_internal
,
571 uLong fileNameBufferSize
,
573 uLong extraFieldBufferSize
,
575 uLong commentBufferSize
));
577 local
int unzlocal_GetCurrentFileInfoInternal (file
,
580 szFileName
, fileNameBufferSize
,
581 extraField
, extraFieldBufferSize
,
582 szComment
, commentBufferSize
)
584 unz_file_info
*pfile_info
;
585 unz_file_info_internal
*pfile_info_internal
;
587 uLong fileNameBufferSize
;
589 uLong extraFieldBufferSize
;
591 uLong commentBufferSize
;
594 unz_file_info file_info
;
595 unz_file_info_internal file_info_internal
;
601 return UNZ_PARAMERROR
;
603 if (fseek(s
->file
,s
->pos_in_central_dir
+s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
607 /* we check the magic */
609 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
611 else if (uMagic
!=0x02014b50)
614 if (unzlocal_getShort(s
->file
,&file_info
.version
) != UNZ_OK
)
617 if (unzlocal_getShort(s
->file
,&file_info
.version_needed
) != UNZ_OK
)
620 if (unzlocal_getShort(s
->file
,&file_info
.flag
) != UNZ_OK
)
623 if (unzlocal_getShort(s
->file
,&file_info
.compression_method
) != UNZ_OK
)
626 if (unzlocal_getLong(s
->file
,&file_info
.dosDate
) != UNZ_OK
)
629 unzlocal_DosDateToTmuDate(file_info
.dosDate
,&file_info
.tmu_date
);
631 if (unzlocal_getLong(s
->file
,&file_info
.crc
) != UNZ_OK
)
634 if (unzlocal_getLong(s
->file
,&file_info
.compressed_size
) != UNZ_OK
)
637 if (unzlocal_getLong(s
->file
,&file_info
.uncompressed_size
) != UNZ_OK
)
640 if (unzlocal_getShort(s
->file
,&file_info
.size_filename
) != UNZ_OK
)
643 if (unzlocal_getShort(s
->file
,&file_info
.size_file_extra
) != UNZ_OK
)
646 if (unzlocal_getShort(s
->file
,&file_info
.size_file_comment
) != UNZ_OK
)
649 if (unzlocal_getShort(s
->file
,&file_info
.disk_num_start
) != UNZ_OK
)
652 if (unzlocal_getShort(s
->file
,&file_info
.internal_fa
) != UNZ_OK
)
655 if (unzlocal_getLong(s
->file
,&file_info
.external_fa
) != UNZ_OK
)
658 if (unzlocal_getLong(s
->file
,&file_info_internal
.offset_curfile
) != UNZ_OK
)
661 lSeek
+=file_info
.size_filename
;
662 if ((err
==UNZ_OK
) && (szFileName
!=NULL
))
665 if (file_info
.size_filename
<fileNameBufferSize
)
667 *(szFileName
+file_info
.size_filename
)='\0';
668 uSizeRead
= file_info
.size_filename
;
671 uSizeRead
= fileNameBufferSize
;
673 if ((file_info
.size_filename
>0) && (fileNameBufferSize
>0))
674 if (fread(szFileName
,(uInt
)uSizeRead
,1,s
->file
)!=1)
680 if ((err
==UNZ_OK
) && (extraField
!=NULL
))
683 if (file_info
.size_file_extra
<extraFieldBufferSize
)
684 uSizeRead
= file_info
.size_file_extra
;
686 uSizeRead
= extraFieldBufferSize
;
689 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
693 if ((file_info
.size_file_extra
>0) && (extraFieldBufferSize
>0))
694 if (fread(extraField
,(uInt
)uSizeRead
,1,s
->file
)!=1)
696 lSeek
+= file_info
.size_file_extra
- uSizeRead
;
699 lSeek
+=file_info
.size_file_extra
;
702 if ((err
==UNZ_OK
) && (szComment
!=NULL
))
705 if (file_info
.size_file_comment
<commentBufferSize
)
707 *(szComment
+file_info
.size_file_comment
)='\0';
708 uSizeRead
= file_info
.size_file_comment
;
711 uSizeRead
= commentBufferSize
;
714 if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0)
718 if ((file_info
.size_file_comment
>0) && (commentBufferSize
>0))
719 if (fread(szComment
,(uInt
)uSizeRead
,1,s
->file
)!=1)
721 lSeek
+=file_info
.size_file_comment
- uSizeRead
;
724 lSeek
+=file_info
.size_file_comment
;
726 if ((err
==UNZ_OK
) && (pfile_info
!=NULL
))
727 *pfile_info
=file_info
;
729 if ((err
==UNZ_OK
) && (pfile_info_internal
!=NULL
))
730 *pfile_info_internal
=file_info_internal
;
738 Write info about the ZipFile in the *pglobal_info structure.
739 No preparation of the structure is needed
740 return UNZ_OK if there is no problem.
742 extern int ZEXPORT
unzGetCurrentFileInfo (file
,
744 szFileName
, fileNameBufferSize
,
745 extraField
, extraFieldBufferSize
,
746 szComment
, commentBufferSize
)
748 unz_file_info
*pfile_info
;
750 uLong fileNameBufferSize
;
752 uLong extraFieldBufferSize
;
754 uLong commentBufferSize
;
756 return unzlocal_GetCurrentFileInfoInternal(file
,pfile_info
,NULL
,
757 szFileName
,fileNameBufferSize
,
758 extraField
,extraFieldBufferSize
,
759 szComment
,commentBufferSize
);
763 Set the current file of the zipfile to the first file.
764 return UNZ_OK if there is no problem
766 extern int ZEXPORT
unzGoToFirstFile (file
)
772 return UNZ_PARAMERROR
;
774 s
->pos_in_central_dir
=s
->offset_central_dir
;
776 err
=unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
777 &s
->cur_file_info_internal
,
778 NULL
,0,NULL
,0,NULL
,0);
779 s
->current_file_ok
= (err
== UNZ_OK
);
785 Set the current file of the zipfile to the next file.
786 return UNZ_OK if there is no problem
787 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
789 extern int ZEXPORT
unzGoToNextFile (file
)
796 return UNZ_PARAMERROR
;
798 if (!s
->current_file_ok
)
799 return UNZ_END_OF_LIST_OF_FILE
;
800 if (s
->num_file
+1==s
->gi
.number_entry
)
801 return UNZ_END_OF_LIST_OF_FILE
;
803 s
->pos_in_central_dir
+= SIZECENTRALDIRITEM
+ s
->cur_file_info
.size_filename
+
804 s
->cur_file_info
.size_file_extra
+ s
->cur_file_info
.size_file_comment
;
806 err
= unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
807 &s
->cur_file_info_internal
,
808 NULL
,0,NULL
,0,NULL
,0);
809 s
->current_file_ok
= (err
== UNZ_OK
);
815 Try locate the file szFileName in the zipfile.
816 For the iCaseSensitivity signification, see unzipStringFileNameCompare
819 UNZ_OK if the file is found. It becomes the current file.
820 UNZ_END_OF_LIST_OF_FILE if the file is not found
822 extern int ZEXPORT
unzLocateFile (file
, szFileName
, iCaseSensitivity
)
824 const char *szFileName
;
825 int iCaseSensitivity
;
832 uLong pos_in_central_dirSaved
;
836 return UNZ_PARAMERROR
;
838 if (strlen(szFileName
)>=UNZ_MAXFILENAMEINZIP
)
839 return UNZ_PARAMERROR
;
842 if (!s
->current_file_ok
)
843 return UNZ_END_OF_LIST_OF_FILE
;
845 num_fileSaved
= s
->num_file
;
846 pos_in_central_dirSaved
= s
->pos_in_central_dir
;
848 err
= unzGoToFirstFile(file
);
850 while (err
== UNZ_OK
)
852 char szCurrentFileName
[UNZ_MAXFILENAMEINZIP
+1];
853 unzGetCurrentFileInfo(file
,NULL
,
854 szCurrentFileName
,sizeof(szCurrentFileName
)-1,
856 if (unzStringFileNameCompare(szCurrentFileName
,
857 szFileName
,iCaseSensitivity
)==0)
859 err
= unzGoToNextFile(file
);
862 s
->num_file
= num_fileSaved
;
863 s
->pos_in_central_dir
= pos_in_central_dirSaved
;
869 Read the local header of the current zipfile
870 Check the coherency of the local header and info in the end of central
871 directory about this file
872 store in *piSizeVar the size of extra info in local header
873 (filename and size of extra field data)
875 local
int unzlocal_CheckCurrentFileCoherencyHeader (s
,piSizeVar
,
876 poffset_local_extrafield
,
877 psize_local_extrafield
)
880 uLong
*poffset_local_extrafield
;
881 uInt
*psize_local_extrafield
;
883 uLong uMagic
,uData
,uFlags
;
885 uLong size_extra_field
;
889 *poffset_local_extrafield
= 0;
890 *psize_local_extrafield
= 0;
892 if (fseek(s
->file
,s
->cur_file_info_internal
.offset_curfile
+
893 s
->byte_before_the_zipfile
,SEEK_SET
)!=0)
898 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
)
900 else if (uMagic
!=0x04034b50)
903 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
906 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
909 if (unzlocal_getShort(s
->file
,&uFlags
) != UNZ_OK
)
912 if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
)
914 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compression_method
))
917 if ((err
==UNZ_OK
) && (s
->cur_file_info
.compression_method
!=0) &&
918 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
921 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* date/time */
924 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* crc */
926 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.crc
) &&
930 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size compr */
932 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compressed_size
) &&
936 if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size uncompr */
938 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.uncompressed_size
) &&
943 if (unzlocal_getShort(s
->file
,&size_filename
) != UNZ_OK
)
945 else if ((err
==UNZ_OK
) && (size_filename
!=s
->cur_file_info
.size_filename
))
948 *piSizeVar
+= (uInt
)size_filename
;
950 if (unzlocal_getShort(s
->file
,&size_extra_field
) != UNZ_OK
)
952 *poffset_local_extrafield
= s
->cur_file_info_internal
.offset_curfile
+
953 SIZEZIPLOCALHEADER
+ size_filename
;
954 *psize_local_extrafield
= (uInt
)size_extra_field
;
956 *piSizeVar
+= (uInt
)size_extra_field
;
962 Open for reading data the current file in the zipfile.
963 If there is no error and the file is opened, the return value is UNZ_OK.
965 extern int ZEXPORT
unzOpenCurrentFile (file
)
972 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
973 uLong offset_local_extrafield
; /* offset of the local extra field */
974 uInt size_local_extrafield
; /* size of the local extra field */
977 return UNZ_PARAMERROR
;
979 if (!s
->current_file_ok
)
980 return UNZ_PARAMERROR
;
982 if (s
->pfile_in_zip_read
!= NULL
)
983 unzCloseCurrentFile(file
);
985 if (unzlocal_CheckCurrentFileCoherencyHeader(s
,&iSizeVar
,
986 &offset_local_extrafield
,&size_local_extrafield
)!=UNZ_OK
)
987 return UNZ_BADZIPFILE
;
989 pfile_in_zip_read_info
= (file_in_zip_read_info_s
*)
990 ALLOC(sizeof(file_in_zip_read_info_s
));
991 if (pfile_in_zip_read_info
==NULL
)
992 return UNZ_INTERNALERROR
;
994 pfile_in_zip_read_info
->read_buffer
=(char*)ALLOC(UNZ_BUFSIZE
);
995 pfile_in_zip_read_info
->offset_local_extrafield
= offset_local_extrafield
;
996 pfile_in_zip_read_info
->size_local_extrafield
= size_local_extrafield
;
997 pfile_in_zip_read_info
->pos_local_extrafield
=0;
999 if (pfile_in_zip_read_info
->read_buffer
==NULL
)
1001 TRYFREE(pfile_in_zip_read_info
);
1002 return UNZ_INTERNALERROR
;
1005 pfile_in_zip_read_info
->stream_initialised
=0;
1007 if ((s
->cur_file_info
.compression_method
!=0) &&
1008 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
1010 Store
= s
->cur_file_info
.compression_method
==0;
1012 pfile_in_zip_read_info
->crc32_wait
=s
->cur_file_info
.crc
;
1013 pfile_in_zip_read_info
->crc32
=0;
1014 pfile_in_zip_read_info
->compression_method
=
1015 s
->cur_file_info
.compression_method
;
1016 pfile_in_zip_read_info
->file
=s
->file
;
1017 pfile_in_zip_read_info
->byte_before_the_zipfile
=s
->byte_before_the_zipfile
;
1019 pfile_in_zip_read_info
->stream
.total_out
= 0;
1023 pfile_in_zip_read_info
->stream
.zalloc
= (alloc_func
)0;
1024 pfile_in_zip_read_info
->stream
.zfree
= (free_func
)0;
1025 pfile_in_zip_read_info
->stream
.opaque
= (voidpf
)0;
1027 err
=inflateInit2(&pfile_in_zip_read_info
->stream
, -MAX_WBITS
);
1029 pfile_in_zip_read_info
->stream_initialised
=1;
1030 /* windowBits is passed < 0 to tell that there is no zlib header.
1031 * Note that in this case inflate *requires* an extra "dummy" byte
1032 * after the compressed stream in order to complete decompression and
1033 * return Z_STREAM_END.
1034 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1035 * size of both compressed and uncompressed data
1038 pfile_in_zip_read_info
->rest_read_compressed
=
1039 s
->cur_file_info
.compressed_size
;
1040 pfile_in_zip_read_info
->rest_read_uncompressed
=
1041 s
->cur_file_info
.uncompressed_size
;
1044 pfile_in_zip_read_info
->pos_in_zipfile
=
1045 s
->cur_file_info_internal
.offset_curfile
+ SIZEZIPLOCALHEADER
+
1048 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)0;
1051 s
->pfile_in_zip_read
= pfile_in_zip_read_info
;
1057 Read bytes from the current file.
1058 buf contain buffer where data must be copied
1059 len the size of buf.
1061 return the number of byte copied if somes bytes are copied
1062 return 0 if the end of file was reached
1063 return <0 with error code if there is an error
1064 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1066 extern int ZEXPORT
unzReadCurrentFile (file
, buf
, len
)
1074 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1076 return UNZ_PARAMERROR
;
1078 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1080 if (pfile_in_zip_read_info
==NULL
)
1081 return UNZ_PARAMERROR
;
1084 if ((pfile_in_zip_read_info
->read_buffer
== NULL
))
1085 return UNZ_END_OF_LIST_OF_FILE
;
1089 pfile_in_zip_read_info
->stream
.next_out
= (Bytef
*)buf
;
1091 pfile_in_zip_read_info
->stream
.avail_out
= (uInt
)len
;
1093 if (len
>pfile_in_zip_read_info
->rest_read_uncompressed
)
1094 pfile_in_zip_read_info
->stream
.avail_out
=
1095 (uInt
)pfile_in_zip_read_info
->rest_read_uncompressed
;
1097 while (pfile_in_zip_read_info
->stream
.avail_out
>0)
1099 if ((pfile_in_zip_read_info
->stream
.avail_in
==0) &&
1100 (pfile_in_zip_read_info
->rest_read_compressed
>0))
1102 uInt uReadThis
= UNZ_BUFSIZE
;
1103 if (pfile_in_zip_read_info
->rest_read_compressed
<uReadThis
)
1104 uReadThis
= (uInt
)pfile_in_zip_read_info
->rest_read_compressed
;
1107 if (fseek(pfile_in_zip_read_info
->file
,
1108 pfile_in_zip_read_info
->pos_in_zipfile
+
1109 pfile_in_zip_read_info
->byte_before_the_zipfile
,SEEK_SET
)!=0)
1111 if (fread(pfile_in_zip_read_info
->read_buffer
,uReadThis
,1,
1112 pfile_in_zip_read_info
->file
)!=1)
1114 pfile_in_zip_read_info
->pos_in_zipfile
+= uReadThis
;
1116 pfile_in_zip_read_info
->rest_read_compressed
-=uReadThis
;
1118 pfile_in_zip_read_info
->stream
.next_in
=
1119 (Bytef
*)pfile_in_zip_read_info
->read_buffer
;
1120 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)uReadThis
;
1123 if (pfile_in_zip_read_info
->compression_method
==0)
1126 if (pfile_in_zip_read_info
->stream
.avail_out
<
1127 pfile_in_zip_read_info
->stream
.avail_in
)
1128 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_out
;
1130 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_in
;
1132 for (i
=0;i
<uDoCopy
;i
++)
1133 *(pfile_in_zip_read_info
->stream
.next_out
+i
) =
1134 *(pfile_in_zip_read_info
->stream
.next_in
+i
);
1136 pfile_in_zip_read_info
->crc32
= crc32(pfile_in_zip_read_info
->crc32
,
1137 pfile_in_zip_read_info
->stream
.next_out
,
1139 pfile_in_zip_read_info
->rest_read_uncompressed
-=uDoCopy
;
1140 pfile_in_zip_read_info
->stream
.avail_in
-= uDoCopy
;
1141 pfile_in_zip_read_info
->stream
.avail_out
-= uDoCopy
;
1142 pfile_in_zip_read_info
->stream
.next_out
+= uDoCopy
;
1143 pfile_in_zip_read_info
->stream
.next_in
+= uDoCopy
;
1144 pfile_in_zip_read_info
->stream
.total_out
+= uDoCopy
;
1149 uLong uTotalOutBefore
,uTotalOutAfter
;
1150 const Bytef
*bufBefore
;
1152 int flush
=Z_SYNC_FLUSH
;
1154 uTotalOutBefore
= pfile_in_zip_read_info
->stream
.total_out
;
1155 bufBefore
= pfile_in_zip_read_info
->stream
.next_out
;
1158 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1159 pfile_in_zip_read_info->stream.avail_out) &&
1160 (pfile_in_zip_read_info->rest_read_compressed == 0))
1163 err
=inflate(&pfile_in_zip_read_info
->stream
,flush
);
1165 uTotalOutAfter
= pfile_in_zip_read_info
->stream
.total_out
;
1166 uOutThis
= uTotalOutAfter
-uTotalOutBefore
;
1168 pfile_in_zip_read_info
->crc32
=
1169 crc32(pfile_in_zip_read_info
->crc32
,bufBefore
,
1172 pfile_in_zip_read_info
->rest_read_uncompressed
-=
1175 iRead
+= (uInt
)(uTotalOutAfter
- uTotalOutBefore
);
1177 if (err
==Z_STREAM_END
)
1178 return (iRead
==0) ? UNZ_EOF
: iRead
;
1191 Give the current position in uncompressed data
1193 extern z_off_t ZEXPORT
unztell (file
)
1197 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 return (z_off_t
)pfile_in_zip_read_info
->stream
.total_out
;
1211 return 1 if the end of file was reached, 0 elsewhere
1213 extern int ZEXPORT
unzeof (file
)
1217 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1219 return UNZ_PARAMERROR
;
1221 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1223 if (pfile_in_zip_read_info
==NULL
)
1224 return UNZ_PARAMERROR
;
1226 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1235 Read extra field from the current file (opened by unzOpenCurrentFile)
1236 This is the local-header version of the extra field (sometimes, there is
1237 more info in the local-header version than in the central-header)
1239 if buf==NULL, it return the size of the local extra field that can be read
1241 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1243 the return value is the number of bytes copied in buf, or (if <0)
1246 extern int ZEXPORT
unzGetLocalExtrafield (file
,buf
,len
)
1252 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1257 return UNZ_PARAMERROR
;
1259 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1261 if (pfile_in_zip_read_info
==NULL
)
1262 return UNZ_PARAMERROR
;
1264 size_to_read
= (pfile_in_zip_read_info
->size_local_extrafield
-
1265 pfile_in_zip_read_info
->pos_local_extrafield
);
1268 return (int)size_to_read
;
1270 if (len
>size_to_read
)
1271 read_now
= (uInt
)size_to_read
;
1273 read_now
= (uInt
)len
;
1278 if (fseek(pfile_in_zip_read_info
->file
,
1279 pfile_in_zip_read_info
->offset_local_extrafield
+
1280 pfile_in_zip_read_info
->pos_local_extrafield
,SEEK_SET
)!=0)
1283 if (fread(buf
,(uInt
)size_to_read
,1,pfile_in_zip_read_info
->file
)!=1)
1286 return (int)read_now
;
1290 Close the file in zip opened with unzipOpenCurrentFile
1291 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1293 extern int ZEXPORT
unzCloseCurrentFile (file
)
1299 file_in_zip_read_info_s
* pfile_in_zip_read_info
;
1301 return UNZ_PARAMERROR
;
1303 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1305 if (pfile_in_zip_read_info
==NULL
)
1306 return UNZ_PARAMERROR
;
1309 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1311 if (pfile_in_zip_read_info
->crc32
!= pfile_in_zip_read_info
->crc32_wait
)
1316 TRYFREE(pfile_in_zip_read_info
->read_buffer
);
1317 pfile_in_zip_read_info
->read_buffer
= NULL
;
1318 if (pfile_in_zip_read_info
->stream_initialised
)
1319 inflateEnd(&pfile_in_zip_read_info
->stream
);
1321 pfile_in_zip_read_info
->stream_initialised
= 0;
1322 TRYFREE(pfile_in_zip_read_info
);
1324 s
->pfile_in_zip_read
=NULL
;
1331 Get the global comment string of the ZipFile, in the szComment buffer.
1332 uSizeBuf is the size of the szComment buffer.
1333 return the number of byte copied or an error code <0
1335 extern int ZEXPORT
unzGetGlobalComment (file
, szComment
, uSizeBuf
)
1344 return UNZ_PARAMERROR
;
1347 uReadThis
= uSizeBuf
;
1348 if (uReadThis
>s
->gi
.size_comment
)
1349 uReadThis
= s
->gi
.size_comment
;
1351 if (fseek(s
->file
,s
->central_pos
+22,SEEK_SET
)!=0)
1357 if (fread(szComment
,(uInt
)uReadThis
,1,s
->file
)!=1)
1361 if ((szComment
!= NULL
) && (uSizeBuf
> s
->gi
.size_comment
))
1362 *(szComment
+s
->gi
.size_comment
)='\0';
1363 return (int)uReadThis
;
1368 /* the file shouldn't be empty, som compilers don't like it */
1369 static const int dummyVariableInUnzip
= 17;
1371 #endif /* wxUSE_ZLIB && wxUSE_ZIPSTREAM */