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*/
19 #include "mm/memory.h"
20 #include "toolbox/logging.h"
40 #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
41 !defined(CASESENSITIVITYDEFAULT_NO)
42 #define CASESENSITIVITYDEFAULT_NO
47 #define UNZ_BUFSIZE (16384)
50 #ifndef UNZ_MAXFILENAMEINZIP
51 #define UNZ_MAXFILENAMEINZIP (256)
55 # define ALLOC(size) (malloc(size))
58 # define TRYFREE(p) {if (p) free(p);}
61 #define SIZECENTRALDIRITEM (0x2e)
62 #define SIZEZIPLOCALHEADER (0x1e)
65 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
79 const char unz_copyright[] =
80 " unzip 0.15 Copyright 1998 Gilles Vollant ";
83 /* ===========================================================================
84 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
86 IN assertion: the stream s has been sucessfully opened for reading.
90 int unzlocal_getByte(fin,pi)
95 int err = fread(&c, 1, 1, fin);
111 /* ===========================================================================
112 Reads a long in LSB order from the given gz_stream. Sets
114 int unzlocal_getShort (fin,pX)
122 err = unzlocal_getByte(fin,&i);
126 err = unzlocal_getByte(fin,&i);
136 int unzlocal_getLong (fin,pX)
144 err = unzlocal_getByte(fin,&i);
148 err = unzlocal_getByte(fin,&i);
152 err = unzlocal_getByte(fin,&i);
156 err = unzlocal_getByte(fin,&i);
167 /* My own strcmpi / strcasecmp */
168 int strcmpcasenosensitive_internal (fileName1,fileName2)
169 const char* fileName1;
170 const char* fileName2;
174 char c1=*(fileName1++);
175 char c2=*(fileName2++);
176 if ((c1>='a') && (c1<='z'))
178 if ((c2>='a') && (c2<='z'))
181 return ((c2=='\0') ? 0 : -1);
192 #ifdef CASESENSITIVITYDEFAULT_NO
193 #define CASESENSITIVITYDEFAULTVALUE 2
195 #define CASESENSITIVITYDEFAULTVALUE 1
198 #ifndef STRCMPCASENOSENTIVEFUNCTION
199 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
203 Compare two filename (fileName1,fileName2).
204 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
205 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
207 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
208 (like 1 on Unix, 2 on Windows)
211 int unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
212 const char* fileName1;
213 const char* fileName2;
214 int iCaseSensitivity;
216 if (iCaseSensitivity==0)
217 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
219 if (iCaseSensitivity==1)
220 return strcmp(fileName1,fileName2);
222 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
225 #define BUFREADCOMMENT (0x400)
228 Locate the Central directory of a zipfile (at the end, just before
231 uLong unzlocal_SearchCentralDir(fin)
237 uLong uMaxBack=0xffff; /* maximum size of global comment */
240 if (fseek(fin,0,SEEK_END) != 0)
244 uSizeFile = ftell( fin );
246 if (uMaxBack>uSizeFile)
247 uMaxBack = uSizeFile;
249 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
254 while (uBackRead<uMaxBack)
256 uLong uReadSize,uReadPos ;
258 if (uBackRead+BUFREADCOMMENT>uMaxBack)
259 uBackRead = uMaxBack;
261 uBackRead+=BUFREADCOMMENT;
262 uReadPos = uSizeFile-uBackRead ;
264 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
265 (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
266 if (fseek(fin,uReadPos,SEEK_SET)!=0)
269 if (fread(buf,(uInt)uReadSize,1,fin)!=1)
272 for (i=(int)uReadSize-3; (i--)>0;)
273 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
274 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
276 uPosFound = uReadPos+i;
288 Open a Zip file. path contain the full pathname (by example,
289 on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
291 If the zipfile cannot be opened (file don't exist or in not valid), the
292 return value is NULL.
293 Else, the return value is a unzFile Handle, usable with other function
294 of this unzip package.
296 unzFile unzOpen (path)
301 uLong central_pos,uL;
304 uLong number_disk; /* number of the current dist, used for
305 spaning ZIP, unsupported, always 0*/
306 uLong number_disk_with_CD; /* number the the disk with central dir, used
307 for spaning ZIP, unsupported, always 0*/
308 uLong number_entry_CD; /* total number of entries in
310 (same than number_entry on nospan) */
314 if (unz_copyright[0]!=' ')
317 fin=fopen(path,"rb");
321 central_pos = unzlocal_SearchCentralDir(fin);
325 if (fseek(fin,central_pos,SEEK_SET)!=0)
328 /* the signature, already checked */
329 if (unzlocal_getLong(fin,&uL)!=UNZ_OK)
332 /* number of this disk */
333 if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK)
336 /* number of the disk with the start of the central directory */
337 if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK)
340 /* total number of entries in the central dir on this disk */
341 if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK)
344 /* total number of entries in the central dir */
345 if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK)
348 if ((number_entry_CD!=us.gi.number_entry) ||
349 (number_disk_with_CD!=0) ||
353 /* size of the central directory */
354 if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK)
356 /* offset of start of central directory with respect to the
357 starting disk number */
358 if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK)
361 /* zipfile comment length */
362 if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK)
365 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
376 us.byte_before_the_zipfile = central_pos -
377 (us.offset_central_dir+us.size_central_dir);
378 us.central_pos = central_pos;
379 us.pfile_in_zip_read = NULL;
382 s=(unz_s*)ALLOC(sizeof(unz_s));
385 cacao_create_directoryList(s);
387 unzGoToFirstFile((unzFile)s);
393 Close a ZipFile opened with unzipOpen.
394 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
395 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
396 return UNZ_OK if there is no problem. */
402 return UNZ_PARAMERROR;
405 if (s->pfile_in_zip_read!=NULL)
406 unzCloseCurrentFile(file);
415 Write info about the ZipFile in the *pglobal_info structure.
416 No preparation of the structure is needed
417 return UNZ_OK if there is no problem. */
418 int unzGetGlobalInfo (file,pglobal_info)
420 unz_global_info *pglobal_info;
424 return UNZ_PARAMERROR;
432 Translate date/time from Dos format to tm_unz (readable more easilty)
434 void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
439 uDate = (uLong)(ulDosDate>>16);
440 ptm->tm_mday = (uInt)(uDate&0x1f) ;
441 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
442 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
444 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
445 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
446 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
450 Get Info about the current file in the zipfile, with internal only info
452 int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
453 unz_file_info *pfile_info,
454 unz_file_info_internal
455 *pfile_info_internal,
457 uLong fileNameBufferSize,
459 uLong extraFieldBufferSize,
461 uLong commentBufferSize));
463 int unzlocal_GetCurrentFileInfoInternal (file,
466 szFileName, fileNameBufferSize,
467 extraField, extraFieldBufferSize,
468 szComment, commentBufferSize)
470 unz_file_info *pfile_info;
471 unz_file_info_internal *pfile_info_internal;
473 uLong fileNameBufferSize;
475 uLong extraFieldBufferSize;
477 uLong commentBufferSize;
480 unz_file_info file_info;
481 unz_file_info_internal file_info_internal;
487 return UNZ_PARAMERROR;
489 if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0)
493 /* we check the magic */
495 if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
497 else if (uMagic!=0x02014b50)
501 if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK)
504 if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK)
507 if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK)
510 if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK)
513 if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK)
516 unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
518 if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK)
521 if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK)
524 if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK)
527 if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK)
530 if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK)
533 if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK)
536 if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK)
539 if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK)
542 if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK)
545 if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK)
548 lSeek+=file_info.size_filename;
549 if ((err==UNZ_OK) && (szFileName!=NULL))
552 if (file_info.size_filename<fileNameBufferSize)
554 *(szFileName+file_info.size_filename)='\0';
555 uSizeRead = file_info.size_filename;
558 uSizeRead = fileNameBufferSize;
560 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
561 if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1)
567 if ((err==UNZ_OK) && (extraField!=NULL))
570 if (file_info.size_file_extra<extraFieldBufferSize)
571 uSizeRead = file_info.size_file_extra;
573 uSizeRead = extraFieldBufferSize;
576 if (fseek(s->file,lSeek,SEEK_CUR)==0)
582 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
583 if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1)
585 lSeek += file_info.size_file_extra - uSizeRead;
588 lSeek+=file_info.size_file_extra;
591 if ((err==UNZ_OK) && (szComment!=NULL))
594 if (file_info.size_file_comment<commentBufferSize)
596 *(szComment+file_info.size_file_comment)='\0';
597 uSizeRead = file_info.size_file_comment;
600 uSizeRead = commentBufferSize;
603 if (fseek(s->file,lSeek,SEEK_CUR)==0)
609 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
610 if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1)
612 lSeek+=file_info.size_file_comment - uSizeRead;
615 lSeek+=file_info.size_file_comment;
617 if ((err==UNZ_OK) && (pfile_info!=NULL))
618 *pfile_info=file_info;
620 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
621 *pfile_info_internal=file_info_internal;
629 Write info about the ZipFile in the *pglobal_info structure.
630 No preparation of the structure is needed
631 return UNZ_OK if there is no problem.
633 int unzGetCurrentFileInfo (file,
635 szFileName, fileNameBufferSize,
636 extraField, extraFieldBufferSize,
637 szComment, commentBufferSize)
639 unz_file_info *pfile_info;
641 uLong fileNameBufferSize;
643 uLong extraFieldBufferSize;
645 uLong commentBufferSize;
647 return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
648 szFileName,fileNameBufferSize,
649 extraField,extraFieldBufferSize,
650 szComment,commentBufferSize);
654 Set the current file of the zipfile to the first file.
655 return UNZ_OK if there is no problem
657 int unzGoToFirstFile (file)
663 return UNZ_PARAMERROR;
665 s->pos_in_central_dir=s->offset_central_dir;
667 err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
668 &s->cur_file_info_internal,
669 NULL,0,NULL,0,NULL,0);
670 s->current_file_ok = (err == UNZ_OK);
677 Set the current file of the zipfile to the next file.
678 return UNZ_OK if there is no problem
679 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
681 int unzGoToNextFile (file)
688 return UNZ_PARAMERROR;
690 if (!s->current_file_ok)
691 return UNZ_END_OF_LIST_OF_FILE;
692 if (s->num_file+1==s->gi.number_entry)
693 return UNZ_END_OF_LIST_OF_FILE;
695 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
696 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
698 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
699 &s->cur_file_info_internal,
700 NULL,0,NULL,0,NULL,0);
701 s->current_file_ok = (err == UNZ_OK);
706 void cacao_create_directoryList(unzFile file)
709 unz_s *s=(unz_s*)file;
715 s->cacao_dir_list = NULL;
717 if (unzGoToFirstFile(file) != UNZ_OK)
721 if (unzGetCurrentFileInfo(file, &tmp, filename, 200, 0, 0, 0, 0) != UNZ_OK) {
722 log_text("Error in ZIP archive");
726 if ((c = strstr(filename, ".class")))
729 if (!s->cacao_dir_list) {
730 ent = s->cacao_dir_list = NEW(cacao_entry_s);
733 ent->next = NEW(cacao_entry_s);
739 ent->name = utf_new_char(filename);
740 ent->pos = s->pos_in_central_dir;
741 } while (unzGoToNextFile(file) == UNZ_OK);
746 Try locate the file szFileName in the zipfile.
747 For the iCaseSensitivity signification, see unzipStringFileNameCompare
750 UNZ_OK if the file is found. It becomes the current file.
751 UNZ_END_OF_LIST_OF_FILE if the file is not found
753 int unzLocateFile (file, szFileName, iCaseSensitivity)
755 const char *szFileName;
756 int iCaseSensitivity;
763 uLong pos_in_central_dirSaved;
765 printf("Starting lookup\n");
769 return UNZ_PARAMERROR;
771 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
772 return UNZ_PARAMERROR;
775 if (!s->current_file_ok)
776 return UNZ_END_OF_LIST_OF_FILE;
778 num_fileSaved = s->num_file;
779 pos_in_central_dirSaved = s->pos_in_central_dir;
781 err = unzGoToFirstFile(file);
783 while (err == UNZ_OK)
785 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
786 unzGetCurrentFileInfo(file,NULL,
787 szCurrentFileName,sizeof(szCurrentFileName)-1,
789 if (unzStringFileNameCompare(szCurrentFileName,
790 szFileName,iCaseSensitivity)==0) {
791 printf("class found in zip directory\n");
796 err = unzGoToNextFile(file);
799 s->num_file = num_fileSaved ;
800 s->pos_in_central_dir = pos_in_central_dirSaved ;
804 int cacao_locate(unzFile file, utf* filename)
811 for (ent = s->cacao_dir_list; ent; ent = ent->next) {
813 printf("searching: ");utf_display(filename);
814 printf(" current: ");utf_display(ent->name);
817 if (ent->name == filename) {
818 s->pos_in_central_dir = ent->pos;
819 return unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info,
820 &s->cur_file_info_internal,
821 NULL, 0, NULL, 0, NULL, 0);
825 return UNZ_END_OF_LIST_OF_FILE;
831 Read the local header of the current zipfile
832 Check the coherency of the local header and info in the end of central
833 directory about this file
834 store in *piSizeVar the size of extra info in local header
835 (filename and size of extra field data)
837 int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
838 poffset_local_extrafield,
839 psize_local_extrafield)
842 uLong *poffset_local_extrafield;
843 uInt *psize_local_extrafield;
845 uLong uMagic,uData,uFlags;
847 uLong size_extra_field;
851 *poffset_local_extrafield = 0;
852 *psize_local_extrafield = 0;
854 if (fseek(s->file,s->cur_file_info_internal.offset_curfile +
855 s->byte_before_the_zipfile,SEEK_SET)!=0)
860 if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
862 else if (uMagic!=0x04034b50)
866 if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
869 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
872 if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK)
875 if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
877 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
880 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
881 (s->cur_file_info.compression_method!=Z_DEFLATED))
884 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */
887 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */
889 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
893 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */
895 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
899 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */
901 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
906 if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK)
908 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
911 *piSizeVar += (uInt)size_filename;
913 if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK)
915 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
916 SIZEZIPLOCALHEADER + size_filename;
917 *psize_local_extrafield = (uInt)size_extra_field;
919 *piSizeVar += (uInt)size_extra_field;
925 Open for reading data the current file in the zipfile.
926 If there is no error and the file is opened, the return value is UNZ_OK.
928 int unzOpenCurrentFile (file)
935 file_in_zip_read_info_s* pfile_in_zip_read_info;
936 uLong offset_local_extrafield; /* offset of the local extra field */
937 uInt size_local_extrafield; /* size of the local extra field */
940 return UNZ_PARAMERROR;
942 if (!s->current_file_ok)
943 return UNZ_PARAMERROR;
945 if (s->pfile_in_zip_read != NULL)
946 unzCloseCurrentFile(file);
948 if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
949 &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
950 return UNZ_BADZIPFILE;
952 pfile_in_zip_read_info = (file_in_zip_read_info_s*)
953 ALLOC(sizeof(file_in_zip_read_info_s));
954 if (pfile_in_zip_read_info==NULL)
955 return UNZ_INTERNALERROR;
957 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
958 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
959 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
960 pfile_in_zip_read_info->pos_local_extrafield=0;
962 if (pfile_in_zip_read_info->read_buffer==NULL)
964 TRYFREE(pfile_in_zip_read_info);
965 return UNZ_INTERNALERROR;
968 pfile_in_zip_read_info->stream_initialised=0;
970 if ((s->cur_file_info.compression_method!=0) &&
971 (s->cur_file_info.compression_method!=Z_DEFLATED))
973 Store = s->cur_file_info.compression_method==0;
975 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
976 pfile_in_zip_read_info->crc32=0;
977 pfile_in_zip_read_info->compression_method =
978 s->cur_file_info.compression_method;
979 pfile_in_zip_read_info->file=s->file;
980 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
982 pfile_in_zip_read_info->stream.total_out = 0;
986 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
987 pfile_in_zip_read_info->stream.zfree = (free_func)0;
988 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
990 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
992 pfile_in_zip_read_info->stream_initialised=1;
993 /* windowBits is passed < 0 to tell that there is no zlib header.
994 * Note that in this case inflate *requires* an extra "dummy" byte
995 * after the compressed stream in order to complete decompression and
996 * return Z_STREAM_END.
997 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
998 * size of both compressed and uncompressed data
1001 pfile_in_zip_read_info->rest_read_compressed =
1002 s->cur_file_info.compressed_size ;
1003 pfile_in_zip_read_info->rest_read_uncompressed =
1004 s->cur_file_info.uncompressed_size ;
1007 pfile_in_zip_read_info->pos_in_zipfile =
1008 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1011 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1014 s->pfile_in_zip_read = pfile_in_zip_read_info;
1021 Read bytes from the current file.
1022 buf contain buffer where data must be copied
1023 len the size of buf.
1025 return the number of byte copied if somes bytes are copied
1026 return 0 if the end of file was reached
1027 return <0 with error code if there is an error
1028 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1030 int unzReadCurrentFile (file, buf, len)
1038 file_in_zip_read_info_s* pfile_in_zip_read_info;
1040 return UNZ_PARAMERROR;
1042 pfile_in_zip_read_info=s->pfile_in_zip_read;
1044 if (pfile_in_zip_read_info==NULL)
1045 return UNZ_PARAMERROR;
1048 if ((pfile_in_zip_read_info->read_buffer == NULL))
1049 return UNZ_END_OF_LIST_OF_FILE;
1053 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1055 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1057 if (len>pfile_in_zip_read_info->rest_read_uncompressed)
1058 pfile_in_zip_read_info->stream.avail_out =
1059 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1061 while (pfile_in_zip_read_info->stream.avail_out>0)
1063 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1064 (pfile_in_zip_read_info->rest_read_compressed>0))
1066 uInt uReadThis = UNZ_BUFSIZE;
1067 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1068 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1071 if (fseek(pfile_in_zip_read_info->file,
1072 pfile_in_zip_read_info->pos_in_zipfile +
1073 pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0)
1075 if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1,
1076 pfile_in_zip_read_info->file)!=1)
1078 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1080 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1082 pfile_in_zip_read_info->stream.next_in =
1083 (Bytef*)pfile_in_zip_read_info->read_buffer;
1084 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1087 if (pfile_in_zip_read_info->compression_method==0)
1090 if (pfile_in_zip_read_info->stream.avail_out <
1091 pfile_in_zip_read_info->stream.avail_in)
1092 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1094 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1096 for (i=0;i<uDoCopy;i++)
1097 *(pfile_in_zip_read_info->stream.next_out+i) =
1098 *(pfile_in_zip_read_info->stream.next_in+i);
1100 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1101 pfile_in_zip_read_info->stream.next_out,
1103 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1104 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1105 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1106 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1107 pfile_in_zip_read_info->stream.next_in += uDoCopy;
1108 pfile_in_zip_read_info->stream.total_out += uDoCopy;
1113 uLong uTotalOutBefore,uTotalOutAfter;
1114 const Bytef *bufBefore;
1116 int flush=Z_SYNC_FLUSH;
1118 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1119 bufBefore = pfile_in_zip_read_info->stream.next_out;
1122 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1123 pfile_in_zip_read_info->stream.avail_out) &&
1124 (pfile_in_zip_read_info->rest_read_compressed == 0))
1127 err=inflate(&pfile_in_zip_read_info->stream,flush);
1129 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1130 uOutThis = uTotalOutAfter-uTotalOutBefore;
1132 pfile_in_zip_read_info->crc32 =
1133 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1136 pfile_in_zip_read_info->rest_read_uncompressed -=
1139 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1141 if (err==Z_STREAM_END)
1142 return (iRead==0) ? UNZ_EOF : iRead;
1155 Give the current position in uncompressed data
1157 z_off_t unztell (file)
1161 file_in_zip_read_info_s* pfile_in_zip_read_info;
1163 return UNZ_PARAMERROR;
1165 pfile_in_zip_read_info=s->pfile_in_zip_read;
1167 if (pfile_in_zip_read_info==NULL)
1168 return UNZ_PARAMERROR;
1170 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1175 return 1 if the end of file was reached, 0 elsewhere
1181 file_in_zip_read_info_s* pfile_in_zip_read_info;
1183 return UNZ_PARAMERROR;
1185 pfile_in_zip_read_info=s->pfile_in_zip_read;
1187 if (pfile_in_zip_read_info==NULL)
1188 return UNZ_PARAMERROR;
1190 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1199 Read extra field from the current file (opened by unzOpenCurrentFile)
1200 This is the local-header version of the extra field (sometimes, there is
1201 more info in the local-header version than in the central-header)
1203 if buf==NULL, it return the size of the local extra field that can be read
1205 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1207 the return value is the number of bytes copied in buf, or (if <0)
1210 int unzGetLocalExtrafield (file,buf,len)
1216 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 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1229 pfile_in_zip_read_info->pos_local_extrafield);
1232 return (int)size_to_read;
1234 if (len>size_to_read)
1235 read_now = (uInt)size_to_read;
1237 read_now = (uInt)len ;
1242 if (fseek(pfile_in_zip_read_info->file,
1243 pfile_in_zip_read_info->offset_local_extrafield +
1244 pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0)
1247 if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1)
1250 return (int)read_now;
1254 Close the file in zip opened with unzipOpenCurrentFile
1255 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1257 int unzCloseCurrentFile (file)
1263 file_in_zip_read_info_s* pfile_in_zip_read_info;
1265 return UNZ_PARAMERROR;
1267 pfile_in_zip_read_info=s->pfile_in_zip_read;
1269 if (pfile_in_zip_read_info==NULL)
1270 return UNZ_PARAMERROR;
1273 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1275 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1280 TRYFREE(pfile_in_zip_read_info->read_buffer);
1281 pfile_in_zip_read_info->read_buffer = NULL;
1282 if (pfile_in_zip_read_info->stream_initialised)
1283 inflateEnd(&pfile_in_zip_read_info->stream);
1285 pfile_in_zip_read_info->stream_initialised = 0;
1286 TRYFREE(pfile_in_zip_read_info);
1288 s->pfile_in_zip_read=NULL;
1295 Get the global comment string of the ZipFile, in the szComment buffer.
1296 uSizeBuf is the size of the szComment buffer.
1297 return the number of byte copied or an error code <0
1299 int unzGetGlobalComment (file, szComment, uSizeBuf)
1304 /* int err=UNZ_OK; */
1308 return UNZ_PARAMERROR;
1311 uReadThis = uSizeBuf;
1312 if (uReadThis>s->gi.size_comment)
1313 uReadThis = s->gi.size_comment;
1315 if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0)
1321 if (fread(szComment,(uInt)uReadThis,1,s->file)!=1)
1325 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1326 *(szComment+s->gi.size_comment)='\0';
1327 return (int)uReadThis;