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*/
36 #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
37 !defined(CASESENSITIVITYDEFAULT_NO)
38 #define CASESENSITIVITYDEFAULT_NO
43 #define UNZ_BUFSIZE (16384)
46 #ifndef UNZ_MAXFILENAMEINZIP
47 #define UNZ_MAXFILENAMEINZIP (256)
51 # define ALLOC(size) (malloc(size))
54 # define TRYFREE(p) {if (p) free(p);}
57 #define SIZECENTRALDIRITEM (0x2e)
58 #define SIZEZIPLOCALHEADER (0x1e)
61 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
75 const char unz_copyright[] =
76 " unzip 0.15 Copyright 1998 Gilles Vollant ";
78 /* unz_file_info_interntal contain internal info about a file in zipfile*/
79 typedef struct unz_file_info_internal_s
81 uLong offset_curfile;/* relative offset of local header 4 bytes */
82 } unz_file_info_internal;
85 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
86 when reading and decompress it */
89 char *read_buffer; /* internal buffer for compressed data */
90 z_stream stream; /* zLib stream structure for inflate */
92 uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
93 uLong stream_initialised; /* flag set if stream structure is initialised*/
95 uLong offset_local_extrafield;/* offset of the local extra field */
96 uInt size_local_extrafield;/* size of the local extra field */
97 uLong pos_local_extrafield; /* position in the local extra field in read*/
99 uLong crc32; /* crc32 of all data uncompressed */
100 uLong crc32_wait; /* crc32 we must obtain after decompress all */
101 uLong rest_read_compressed; /* number of byte to be decompressed */
102 uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
103 FILE* file; /* io structore of the zipfile */
104 uLong compression_method; /* compression method (0==store) */
105 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
106 } file_in_zip_read_info_s;
110 typedef struct cacao_entry
112 struct cacao_entry *next;
117 /* unz_s contain internal information about the zipfile
121 FILE* file; /* io structore of the zipfile */
122 unz_global_info gi; /* public global information */
123 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
124 uLong num_file; /* number of the current file in the zipfile*/
125 uLong pos_in_central_dir; /* pos of the current file in the central dir*/
126 uLong current_file_ok; /* flag about the usability of the current file*/
127 uLong central_pos; /* position of the beginning of the central dir*/
129 uLong size_central_dir; /* size of the central directory */
130 uLong offset_central_dir; /* offset of start of central directory with
131 respect to the starting disk number */
133 unz_file_info cur_file_info; /* public info about the current file in zip*/
134 unz_file_info_internal cur_file_info_internal; /* private info about it*/
135 file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
136 file if we are decompressing it */
137 cacao_entry_s *cacao_dir_list;
141 /* ===========================================================================
142 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
144 IN assertion: the stream s has been sucessfully opened for reading.
148 int unzlocal_getByte(fin,pi)
153 int err = fread(&c, 1, 1, fin);
169 /* ===========================================================================
170 Reads a long in LSB order from the given gz_stream. Sets
172 int unzlocal_getShort (fin,pX)
180 err = unzlocal_getByte(fin,&i);
184 err = unzlocal_getByte(fin,&i);
194 int unzlocal_getLong (fin,pX)
202 err = unzlocal_getByte(fin,&i);
206 err = unzlocal_getByte(fin,&i);
210 err = unzlocal_getByte(fin,&i);
214 err = unzlocal_getByte(fin,&i);
225 /* My own strcmpi / strcasecmp */
226 int strcmpcasenosensitive_internal (fileName1,fileName2)
227 const char* fileName1;
228 const char* fileName2;
232 char c1=*(fileName1++);
233 char c2=*(fileName2++);
234 if ((c1>='a') && (c1<='z'))
236 if ((c2>='a') && (c2<='z'))
239 return ((c2=='\0') ? 0 : -1);
250 #ifdef CASESENSITIVITYDEFAULT_NO
251 #define CASESENSITIVITYDEFAULTVALUE 2
253 #define CASESENSITIVITYDEFAULTVALUE 1
256 #ifndef STRCMPCASENOSENTIVEFUNCTION
257 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
261 Compare two filename (fileName1,fileName2).
262 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
263 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
265 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
266 (like 1 on Unix, 2 on Windows)
269 int unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
270 const char* fileName1;
271 const char* fileName2;
272 int iCaseSensitivity;
274 if (iCaseSensitivity==0)
275 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
277 if (iCaseSensitivity==1)
278 return strcmp(fileName1,fileName2);
280 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
283 #define BUFREADCOMMENT (0x400)
286 Locate the Central directory of a zipfile (at the end, just before
289 uLong unzlocal_SearchCentralDir(fin)
295 uLong uMaxBack=0xffff; /* maximum size of global comment */
298 if (fseek(fin,0,SEEK_END) != 0)
302 uSizeFile = ftell( fin );
304 if (uMaxBack>uSizeFile)
305 uMaxBack = uSizeFile;
307 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
312 while (uBackRead<uMaxBack)
314 uLong uReadSize,uReadPos ;
316 if (uBackRead+BUFREADCOMMENT>uMaxBack)
317 uBackRead = uMaxBack;
319 uBackRead+=BUFREADCOMMENT;
320 uReadPos = uSizeFile-uBackRead ;
322 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
323 (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
324 if (fseek(fin,uReadPos,SEEK_SET)!=0)
327 if (fread(buf,(uInt)uReadSize,1,fin)!=1)
330 for (i=(int)uReadSize-3; (i--)>0;)
331 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
332 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
334 uPosFound = uReadPos+i;
346 Open a Zip file. path contain the full pathname (by example,
347 on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
349 If the zipfile cannot be opened (file don't exist or in not valid), the
350 return value is NULL.
351 Else, the return value is a unzFile Handle, usable with other function
352 of this unzip package.
354 unzFile unzOpen (path)
359 uLong central_pos,uL;
362 uLong number_disk; /* number of the current dist, used for
363 spaning ZIP, unsupported, always 0*/
364 uLong number_disk_with_CD; /* number the the disk with central dir, used
365 for spaning ZIP, unsupported, always 0*/
366 uLong number_entry_CD; /* total number of entries in
368 (same than number_entry on nospan) */
372 if (unz_copyright[0]!=' ')
375 fin=fopen(path,"rb");
379 central_pos = unzlocal_SearchCentralDir(fin);
383 if (fseek(fin,central_pos,SEEK_SET)!=0)
386 /* the signature, already checked */
387 if (unzlocal_getLong(fin,&uL)!=UNZ_OK)
390 /* number of this disk */
391 if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK)
394 /* number of the disk with the start of the central directory */
395 if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK)
398 /* total number of entries in the central dir on this disk */
399 if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK)
402 /* total number of entries in the central dir */
403 if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK)
406 if ((number_entry_CD!=us.gi.number_entry) ||
407 (number_disk_with_CD!=0) ||
411 /* size of the central directory */
412 if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK)
414 /* offset of start of central directory with respect to the
415 starting disk number */
416 if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK)
419 /* zipfile comment length */
420 if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK)
423 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
434 us.byte_before_the_zipfile = central_pos -
435 (us.offset_central_dir+us.size_central_dir);
436 us.central_pos = central_pos;
437 us.pfile_in_zip_read = NULL;
440 s=(unz_s*)ALLOC(sizeof(unz_s));
443 cacao_create_directoryList(s);
445 unzGoToFirstFile((unzFile)s);
451 Close a ZipFile opened with unzipOpen.
452 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
453 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
454 return UNZ_OK if there is no problem. */
460 return UNZ_PARAMERROR;
463 if (s->pfile_in_zip_read!=NULL)
464 unzCloseCurrentFile(file);
473 Write info about the ZipFile in the *pglobal_info structure.
474 No preparation of the structure is needed
475 return UNZ_OK if there is no problem. */
476 int unzGetGlobalInfo (file,pglobal_info)
478 unz_global_info *pglobal_info;
482 return UNZ_PARAMERROR;
490 Translate date/time from Dos format to tm_unz (readable more easilty)
492 void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
497 uDate = (uLong)(ulDosDate>>16);
498 ptm->tm_mday = (uInt)(uDate&0x1f) ;
499 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
500 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
502 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
503 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
504 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
508 Get Info about the current file in the zipfile, with internal only info
510 int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
511 unz_file_info *pfile_info,
512 unz_file_info_internal
513 *pfile_info_internal,
515 uLong fileNameBufferSize,
517 uLong extraFieldBufferSize,
519 uLong commentBufferSize));
521 int unzlocal_GetCurrentFileInfoInternal (file,
524 szFileName, fileNameBufferSize,
525 extraField, extraFieldBufferSize,
526 szComment, commentBufferSize)
528 unz_file_info *pfile_info;
529 unz_file_info_internal *pfile_info_internal;
531 uLong fileNameBufferSize;
533 uLong extraFieldBufferSize;
535 uLong commentBufferSize;
538 unz_file_info file_info;
539 unz_file_info_internal file_info_internal;
545 return UNZ_PARAMERROR;
547 if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0)
551 /* we check the magic */
553 if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
555 else if (uMagic!=0x02014b50)
558 if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK)
561 if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK)
564 if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK)
567 if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK)
570 if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK)
573 unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
575 if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK)
578 if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK)
581 if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK)
584 if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK)
587 if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK)
590 if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK)
593 if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK)
596 if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK)
599 if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK)
602 if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK)
605 lSeek+=file_info.size_filename;
606 if ((err==UNZ_OK) && (szFileName!=NULL))
609 if (file_info.size_filename<fileNameBufferSize)
611 *(szFileName+file_info.size_filename)='\0';
612 uSizeRead = file_info.size_filename;
615 uSizeRead = fileNameBufferSize;
617 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
618 if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1)
624 if ((err==UNZ_OK) && (extraField!=NULL))
627 if (file_info.size_file_extra<extraFieldBufferSize)
628 uSizeRead = file_info.size_file_extra;
630 uSizeRead = extraFieldBufferSize;
633 if (fseek(s->file,lSeek,SEEK_CUR)==0)
637 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
638 if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1)
640 lSeek += file_info.size_file_extra - uSizeRead;
643 lSeek+=file_info.size_file_extra;
646 if ((err==UNZ_OK) && (szComment!=NULL))
649 if (file_info.size_file_comment<commentBufferSize)
651 *(szComment+file_info.size_file_comment)='\0';
652 uSizeRead = file_info.size_file_comment;
655 uSizeRead = commentBufferSize;
658 if (fseek(s->file,lSeek,SEEK_CUR)==0)
662 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
663 if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1)
665 lSeek+=file_info.size_file_comment - uSizeRead;
668 lSeek+=file_info.size_file_comment;
670 if ((err==UNZ_OK) && (pfile_info!=NULL))
671 *pfile_info=file_info;
673 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
674 *pfile_info_internal=file_info_internal;
682 Write info about the ZipFile in the *pglobal_info structure.
683 No preparation of the structure is needed
684 return UNZ_OK if there is no problem.
686 int unzGetCurrentFileInfo (file,
688 szFileName, fileNameBufferSize,
689 extraField, extraFieldBufferSize,
690 szComment, commentBufferSize)
692 unz_file_info *pfile_info;
694 uLong fileNameBufferSize;
696 uLong extraFieldBufferSize;
698 uLong commentBufferSize;
700 return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
701 szFileName,fileNameBufferSize,
702 extraField,extraFieldBufferSize,
703 szComment,commentBufferSize);
707 Set the current file of the zipfile to the first file.
708 return UNZ_OK if there is no problem
710 int unzGoToFirstFile (file)
716 return UNZ_PARAMERROR;
718 s->pos_in_central_dir=s->offset_central_dir;
720 err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
721 &s->cur_file_info_internal,
722 NULL,0,NULL,0,NULL,0);
723 s->current_file_ok = (err == UNZ_OK);
730 Set the current file of the zipfile to the next file.
731 return UNZ_OK if there is no problem
732 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
734 int unzGoToNextFile (file)
741 return UNZ_PARAMERROR;
743 if (!s->current_file_ok)
744 return UNZ_END_OF_LIST_OF_FILE;
745 if (s->num_file+1==s->gi.number_entry)
746 return UNZ_END_OF_LIST_OF_FILE;
748 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
749 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
751 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
752 &s->cur_file_info_internal,
753 NULL,0,NULL,0,NULL,0);
754 s->current_file_ok = (err == UNZ_OK);
759 void cacao_create_directoryList(unzFile file)
762 unz_s* s=(unz_s*)file;
767 if (unzGoToFirstFile(file)!=UNZ_OK) {
772 ent = s->cacao_dir_list = (cacao_entry_s *) ALLOC(sizeof(cacao_entry_s));
774 ent->pos=s->pos_in_central_dir;
776 if (unzGetCurrentFileInfo (file,
782 panic("Error in ZIP archive");
787 ent->name=utf_new_char(filename);
788 while (unzGoToNextFile(file)==UNZ_OK) {
790 ent->next=(cacao_entry_s*)ALLOC(sizeof(cacao_entry_s));
793 ent->pos=s->pos_in_central_dir;
795 if (unzGetCurrentFileInfo (file,
801 panic("Error in ZIP archive");
803 c=strstr(filename,".class");
805 ent->name=utf_new_char(filename);
807 printf("Archive contains %d files\n",i);
812 Try locate the file szFileName in the zipfile.
813 For the iCaseSensitivity signification, see unzipStringFileNameCompare
816 UNZ_OK if the file is found. It becomes the current file.
817 UNZ_END_OF_LIST_OF_FILE if the file is not found
819 int unzLocateFile (file, szFileName, iCaseSensitivity)
821 const char *szFileName;
822 int iCaseSensitivity;
829 uLong pos_in_central_dirSaved;
831 printf("Starting lookup\n");
835 return UNZ_PARAMERROR;
837 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
838 return UNZ_PARAMERROR;
841 if (!s->current_file_ok)
842 return UNZ_END_OF_LIST_OF_FILE;
844 num_fileSaved = s->num_file;
845 pos_in_central_dirSaved = s->pos_in_central_dir;
847 err = unzGoToFirstFile(file);
849 while (err == UNZ_OK)
851 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
852 unzGetCurrentFileInfo(file,NULL,
853 szCurrentFileName,sizeof(szCurrentFileName)-1,
855 if (unzStringFileNameCompare(szCurrentFileName,
856 szFileName,iCaseSensitivity)==0) {
857 printf("class found in zip directory\n");
862 err = unzGoToNextFile(file);
865 s->num_file = num_fileSaved ;
866 s->pos_in_central_dir = pos_in_central_dirSaved ;
870 int cacao_locate(unzFile file,utf* filename) {
871 unz_s* s=(unz_s*)file;
873 for (ent=s->cacao_dir_list;ent;ent=ent->next) {
874 /* printf("searching: ");utf_display(filename);
875 printf(" current: ");utf_display(ent->name);
877 if (ent->name==filename) {
878 s->pos_in_central_dir=ent->pos;
879 return unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
880 &s->cur_file_info_internal,
881 NULL,0,NULL,0,NULL,0);
884 return UNZ_END_OF_LIST_OF_FILE;
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 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 int 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 int 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 z_off_t 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
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 int 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 int 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 int 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;