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);
890 Read the local header of the current zipfile
891 Check the coherency of the local header and info in the end of central
892 directory about this file
893 store in *piSizeVar the size of extra info in local header
894 (filename and size of extra field data)
896 local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
897 poffset_local_extrafield,
898 psize_local_extrafield)
901 uLong *poffset_local_extrafield;
902 uInt *psize_local_extrafield;
904 uLong uMagic,uData,uFlags;
906 uLong size_extra_field;
910 *poffset_local_extrafield = 0;
911 *psize_local_extrafield = 0;
913 if (fseek(s->file,s->cur_file_info_internal.offset_curfile +
914 s->byte_before_the_zipfile,SEEK_SET)!=0)
919 if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
921 else if (uMagic!=0x04034b50)
924 if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
927 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
930 if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK)
933 if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
935 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
938 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
939 (s->cur_file_info.compression_method!=Z_DEFLATED))
942 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */
945 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */
947 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
951 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */
953 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
957 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */
959 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
964 if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK)
966 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
969 *piSizeVar += (uInt)size_filename;
971 if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK)
973 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
974 SIZEZIPLOCALHEADER + size_filename;
975 *psize_local_extrafield = (uInt)size_extra_field;
977 *piSizeVar += (uInt)size_extra_field;
983 Open for reading data the current file in the zipfile.
984 If there is no error and the file is opened, the return value is UNZ_OK.
986 extern int ZEXPORT unzOpenCurrentFile (file)
993 file_in_zip_read_info_s* pfile_in_zip_read_info;
994 uLong offset_local_extrafield; /* offset of the local extra field */
995 uInt size_local_extrafield; /* size of the local extra field */
998 return UNZ_PARAMERROR;
1000 if (!s->current_file_ok)
1001 return UNZ_PARAMERROR;
1003 if (s->pfile_in_zip_read != NULL)
1004 unzCloseCurrentFile(file);
1006 if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
1007 &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1008 return UNZ_BADZIPFILE;
1010 pfile_in_zip_read_info = (file_in_zip_read_info_s*)
1011 ALLOC(sizeof(file_in_zip_read_info_s));
1012 if (pfile_in_zip_read_info==NULL)
1013 return UNZ_INTERNALERROR;
1015 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1016 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1017 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1018 pfile_in_zip_read_info->pos_local_extrafield=0;
1020 if (pfile_in_zip_read_info->read_buffer==NULL)
1022 TRYFREE(pfile_in_zip_read_info);
1023 return UNZ_INTERNALERROR;
1026 pfile_in_zip_read_info->stream_initialised=0;
1028 if ((s->cur_file_info.compression_method!=0) &&
1029 (s->cur_file_info.compression_method!=Z_DEFLATED))
1031 Store = s->cur_file_info.compression_method==0;
1033 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1034 pfile_in_zip_read_info->crc32=0;
1035 pfile_in_zip_read_info->compression_method =
1036 s->cur_file_info.compression_method;
1037 pfile_in_zip_read_info->file=s->file;
1038 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1040 pfile_in_zip_read_info->stream.total_out = 0;
1044 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1045 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1046 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1048 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1050 pfile_in_zip_read_info->stream_initialised=1;
1051 /* windowBits is passed < 0 to tell that there is no zlib header.
1052 * Note that in this case inflate *requires* an extra "dummy" byte
1053 * after the compressed stream in order to complete decompression and
1054 * return Z_STREAM_END.
1055 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1056 * size of both compressed and uncompressed data
1059 pfile_in_zip_read_info->rest_read_compressed =
1060 s->cur_file_info.compressed_size ;
1061 pfile_in_zip_read_info->rest_read_uncompressed =
1062 s->cur_file_info.uncompressed_size ;
1065 pfile_in_zip_read_info->pos_in_zipfile =
1066 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1069 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1072 s->pfile_in_zip_read = pfile_in_zip_read_info;
1079 Read bytes from the current file.
1080 buf contain buffer where data must be copied
1081 len the size of buf.
1083 return the number of byte copied if somes bytes are copied
1084 return 0 if the end of file was reached
1085 return <0 with error code if there is an error
1086 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1088 extern int ZEXPORT unzReadCurrentFile (file, buf, len)
1096 file_in_zip_read_info_s* pfile_in_zip_read_info;
1098 return UNZ_PARAMERROR;
1100 pfile_in_zip_read_info=s->pfile_in_zip_read;
1102 if (pfile_in_zip_read_info==NULL)
1103 return UNZ_PARAMERROR;
1106 if ((pfile_in_zip_read_info->read_buffer == NULL))
1107 return UNZ_END_OF_LIST_OF_FILE;
1111 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1113 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1115 if (len>pfile_in_zip_read_info->rest_read_uncompressed)
1116 pfile_in_zip_read_info->stream.avail_out =
1117 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1119 while (pfile_in_zip_read_info->stream.avail_out>0)
1121 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1122 (pfile_in_zip_read_info->rest_read_compressed>0))
1124 uInt uReadThis = UNZ_BUFSIZE;
1125 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1126 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1129 if (fseek(pfile_in_zip_read_info->file,
1130 pfile_in_zip_read_info->pos_in_zipfile +
1131 pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0)
1133 if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1,
1134 pfile_in_zip_read_info->file)!=1)
1136 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1138 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1140 pfile_in_zip_read_info->stream.next_in =
1141 (Bytef*)pfile_in_zip_read_info->read_buffer;
1142 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1145 if (pfile_in_zip_read_info->compression_method==0)
1148 if (pfile_in_zip_read_info->stream.avail_out <
1149 pfile_in_zip_read_info->stream.avail_in)
1150 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1152 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1154 for (i=0;i<uDoCopy;i++)
1155 *(pfile_in_zip_read_info->stream.next_out+i) =
1156 *(pfile_in_zip_read_info->stream.next_in+i);
1158 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1159 pfile_in_zip_read_info->stream.next_out,
1161 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1162 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1163 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1164 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1165 pfile_in_zip_read_info->stream.next_in += uDoCopy;
1166 pfile_in_zip_read_info->stream.total_out += uDoCopy;
1171 uLong uTotalOutBefore,uTotalOutAfter;
1172 const Bytef *bufBefore;
1174 int flush=Z_SYNC_FLUSH;
1176 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1177 bufBefore = pfile_in_zip_read_info->stream.next_out;
1180 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1181 pfile_in_zip_read_info->stream.avail_out) &&
1182 (pfile_in_zip_read_info->rest_read_compressed == 0))
1185 err=inflate(&pfile_in_zip_read_info->stream,flush);
1187 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1188 uOutThis = uTotalOutAfter-uTotalOutBefore;
1190 pfile_in_zip_read_info->crc32 =
1191 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1194 pfile_in_zip_read_info->rest_read_uncompressed -=
1197 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1199 if (err==Z_STREAM_END)
1200 return (iRead==0) ? UNZ_EOF : iRead;
1213 Give the current position in uncompressed data
1215 extern z_off_t ZEXPORT unztell (file)
1219 file_in_zip_read_info_s* pfile_in_zip_read_info;
1221 return UNZ_PARAMERROR;
1223 pfile_in_zip_read_info=s->pfile_in_zip_read;
1225 if (pfile_in_zip_read_info==NULL)
1226 return UNZ_PARAMERROR;
1228 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1233 return 1 if the end of file was reached, 0 elsewhere
1235 extern int ZEXPORT unzeof (file)
1239 file_in_zip_read_info_s* pfile_in_zip_read_info;
1241 return UNZ_PARAMERROR;
1243 pfile_in_zip_read_info=s->pfile_in_zip_read;
1245 if (pfile_in_zip_read_info==NULL)
1246 return UNZ_PARAMERROR;
1248 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1257 Read extra field from the current file (opened by unzOpenCurrentFile)
1258 This is the local-header version of the extra field (sometimes, there is
1259 more info in the local-header version than in the central-header)
1261 if buf==NULL, it return the size of the local extra field that can be read
1263 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1265 the return value is the number of bytes copied in buf, or (if <0)
1268 extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
1274 file_in_zip_read_info_s* pfile_in_zip_read_info;
1279 return UNZ_PARAMERROR;
1281 pfile_in_zip_read_info=s->pfile_in_zip_read;
1283 if (pfile_in_zip_read_info==NULL)
1284 return UNZ_PARAMERROR;
1286 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1287 pfile_in_zip_read_info->pos_local_extrafield);
1290 return (int)size_to_read;
1292 if (len>size_to_read)
1293 read_now = (uInt)size_to_read;
1295 read_now = (uInt)len ;
1300 if (fseek(pfile_in_zip_read_info->file,
1301 pfile_in_zip_read_info->offset_local_extrafield +
1302 pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0)
1305 if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1)
1308 return (int)read_now;
1312 Close the file in zip opened with unzipOpenCurrentFile
1313 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1315 extern int ZEXPORT unzCloseCurrentFile (file)
1321 file_in_zip_read_info_s* pfile_in_zip_read_info;
1323 return UNZ_PARAMERROR;
1325 pfile_in_zip_read_info=s->pfile_in_zip_read;
1327 if (pfile_in_zip_read_info==NULL)
1328 return UNZ_PARAMERROR;
1331 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1333 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1338 TRYFREE(pfile_in_zip_read_info->read_buffer);
1339 pfile_in_zip_read_info->read_buffer = NULL;
1340 if (pfile_in_zip_read_info->stream_initialised)
1341 inflateEnd(&pfile_in_zip_read_info->stream);
1343 pfile_in_zip_read_info->stream_initialised = 0;
1344 TRYFREE(pfile_in_zip_read_info);
1346 s->pfile_in_zip_read=NULL;
1353 Get the global comment string of the ZipFile, in the szComment buffer.
1354 uSizeBuf is the size of the szComment buffer.
1355 return the number of byte copied or an error code <0
1357 extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
1366 return UNZ_PARAMERROR;
1369 uReadThis = uSizeBuf;
1370 if (uReadThis>s->gi.size_comment)
1371 uReadThis = s->gi.size_comment;
1373 if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0)
1379 if (fread(szComment,(uInt)uReadThis,1,s->file)!=1)
1383 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1384 *(szComment+s->gi.size_comment)='\0';
1385 return (int)uReadThis;