1 /* unzip.c -- IO on .zip files using zlib
2 Version 0.15 beta, Mar 19th, 1998,
4 Read unzip.h for more info
29 /* compile with -Dlocal if your debugger can't find static symbols */
33 #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
34 !defined(CASESENSITIVITYDEFAULT_NO)
35 #define CASESENSITIVITYDEFAULT_NO
40 #define UNZ_BUFSIZE (16384)
43 #ifndef UNZ_MAXFILENAMEINZIP
44 #define UNZ_MAXFILENAMEINZIP (256)
48 # define ALLOC(size) (malloc(size))
51 # define TRYFREE(p) {if (p) free(p);}
54 #define SIZECENTRALDIRITEM (0x2e)
55 #define SIZEZIPLOCALHEADER (0x1e)
58 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
72 const char unz_copyright[] =
73 " unzip 0.15 Copyright 1998 Gilles Vollant ";
75 /* unz_file_info_interntal contain internal info about a file in zipfile*/
76 typedef struct unz_file_info_internal_s
78 uLong offset_curfile;/* relative offset of local header 4 bytes */
79 } unz_file_info_internal;
82 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
83 when reading and decompress it */
86 char *read_buffer; /* internal buffer for compressed data */
87 z_stream stream; /* zLib stream structure for inflate */
89 uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
90 uLong stream_initialised; /* flag set if stream structure is initialised*/
92 uLong offset_local_extrafield;/* offset of the local extra field */
93 uInt size_local_extrafield;/* size of the local extra field */
94 uLong pos_local_extrafield; /* position in the local extra field in read*/
96 uLong crc32; /* crc32 of all data uncompressed */
97 uLong crc32_wait; /* crc32 we must obtain after decompress all */
98 uLong rest_read_compressed; /* number of byte to be decompressed */
99 uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
100 FILE* file; /* io structore of the zipfile */
101 uLong compression_method; /* compression method (0==store) */
102 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
103 } file_in_zip_read_info_s;
106 /* unz_s contain internal information about the zipfile
110 FILE* file; /* io structore of the zipfile */
111 unz_global_info gi; /* public global information */
112 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
113 uLong num_file; /* number of the current file in the zipfile*/
114 uLong pos_in_central_dir; /* pos of the current file in the central dir*/
115 uLong current_file_ok; /* flag about the usability of the current file*/
116 uLong central_pos; /* position of the beginning of the central dir*/
118 uLong size_central_dir; /* size of the central directory */
119 uLong offset_central_dir; /* offset of start of central directory with
120 respect to the starting disk number */
122 unz_file_info cur_file_info; /* public info about the current file in zip*/
123 unz_file_info_internal cur_file_info_internal; /* private info about it*/
124 file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
125 file if we are decompressing it */
129 /* ===========================================================================
130 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
132 IN assertion: the stream s has been sucessfully opened for reading.
136 local int unzlocal_getByte(fin,pi)
141 int err = fread(&c, 1, 1, fin);
157 /* ===========================================================================
158 Reads a long in LSB order from the given gz_stream. Sets
160 local int unzlocal_getShort (fin,pX)
168 err = unzlocal_getByte(fin,&i);
172 err = unzlocal_getByte(fin,&i);
182 local int unzlocal_getLong (fin,pX)
190 err = unzlocal_getByte(fin,&i);
194 err = unzlocal_getByte(fin,&i);
198 err = unzlocal_getByte(fin,&i);
202 err = unzlocal_getByte(fin,&i);
213 /* My own strcmpi / strcasecmp */
214 local int strcmpcasenosensitive_internal (fileName1,fileName2)
215 const char* fileName1;
216 const char* fileName2;
220 char c1=*(fileName1++);
221 char c2=*(fileName2++);
222 if ((c1>='a') && (c1<='z'))
224 if ((c2>='a') && (c2<='z'))
227 return ((c2=='\0') ? 0 : -1);
238 #ifdef CASESENSITIVITYDEFAULT_NO
239 #define CASESENSITIVITYDEFAULTVALUE 2
241 #define CASESENSITIVITYDEFAULTVALUE 1
244 #ifndef STRCMPCASENOSENTIVEFUNCTION
245 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
249 Compare two filename (fileName1,fileName2).
250 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
251 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
253 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
254 (like 1 on Unix, 2 on Windows)
257 extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
258 const char* fileName1;
259 const char* fileName2;
260 int iCaseSensitivity;
262 if (iCaseSensitivity==0)
263 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
265 if (iCaseSensitivity==1)
266 return strcmp(fileName1,fileName2);
268 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
271 #define BUFREADCOMMENT (0x400)
274 Locate the Central directory of a zipfile (at the end, just before
277 local uLong unzlocal_SearchCentralDir(fin)
283 uLong uMaxBack=0xffff; /* maximum size of global comment */
286 if (fseek(fin,0,SEEK_END) != 0)
290 uSizeFile = ftell( fin );
292 if (uMaxBack>uSizeFile)
293 uMaxBack = uSizeFile;
295 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
300 while (uBackRead<uMaxBack)
302 uLong uReadSize,uReadPos ;
304 if (uBackRead+BUFREADCOMMENT>uMaxBack)
305 uBackRead = uMaxBack;
307 uBackRead+=BUFREADCOMMENT;
308 uReadPos = uSizeFile-uBackRead ;
310 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
311 (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
312 if (fseek(fin,uReadPos,SEEK_SET)!=0)
315 if (fread(buf,(uInt)uReadSize,1,fin)!=1)
318 for (i=(int)uReadSize-3; (i--)>0;)
319 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
320 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
322 uPosFound = uReadPos+i;
334 Open a Zip file. path contain the full pathname (by example,
335 on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
337 If the zipfile cannot be opened (file don't exist or in not valid), the
338 return value is NULL.
339 Else, the return value is a unzFile Handle, usable with other function
340 of this unzip package.
342 extern unzFile ZEXPORT unzOpen (path)
347 uLong central_pos,uL;
350 uLong number_disk; /* number of the current dist, used for
351 spaning ZIP, unsupported, always 0*/
352 uLong number_disk_with_CD; /* number the the disk with central dir, used
353 for spaning ZIP, unsupported, always 0*/
354 uLong number_entry_CD; /* total number of entries in
356 (same than number_entry on nospan) */
360 if (unz_copyright[0]!=' ')
363 fin=fopen(path,"rb");
367 central_pos = unzlocal_SearchCentralDir(fin);
371 if (fseek(fin,central_pos,SEEK_SET)!=0)
374 /* the signature, already checked */
375 if (unzlocal_getLong(fin,&uL)!=UNZ_OK)
378 /* number of this disk */
379 if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK)
382 /* number of the disk with the start of the central directory */
383 if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK)
386 /* total number of entries in the central dir on this disk */
387 if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK)
390 /* total number of entries in the central dir */
391 if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK)
394 if ((number_entry_CD!=us.gi.number_entry) ||
395 (number_disk_with_CD!=0) ||
399 /* size of the central directory */
400 if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK)
403 /* offset of start of central directory with respect to the
404 starting disk number */
405 if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK)
408 /* zipfile comment length */
409 if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK)
412 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
423 us.byte_before_the_zipfile = central_pos -
424 (us.offset_central_dir+us.size_central_dir);
425 us.central_pos = central_pos;
426 us.pfile_in_zip_read = NULL;
429 s=(unz_s*)ALLOC(sizeof(unz_s));
431 unzGoToFirstFile((unzFile)s);
437 Close a ZipFile opened with unzipOpen.
438 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
439 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
440 return UNZ_OK if there is no problem. */
441 extern int ZEXPORT unzClose (file)
446 return UNZ_PARAMERROR;
449 if (s->pfile_in_zip_read!=NULL)
450 unzCloseCurrentFile(file);
459 Write info about the ZipFile in the *pglobal_info structure.
460 No preparation of the structure is needed
461 return UNZ_OK if there is no problem. */
462 extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
464 unz_global_info *pglobal_info;
468 return UNZ_PARAMERROR;
476 Translate date/time from Dos format to tm_unz (readable more easilty)
478 local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
483 uDate = (uLong)(ulDosDate>>16);
484 ptm->tm_mday = (uInt)(uDate&0x1f) ;
485 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
486 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
488 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
489 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
490 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
494 Get Info about the current file in the zipfile, with internal only info
496 local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
497 unz_file_info *pfile_info,
498 unz_file_info_internal
499 *pfile_info_internal,
501 uLong fileNameBufferSize,
503 uLong extraFieldBufferSize,
505 uLong commentBufferSize));
507 local int unzlocal_GetCurrentFileInfoInternal (file,
510 szFileName, fileNameBufferSize,
511 extraField, extraFieldBufferSize,
512 szComment, commentBufferSize)
514 unz_file_info *pfile_info;
515 unz_file_info_internal *pfile_info_internal;
517 uLong fileNameBufferSize;
519 uLong extraFieldBufferSize;
521 uLong commentBufferSize;
524 unz_file_info file_info;
525 unz_file_info_internal file_info_internal;
531 return UNZ_PARAMERROR;
533 if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0)
537 /* we check the magic */
540 if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
542 else if (uMagic!=0x02014b50)
546 if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK)
549 if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK)
552 if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK)
555 if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK)
558 if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK)
561 unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
563 if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK)
566 if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK)
569 if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK)
572 if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK)
575 if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK)
578 if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK)
581 if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK)
584 if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK)
587 if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK)
590 if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK)
593 lSeek+=file_info.size_filename;
594 if ((err==UNZ_OK) && (szFileName!=NULL))
597 if (file_info.size_filename<fileNameBufferSize)
599 *(szFileName+file_info.size_filename)='\0';
600 uSizeRead = file_info.size_filename;
603 uSizeRead = fileNameBufferSize;
605 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
606 if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1)
612 if ((err==UNZ_OK) && (extraField!=NULL))
615 if (file_info.size_file_extra<extraFieldBufferSize)
616 uSizeRead = file_info.size_file_extra;
618 uSizeRead = extraFieldBufferSize;
622 if (fseek(s->file,lSeek,SEEK_CUR)==0)
627 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
628 if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1)
630 lSeek += file_info.size_file_extra - uSizeRead;
633 lSeek+=file_info.size_file_extra;
636 if ((err==UNZ_OK) && (szComment!=NULL))
639 if (file_info.size_file_comment<commentBufferSize)
641 *(szComment+file_info.size_file_comment)='\0';
642 uSizeRead = file_info.size_file_comment;
645 uSizeRead = commentBufferSize;
649 if (fseek(s->file,lSeek,SEEK_CUR)==0)
654 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
655 if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1)
657 lSeek+=file_info.size_file_comment - uSizeRead;
660 lSeek+=file_info.size_file_comment;
662 if ((err==UNZ_OK) && (pfile_info!=NULL))
663 *pfile_info=file_info;
665 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
666 *pfile_info_internal=file_info_internal;
674 Write info about the ZipFile in the *pglobal_info structure.
675 No preparation of the structure is needed
676 return UNZ_OK if there is no problem.
678 extern int ZEXPORT unzGetCurrentFileInfo (file,
680 szFileName, fileNameBufferSize,
681 extraField, extraFieldBufferSize,
682 szComment, commentBufferSize)
684 unz_file_info *pfile_info;
686 uLong fileNameBufferSize;
688 uLong extraFieldBufferSize;
690 uLong commentBufferSize;
692 return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
693 szFileName,fileNameBufferSize,
694 extraField,extraFieldBufferSize,
695 szComment,commentBufferSize);
699 Set the current file of the zipfile to the first file.
700 return UNZ_OK if there is no problem
702 extern int ZEXPORT unzGoToFirstFile (file)
708 return UNZ_PARAMERROR;
710 s->pos_in_central_dir=s->offset_central_dir;
712 err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
713 &s->cur_file_info_internal,
714 NULL,0,NULL,0,NULL,0);
715 s->current_file_ok = (err == UNZ_OK);
721 Set the current file of the zipfile to the next file.
722 return UNZ_OK if there is no problem
723 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
725 extern int ZEXPORT unzGoToNextFile (file)
732 return UNZ_PARAMERROR;
734 if (!s->current_file_ok)
735 return UNZ_END_OF_LIST_OF_FILE;
736 if (s->num_file+1==s->gi.number_entry)
737 return UNZ_END_OF_LIST_OF_FILE;
739 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
740 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
742 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
743 &s->cur_file_info_internal,
744 NULL,0,NULL,0,NULL,0);
745 s->current_file_ok = (err == UNZ_OK);
751 Try locate the file szFileName in the zipfile.
752 For the iCaseSensitivity signification, see unzipStringFileNameCompare
755 UNZ_OK if the file is found. It becomes the current file.
756 UNZ_END_OF_LIST_OF_FILE if the file is not found
758 extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
760 const char *szFileName;
761 int iCaseSensitivity;
768 uLong pos_in_central_dirSaved;
772 return UNZ_PARAMERROR;
774 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
775 return UNZ_PARAMERROR;
778 if (!s->current_file_ok)
779 return UNZ_END_OF_LIST_OF_FILE;
781 num_fileSaved = s->num_file;
782 pos_in_central_dirSaved = s->pos_in_central_dir;
784 err = unzGoToFirstFile(file);
786 while (err == UNZ_OK)
788 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
789 unzGetCurrentFileInfo(file,NULL,
790 szCurrentFileName,sizeof(szCurrentFileName)-1,
792 if (unzStringFileNameCompare(szCurrentFileName,
793 szFileName,iCaseSensitivity)==0)
795 err = unzGoToNextFile(file);
798 s->num_file = num_fileSaved ;
799 s->pos_in_central_dir = pos_in_central_dirSaved ;
805 Read the local header of the current zipfile
806 Check the coherency of the local header and info in the end of central
807 directory about this file
808 store in *piSizeVar the size of extra info in local header
809 (filename and size of extra field data)
811 local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
812 poffset_local_extrafield,
813 psize_local_extrafield)
816 uLong *poffset_local_extrafield;
817 uInt *psize_local_extrafield;
819 uLong uMagic,uData,uFlags;
821 uLong size_extra_field;
825 *poffset_local_extrafield = 0;
826 *psize_local_extrafield = 0;
828 if (fseek(s->file,s->cur_file_info_internal.offset_curfile +
829 s->byte_before_the_zipfile,SEEK_SET)!=0)
835 if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
837 else if (uMagic!=0x04034b50)
841 if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
844 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
847 if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK)
850 if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
852 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
855 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
856 (s->cur_file_info.compression_method!=Z_DEFLATED))
859 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */
862 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */
864 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
868 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */
870 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
874 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */
876 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
881 if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK)
883 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
886 *piSizeVar += (uInt)size_filename;
888 if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK)
890 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
891 SIZEZIPLOCALHEADER + size_filename;
892 *psize_local_extrafield = (uInt)size_extra_field;
894 *piSizeVar += (uInt)size_extra_field;
900 Open for reading data the current file in the zipfile.
901 If there is no error and the file is opened, the return value is UNZ_OK.
903 extern int ZEXPORT unzOpenCurrentFile (file)
910 file_in_zip_read_info_s* pfile_in_zip_read_info;
911 uLong offset_local_extrafield; /* offset of the local extra field */
912 uInt size_local_extrafield; /* size of the local extra field */
915 return UNZ_PARAMERROR;
917 if (!s->current_file_ok)
918 return UNZ_PARAMERROR;
920 if (s->pfile_in_zip_read != NULL)
921 unzCloseCurrentFile(file);
923 if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
924 &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
925 return UNZ_BADZIPFILE;
927 pfile_in_zip_read_info = (file_in_zip_read_info_s*)
928 ALLOC(sizeof(file_in_zip_read_info_s));
929 if (pfile_in_zip_read_info==NULL)
930 return UNZ_INTERNALERROR;
932 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
933 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
934 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
935 pfile_in_zip_read_info->pos_local_extrafield=0;
937 if (pfile_in_zip_read_info->read_buffer==NULL)
939 TRYFREE(pfile_in_zip_read_info);
940 return UNZ_INTERNALERROR;
943 pfile_in_zip_read_info->stream_initialised=0;
945 if ((s->cur_file_info.compression_method!=0) &&
946 (s->cur_file_info.compression_method!=Z_DEFLATED))
948 Store = s->cur_file_info.compression_method==0;
950 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
951 pfile_in_zip_read_info->crc32=0;
952 pfile_in_zip_read_info->compression_method =
953 s->cur_file_info.compression_method;
954 pfile_in_zip_read_info->file=s->file;
955 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
957 pfile_in_zip_read_info->stream.total_out = 0;
961 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
962 pfile_in_zip_read_info->stream.zfree = (free_func)0;
963 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
965 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
967 pfile_in_zip_read_info->stream_initialised=1;
968 /* windowBits is passed < 0 to tell that there is no zlib header.
969 * Note that in this case inflate *requires* an extra "dummy" byte
970 * after the compressed stream in order to complete decompression and
971 * return Z_STREAM_END.
972 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
973 * size of both compressed and uncompressed data
976 pfile_in_zip_read_info->rest_read_compressed =
977 s->cur_file_info.compressed_size ;
978 pfile_in_zip_read_info->rest_read_uncompressed =
979 s->cur_file_info.uncompressed_size ;
982 pfile_in_zip_read_info->pos_in_zipfile =
983 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
986 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
989 s->pfile_in_zip_read = pfile_in_zip_read_info;
995 Read bytes from the current file.
996 buf contain buffer where data must be copied
999 return the number of byte copied if somes bytes are copied
1000 return 0 if the end of file was reached
1001 return <0 with error code if there is an error
1002 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1004 extern int ZEXPORT unzReadCurrentFile (file, buf, len)
1012 file_in_zip_read_info_s* pfile_in_zip_read_info;
1014 return UNZ_PARAMERROR;
1016 pfile_in_zip_read_info=s->pfile_in_zip_read;
1018 if (pfile_in_zip_read_info==NULL)
1019 return UNZ_PARAMERROR;
1022 if ((pfile_in_zip_read_info->read_buffer == NULL))
1023 return UNZ_END_OF_LIST_OF_FILE;
1027 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1029 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1031 if (len>pfile_in_zip_read_info->rest_read_uncompressed)
1032 pfile_in_zip_read_info->stream.avail_out =
1033 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1035 while (pfile_in_zip_read_info->stream.avail_out>0)
1037 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1038 (pfile_in_zip_read_info->rest_read_compressed>0))
1040 uInt uReadThis = UNZ_BUFSIZE;
1041 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1042 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1045 if (fseek(pfile_in_zip_read_info->file,
1046 pfile_in_zip_read_info->pos_in_zipfile +
1047 pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0)
1049 if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1,
1050 pfile_in_zip_read_info->file)!=1)
1052 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1054 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1056 pfile_in_zip_read_info->stream.next_in =
1057 (Bytef*)pfile_in_zip_read_info->read_buffer;
1058 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1061 if (pfile_in_zip_read_info->compression_method==0)
1064 if (pfile_in_zip_read_info->stream.avail_out <
1065 pfile_in_zip_read_info->stream.avail_in)
1066 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1068 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1070 for (i=0;i<uDoCopy;i++)
1071 *(pfile_in_zip_read_info->stream.next_out+i) =
1072 *(pfile_in_zip_read_info->stream.next_in+i);
1074 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1075 pfile_in_zip_read_info->stream.next_out,
1077 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1078 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1079 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1080 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1081 pfile_in_zip_read_info->stream.next_in += uDoCopy;
1082 pfile_in_zip_read_info->stream.total_out += uDoCopy;
1087 uLong uTotalOutBefore,uTotalOutAfter;
1088 const Bytef *bufBefore;
1090 int flush=Z_SYNC_FLUSH;
1092 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1093 bufBefore = pfile_in_zip_read_info->stream.next_out;
1096 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1097 pfile_in_zip_read_info->stream.avail_out) &&
1098 (pfile_in_zip_read_info->rest_read_compressed == 0))
1101 err=inflate(&pfile_in_zip_read_info->stream,flush);
1103 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1104 uOutThis = uTotalOutAfter-uTotalOutBefore;
1106 pfile_in_zip_read_info->crc32 =
1107 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1110 pfile_in_zip_read_info->rest_read_uncompressed -=
1113 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1115 if (err==Z_STREAM_END)
1116 return (iRead==0) ? UNZ_EOF : iRead;
1129 Give the current position in uncompressed data
1131 extern z_off_t ZEXPORT unztell (file)
1135 file_in_zip_read_info_s* pfile_in_zip_read_info;
1137 return UNZ_PARAMERROR;
1139 pfile_in_zip_read_info=s->pfile_in_zip_read;
1141 if (pfile_in_zip_read_info==NULL)
1142 return UNZ_PARAMERROR;
1144 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1149 return 1 if the end of file was reached, 0 elsewhere
1151 extern int ZEXPORT unzeof (file)
1155 file_in_zip_read_info_s* pfile_in_zip_read_info;
1157 return UNZ_PARAMERROR;
1159 pfile_in_zip_read_info=s->pfile_in_zip_read;
1161 if (pfile_in_zip_read_info==NULL)
1162 return UNZ_PARAMERROR;
1164 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1173 Read extra field from the current file (opened by unzOpenCurrentFile)
1174 This is the local-header version of the extra field (sometimes, there is
1175 more info in the local-header version than in the central-header)
1177 if buf==NULL, it return the size of the local extra field that can be read
1179 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1181 the return value is the number of bytes copied in buf, or (if <0)
1184 extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
1190 file_in_zip_read_info_s* pfile_in_zip_read_info;
1195 return UNZ_PARAMERROR;
1197 pfile_in_zip_read_info=s->pfile_in_zip_read;
1199 if (pfile_in_zip_read_info==NULL)
1200 return UNZ_PARAMERROR;
1202 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1203 pfile_in_zip_read_info->pos_local_extrafield);
1206 return (int)size_to_read;
1208 if (len>size_to_read)
1209 read_now = (uInt)size_to_read;
1211 read_now = (uInt)len ;
1216 if (fseek(pfile_in_zip_read_info->file,
1217 pfile_in_zip_read_info->offset_local_extrafield +
1218 pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0)
1221 if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1)
1224 return (int)read_now;
1228 Close the file in zip opened with unzipOpenCurrentFile
1229 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1231 extern int ZEXPORT unzCloseCurrentFile (file)
1237 file_in_zip_read_info_s* pfile_in_zip_read_info;
1239 return UNZ_PARAMERROR;
1241 pfile_in_zip_read_info=s->pfile_in_zip_read;
1243 if (pfile_in_zip_read_info==NULL)
1244 return UNZ_PARAMERROR;
1247 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1249 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1254 TRYFREE(pfile_in_zip_read_info->read_buffer);
1255 pfile_in_zip_read_info->read_buffer = NULL;
1256 if (pfile_in_zip_read_info->stream_initialised)
1257 inflateEnd(&pfile_in_zip_read_info->stream);
1259 pfile_in_zip_read_info->stream_initialised = 0;
1260 TRYFREE(pfile_in_zip_read_info);
1262 s->pfile_in_zip_read=NULL;
1269 Get the global comment string of the ZipFile, in the szComment buffer.
1270 uSizeBuf is the size of the szComment buffer.
1271 return the number of byte copied or an error code <0
1273 extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
1281 return UNZ_PARAMERROR;
1284 uReadThis = uSizeBuf;
1285 if (uReadThis>s->gi.size_comment)
1286 uReadThis = s->gi.size_comment;
1288 if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0)
1294 if (fread(szComment,(uInt)uReadThis,1,s->file)!=1)
1298 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1299 *(szComment+s->gi.size_comment)='\0';
1300 return (int)uReadThis;