4 /* unzip.c -- IO on .zip files using zlib
5 Version 0.15 beta, Mar 19th, 1998,
7 Read unzip.h for more info
10 /* Modified my Joseph Wenninger*/
17 #include "toolbox/logging.h"
37 #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
38 !defined(CASESENSITIVITYDEFAULT_NO)
39 #define CASESENSITIVITYDEFAULT_NO
44 #define UNZ_BUFSIZE (16384)
47 #ifndef UNZ_MAXFILENAMEINZIP
48 #define UNZ_MAXFILENAMEINZIP (256)
52 # define ALLOC(size) (malloc(size))
55 # define TRYFREE(p) {if (p) free(p);}
58 #define SIZECENTRALDIRITEM (0x2e)
59 #define SIZEZIPLOCALHEADER (0x1e)
62 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
76 const char unz_copyright[] =
77 " unzip 0.15 Copyright 1998 Gilles Vollant ";
80 /* ===========================================================================
81 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
83 IN assertion: the stream s has been sucessfully opened for reading.
87 int unzlocal_getByte(fin,pi)
92 int err = fread(&c, 1, 1, fin);
108 /* ===========================================================================
109 Reads a long in LSB order from the given gz_stream. Sets
111 int unzlocal_getShort (fin,pX)
119 err = unzlocal_getByte(fin,&i);
123 err = unzlocal_getByte(fin,&i);
133 int unzlocal_getLong (fin,pX)
141 err = unzlocal_getByte(fin,&i);
145 err = unzlocal_getByte(fin,&i);
149 err = unzlocal_getByte(fin,&i);
153 err = unzlocal_getByte(fin,&i);
164 /* My own strcmpi / strcasecmp */
165 int strcmpcasenosensitive_internal (fileName1,fileName2)
166 const char* fileName1;
167 const char* fileName2;
171 char c1=*(fileName1++);
172 char c2=*(fileName2++);
173 if ((c1>='a') && (c1<='z'))
175 if ((c2>='a') && (c2<='z'))
178 return ((c2=='\0') ? 0 : -1);
189 #ifdef CASESENSITIVITYDEFAULT_NO
190 #define CASESENSITIVITYDEFAULTVALUE 2
192 #define CASESENSITIVITYDEFAULTVALUE 1
195 #ifndef STRCMPCASENOSENTIVEFUNCTION
196 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
200 Compare two filename (fileName1,fileName2).
201 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
202 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
204 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
205 (like 1 on Unix, 2 on Windows)
208 int unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
209 const char* fileName1;
210 const char* fileName2;
211 int iCaseSensitivity;
213 if (iCaseSensitivity==0)
214 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
216 if (iCaseSensitivity==1)
217 return strcmp(fileName1,fileName2);
219 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
222 #define BUFREADCOMMENT (0x400)
225 Locate the Central directory of a zipfile (at the end, just before
228 uLong unzlocal_SearchCentralDir(fin)
234 uLong uMaxBack=0xffff; /* maximum size of global comment */
237 if (fseek(fin,0,SEEK_END) != 0)
241 uSizeFile = ftell( fin );
243 if (uMaxBack>uSizeFile)
244 uMaxBack = uSizeFile;
246 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
251 while (uBackRead<uMaxBack)
253 uLong uReadSize,uReadPos ;
255 if (uBackRead+BUFREADCOMMENT>uMaxBack)
256 uBackRead = uMaxBack;
258 uBackRead+=BUFREADCOMMENT;
259 uReadPos = uSizeFile-uBackRead ;
261 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
262 (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
263 if (fseek(fin,uReadPos,SEEK_SET)!=0)
266 if (fread(buf,(uInt)uReadSize,1,fin)!=1)
269 for (i=(int)uReadSize-3; (i--)>0;)
270 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
271 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
273 uPosFound = uReadPos+i;
285 Open a Zip file. path contain the full pathname (by example,
286 on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
288 If the zipfile cannot be opened (file don't exist or in not valid), the
289 return value is NULL.
290 Else, the return value is a unzFile Handle, usable with other function
291 of this unzip package.
293 unzFile unzOpen (path)
298 uLong central_pos,uL;
301 uLong number_disk; /* number of the current dist, used for
302 spaning ZIP, unsupported, always 0*/
303 uLong number_disk_with_CD; /* number the the disk with central dir, used
304 for spaning ZIP, unsupported, always 0*/
305 uLong number_entry_CD; /* total number of entries in
307 (same than number_entry on nospan) */
311 if (unz_copyright[0]!=' ')
314 fin=fopen(path,"rb");
318 central_pos = unzlocal_SearchCentralDir(fin);
322 if (fseek(fin,central_pos,SEEK_SET)!=0)
325 /* the signature, already checked */
326 if (unzlocal_getLong(fin,&uL)!=UNZ_OK)
329 /* number of this disk */
330 if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK)
333 /* number of the disk with the start of the central directory */
334 if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK)
337 /* total number of entries in the central dir on this disk */
338 if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK)
341 /* total number of entries in the central dir */
342 if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK)
345 if ((number_entry_CD!=us.gi.number_entry) ||
346 (number_disk_with_CD!=0) ||
350 /* size of the central directory */
351 if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK)
353 /* offset of start of central directory with respect to the
354 starting disk number */
355 if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK)
358 /* zipfile comment length */
359 if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK)
362 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
373 us.byte_before_the_zipfile = central_pos -
374 (us.offset_central_dir+us.size_central_dir);
375 us.central_pos = central_pos;
376 us.pfile_in_zip_read = NULL;
379 s=(unz_s*)ALLOC(sizeof(unz_s));
382 cacao_create_directoryList(s);
384 unzGoToFirstFile((unzFile)s);
390 Close a ZipFile opened with unzipOpen.
391 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
392 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
393 return UNZ_OK if there is no problem. */
399 return UNZ_PARAMERROR;
402 if (s->pfile_in_zip_read!=NULL)
403 unzCloseCurrentFile(file);
412 Write info about the ZipFile in the *pglobal_info structure.
413 No preparation of the structure is needed
414 return UNZ_OK if there is no problem. */
415 int unzGetGlobalInfo (file,pglobal_info)
417 unz_global_info *pglobal_info;
421 return UNZ_PARAMERROR;
429 Translate date/time from Dos format to tm_unz (readable more easilty)
431 void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
436 uDate = (uLong)(ulDosDate>>16);
437 ptm->tm_mday = (uInt)(uDate&0x1f) ;
438 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
439 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
441 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
442 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
443 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
447 Get Info about the current file in the zipfile, with internal only info
449 int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
450 unz_file_info *pfile_info,
451 unz_file_info_internal
452 *pfile_info_internal,
454 uLong fileNameBufferSize,
456 uLong extraFieldBufferSize,
458 uLong commentBufferSize));
460 int unzlocal_GetCurrentFileInfoInternal (file,
463 szFileName, fileNameBufferSize,
464 extraField, extraFieldBufferSize,
465 szComment, commentBufferSize)
467 unz_file_info *pfile_info;
468 unz_file_info_internal *pfile_info_internal;
470 uLong fileNameBufferSize;
472 uLong extraFieldBufferSize;
474 uLong commentBufferSize;
477 unz_file_info file_info;
478 unz_file_info_internal file_info_internal;
484 return UNZ_PARAMERROR;
486 if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0)
490 /* we check the magic */
492 if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
494 else if (uMagic!=0x02014b50)
498 if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK)
501 if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK)
504 if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK)
507 if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK)
510 if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK)
513 unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
515 if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK)
518 if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK)
521 if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK)
524 if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK)
527 if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK)
530 if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK)
533 if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK)
536 if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK)
539 if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK)
542 if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK)
545 lSeek+=file_info.size_filename;
546 if ((err==UNZ_OK) && (szFileName!=NULL))
549 if (file_info.size_filename<fileNameBufferSize)
551 *(szFileName+file_info.size_filename)='\0';
552 uSizeRead = file_info.size_filename;
555 uSizeRead = fileNameBufferSize;
557 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
558 if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1)
564 if ((err==UNZ_OK) && (extraField!=NULL))
567 if (file_info.size_file_extra<extraFieldBufferSize)
568 uSizeRead = file_info.size_file_extra;
570 uSizeRead = extraFieldBufferSize;
573 if (fseek(s->file,lSeek,SEEK_CUR)==0)
579 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
580 if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1)
582 lSeek += file_info.size_file_extra - uSizeRead;
585 lSeek+=file_info.size_file_extra;
588 if ((err==UNZ_OK) && (szComment!=NULL))
591 if (file_info.size_file_comment<commentBufferSize)
593 *(szComment+file_info.size_file_comment)='\0';
594 uSizeRead = file_info.size_file_comment;
597 uSizeRead = commentBufferSize;
600 if (fseek(s->file,lSeek,SEEK_CUR)==0)
606 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
607 if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1)
609 lSeek+=file_info.size_file_comment - uSizeRead;
612 lSeek+=file_info.size_file_comment;
614 if ((err==UNZ_OK) && (pfile_info!=NULL))
615 *pfile_info=file_info;
617 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
618 *pfile_info_internal=file_info_internal;
626 Write info about the ZipFile in the *pglobal_info structure.
627 No preparation of the structure is needed
628 return UNZ_OK if there is no problem.
630 int unzGetCurrentFileInfo (file,
632 szFileName, fileNameBufferSize,
633 extraField, extraFieldBufferSize,
634 szComment, commentBufferSize)
636 unz_file_info *pfile_info;
638 uLong fileNameBufferSize;
640 uLong extraFieldBufferSize;
642 uLong commentBufferSize;
644 return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
645 szFileName,fileNameBufferSize,
646 extraField,extraFieldBufferSize,
647 szComment,commentBufferSize);
651 Set the current file of the zipfile to the first file.
652 return UNZ_OK if there is no problem
654 int unzGoToFirstFile (file)
660 return UNZ_PARAMERROR;
662 s->pos_in_central_dir=s->offset_central_dir;
664 err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
665 &s->cur_file_info_internal,
666 NULL,0,NULL,0,NULL,0);
667 s->current_file_ok = (err == UNZ_OK);
674 Set the current file of the zipfile to the next file.
675 return UNZ_OK if there is no problem
676 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
678 int unzGoToNextFile (file)
685 return UNZ_PARAMERROR;
687 if (!s->current_file_ok)
688 return UNZ_END_OF_LIST_OF_FILE;
689 if (s->num_file+1==s->gi.number_entry)
690 return UNZ_END_OF_LIST_OF_FILE;
692 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
693 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
695 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
696 &s->cur_file_info_internal,
697 NULL,0,NULL,0,NULL,0);
698 s->current_file_ok = (err == UNZ_OK);
703 void cacao_create_directoryList(unzFile file)
706 unz_s* s=(unz_s*)file;
711 if (unzGoToFirstFile(file)!=UNZ_OK) {
716 ent = s->cacao_dir_list = (cacao_entry_s *) ALLOC(sizeof(cacao_entry_s));
718 ent->pos=s->pos_in_central_dir;
720 if (unzGetCurrentFileInfo (file,
726 panic("Error in ZIP archive");
731 ent->name=utf_new_char(filename);
732 while (unzGoToNextFile(file)==UNZ_OK) {
734 ent->next=(cacao_entry_s*)ALLOC(sizeof(cacao_entry_s));
737 ent->pos=s->pos_in_central_dir;
739 if (unzGetCurrentFileInfo (file,
745 panic("Error in ZIP archive");
747 c=strstr(filename,".class");
749 ent->name=utf_new_char(filename);
751 /*printf("Archive contains %d files\n",i);*/
756 Try locate the file szFileName in the zipfile.
757 For the iCaseSensitivity signification, see unzipStringFileNameCompare
760 UNZ_OK if the file is found. It becomes the current file.
761 UNZ_END_OF_LIST_OF_FILE if the file is not found
763 int unzLocateFile (file, szFileName, iCaseSensitivity)
765 const char *szFileName;
766 int iCaseSensitivity;
773 uLong pos_in_central_dirSaved;
775 printf("Starting lookup\n");
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) {
801 printf("class found in zip directory\n");
806 err = unzGoToNextFile(file);
809 s->num_file = num_fileSaved ;
810 s->pos_in_central_dir = pos_in_central_dirSaved ;
814 int cacao_locate(unzFile file,utf* filename) {
815 unz_s* s=(unz_s*)file;
817 for (ent=s->cacao_dir_list;ent;ent=ent->next) {
818 /* printf("searching: ");utf_display(filename);
819 printf(" current: ");utf_display(ent->name);
821 if (ent->name==filename) {
822 s->pos_in_central_dir=ent->pos;
823 return unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
824 &s->cur_file_info_internal,
825 NULL,0,NULL,0,NULL,0);
828 return UNZ_END_OF_LIST_OF_FILE;
833 Read the local header of the current zipfile
834 Check the coherency of the local header and info in the end of central
835 directory about this file
836 store in *piSizeVar the size of extra info in local header
837 (filename and size of extra field data)
839 int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
840 poffset_local_extrafield,
841 psize_local_extrafield)
844 uLong *poffset_local_extrafield;
845 uInt *psize_local_extrafield;
847 uLong uMagic,uData,uFlags;
849 uLong size_extra_field;
853 *poffset_local_extrafield = 0;
854 *psize_local_extrafield = 0;
856 if (fseek(s->file,s->cur_file_info_internal.offset_curfile +
857 s->byte_before_the_zipfile,SEEK_SET)!=0)
862 if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
864 else if (uMagic!=0x04034b50)
868 if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
871 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
874 if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK)
877 if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
879 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
882 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
883 (s->cur_file_info.compression_method!=Z_DEFLATED))
886 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */
889 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */
891 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
895 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */
897 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
901 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */
903 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
908 if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK)
910 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
913 *piSizeVar += (uInt)size_filename;
915 if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK)
917 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
918 SIZEZIPLOCALHEADER + size_filename;
919 *psize_local_extrafield = (uInt)size_extra_field;
921 *piSizeVar += (uInt)size_extra_field;
927 Open for reading data the current file in the zipfile.
928 If there is no error and the file is opened, the return value is UNZ_OK.
930 int unzOpenCurrentFile (file)
937 file_in_zip_read_info_s* pfile_in_zip_read_info;
938 uLong offset_local_extrafield; /* offset of the local extra field */
939 uInt size_local_extrafield; /* size of the local extra field */
942 return UNZ_PARAMERROR;
944 if (!s->current_file_ok)
945 return UNZ_PARAMERROR;
947 if (s->pfile_in_zip_read != NULL)
948 unzCloseCurrentFile(file);
950 if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
951 &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
952 return UNZ_BADZIPFILE;
954 pfile_in_zip_read_info = (file_in_zip_read_info_s*)
955 ALLOC(sizeof(file_in_zip_read_info_s));
956 if (pfile_in_zip_read_info==NULL)
957 return UNZ_INTERNALERROR;
959 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
960 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
961 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
962 pfile_in_zip_read_info->pos_local_extrafield=0;
964 if (pfile_in_zip_read_info->read_buffer==NULL)
966 TRYFREE(pfile_in_zip_read_info);
967 return UNZ_INTERNALERROR;
970 pfile_in_zip_read_info->stream_initialised=0;
972 if ((s->cur_file_info.compression_method!=0) &&
973 (s->cur_file_info.compression_method!=Z_DEFLATED))
975 Store = s->cur_file_info.compression_method==0;
977 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
978 pfile_in_zip_read_info->crc32=0;
979 pfile_in_zip_read_info->compression_method =
980 s->cur_file_info.compression_method;
981 pfile_in_zip_read_info->file=s->file;
982 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
984 pfile_in_zip_read_info->stream.total_out = 0;
988 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
989 pfile_in_zip_read_info->stream.zfree = (free_func)0;
990 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
992 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
994 pfile_in_zip_read_info->stream_initialised=1;
995 /* windowBits is passed < 0 to tell that there is no zlib header.
996 * Note that in this case inflate *requires* an extra "dummy" byte
997 * after the compressed stream in order to complete decompression and
998 * return Z_STREAM_END.
999 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1000 * size of both compressed and uncompressed data
1003 pfile_in_zip_read_info->rest_read_compressed =
1004 s->cur_file_info.compressed_size ;
1005 pfile_in_zip_read_info->rest_read_uncompressed =
1006 s->cur_file_info.uncompressed_size ;
1009 pfile_in_zip_read_info->pos_in_zipfile =
1010 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1013 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1016 s->pfile_in_zip_read = pfile_in_zip_read_info;
1023 Read bytes from the current file.
1024 buf contain buffer where data must be copied
1025 len the size of buf.
1027 return the number of byte copied if somes bytes are copied
1028 return 0 if the end of file was reached
1029 return <0 with error code if there is an error
1030 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1032 int unzReadCurrentFile (file, buf, len)
1040 file_in_zip_read_info_s* pfile_in_zip_read_info;
1042 return UNZ_PARAMERROR;
1044 pfile_in_zip_read_info=s->pfile_in_zip_read;
1046 if (pfile_in_zip_read_info==NULL)
1047 return UNZ_PARAMERROR;
1050 if ((pfile_in_zip_read_info->read_buffer == NULL))
1051 return UNZ_END_OF_LIST_OF_FILE;
1055 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1057 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1059 if (len>pfile_in_zip_read_info->rest_read_uncompressed)
1060 pfile_in_zip_read_info->stream.avail_out =
1061 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1063 while (pfile_in_zip_read_info->stream.avail_out>0)
1065 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1066 (pfile_in_zip_read_info->rest_read_compressed>0))
1068 uInt uReadThis = UNZ_BUFSIZE;
1069 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1070 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1073 if (fseek(pfile_in_zip_read_info->file,
1074 pfile_in_zip_read_info->pos_in_zipfile +
1075 pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0)
1077 if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1,
1078 pfile_in_zip_read_info->file)!=1)
1080 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1082 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1084 pfile_in_zip_read_info->stream.next_in =
1085 (Bytef*)pfile_in_zip_read_info->read_buffer;
1086 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1089 if (pfile_in_zip_read_info->compression_method==0)
1092 if (pfile_in_zip_read_info->stream.avail_out <
1093 pfile_in_zip_read_info->stream.avail_in)
1094 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1096 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1098 for (i=0;i<uDoCopy;i++)
1099 *(pfile_in_zip_read_info->stream.next_out+i) =
1100 *(pfile_in_zip_read_info->stream.next_in+i);
1102 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1103 pfile_in_zip_read_info->stream.next_out,
1105 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1106 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1107 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1108 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1109 pfile_in_zip_read_info->stream.next_in += uDoCopy;
1110 pfile_in_zip_read_info->stream.total_out += uDoCopy;
1115 uLong uTotalOutBefore,uTotalOutAfter;
1116 const Bytef *bufBefore;
1118 int flush=Z_SYNC_FLUSH;
1120 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1121 bufBefore = pfile_in_zip_read_info->stream.next_out;
1124 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1125 pfile_in_zip_read_info->stream.avail_out) &&
1126 (pfile_in_zip_read_info->rest_read_compressed == 0))
1129 err=inflate(&pfile_in_zip_read_info->stream,flush);
1131 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1132 uOutThis = uTotalOutAfter-uTotalOutBefore;
1134 pfile_in_zip_read_info->crc32 =
1135 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1138 pfile_in_zip_read_info->rest_read_uncompressed -=
1141 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1143 if (err==Z_STREAM_END)
1144 return (iRead==0) ? UNZ_EOF : iRead;
1157 Give the current position in uncompressed data
1159 z_off_t unztell (file)
1163 file_in_zip_read_info_s* pfile_in_zip_read_info;
1165 return UNZ_PARAMERROR;
1167 pfile_in_zip_read_info=s->pfile_in_zip_read;
1169 if (pfile_in_zip_read_info==NULL)
1170 return UNZ_PARAMERROR;
1172 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1177 return 1 if the end of file was reached, 0 elsewhere
1183 file_in_zip_read_info_s* pfile_in_zip_read_info;
1185 return UNZ_PARAMERROR;
1187 pfile_in_zip_read_info=s->pfile_in_zip_read;
1189 if (pfile_in_zip_read_info==NULL)
1190 return UNZ_PARAMERROR;
1192 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1201 Read extra field from the current file (opened by unzOpenCurrentFile)
1202 This is the local-header version of the extra field (sometimes, there is
1203 more info in the local-header version than in the central-header)
1205 if buf==NULL, it return the size of the local extra field that can be read
1207 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1209 the return value is the number of bytes copied in buf, or (if <0)
1212 int unzGetLocalExtrafield (file,buf,len)
1218 file_in_zip_read_info_s* pfile_in_zip_read_info;
1223 return UNZ_PARAMERROR;
1225 pfile_in_zip_read_info=s->pfile_in_zip_read;
1227 if (pfile_in_zip_read_info==NULL)
1228 return UNZ_PARAMERROR;
1230 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1231 pfile_in_zip_read_info->pos_local_extrafield);
1234 return (int)size_to_read;
1236 if (len>size_to_read)
1237 read_now = (uInt)size_to_read;
1239 read_now = (uInt)len ;
1244 if (fseek(pfile_in_zip_read_info->file,
1245 pfile_in_zip_read_info->offset_local_extrafield +
1246 pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0)
1249 if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1)
1252 return (int)read_now;
1256 Close the file in zip opened with unzipOpenCurrentFile
1257 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1259 int unzCloseCurrentFile (file)
1265 file_in_zip_read_info_s* pfile_in_zip_read_info;
1267 return UNZ_PARAMERROR;
1269 pfile_in_zip_read_info=s->pfile_in_zip_read;
1271 if (pfile_in_zip_read_info==NULL)
1272 return UNZ_PARAMERROR;
1275 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1277 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1282 TRYFREE(pfile_in_zip_read_info->read_buffer);
1283 pfile_in_zip_read_info->read_buffer = NULL;
1284 if (pfile_in_zip_read_info->stream_initialised)
1285 inflateEnd(&pfile_in_zip_read_info->stream);
1287 pfile_in_zip_read_info->stream_initialised = 0;
1288 TRYFREE(pfile_in_zip_read_info);
1290 s->pfile_in_zip_read=NULL;
1297 Get the global comment string of the ZipFile, in the szComment buffer.
1298 uSizeBuf is the size of the szComment buffer.
1299 return the number of byte copied or an error code <0
1301 int unzGetGlobalComment (file, szComment, uSizeBuf)
1310 return UNZ_PARAMERROR;
1313 uReadThis = uSizeBuf;
1314 if (uReadThis>s->gi.size_comment)
1315 uReadThis = s->gi.size_comment;
1317 if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0)
1323 if (fread(szComment,(uInt)uReadThis,1,s->file)!=1)
1327 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1328 *(szComment+s->gi.size_comment)='\0';
1329 return (int)uReadThis;