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;
736 } while (unzGoToNextFile(file) == UNZ_OK);
741 Try locate the file szFileName in the zipfile.
742 For the iCaseSensitivity signification, see unzipStringFileNameCompare
745 UNZ_OK if the file is found. It becomes the current file.
746 UNZ_END_OF_LIST_OF_FILE if the file is not found
748 int unzLocateFile (file, szFileName, iCaseSensitivity)
750 const char *szFileName;
751 int iCaseSensitivity;
758 uLong pos_in_central_dirSaved;
760 printf("Starting lookup\n");
764 return UNZ_PARAMERROR;
766 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
767 return UNZ_PARAMERROR;
770 if (!s->current_file_ok)
771 return UNZ_END_OF_LIST_OF_FILE;
773 num_fileSaved = s->num_file;
774 pos_in_central_dirSaved = s->pos_in_central_dir;
776 err = unzGoToFirstFile(file);
778 while (err == UNZ_OK)
780 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
781 unzGetCurrentFileInfo(file,NULL,
782 szCurrentFileName,sizeof(szCurrentFileName)-1,
784 if (unzStringFileNameCompare(szCurrentFileName,
785 szFileName,iCaseSensitivity)==0) {
786 printf("class found in zip directory\n");
791 err = unzGoToNextFile(file);
794 s->num_file = num_fileSaved ;
795 s->pos_in_central_dir = pos_in_central_dirSaved ;
799 int cacao_locate(unzFile file, utf* filename)
806 for (ent = s->cacao_dir_list; ent; ent = ent->next) {
808 printf("searching: ");utf_display(filename);
809 printf(" current: ");utf_display(ent->name);
812 if (ent->name == filename) {
813 s->pos_in_central_dir = ent->pos;
814 return unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info,
815 &s->cur_file_info_internal,
816 NULL, 0, NULL, 0, NULL, 0);
820 return UNZ_END_OF_LIST_OF_FILE;
826 Read the local header of the current zipfile
827 Check the coherency of the local header and info in the end of central
828 directory about this file
829 store in *piSizeVar the size of extra info in local header
830 (filename and size of extra field data)
832 int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
833 poffset_local_extrafield,
834 psize_local_extrafield)
837 uLong *poffset_local_extrafield;
838 uInt *psize_local_extrafield;
840 uLong uMagic,uData,uFlags;
842 uLong size_extra_field;
846 *poffset_local_extrafield = 0;
847 *psize_local_extrafield = 0;
849 if (fseek(s->file,s->cur_file_info_internal.offset_curfile +
850 s->byte_before_the_zipfile,SEEK_SET)!=0)
855 if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
857 else if (uMagic!=0x04034b50)
861 if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
864 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
867 if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK)
870 if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
872 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
875 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
876 (s->cur_file_info.compression_method!=Z_DEFLATED))
879 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */
882 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */
884 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
888 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */
890 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
894 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */
896 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
901 if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK)
903 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
906 *piSizeVar += (uInt)size_filename;
908 if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK)
910 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
911 SIZEZIPLOCALHEADER + size_filename;
912 *psize_local_extrafield = (uInt)size_extra_field;
914 *piSizeVar += (uInt)size_extra_field;
920 Open for reading data the current file in the zipfile.
921 If there is no error and the file is opened, the return value is UNZ_OK.
923 int unzOpenCurrentFile (file)
930 file_in_zip_read_info_s* pfile_in_zip_read_info;
931 uLong offset_local_extrafield; /* offset of the local extra field */
932 uInt size_local_extrafield; /* size of the local extra field */
935 return UNZ_PARAMERROR;
937 if (!s->current_file_ok)
938 return UNZ_PARAMERROR;
940 if (s->pfile_in_zip_read != NULL)
941 unzCloseCurrentFile(file);
943 if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
944 &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
945 return UNZ_BADZIPFILE;
947 pfile_in_zip_read_info = (file_in_zip_read_info_s*)
948 ALLOC(sizeof(file_in_zip_read_info_s));
949 if (pfile_in_zip_read_info==NULL)
950 return UNZ_INTERNALERROR;
952 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
953 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
954 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
955 pfile_in_zip_read_info->pos_local_extrafield=0;
957 if (pfile_in_zip_read_info->read_buffer==NULL)
959 TRYFREE(pfile_in_zip_read_info);
960 return UNZ_INTERNALERROR;
963 pfile_in_zip_read_info->stream_initialised=0;
965 if ((s->cur_file_info.compression_method!=0) &&
966 (s->cur_file_info.compression_method!=Z_DEFLATED))
968 Store = s->cur_file_info.compression_method==0;
970 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
971 pfile_in_zip_read_info->crc32=0;
972 pfile_in_zip_read_info->compression_method =
973 s->cur_file_info.compression_method;
974 pfile_in_zip_read_info->file=s->file;
975 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
977 pfile_in_zip_read_info->stream.total_out = 0;
981 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
982 pfile_in_zip_read_info->stream.zfree = (free_func)0;
983 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
985 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
987 pfile_in_zip_read_info->stream_initialised=1;
988 /* windowBits is passed < 0 to tell that there is no zlib header.
989 * Note that in this case inflate *requires* an extra "dummy" byte
990 * after the compressed stream in order to complete decompression and
991 * return Z_STREAM_END.
992 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
993 * size of both compressed and uncompressed data
996 pfile_in_zip_read_info->rest_read_compressed =
997 s->cur_file_info.compressed_size ;
998 pfile_in_zip_read_info->rest_read_uncompressed =
999 s->cur_file_info.uncompressed_size ;
1002 pfile_in_zip_read_info->pos_in_zipfile =
1003 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1006 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1009 s->pfile_in_zip_read = pfile_in_zip_read_info;
1016 Read bytes from the current file.
1017 buf contain buffer where data must be copied
1018 len the size of buf.
1020 return the number of byte copied if somes bytes are copied
1021 return 0 if the end of file was reached
1022 return <0 with error code if there is an error
1023 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1025 int unzReadCurrentFile (file, buf, len)
1033 file_in_zip_read_info_s* pfile_in_zip_read_info;
1035 return UNZ_PARAMERROR;
1037 pfile_in_zip_read_info=s->pfile_in_zip_read;
1039 if (pfile_in_zip_read_info==NULL)
1040 return UNZ_PARAMERROR;
1043 if ((pfile_in_zip_read_info->read_buffer == NULL))
1044 return UNZ_END_OF_LIST_OF_FILE;
1048 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1050 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1052 if (len>pfile_in_zip_read_info->rest_read_uncompressed)
1053 pfile_in_zip_read_info->stream.avail_out =
1054 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1056 while (pfile_in_zip_read_info->stream.avail_out>0)
1058 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1059 (pfile_in_zip_read_info->rest_read_compressed>0))
1061 uInt uReadThis = UNZ_BUFSIZE;
1062 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1063 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1066 if (fseek(pfile_in_zip_read_info->file,
1067 pfile_in_zip_read_info->pos_in_zipfile +
1068 pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0)
1070 if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1,
1071 pfile_in_zip_read_info->file)!=1)
1073 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1075 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1077 pfile_in_zip_read_info->stream.next_in =
1078 (Bytef*)pfile_in_zip_read_info->read_buffer;
1079 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1082 if (pfile_in_zip_read_info->compression_method==0)
1085 if (pfile_in_zip_read_info->stream.avail_out <
1086 pfile_in_zip_read_info->stream.avail_in)
1087 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1089 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1091 for (i=0;i<uDoCopy;i++)
1092 *(pfile_in_zip_read_info->stream.next_out+i) =
1093 *(pfile_in_zip_read_info->stream.next_in+i);
1095 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1096 pfile_in_zip_read_info->stream.next_out,
1098 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1099 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1100 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1101 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1102 pfile_in_zip_read_info->stream.next_in += uDoCopy;
1103 pfile_in_zip_read_info->stream.total_out += uDoCopy;
1108 uLong uTotalOutBefore,uTotalOutAfter;
1109 const Bytef *bufBefore;
1111 int flush=Z_SYNC_FLUSH;
1113 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1114 bufBefore = pfile_in_zip_read_info->stream.next_out;
1117 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1118 pfile_in_zip_read_info->stream.avail_out) &&
1119 (pfile_in_zip_read_info->rest_read_compressed == 0))
1122 err=inflate(&pfile_in_zip_read_info->stream,flush);
1124 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1125 uOutThis = uTotalOutAfter-uTotalOutBefore;
1127 pfile_in_zip_read_info->crc32 =
1128 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1131 pfile_in_zip_read_info->rest_read_uncompressed -=
1134 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1136 if (err==Z_STREAM_END)
1137 return (iRead==0) ? UNZ_EOF : iRead;
1150 Give the current position in uncompressed data
1152 z_off_t unztell (file)
1156 file_in_zip_read_info_s* pfile_in_zip_read_info;
1158 return UNZ_PARAMERROR;
1160 pfile_in_zip_read_info=s->pfile_in_zip_read;
1162 if (pfile_in_zip_read_info==NULL)
1163 return UNZ_PARAMERROR;
1165 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1170 return 1 if the end of file was reached, 0 elsewhere
1176 file_in_zip_read_info_s* pfile_in_zip_read_info;
1178 return UNZ_PARAMERROR;
1180 pfile_in_zip_read_info=s->pfile_in_zip_read;
1182 if (pfile_in_zip_read_info==NULL)
1183 return UNZ_PARAMERROR;
1185 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1194 Read extra field from the current file (opened by unzOpenCurrentFile)
1195 This is the local-header version of the extra field (sometimes, there is
1196 more info in the local-header version than in the central-header)
1198 if buf==NULL, it return the size of the local extra field that can be read
1200 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1202 the return value is the number of bytes copied in buf, or (if <0)
1205 int unzGetLocalExtrafield (file,buf,len)
1211 file_in_zip_read_info_s* pfile_in_zip_read_info;
1216 return UNZ_PARAMERROR;
1218 pfile_in_zip_read_info=s->pfile_in_zip_read;
1220 if (pfile_in_zip_read_info==NULL)
1221 return UNZ_PARAMERROR;
1223 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1224 pfile_in_zip_read_info->pos_local_extrafield);
1227 return (int)size_to_read;
1229 if (len>size_to_read)
1230 read_now = (uInt)size_to_read;
1232 read_now = (uInt)len ;
1237 if (fseek(pfile_in_zip_read_info->file,
1238 pfile_in_zip_read_info->offset_local_extrafield +
1239 pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0)
1242 if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1)
1245 return (int)read_now;
1249 Close the file in zip opened with unzipOpenCurrentFile
1250 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1252 int unzCloseCurrentFile (file)
1258 file_in_zip_read_info_s* pfile_in_zip_read_info;
1260 return UNZ_PARAMERROR;
1262 pfile_in_zip_read_info=s->pfile_in_zip_read;
1264 if (pfile_in_zip_read_info==NULL)
1265 return UNZ_PARAMERROR;
1268 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1270 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1275 TRYFREE(pfile_in_zip_read_info->read_buffer);
1276 pfile_in_zip_read_info->read_buffer = NULL;
1277 if (pfile_in_zip_read_info->stream_initialised)
1278 inflateEnd(&pfile_in_zip_read_info->stream);
1280 pfile_in_zip_read_info->stream_initialised = 0;
1281 TRYFREE(pfile_in_zip_read_info);
1283 s->pfile_in_zip_read=NULL;
1290 Get the global comment string of the ZipFile, in the szComment buffer.
1291 uSizeBuf is the size of the szComment buffer.
1292 return the number of byte copied or an error code <0
1294 int unzGetGlobalComment (file, szComment, uSizeBuf)
1299 /* int err=UNZ_OK; */
1303 return UNZ_PARAMERROR;
1306 uReadThis = uSizeBuf;
1307 if (uReadThis>s->gi.size_comment)
1308 uReadThis = s->gi.size_comment;
1310 if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0)
1316 if (fread(szComment,(uInt)uReadThis,1,s->file)!=1)
1320 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1321 *(szComment+s->gi.size_comment)='\0';
1322 return (int)uReadThis;