4 /* unzip.c -- IO on .zip files using zlib
5 Version 0.15 beta, Mar 19th, 1998,
7 Read unzip.h for more info
35 /* compile with -Dlocal if your debugger can't find static symbols */
39 #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
40 !defined(CASESENSITIVITYDEFAULT_NO)
41 #define CASESENSITIVITYDEFAULT_NO
46 #define UNZ_BUFSIZE (16384)
49 #ifndef UNZ_MAXFILENAMEINZIP
50 #define UNZ_MAXFILENAMEINZIP (256)
54 # define ALLOC(size) (malloc(size))
57 # define TRYFREE(p) {if (p) free(p);}
60 #define SIZECENTRALDIRITEM (0x2e)
61 #define SIZEZIPLOCALHEADER (0x1e)
64 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
78 const char unz_copyright[] =
79 " unzip 0.15 Copyright 1998 Gilles Vollant ";
81 /* unz_file_info_interntal contain internal info about a file in zipfile*/
82 typedef struct unz_file_info_internal_s
84 uLong offset_curfile;/* relative offset of local header 4 bytes */
85 } unz_file_info_internal;
88 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
89 when reading and decompress it */
92 char *read_buffer; /* internal buffer for compressed data */
93 z_stream stream; /* zLib stream structure for inflate */
95 uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
96 uLong stream_initialised; /* flag set if stream structure is initialised*/
98 uLong offset_local_extrafield;/* offset of the local extra field */
99 uInt size_local_extrafield;/* size of the local extra field */
100 uLong pos_local_extrafield; /* position in the local extra field in read*/
102 uLong crc32; /* crc32 of all data uncompressed */
103 uLong crc32_wait; /* crc32 we must obtain after decompress all */
104 uLong rest_read_compressed; /* number of byte to be decompressed */
105 uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
106 FILE* file; /* io structore of the zipfile */
107 uLong compression_method; /* compression method (0==store) */
108 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
109 } file_in_zip_read_info_s;
113 typedef struct cacao_entry
115 struct cacao_entry *next;
120 /* unz_s contain internal information about the zipfile
124 FILE* file; /* io structore of the zipfile */
125 unz_global_info gi; /* public global information */
126 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
127 uLong num_file; /* number of the current file in the zipfile*/
128 uLong pos_in_central_dir; /* pos of the current file in the central dir*/
129 uLong current_file_ok; /* flag about the usability of the current file*/
130 uLong central_pos; /* position of the beginning of the central dir*/
132 uLong size_central_dir; /* size of the central directory */
133 uLong offset_central_dir; /* offset of start of central directory with
134 respect to the starting disk number */
136 unz_file_info cur_file_info; /* public info about the current file in zip*/
137 unz_file_info_internal cur_file_info_internal; /* private info about it*/
138 file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
139 file if we are decompressing it */
140 cacao_entry_s *cacao_dir_list;
144 /* ===========================================================================
145 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
147 IN assertion: the stream s has been sucessfully opened for reading.
151 local int unzlocal_getByte(fin,pi)
156 int err = fread(&c, 1, 1, fin);
172 /* ===========================================================================
173 Reads a long in LSB order from the given gz_stream. Sets
175 local int unzlocal_getShort (fin,pX)
183 err = unzlocal_getByte(fin,&i);
187 err = unzlocal_getByte(fin,&i);
197 local int unzlocal_getLong (fin,pX)
205 err = unzlocal_getByte(fin,&i);
209 err = unzlocal_getByte(fin,&i);
213 err = unzlocal_getByte(fin,&i);
217 err = unzlocal_getByte(fin,&i);
228 /* My own strcmpi / strcasecmp */
229 local int strcmpcasenosensitive_internal (fileName1,fileName2)
230 const char* fileName1;
231 const char* fileName2;
235 char c1=*(fileName1++);
236 char c2=*(fileName2++);
237 if ((c1>='a') && (c1<='z'))
239 if ((c2>='a') && (c2<='z'))
242 return ((c2=='\0') ? 0 : -1);
253 #ifdef CASESENSITIVITYDEFAULT_NO
254 #define CASESENSITIVITYDEFAULTVALUE 2
256 #define CASESENSITIVITYDEFAULTVALUE 1
259 #ifndef STRCMPCASENOSENTIVEFUNCTION
260 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
264 Compare two filename (fileName1,fileName2).
265 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
266 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
268 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
269 (like 1 on Unix, 2 on Windows)
272 extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
273 const char* fileName1;
274 const char* fileName2;
275 int iCaseSensitivity;
277 if (iCaseSensitivity==0)
278 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
280 if (iCaseSensitivity==1)
281 return strcmp(fileName1,fileName2);
283 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
286 #define BUFREADCOMMENT (0x400)
289 Locate the Central directory of a zipfile (at the end, just before
292 local uLong unzlocal_SearchCentralDir(fin)
298 uLong uMaxBack=0xffff; /* maximum size of global comment */
301 if (fseek(fin,0,SEEK_END) != 0)
305 uSizeFile = ftell( fin );
307 if (uMaxBack>uSizeFile)
308 uMaxBack = uSizeFile;
310 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
315 while (uBackRead<uMaxBack)
317 uLong uReadSize,uReadPos ;
319 if (uBackRead+BUFREADCOMMENT>uMaxBack)
320 uBackRead = uMaxBack;
322 uBackRead+=BUFREADCOMMENT;
323 uReadPos = uSizeFile-uBackRead ;
325 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
326 (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
327 if (fseek(fin,uReadPos,SEEK_SET)!=0)
330 if (fread(buf,(uInt)uReadSize,1,fin)!=1)
333 for (i=(int)uReadSize-3; (i--)>0;)
334 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
335 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
337 uPosFound = uReadPos+i;
349 Open a Zip file. path contain the full pathname (by example,
350 on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
352 If the zipfile cannot be opened (file don't exist or in not valid), the
353 return value is NULL.
354 Else, the return value is a unzFile Handle, usable with other function
355 of this unzip package.
357 extern unzFile ZEXPORT unzOpen (path)
362 uLong central_pos,uL;
365 uLong number_disk; /* number of the current dist, used for
366 spaning ZIP, unsupported, always 0*/
367 uLong number_disk_with_CD; /* number the the disk with central dir, used
368 for spaning ZIP, unsupported, always 0*/
369 uLong number_entry_CD; /* total number of entries in
371 (same than number_entry on nospan) */
375 if (unz_copyright[0]!=' ')
378 fin=fopen(path,"rb");
382 central_pos = unzlocal_SearchCentralDir(fin);
386 if (fseek(fin,central_pos,SEEK_SET)!=0)
389 /* the signature, already checked */
390 if (unzlocal_getLong(fin,&uL)!=UNZ_OK)
393 /* number of this disk */
394 if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK)
397 /* number of the disk with the start of the central directory */
398 if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK)
401 /* total number of entries in the central dir on this disk */
402 if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK)
405 /* total number of entries in the central dir */
406 if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK)
409 if ((number_entry_CD!=us.gi.number_entry) ||
410 (number_disk_with_CD!=0) ||
414 /* size of the central directory */
415 if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK)
417 /* offset of start of central directory with respect to the
418 starting disk number */
419 if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK)
422 /* zipfile comment length */
423 if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK)
426 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
437 us.byte_before_the_zipfile = central_pos -
438 (us.offset_central_dir+us.size_central_dir);
439 us.central_pos = central_pos;
440 us.pfile_in_zip_read = NULL;
443 s=(unz_s*)ALLOC(sizeof(unz_s));
446 cacao_create_directoryList(s);
448 unzGoToFirstFile((unzFile)s);
454 Close a ZipFile opened with unzipOpen.
455 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
456 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
457 return UNZ_OK if there is no problem. */
458 extern int ZEXPORT unzClose (file)
463 return UNZ_PARAMERROR;
466 if (s->pfile_in_zip_read!=NULL)
467 unzCloseCurrentFile(file);
476 Write info about the ZipFile in the *pglobal_info structure.
477 No preparation of the structure is needed
478 return UNZ_OK if there is no problem. */
479 extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
481 unz_global_info *pglobal_info;
485 return UNZ_PARAMERROR;
493 Translate date/time from Dos format to tm_unz (readable more easilty)
495 local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
500 uDate = (uLong)(ulDosDate>>16);
501 ptm->tm_mday = (uInt)(uDate&0x1f) ;
502 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
503 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
505 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
506 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
507 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
511 Get Info about the current file in the zipfile, with internal only info
513 local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
514 unz_file_info *pfile_info,
515 unz_file_info_internal
516 *pfile_info_internal,
518 uLong fileNameBufferSize,
520 uLong extraFieldBufferSize,
522 uLong commentBufferSize));
524 local int unzlocal_GetCurrentFileInfoInternal (file,
527 szFileName, fileNameBufferSize,
528 extraField, extraFieldBufferSize,
529 szComment, commentBufferSize)
531 unz_file_info *pfile_info;
532 unz_file_info_internal *pfile_info_internal;
534 uLong fileNameBufferSize;
536 uLong extraFieldBufferSize;
538 uLong commentBufferSize;
541 unz_file_info file_info;
542 unz_file_info_internal file_info_internal;
548 return UNZ_PARAMERROR;
550 if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0)
554 /* we check the magic */
556 if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
558 else if (uMagic!=0x02014b50)
561 if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK)
564 if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK)
567 if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK)
570 if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK)
573 if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK)
576 unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
578 if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK)
581 if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK)
584 if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK)
587 if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK)
590 if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK)
593 if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK)
596 if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK)
599 if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK)
602 if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK)
605 if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK)
608 lSeek+=file_info.size_filename;
609 if ((err==UNZ_OK) && (szFileName!=NULL))
612 if (file_info.size_filename<fileNameBufferSize)
614 *(szFileName+file_info.size_filename)='\0';
615 uSizeRead = file_info.size_filename;
618 uSizeRead = fileNameBufferSize;
620 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
621 if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1)
627 if ((err==UNZ_OK) && (extraField!=NULL))
630 if (file_info.size_file_extra<extraFieldBufferSize)
631 uSizeRead = file_info.size_file_extra;
633 uSizeRead = extraFieldBufferSize;
636 if (fseek(s->file,lSeek,SEEK_CUR)==0)
640 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
641 if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1)
643 lSeek += file_info.size_file_extra - uSizeRead;
646 lSeek+=file_info.size_file_extra;
649 if ((err==UNZ_OK) && (szComment!=NULL))
652 if (file_info.size_file_comment<commentBufferSize)
654 *(szComment+file_info.size_file_comment)='\0';
655 uSizeRead = file_info.size_file_comment;
658 uSizeRead = commentBufferSize;
661 if (fseek(s->file,lSeek,SEEK_CUR)==0)
665 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
666 if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1)
668 lSeek+=file_info.size_file_comment - uSizeRead;
671 lSeek+=file_info.size_file_comment;
673 if ((err==UNZ_OK) && (pfile_info!=NULL))
674 *pfile_info=file_info;
676 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
677 *pfile_info_internal=file_info_internal;
685 Write info about the ZipFile in the *pglobal_info structure.
686 No preparation of the structure is needed
687 return UNZ_OK if there is no problem.
689 extern int ZEXPORT unzGetCurrentFileInfo (file,
691 szFileName, fileNameBufferSize,
692 extraField, extraFieldBufferSize,
693 szComment, commentBufferSize)
695 unz_file_info *pfile_info;
697 uLong fileNameBufferSize;
699 uLong extraFieldBufferSize;
701 uLong commentBufferSize;
703 return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
704 szFileName,fileNameBufferSize,
705 extraField,extraFieldBufferSize,
706 szComment,commentBufferSize);
710 Set the current file of the zipfile to the first file.
711 return UNZ_OK if there is no problem
713 extern int ZEXPORT unzGoToFirstFile (file)
719 return UNZ_PARAMERROR;
721 s->pos_in_central_dir=s->offset_central_dir;
723 err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
724 &s->cur_file_info_internal,
725 NULL,0,NULL,0,NULL,0);
726 s->current_file_ok = (err == UNZ_OK);
733 Set the current file of the zipfile to the next file.
734 return UNZ_OK if there is no problem
735 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
737 extern int ZEXPORT unzGoToNextFile (file)
744 return UNZ_PARAMERROR;
746 if (!s->current_file_ok)
747 return UNZ_END_OF_LIST_OF_FILE;
748 if (s->num_file+1==s->gi.number_entry)
749 return UNZ_END_OF_LIST_OF_FILE;
751 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
752 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
754 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
755 &s->cur_file_info_internal,
756 NULL,0,NULL,0,NULL,0);
757 s->current_file_ok = (err == UNZ_OK);
762 void cacao_create_directoryList(unzFile file)
765 unz_s* s=(unz_s*)file;
770 if (unzGoToFirstFile(file)!=UNZ_OK) {
775 ent = s->cacao_dir_list = (cacao_entry_s *) ALLOC(sizeof(cacao_entry_s));
777 ent->pos=s->pos_in_central_dir;
779 if (unzGetCurrentFileInfo (file,
785 panic("Error in ZIP archive");
790 ent->name=utf_new_char(filename);
791 while (unzGoToNextFile(file)==UNZ_OK) {
793 ent->next=(cacao_entry_s*)ALLOC(sizeof(cacao_entry_s));
796 ent->pos=s->pos_in_central_dir;
798 if (unzGetCurrentFileInfo (file,
804 panic("Error in ZIP archive");
806 c=strstr(filename,".class");
808 ent->name=utf_new_char(filename);
810 printf("Archive contains %d files\n",i);
815 Try locate the file szFileName in the zipfile.
816 For the iCaseSensitivity signification, see unzipStringFileNameCompare
819 UNZ_OK if the file is found. It becomes the current file.
820 UNZ_END_OF_LIST_OF_FILE if the file is not found
822 extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
824 const char *szFileName;
825 int iCaseSensitivity;
832 uLong pos_in_central_dirSaved;
834 printf("Starting lookup\n");
838 return UNZ_PARAMERROR;
840 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
841 return UNZ_PARAMERROR;
844 if (!s->current_file_ok)
845 return UNZ_END_OF_LIST_OF_FILE;
847 num_fileSaved = s->num_file;
848 pos_in_central_dirSaved = s->pos_in_central_dir;
850 err = unzGoToFirstFile(file);
852 while (err == UNZ_OK)
854 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
855 unzGetCurrentFileInfo(file,NULL,
856 szCurrentFileName,sizeof(szCurrentFileName)-1,
858 if (unzStringFileNameCompare(szCurrentFileName,
859 szFileName,iCaseSensitivity)==0) {
860 printf("class found in zip directory\n");
865 err = unzGoToNextFile(file);
868 s->num_file = num_fileSaved ;
869 s->pos_in_central_dir = pos_in_central_dirSaved ;
873 int cacao_locate(unzFile file,utf* filename) {
874 unz_s* s=(unz_s*)file;
876 for (ent=s->cacao_dir_list;ent;ent=ent->next) {
877 /* printf("searching: ");utf_display(filename);
878 printf(" current: ");utf_display(ent->name);
880 if (ent->name==filename) {
881 s->pos_in_central_dir=ent->pos;
882 return unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
883 &s->cur_file_info_internal,
884 NULL,0,NULL,0,NULL,0);
887 return UNZ_END_OF_LIST_OF_FILE;
892 Read the local header of the current zipfile
893 Check the coherency of the local header and info in the end of central
894 directory about this file
895 store in *piSizeVar the size of extra info in local header
896 (filename and size of extra field data)
898 local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
899 poffset_local_extrafield,
900 psize_local_extrafield)
903 uLong *poffset_local_extrafield;
904 uInt *psize_local_extrafield;
906 uLong uMagic,uData,uFlags;
908 uLong size_extra_field;
912 *poffset_local_extrafield = 0;
913 *psize_local_extrafield = 0;
915 if (fseek(s->file,s->cur_file_info_internal.offset_curfile +
916 s->byte_before_the_zipfile,SEEK_SET)!=0)
921 if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
923 else if (uMagic!=0x04034b50)
926 if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
929 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
932 if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK)
935 if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
937 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
940 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
941 (s->cur_file_info.compression_method!=Z_DEFLATED))
944 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */
947 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */
949 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
953 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */
955 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
959 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */
961 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
966 if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK)
968 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
971 *piSizeVar += (uInt)size_filename;
973 if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK)
975 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
976 SIZEZIPLOCALHEADER + size_filename;
977 *psize_local_extrafield = (uInt)size_extra_field;
979 *piSizeVar += (uInt)size_extra_field;
985 Open for reading data the current file in the zipfile.
986 If there is no error and the file is opened, the return value is UNZ_OK.
988 extern int ZEXPORT unzOpenCurrentFile (file)
995 file_in_zip_read_info_s* pfile_in_zip_read_info;
996 uLong offset_local_extrafield; /* offset of the local extra field */
997 uInt size_local_extrafield; /* size of the local extra field */
1000 return UNZ_PARAMERROR;
1002 if (!s->current_file_ok)
1003 return UNZ_PARAMERROR;
1005 if (s->pfile_in_zip_read != NULL)
1006 unzCloseCurrentFile(file);
1008 if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
1009 &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1010 return UNZ_BADZIPFILE;
1012 pfile_in_zip_read_info = (file_in_zip_read_info_s*)
1013 ALLOC(sizeof(file_in_zip_read_info_s));
1014 if (pfile_in_zip_read_info==NULL)
1015 return UNZ_INTERNALERROR;
1017 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1018 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1019 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1020 pfile_in_zip_read_info->pos_local_extrafield=0;
1022 if (pfile_in_zip_read_info->read_buffer==NULL)
1024 TRYFREE(pfile_in_zip_read_info);
1025 return UNZ_INTERNALERROR;
1028 pfile_in_zip_read_info->stream_initialised=0;
1030 if ((s->cur_file_info.compression_method!=0) &&
1031 (s->cur_file_info.compression_method!=Z_DEFLATED))
1033 Store = s->cur_file_info.compression_method==0;
1035 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1036 pfile_in_zip_read_info->crc32=0;
1037 pfile_in_zip_read_info->compression_method =
1038 s->cur_file_info.compression_method;
1039 pfile_in_zip_read_info->file=s->file;
1040 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1042 pfile_in_zip_read_info->stream.total_out = 0;
1046 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1047 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1048 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1050 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1052 pfile_in_zip_read_info->stream_initialised=1;
1053 /* windowBits is passed < 0 to tell that there is no zlib header.
1054 * Note that in this case inflate *requires* an extra "dummy" byte
1055 * after the compressed stream in order to complete decompression and
1056 * return Z_STREAM_END.
1057 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1058 * size of both compressed and uncompressed data
1061 pfile_in_zip_read_info->rest_read_compressed =
1062 s->cur_file_info.compressed_size ;
1063 pfile_in_zip_read_info->rest_read_uncompressed =
1064 s->cur_file_info.uncompressed_size ;
1067 pfile_in_zip_read_info->pos_in_zipfile =
1068 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1071 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1074 s->pfile_in_zip_read = pfile_in_zip_read_info;
1081 Read bytes from the current file.
1082 buf contain buffer where data must be copied
1083 len the size of buf.
1085 return the number of byte copied if somes bytes are copied
1086 return 0 if the end of file was reached
1087 return <0 with error code if there is an error
1088 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1090 extern int ZEXPORT unzReadCurrentFile (file, buf, len)
1098 file_in_zip_read_info_s* pfile_in_zip_read_info;
1100 return UNZ_PARAMERROR;
1102 pfile_in_zip_read_info=s->pfile_in_zip_read;
1104 if (pfile_in_zip_read_info==NULL)
1105 return UNZ_PARAMERROR;
1108 if ((pfile_in_zip_read_info->read_buffer == NULL))
1109 return UNZ_END_OF_LIST_OF_FILE;
1113 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1115 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1117 if (len>pfile_in_zip_read_info->rest_read_uncompressed)
1118 pfile_in_zip_read_info->stream.avail_out =
1119 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1121 while (pfile_in_zip_read_info->stream.avail_out>0)
1123 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1124 (pfile_in_zip_read_info->rest_read_compressed>0))
1126 uInt uReadThis = UNZ_BUFSIZE;
1127 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1128 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1131 if (fseek(pfile_in_zip_read_info->file,
1132 pfile_in_zip_read_info->pos_in_zipfile +
1133 pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0)
1135 if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1,
1136 pfile_in_zip_read_info->file)!=1)
1138 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1140 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1142 pfile_in_zip_read_info->stream.next_in =
1143 (Bytef*)pfile_in_zip_read_info->read_buffer;
1144 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1147 if (pfile_in_zip_read_info->compression_method==0)
1150 if (pfile_in_zip_read_info->stream.avail_out <
1151 pfile_in_zip_read_info->stream.avail_in)
1152 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1154 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1156 for (i=0;i<uDoCopy;i++)
1157 *(pfile_in_zip_read_info->stream.next_out+i) =
1158 *(pfile_in_zip_read_info->stream.next_in+i);
1160 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1161 pfile_in_zip_read_info->stream.next_out,
1163 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1164 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1165 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1166 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1167 pfile_in_zip_read_info->stream.next_in += uDoCopy;
1168 pfile_in_zip_read_info->stream.total_out += uDoCopy;
1173 uLong uTotalOutBefore,uTotalOutAfter;
1174 const Bytef *bufBefore;
1176 int flush=Z_SYNC_FLUSH;
1178 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1179 bufBefore = pfile_in_zip_read_info->stream.next_out;
1182 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1183 pfile_in_zip_read_info->stream.avail_out) &&
1184 (pfile_in_zip_read_info->rest_read_compressed == 0))
1187 err=inflate(&pfile_in_zip_read_info->stream,flush);
1189 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1190 uOutThis = uTotalOutAfter-uTotalOutBefore;
1192 pfile_in_zip_read_info->crc32 =
1193 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1196 pfile_in_zip_read_info->rest_read_uncompressed -=
1199 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1201 if (err==Z_STREAM_END)
1202 return (iRead==0) ? UNZ_EOF : iRead;
1215 Give the current position in uncompressed data
1217 extern z_off_t ZEXPORT unztell (file)
1221 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 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1235 return 1 if the end of file was reached, 0 elsewhere
1237 extern int ZEXPORT unzeof (file)
1241 file_in_zip_read_info_s* pfile_in_zip_read_info;
1243 return UNZ_PARAMERROR;
1245 pfile_in_zip_read_info=s->pfile_in_zip_read;
1247 if (pfile_in_zip_read_info==NULL)
1248 return UNZ_PARAMERROR;
1250 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1259 Read extra field from the current file (opened by unzOpenCurrentFile)
1260 This is the local-header version of the extra field (sometimes, there is
1261 more info in the local-header version than in the central-header)
1263 if buf==NULL, it return the size of the local extra field that can be read
1265 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1267 the return value is the number of bytes copied in buf, or (if <0)
1270 extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
1276 file_in_zip_read_info_s* pfile_in_zip_read_info;
1281 return UNZ_PARAMERROR;
1283 pfile_in_zip_read_info=s->pfile_in_zip_read;
1285 if (pfile_in_zip_read_info==NULL)
1286 return UNZ_PARAMERROR;
1288 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1289 pfile_in_zip_read_info->pos_local_extrafield);
1292 return (int)size_to_read;
1294 if (len>size_to_read)
1295 read_now = (uInt)size_to_read;
1297 read_now = (uInt)len ;
1302 if (fseek(pfile_in_zip_read_info->file,
1303 pfile_in_zip_read_info->offset_local_extrafield +
1304 pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0)
1307 if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1)
1310 return (int)read_now;
1314 Close the file in zip opened with unzipOpenCurrentFile
1315 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1317 extern int ZEXPORT unzCloseCurrentFile (file)
1323 file_in_zip_read_info_s* pfile_in_zip_read_info;
1325 return UNZ_PARAMERROR;
1327 pfile_in_zip_read_info=s->pfile_in_zip_read;
1329 if (pfile_in_zip_read_info==NULL)
1330 return UNZ_PARAMERROR;
1333 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1335 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1340 TRYFREE(pfile_in_zip_read_info->read_buffer);
1341 pfile_in_zip_read_info->read_buffer = NULL;
1342 if (pfile_in_zip_read_info->stream_initialised)
1343 inflateEnd(&pfile_in_zip_read_info->stream);
1345 pfile_in_zip_read_info->stream_initialised = 0;
1346 TRYFREE(pfile_in_zip_read_info);
1348 s->pfile_in_zip_read=NULL;
1355 Get the global comment string of the ZipFile, in the szComment buffer.
1356 uSizeBuf is the size of the szComment buffer.
1357 return the number of byte copied or an error code <0
1359 extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
1368 return UNZ_PARAMERROR;
1371 uReadThis = uSizeBuf;
1372 if (uReadThis>s->gi.size_comment)
1373 uReadThis = s->gi.size_comment;
1375 if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0)
1381 if (fread(szComment,(uInt)uReadThis,1,s->file)!=1)
1385 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1386 *(szComment+s->gi.size_comment)='\0';
1387 return (int)uReadThis;