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 "mm/memory.h"
18 #include "toolbox/logging.h"
38 #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
39 !defined(CASESENSITIVITYDEFAULT_NO)
40 #define CASESENSITIVITYDEFAULT_NO
45 #define UNZ_BUFSIZE (16384)
48 #ifndef UNZ_MAXFILENAMEINZIP
49 #define UNZ_MAXFILENAMEINZIP (256)
53 # define ALLOC(size) (malloc(size))
56 # define TRYFREE(p) {if (p) free(p);}
59 #define SIZECENTRALDIRITEM (0x2e)
60 #define SIZEZIPLOCALHEADER (0x1e)
63 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
77 const char unz_copyright[] =
78 " unzip 0.15 Copyright 1998 Gilles Vollant ";
81 /* ===========================================================================
82 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
84 IN assertion: the stream s has been sucessfully opened for reading.
88 int unzlocal_getByte(fin,pi)
93 int err = fread(&c, 1, 1, fin);
109 /* ===========================================================================
110 Reads a long in LSB order from the given gz_stream. Sets
112 int unzlocal_getShort (fin,pX)
120 err = unzlocal_getByte(fin,&i);
124 err = unzlocal_getByte(fin,&i);
134 int unzlocal_getLong (fin,pX)
142 err = unzlocal_getByte(fin,&i);
146 err = unzlocal_getByte(fin,&i);
150 err = unzlocal_getByte(fin,&i);
154 err = unzlocal_getByte(fin,&i);
165 /* My own strcmpi / strcasecmp */
166 int strcmpcasenosensitive_internal (fileName1,fileName2)
167 const char* fileName1;
168 const char* fileName2;
172 char c1=*(fileName1++);
173 char c2=*(fileName2++);
174 if ((c1>='a') && (c1<='z'))
176 if ((c2>='a') && (c2<='z'))
179 return ((c2=='\0') ? 0 : -1);
190 #ifdef CASESENSITIVITYDEFAULT_NO
191 #define CASESENSITIVITYDEFAULTVALUE 2
193 #define CASESENSITIVITYDEFAULTVALUE 1
196 #ifndef STRCMPCASENOSENTIVEFUNCTION
197 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
201 Compare two filename (fileName1,fileName2).
202 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
203 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
205 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
206 (like 1 on Unix, 2 on Windows)
209 int unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
210 const char* fileName1;
211 const char* fileName2;
212 int iCaseSensitivity;
214 if (iCaseSensitivity==0)
215 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
217 if (iCaseSensitivity==1)
218 return strcmp(fileName1,fileName2);
220 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
223 #define BUFREADCOMMENT (0x400)
226 Locate the Central directory of a zipfile (at the end, just before
229 uLong unzlocal_SearchCentralDir(fin)
235 uLong uMaxBack=0xffff; /* maximum size of global comment */
238 if (fseek(fin,0,SEEK_END) != 0)
242 uSizeFile = ftell( fin );
244 if (uMaxBack>uSizeFile)
245 uMaxBack = uSizeFile;
247 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
252 while (uBackRead<uMaxBack)
254 uLong uReadSize,uReadPos ;
256 if (uBackRead+BUFREADCOMMENT>uMaxBack)
257 uBackRead = uMaxBack;
259 uBackRead+=BUFREADCOMMENT;
260 uReadPos = uSizeFile-uBackRead ;
262 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
263 (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
264 if (fseek(fin,uReadPos,SEEK_SET)!=0)
267 if (fread(buf,(uInt)uReadSize,1,fin)!=1)
270 for (i=(int)uReadSize-3; (i--)>0;)
271 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
272 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
274 uPosFound = uReadPos+i;
286 Open a Zip file. path contain the full pathname (by example,
287 on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
289 If the zipfile cannot be opened (file don't exist or in not valid), the
290 return value is NULL.
291 Else, the return value is a unzFile Handle, usable with other function
292 of this unzip package.
294 unzFile unzOpen (path)
299 uLong central_pos,uL;
302 uLong number_disk; /* number of the current dist, used for
303 spaning ZIP, unsupported, always 0*/
304 uLong number_disk_with_CD; /* number the the disk with central dir, used
305 for spaning ZIP, unsupported, always 0*/
306 uLong number_entry_CD; /* total number of entries in
308 (same than number_entry on nospan) */
312 if (unz_copyright[0]!=' ')
315 fin=fopen(path,"rb");
319 central_pos = unzlocal_SearchCentralDir(fin);
323 if (fseek(fin,central_pos,SEEK_SET)!=0)
326 /* the signature, already checked */
327 if (unzlocal_getLong(fin,&uL)!=UNZ_OK)
330 /* number of this disk */
331 if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK)
334 /* number of the disk with the start of the central directory */
335 if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK)
338 /* total number of entries in the central dir on this disk */
339 if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK)
342 /* total number of entries in the central dir */
343 if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK)
346 if ((number_entry_CD!=us.gi.number_entry) ||
347 (number_disk_with_CD!=0) ||
351 /* size of the central directory */
352 if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK)
354 /* offset of start of central directory with respect to the
355 starting disk number */
356 if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK)
359 /* zipfile comment length */
360 if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK)
363 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
374 us.byte_before_the_zipfile = central_pos -
375 (us.offset_central_dir+us.size_central_dir);
376 us.central_pos = central_pos;
377 us.pfile_in_zip_read = NULL;
380 s=(unz_s*)ALLOC(sizeof(unz_s));
383 cacao_create_directoryList(s);
385 unzGoToFirstFile((unzFile)s);
391 Close a ZipFile opened with unzipOpen.
392 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
393 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
394 return UNZ_OK if there is no problem. */
400 return UNZ_PARAMERROR;
403 if (s->pfile_in_zip_read!=NULL)
404 unzCloseCurrentFile(file);
413 Write info about the ZipFile in the *pglobal_info structure.
414 No preparation of the structure is needed
415 return UNZ_OK if there is no problem. */
416 int unzGetGlobalInfo (file,pglobal_info)
418 unz_global_info *pglobal_info;
422 return UNZ_PARAMERROR;
430 Translate date/time from Dos format to tm_unz (readable more easilty)
432 void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
437 uDate = (uLong)(ulDosDate>>16);
438 ptm->tm_mday = (uInt)(uDate&0x1f) ;
439 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
440 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
442 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
443 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
444 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
448 Get Info about the current file in the zipfile, with internal only info
450 int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
451 unz_file_info *pfile_info,
452 unz_file_info_internal
453 *pfile_info_internal,
455 uLong fileNameBufferSize,
457 uLong extraFieldBufferSize,
459 uLong commentBufferSize));
461 int unzlocal_GetCurrentFileInfoInternal (file,
464 szFileName, fileNameBufferSize,
465 extraField, extraFieldBufferSize,
466 szComment, commentBufferSize)
468 unz_file_info *pfile_info;
469 unz_file_info_internal *pfile_info_internal;
471 uLong fileNameBufferSize;
473 uLong extraFieldBufferSize;
475 uLong commentBufferSize;
478 unz_file_info file_info;
479 unz_file_info_internal file_info_internal;
485 return UNZ_PARAMERROR;
487 if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0)
491 /* we check the magic */
493 if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
495 else if (uMagic!=0x02014b50)
499 if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK)
502 if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK)
505 if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK)
508 if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK)
511 if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK)
514 unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
516 if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK)
519 if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK)
522 if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK)
525 if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK)
528 if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK)
531 if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK)
534 if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK)
537 if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK)
540 if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK)
543 if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK)
546 lSeek+=file_info.size_filename;
547 if ((err==UNZ_OK) && (szFileName!=NULL))
550 if (file_info.size_filename<fileNameBufferSize)
552 *(szFileName+file_info.size_filename)='\0';
553 uSizeRead = file_info.size_filename;
556 uSizeRead = fileNameBufferSize;
558 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
559 if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1)
565 if ((err==UNZ_OK) && (extraField!=NULL))
568 if (file_info.size_file_extra<extraFieldBufferSize)
569 uSizeRead = file_info.size_file_extra;
571 uSizeRead = extraFieldBufferSize;
574 if (fseek(s->file,lSeek,SEEK_CUR)==0)
580 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
581 if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1)
583 lSeek += file_info.size_file_extra - uSizeRead;
586 lSeek+=file_info.size_file_extra;
589 if ((err==UNZ_OK) && (szComment!=NULL))
592 if (file_info.size_file_comment<commentBufferSize)
594 *(szComment+file_info.size_file_comment)='\0';
595 uSizeRead = file_info.size_file_comment;
598 uSizeRead = commentBufferSize;
601 if (fseek(s->file,lSeek,SEEK_CUR)==0)
607 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
608 if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1)
610 lSeek+=file_info.size_file_comment - uSizeRead;
613 lSeek+=file_info.size_file_comment;
615 if ((err==UNZ_OK) && (pfile_info!=NULL))
616 *pfile_info=file_info;
618 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
619 *pfile_info_internal=file_info_internal;
627 Write info about the ZipFile in the *pglobal_info structure.
628 No preparation of the structure is needed
629 return UNZ_OK if there is no problem.
631 int unzGetCurrentFileInfo (file,
633 szFileName, fileNameBufferSize,
634 extraField, extraFieldBufferSize,
635 szComment, commentBufferSize)
637 unz_file_info *pfile_info;
639 uLong fileNameBufferSize;
641 uLong extraFieldBufferSize;
643 uLong commentBufferSize;
645 return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
646 szFileName,fileNameBufferSize,
647 extraField,extraFieldBufferSize,
648 szComment,commentBufferSize);
652 Set the current file of the zipfile to the first file.
653 return UNZ_OK if there is no problem
655 int unzGoToFirstFile (file)
661 return UNZ_PARAMERROR;
663 s->pos_in_central_dir=s->offset_central_dir;
665 err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
666 &s->cur_file_info_internal,
667 NULL,0,NULL,0,NULL,0);
668 s->current_file_ok = (err == UNZ_OK);
675 Set the current file of the zipfile to the next file.
676 return UNZ_OK if there is no problem
677 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
679 int unzGoToNextFile (file)
686 return UNZ_PARAMERROR;
688 if (!s->current_file_ok)
689 return UNZ_END_OF_LIST_OF_FILE;
690 if (s->num_file+1==s->gi.number_entry)
691 return UNZ_END_OF_LIST_OF_FILE;
693 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
694 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
696 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
697 &s->cur_file_info_internal,
698 NULL,0,NULL,0,NULL,0);
699 s->current_file_ok = (err == UNZ_OK);
704 void cacao_create_directoryList(unzFile file)
707 unz_s *s=(unz_s*)file;
712 s->cacao_dir_list = NULL;
714 if (unzGoToFirstFile(file) != UNZ_OK)
718 if (unzGetCurrentFileInfo(file, &tmp, filename, 200, 0, 0, 0, 0) != UNZ_OK)
719 panic("Error in ZIP archive");
721 if ((c = strstr(filename, ".class"))) {
724 if (!s->cacao_dir_list) {
725 ent = s->cacao_dir_list = NEW(cacao_entry_s);
728 ent->next = NEW(cacao_entry_s);
734 ent->name = utf_new_char(filename);
735 ent->pos = s->pos_in_central_dir;
737 } while (unzGoToNextFile(file) == UNZ_OK);
742 Try locate the file szFileName in the zipfile.
743 For the iCaseSensitivity signification, see unzipStringFileNameCompare
746 UNZ_OK if the file is found. It becomes the current file.
747 UNZ_END_OF_LIST_OF_FILE if the file is not found
749 int unzLocateFile (file, szFileName, iCaseSensitivity)
751 const char *szFileName;
752 int iCaseSensitivity;
759 uLong pos_in_central_dirSaved;
761 printf("Starting lookup\n");
765 return UNZ_PARAMERROR;
767 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
768 return UNZ_PARAMERROR;
771 if (!s->current_file_ok)
772 return UNZ_END_OF_LIST_OF_FILE;
774 num_fileSaved = s->num_file;
775 pos_in_central_dirSaved = s->pos_in_central_dir;
777 err = unzGoToFirstFile(file);
779 while (err == UNZ_OK)
781 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
782 unzGetCurrentFileInfo(file,NULL,
783 szCurrentFileName,sizeof(szCurrentFileName)-1,
785 if (unzStringFileNameCompare(szCurrentFileName,
786 szFileName,iCaseSensitivity)==0) {
787 printf("class found in zip directory\n");
792 err = unzGoToNextFile(file);
795 s->num_file = num_fileSaved ;
796 s->pos_in_central_dir = pos_in_central_dirSaved ;
800 int cacao_locate(unzFile file, utf* filename)
807 for (ent = s->cacao_dir_list; ent; ent = ent->next) {
809 printf("searching: ");utf_display(filename);
810 printf(" current: ");utf_display(ent->name);
813 if (ent->name == filename) {
814 s->pos_in_central_dir = ent->pos;
815 return unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info,
816 &s->cur_file_info_internal,
817 NULL, 0, NULL, 0, NULL, 0);
821 return UNZ_END_OF_LIST_OF_FILE;
827 Read the local header of the current zipfile
828 Check the coherency of the local header and info in the end of central
829 directory about this file
830 store in *piSizeVar the size of extra info in local header
831 (filename and size of extra field data)
833 int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
834 poffset_local_extrafield,
835 psize_local_extrafield)
838 uLong *poffset_local_extrafield;
839 uInt *psize_local_extrafield;
841 uLong uMagic,uData,uFlags;
843 uLong size_extra_field;
847 *poffset_local_extrafield = 0;
848 *psize_local_extrafield = 0;
850 if (fseek(s->file,s->cur_file_info_internal.offset_curfile +
851 s->byte_before_the_zipfile,SEEK_SET)!=0)
856 if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
858 else if (uMagic!=0x04034b50)
862 if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
865 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
868 if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK)
871 if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
873 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
876 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
877 (s->cur_file_info.compression_method!=Z_DEFLATED))
880 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */
883 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */
885 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
889 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */
891 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
895 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */
897 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
902 if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK)
904 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
907 *piSizeVar += (uInt)size_filename;
909 if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK)
911 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
912 SIZEZIPLOCALHEADER + size_filename;
913 *psize_local_extrafield = (uInt)size_extra_field;
915 *piSizeVar += (uInt)size_extra_field;
921 Open for reading data the current file in the zipfile.
922 If there is no error and the file is opened, the return value is UNZ_OK.
924 int unzOpenCurrentFile (file)
931 file_in_zip_read_info_s* pfile_in_zip_read_info;
932 uLong offset_local_extrafield; /* offset of the local extra field */
933 uInt size_local_extrafield; /* size of the local extra field */
936 return UNZ_PARAMERROR;
938 if (!s->current_file_ok)
939 return UNZ_PARAMERROR;
941 if (s->pfile_in_zip_read != NULL)
942 unzCloseCurrentFile(file);
944 if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
945 &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
946 return UNZ_BADZIPFILE;
948 pfile_in_zip_read_info = (file_in_zip_read_info_s*)
949 ALLOC(sizeof(file_in_zip_read_info_s));
950 if (pfile_in_zip_read_info==NULL)
951 return UNZ_INTERNALERROR;
953 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
954 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
955 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
956 pfile_in_zip_read_info->pos_local_extrafield=0;
958 if (pfile_in_zip_read_info->read_buffer==NULL)
960 TRYFREE(pfile_in_zip_read_info);
961 return UNZ_INTERNALERROR;
964 pfile_in_zip_read_info->stream_initialised=0;
966 if ((s->cur_file_info.compression_method!=0) &&
967 (s->cur_file_info.compression_method!=Z_DEFLATED))
969 Store = s->cur_file_info.compression_method==0;
971 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
972 pfile_in_zip_read_info->crc32=0;
973 pfile_in_zip_read_info->compression_method =
974 s->cur_file_info.compression_method;
975 pfile_in_zip_read_info->file=s->file;
976 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
978 pfile_in_zip_read_info->stream.total_out = 0;
982 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
983 pfile_in_zip_read_info->stream.zfree = (free_func)0;
984 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
986 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
988 pfile_in_zip_read_info->stream_initialised=1;
989 /* windowBits is passed < 0 to tell that there is no zlib header.
990 * Note that in this case inflate *requires* an extra "dummy" byte
991 * after the compressed stream in order to complete decompression and
992 * return Z_STREAM_END.
993 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
994 * size of both compressed and uncompressed data
997 pfile_in_zip_read_info->rest_read_compressed =
998 s->cur_file_info.compressed_size ;
999 pfile_in_zip_read_info->rest_read_uncompressed =
1000 s->cur_file_info.uncompressed_size ;
1003 pfile_in_zip_read_info->pos_in_zipfile =
1004 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1007 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1010 s->pfile_in_zip_read = pfile_in_zip_read_info;
1017 Read bytes from the current file.
1018 buf contain buffer where data must be copied
1019 len the size of buf.
1021 return the number of byte copied if somes bytes are copied
1022 return 0 if the end of file was reached
1023 return <0 with error code if there is an error
1024 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1026 int unzReadCurrentFile (file, buf, len)
1034 file_in_zip_read_info_s* pfile_in_zip_read_info;
1036 return UNZ_PARAMERROR;
1038 pfile_in_zip_read_info=s->pfile_in_zip_read;
1040 if (pfile_in_zip_read_info==NULL)
1041 return UNZ_PARAMERROR;
1044 if ((pfile_in_zip_read_info->read_buffer == NULL))
1045 return UNZ_END_OF_LIST_OF_FILE;
1049 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1051 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1053 if (len>pfile_in_zip_read_info->rest_read_uncompressed)
1054 pfile_in_zip_read_info->stream.avail_out =
1055 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1057 while (pfile_in_zip_read_info->stream.avail_out>0)
1059 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1060 (pfile_in_zip_read_info->rest_read_compressed>0))
1062 uInt uReadThis = UNZ_BUFSIZE;
1063 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1064 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1067 if (fseek(pfile_in_zip_read_info->file,
1068 pfile_in_zip_read_info->pos_in_zipfile +
1069 pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0)
1071 if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1,
1072 pfile_in_zip_read_info->file)!=1)
1074 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1076 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1078 pfile_in_zip_read_info->stream.next_in =
1079 (Bytef*)pfile_in_zip_read_info->read_buffer;
1080 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1083 if (pfile_in_zip_read_info->compression_method==0)
1086 if (pfile_in_zip_read_info->stream.avail_out <
1087 pfile_in_zip_read_info->stream.avail_in)
1088 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1090 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1092 for (i=0;i<uDoCopy;i++)
1093 *(pfile_in_zip_read_info->stream.next_out+i) =
1094 *(pfile_in_zip_read_info->stream.next_in+i);
1096 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1097 pfile_in_zip_read_info->stream.next_out,
1099 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1100 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1101 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1102 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1103 pfile_in_zip_read_info->stream.next_in += uDoCopy;
1104 pfile_in_zip_read_info->stream.total_out += uDoCopy;
1109 uLong uTotalOutBefore,uTotalOutAfter;
1110 const Bytef *bufBefore;
1112 int flush=Z_SYNC_FLUSH;
1114 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1115 bufBefore = pfile_in_zip_read_info->stream.next_out;
1118 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1119 pfile_in_zip_read_info->stream.avail_out) &&
1120 (pfile_in_zip_read_info->rest_read_compressed == 0))
1123 err=inflate(&pfile_in_zip_read_info->stream,flush);
1125 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1126 uOutThis = uTotalOutAfter-uTotalOutBefore;
1128 pfile_in_zip_read_info->crc32 =
1129 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1132 pfile_in_zip_read_info->rest_read_uncompressed -=
1135 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1137 if (err==Z_STREAM_END)
1138 return (iRead==0) ? UNZ_EOF : iRead;
1151 Give the current position in uncompressed data
1153 z_off_t unztell (file)
1157 file_in_zip_read_info_s* pfile_in_zip_read_info;
1159 return UNZ_PARAMERROR;
1161 pfile_in_zip_read_info=s->pfile_in_zip_read;
1163 if (pfile_in_zip_read_info==NULL)
1164 return UNZ_PARAMERROR;
1166 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1171 return 1 if the end of file was reached, 0 elsewhere
1177 file_in_zip_read_info_s* pfile_in_zip_read_info;
1179 return UNZ_PARAMERROR;
1181 pfile_in_zip_read_info=s->pfile_in_zip_read;
1183 if (pfile_in_zip_read_info==NULL)
1184 return UNZ_PARAMERROR;
1186 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1195 Read extra field from the current file (opened by unzOpenCurrentFile)
1196 This is the local-header version of the extra field (sometimes, there is
1197 more info in the local-header version than in the central-header)
1199 if buf==NULL, it return the size of the local extra field that can be read
1201 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1203 the return value is the number of bytes copied in buf, or (if <0)
1206 int unzGetLocalExtrafield (file,buf,len)
1212 file_in_zip_read_info_s* pfile_in_zip_read_info;
1217 return UNZ_PARAMERROR;
1219 pfile_in_zip_read_info=s->pfile_in_zip_read;
1221 if (pfile_in_zip_read_info==NULL)
1222 return UNZ_PARAMERROR;
1224 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1225 pfile_in_zip_read_info->pos_local_extrafield);
1228 return (int)size_to_read;
1230 if (len>size_to_read)
1231 read_now = (uInt)size_to_read;
1233 read_now = (uInt)len ;
1238 if (fseek(pfile_in_zip_read_info->file,
1239 pfile_in_zip_read_info->offset_local_extrafield +
1240 pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0)
1243 if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1)
1246 return (int)read_now;
1250 Close the file in zip opened with unzipOpenCurrentFile
1251 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1253 int unzCloseCurrentFile (file)
1259 file_in_zip_read_info_s* pfile_in_zip_read_info;
1261 return UNZ_PARAMERROR;
1263 pfile_in_zip_read_info=s->pfile_in_zip_read;
1265 if (pfile_in_zip_read_info==NULL)
1266 return UNZ_PARAMERROR;
1269 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1271 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1276 TRYFREE(pfile_in_zip_read_info->read_buffer);
1277 pfile_in_zip_read_info->read_buffer = NULL;
1278 if (pfile_in_zip_read_info->stream_initialised)
1279 inflateEnd(&pfile_in_zip_read_info->stream);
1281 pfile_in_zip_read_info->stream_initialised = 0;
1282 TRYFREE(pfile_in_zip_read_info);
1284 s->pfile_in_zip_read=NULL;
1291 Get the global comment string of the ZipFile, in the szComment buffer.
1292 uSizeBuf is the size of the szComment buffer.
1293 return the number of byte copied or an error code <0
1295 int unzGetGlobalComment (file, szComment, uSizeBuf)
1300 /* int err=UNZ_OK; */
1304 return UNZ_PARAMERROR;
1307 uReadThis = uSizeBuf;
1308 if (uReadThis>s->gi.size_comment)
1309 uReadThis = s->gi.size_comment;
1311 if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0)
1317 if (fread(szComment,(uInt)uReadThis,1,s->file)!=1)
1321 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1322 *(szComment+s->gi.size_comment)='\0';
1323 return (int)uReadThis;