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)
764 unz_s* s=(unz_s*)file;
769 if (unzGoToFirstFile(file)!=UNZ_OK) {
774 cacao_entry_s* ent=s->cacao_dir_list=(cacao_entry_s*)ALLOC(sizeof(cacao_entry_s));
776 ent->pos=s->pos_in_central_dir;
778 if (unzGetCurrentFileInfo (file,
784 panic("Error in ZIP archive");
789 ent->name=utf_new_char(filename);
790 while (unzGoToNextFile(file)==UNZ_OK) {
792 ent->next=(cacao_entry_s*)ALLOC(sizeof(cacao_entry_s));
795 ent->pos=s->pos_in_central_dir;
797 if (unzGetCurrentFileInfo (file,
803 panic("Error in ZIP archive");
805 c=strstr(filename,".class");
807 ent->name=utf_new_char(filename);
809 printf("Archive contains %d files\n",i);
814 Try locate the file szFileName in the zipfile.
815 For the iCaseSensitivity signification, see unzipStringFileNameCompare
818 UNZ_OK if the file is found. It becomes the current file.
819 UNZ_END_OF_LIST_OF_FILE if the file is not found
821 extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
823 const char *szFileName;
824 int iCaseSensitivity;
831 uLong pos_in_central_dirSaved;
833 printf("Starting lookup\n");
837 return UNZ_PARAMERROR;
839 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
840 return UNZ_PARAMERROR;
843 if (!s->current_file_ok)
844 return UNZ_END_OF_LIST_OF_FILE;
846 num_fileSaved = s->num_file;
847 pos_in_central_dirSaved = s->pos_in_central_dir;
849 err = unzGoToFirstFile(file);
851 while (err == UNZ_OK)
853 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
854 unzGetCurrentFileInfo(file,NULL,
855 szCurrentFileName,sizeof(szCurrentFileName)-1,
857 if (unzStringFileNameCompare(szCurrentFileName,
858 szFileName,iCaseSensitivity)==0) {
859 printf("class found in zip directory\n");
864 err = unzGoToNextFile(file);
867 s->num_file = num_fileSaved ;
868 s->pos_in_central_dir = pos_in_central_dirSaved ;
872 int cacao_locate(unzFile file,utf* filename) {
873 unz_s* s=(unz_s*)file;
875 for (ent=s->cacao_dir_list;ent;ent=ent->next) {
876 /* printf("searching: ");utf_display(filename);
877 printf(" current: ");utf_display(ent->name);
879 if (ent->name==filename) {
880 s->pos_in_central_dir=ent->pos;
881 return unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
882 &s->cur_file_info_internal,
883 NULL,0,NULL,0,NULL,0);
889 Read the local header of the current zipfile
890 Check the coherency of the local header and info in the end of central
891 directory about this file
892 store in *piSizeVar the size of extra info in local header
893 (filename and size of extra field data)
895 local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
896 poffset_local_extrafield,
897 psize_local_extrafield)
900 uLong *poffset_local_extrafield;
901 uInt *psize_local_extrafield;
903 uLong uMagic,uData,uFlags;
905 uLong size_extra_field;
909 *poffset_local_extrafield = 0;
910 *psize_local_extrafield = 0;
912 if (fseek(s->file,s->cur_file_info_internal.offset_curfile +
913 s->byte_before_the_zipfile,SEEK_SET)!=0)
918 if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
920 else if (uMagic!=0x04034b50)
923 if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
926 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
929 if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK)
932 if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
934 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
937 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
938 (s->cur_file_info.compression_method!=Z_DEFLATED))
941 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */
944 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */
946 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
950 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */
952 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
956 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */
958 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
963 if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK)
965 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
968 *piSizeVar += (uInt)size_filename;
970 if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK)
972 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
973 SIZEZIPLOCALHEADER + size_filename;
974 *psize_local_extrafield = (uInt)size_extra_field;
976 *piSizeVar += (uInt)size_extra_field;
982 Open for reading data the current file in the zipfile.
983 If there is no error and the file is opened, the return value is UNZ_OK.
985 extern int ZEXPORT unzOpenCurrentFile (file)
992 file_in_zip_read_info_s* pfile_in_zip_read_info;
993 uLong offset_local_extrafield; /* offset of the local extra field */
994 uInt size_local_extrafield; /* size of the local extra field */
997 return UNZ_PARAMERROR;
999 if (!s->current_file_ok)
1000 return UNZ_PARAMERROR;
1002 if (s->pfile_in_zip_read != NULL)
1003 unzCloseCurrentFile(file);
1005 if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
1006 &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1007 return UNZ_BADZIPFILE;
1009 pfile_in_zip_read_info = (file_in_zip_read_info_s*)
1010 ALLOC(sizeof(file_in_zip_read_info_s));
1011 if (pfile_in_zip_read_info==NULL)
1012 return UNZ_INTERNALERROR;
1014 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1015 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1016 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1017 pfile_in_zip_read_info->pos_local_extrafield=0;
1019 if (pfile_in_zip_read_info->read_buffer==NULL)
1021 TRYFREE(pfile_in_zip_read_info);
1022 return UNZ_INTERNALERROR;
1025 pfile_in_zip_read_info->stream_initialised=0;
1027 if ((s->cur_file_info.compression_method!=0) &&
1028 (s->cur_file_info.compression_method!=Z_DEFLATED))
1030 Store = s->cur_file_info.compression_method==0;
1032 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1033 pfile_in_zip_read_info->crc32=0;
1034 pfile_in_zip_read_info->compression_method =
1035 s->cur_file_info.compression_method;
1036 pfile_in_zip_read_info->file=s->file;
1037 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1039 pfile_in_zip_read_info->stream.total_out = 0;
1043 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1044 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1045 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1047 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1049 pfile_in_zip_read_info->stream_initialised=1;
1050 /* windowBits is passed < 0 to tell that there is no zlib header.
1051 * Note that in this case inflate *requires* an extra "dummy" byte
1052 * after the compressed stream in order to complete decompression and
1053 * return Z_STREAM_END.
1054 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1055 * size of both compressed and uncompressed data
1058 pfile_in_zip_read_info->rest_read_compressed =
1059 s->cur_file_info.compressed_size ;
1060 pfile_in_zip_read_info->rest_read_uncompressed =
1061 s->cur_file_info.uncompressed_size ;
1064 pfile_in_zip_read_info->pos_in_zipfile =
1065 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1068 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1071 s->pfile_in_zip_read = pfile_in_zip_read_info;
1078 Read bytes from the current file.
1079 buf contain buffer where data must be copied
1080 len the size of buf.
1082 return the number of byte copied if somes bytes are copied
1083 return 0 if the end of file was reached
1084 return <0 with error code if there is an error
1085 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1087 extern int ZEXPORT unzReadCurrentFile (file, buf, len)
1095 file_in_zip_read_info_s* pfile_in_zip_read_info;
1097 return UNZ_PARAMERROR;
1099 pfile_in_zip_read_info=s->pfile_in_zip_read;
1101 if (pfile_in_zip_read_info==NULL)
1102 return UNZ_PARAMERROR;
1105 if ((pfile_in_zip_read_info->read_buffer == NULL))
1106 return UNZ_END_OF_LIST_OF_FILE;
1110 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1112 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1114 if (len>pfile_in_zip_read_info->rest_read_uncompressed)
1115 pfile_in_zip_read_info->stream.avail_out =
1116 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1118 while (pfile_in_zip_read_info->stream.avail_out>0)
1120 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1121 (pfile_in_zip_read_info->rest_read_compressed>0))
1123 uInt uReadThis = UNZ_BUFSIZE;
1124 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1125 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1128 if (fseek(pfile_in_zip_read_info->file,
1129 pfile_in_zip_read_info->pos_in_zipfile +
1130 pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0)
1132 if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1,
1133 pfile_in_zip_read_info->file)!=1)
1135 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1137 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1139 pfile_in_zip_read_info->stream.next_in =
1140 (Bytef*)pfile_in_zip_read_info->read_buffer;
1141 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1144 if (pfile_in_zip_read_info->compression_method==0)
1147 if (pfile_in_zip_read_info->stream.avail_out <
1148 pfile_in_zip_read_info->stream.avail_in)
1149 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1151 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1153 for (i=0;i<uDoCopy;i++)
1154 *(pfile_in_zip_read_info->stream.next_out+i) =
1155 *(pfile_in_zip_read_info->stream.next_in+i);
1157 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1158 pfile_in_zip_read_info->stream.next_out,
1160 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1161 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1162 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1163 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1164 pfile_in_zip_read_info->stream.next_in += uDoCopy;
1165 pfile_in_zip_read_info->stream.total_out += uDoCopy;
1170 uLong uTotalOutBefore,uTotalOutAfter;
1171 const Bytef *bufBefore;
1173 int flush=Z_SYNC_FLUSH;
1175 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1176 bufBefore = pfile_in_zip_read_info->stream.next_out;
1179 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1180 pfile_in_zip_read_info->stream.avail_out) &&
1181 (pfile_in_zip_read_info->rest_read_compressed == 0))
1184 err=inflate(&pfile_in_zip_read_info->stream,flush);
1186 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1187 uOutThis = uTotalOutAfter-uTotalOutBefore;
1189 pfile_in_zip_read_info->crc32 =
1190 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1193 pfile_in_zip_read_info->rest_read_uncompressed -=
1196 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1198 if (err==Z_STREAM_END)
1199 return (iRead==0) ? UNZ_EOF : iRead;
1212 Give the current position in uncompressed data
1214 extern z_off_t ZEXPORT unztell (file)
1218 file_in_zip_read_info_s* pfile_in_zip_read_info;
1220 return UNZ_PARAMERROR;
1222 pfile_in_zip_read_info=s->pfile_in_zip_read;
1224 if (pfile_in_zip_read_info==NULL)
1225 return UNZ_PARAMERROR;
1227 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1232 return 1 if the end of file was reached, 0 elsewhere
1234 extern int ZEXPORT unzeof (file)
1238 file_in_zip_read_info_s* pfile_in_zip_read_info;
1240 return UNZ_PARAMERROR;
1242 pfile_in_zip_read_info=s->pfile_in_zip_read;
1244 if (pfile_in_zip_read_info==NULL)
1245 return UNZ_PARAMERROR;
1247 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1256 Read extra field from the current file (opened by unzOpenCurrentFile)
1257 This is the local-header version of the extra field (sometimes, there is
1258 more info in the local-header version than in the central-header)
1260 if buf==NULL, it return the size of the local extra field that can be read
1262 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1264 the return value is the number of bytes copied in buf, or (if <0)
1267 extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
1273 file_in_zip_read_info_s* pfile_in_zip_read_info;
1278 return UNZ_PARAMERROR;
1280 pfile_in_zip_read_info=s->pfile_in_zip_read;
1282 if (pfile_in_zip_read_info==NULL)
1283 return UNZ_PARAMERROR;
1285 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1286 pfile_in_zip_read_info->pos_local_extrafield);
1289 return (int)size_to_read;
1291 if (len>size_to_read)
1292 read_now = (uInt)size_to_read;
1294 read_now = (uInt)len ;
1299 if (fseek(pfile_in_zip_read_info->file,
1300 pfile_in_zip_read_info->offset_local_extrafield +
1301 pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0)
1304 if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1)
1307 return (int)read_now;
1311 Close the file in zip opened with unzipOpenCurrentFile
1312 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1314 extern int ZEXPORT unzCloseCurrentFile (file)
1320 file_in_zip_read_info_s* pfile_in_zip_read_info;
1322 return UNZ_PARAMERROR;
1324 pfile_in_zip_read_info=s->pfile_in_zip_read;
1326 if (pfile_in_zip_read_info==NULL)
1327 return UNZ_PARAMERROR;
1330 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1332 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1337 TRYFREE(pfile_in_zip_read_info->read_buffer);
1338 pfile_in_zip_read_info->read_buffer = NULL;
1339 if (pfile_in_zip_read_info->stream_initialised)
1340 inflateEnd(&pfile_in_zip_read_info->stream);
1342 pfile_in_zip_read_info->stream_initialised = 0;
1343 TRYFREE(pfile_in_zip_read_info);
1345 s->pfile_in_zip_read=NULL;
1352 Get the global comment string of the ZipFile, in the szComment buffer.
1353 uSizeBuf is the size of the szComment buffer.
1354 return the number of byte copied or an error code <0
1356 extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
1365 return UNZ_PARAMERROR;
1368 uReadThis = uSizeBuf;
1369 if (uReadThis>s->gi.size_comment)
1370 uReadThis = s->gi.size_comment;
1372 if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0)
1378 if (fread(szComment,(uInt)uReadThis,1,s->file)!=1)
1382 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1383 *(szComment+s->gi.size_comment)='\0';
1384 return (int)uReadThis;