[System.Data] Cleanup after #4893 (PR) (#5841)
[mono-project.git] / support / minizip / unzip.c
blob0b98a87cd5b1557eb9b5bb7bda9e283482127f34
1 /* unzip.c -- IO for uncompress .zip files using zlib
2 Version 1.01e, February 12th, 2005
4 Copyright (C) 1998-2005 Gilles Vollant
6 Read unzip.h for more info
7 */
9 /* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
10 compatibility with older software. The following is from the original crypt.c. Code
11 woven in by Terry Thorsen 1/2003.
14 Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
16 See the accompanying file LICENSE, version 2000-Apr-09 or later
17 (the contents of which are also included in zip.h) for terms of use.
18 If, for some reason, all these files are missing, the Info-ZIP license
19 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
22 crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
24 The encryption/decryption parts of this source code (as opposed to the
25 non-echoing password parts) were originally written in Europe. The
26 whole source package can be freely distributed, including from the USA.
27 (Prior to January 2000, re-export from the US was a violation of US law.)
31 This encryption code is a direct transcription of the algorithm from
32 Roger Schlafly, described by Phil Katz in the file appnote.txt. This
33 file (appnote.txt) is distributed with the PKZIP program (even in the
34 version without encryption capabilities).
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include "zlib.h"
42 #include "unzip.h"
44 #ifdef STDC
45 # include <stddef.h>
46 # include <string.h>
47 # include <stdlib.h>
48 #endif
49 #ifdef NO_ERRNO_H
50 extern int errno;
51 #else
52 # include <errno.h>
53 #endif
56 #ifndef local
57 # define local static
58 #endif
59 /* compile with -Dlocal if your debugger can't find static symbols */
62 #ifndef CASESENSITIVITYDEFAULT_NO
63 # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
64 # define CASESENSITIVITYDEFAULT_NO
65 # endif
66 #endif
69 #ifndef UNZ_BUFSIZE
70 #define UNZ_BUFSIZE (16384)
71 #endif
73 #ifndef UNZ_MAXFILENAMEINZIP
74 #define UNZ_MAXFILENAMEINZIP (256)
75 #endif
77 #ifndef ALLOC
78 # define ALLOC(size) (malloc(size))
79 #endif
80 #ifndef TRYFREE
81 # define TRYFREE(p) {if (p) free(p);}
82 #endif
84 #define SIZECENTRALDIRITEM (0x2e)
85 #define SIZEZIPLOCALHEADER (0x1e)
90 const char unz_copyright[] =
91 " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
93 /* unz_file_info_interntal contain internal info about a file in zipfile*/
94 typedef struct unz_file_info_internal_s
96 uLong offset_curfile;/* relative offset of local header 4 bytes */
97 } unz_file_info_internal;
100 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
101 when reading and decompress it */
102 typedef struct
104 char *read_buffer; /* internal buffer for compressed data */
105 z_stream stream; /* zLib stream structure for inflate */
107 uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
108 uLong stream_initialised; /* flag set if stream structure is initialised*/
110 uLong offset_local_extrafield;/* offset of the local extra field */
111 uInt size_local_extrafield;/* size of the local extra field */
112 uLong pos_local_extrafield; /* position in the local extra field in read*/
114 uLong crc32; /* crc32 of all data uncompressed */
115 uLong crc32_wait; /* crc32 we must obtain after decompress all */
116 uLong rest_read_compressed; /* number of byte to be decompressed */
117 uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
118 zlib_filefunc_def z_filefunc;
119 voidpf filestream; /* io structore of the zipfile */
120 uLong compression_method; /* compression method (0==store) */
121 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
122 int raw;
123 } file_in_zip_read_info_s;
126 /* unz_s contain internal information about the zipfile
128 typedef struct
130 zlib_filefunc_def z_filefunc;
131 voidpf filestream; /* io structore of the zipfile */
132 unz_global_info gi; /* public global information */
133 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
134 uLong num_file; /* number of the current file in the zipfile*/
135 uLong pos_in_central_dir; /* pos of the current file in the central dir*/
136 uLong current_file_ok; /* flag about the usability of the current file*/
137 uLong central_pos; /* position of the beginning of the central dir*/
139 uLong size_central_dir; /* size of the central directory */
140 uLong offset_central_dir; /* offset of start of central directory with
141 respect to the starting disk number */
143 unz_file_info cur_file_info; /* public info about the current file in zip*/
144 unz_file_info_internal cur_file_info_internal; /* private info about it*/
145 file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
146 file if we are decompressing it */
147 int encrypted;
148 # ifndef NOUNCRYPT
149 unsigned long keys[3]; /* keys defining the pseudo-random sequence */
150 const unsigned long* pcrc_32_tab;
151 # endif
152 } unz_s;
155 #ifndef NOUNCRYPT
156 #include "crypt.h"
157 #endif
159 /* ===========================================================================
160 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
161 for end of file.
162 IN assertion: the stream s has been sucessfully opened for reading.
166 local int unzlocal_getByte OF((
167 const zlib_filefunc_def* pzlib_filefunc_def,
168 voidpf filestream,
169 int *pi));
171 local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi)
172 const zlib_filefunc_def* pzlib_filefunc_def;
173 voidpf filestream;
174 int *pi;
176 unsigned char c;
177 int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
178 if (err==1)
180 *pi = (int)c;
181 return UNZ_OK;
183 else
185 if (ZERROR(*pzlib_filefunc_def,filestream))
186 return UNZ_ERRNO;
187 else
188 return UNZ_EOF;
193 /* ===========================================================================
194 Reads a long in LSB order from the given gz_stream. Sets
196 local int unzlocal_getShort OF((
197 const zlib_filefunc_def* pzlib_filefunc_def,
198 voidpf filestream,
199 uLong *pX));
201 local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
202 const zlib_filefunc_def* pzlib_filefunc_def;
203 voidpf filestream;
204 uLong *pX;
206 uLong x ;
207 int i;
208 int err;
210 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
211 x = (uLong)i;
213 if (err==UNZ_OK)
214 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
215 x += ((uLong)i)<<8;
217 if (err==UNZ_OK)
218 *pX = x;
219 else
220 *pX = 0;
221 return err;
224 local int unzlocal_getLong OF((
225 const zlib_filefunc_def* pzlib_filefunc_def,
226 voidpf filestream,
227 uLong *pX));
229 local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
230 const zlib_filefunc_def* pzlib_filefunc_def;
231 voidpf filestream;
232 uLong *pX;
234 uLong x ;
235 int i;
236 int err;
238 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
239 x = (uLong)i;
241 if (err==UNZ_OK)
242 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
243 x += ((uLong)i)<<8;
245 if (err==UNZ_OK)
246 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
247 x += ((uLong)i)<<16;
249 if (err==UNZ_OK)
250 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
251 x += ((uLong)i)<<24;
253 if (err==UNZ_OK)
254 *pX = x;
255 else
256 *pX = 0;
257 return err;
261 /* My own strcmpi / strcasecmp */
262 local int strcmpcasenosensitive_internal (const char *fileName1, const char *fileName2)
264 for (;;)
266 char c1=*(fileName1++);
267 char c2=*(fileName2++);
268 if ((c1>='a') && (c1<='z'))
269 c1 -= 0x20;
270 if ((c2>='a') && (c2<='z'))
271 c2 -= 0x20;
272 if (c1=='\0')
273 return ((c2=='\0') ? 0 : -1);
274 if (c2=='\0')
275 return 1;
276 if (c1<c2)
277 return -1;
278 if (c1>c2)
279 return 1;
284 #ifdef CASESENSITIVITYDEFAULT_NO
285 #define CASESENSITIVITYDEFAULTVALUE 2
286 #else
287 #define CASESENSITIVITYDEFAULTVALUE 1
288 #endif
290 #ifndef STRCMPCASENOSENTIVEFUNCTION
291 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
292 #endif
295 Compare two filename (fileName1,fileName2).
296 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
297 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
298 or strcasecmp)
299 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
300 (like 1 on Unix, 2 on Windows)
303 extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
304 const char* fileName1;
305 const char* fileName2;
306 int iCaseSensitivity;
308 if (iCaseSensitivity==0)
309 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
311 if (iCaseSensitivity==1)
312 return strcmp(fileName1,fileName2);
314 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
317 #ifndef BUFREADCOMMENT
318 #define BUFREADCOMMENT (0x400)
319 #endif
322 Locate the Central directory of a zipfile (at the end, just before
323 the global comment)
325 local uLong unzlocal_SearchCentralDir OF((
326 const zlib_filefunc_def* pzlib_filefunc_def,
327 voidpf filestream));
329 local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream)
330 const zlib_filefunc_def* pzlib_filefunc_def;
331 voidpf filestream;
333 unsigned char* buf;
334 uLong uSizeFile;
335 uLong uBackRead;
336 uLong uMaxBack=0xffff; /* maximum size of global comment */
337 uLong uPosFound=0;
339 if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
340 return 0;
343 uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
345 if (uMaxBack>uSizeFile)
346 uMaxBack = uSizeFile;
348 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
349 if (buf==NULL)
350 return 0;
352 uBackRead = 4;
353 while (uBackRead<uMaxBack)
355 uLong uReadSize,uReadPos ;
356 int i;
357 if (uBackRead+BUFREADCOMMENT>uMaxBack)
358 uBackRead = uMaxBack;
359 else
360 uBackRead+=BUFREADCOMMENT;
361 uReadPos = uSizeFile-uBackRead ;
363 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
364 (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
365 if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
366 break;
368 if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
369 break;
371 for (i=(int)uReadSize-3; (i--)>0;)
372 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
373 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
375 uPosFound = uReadPos+i;
376 break;
379 if (uPosFound!=0)
380 break;
382 TRYFREE(buf);
383 return uPosFound;
387 Open a Zip file. path contain the full pathname (by example,
388 on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
389 "zlib/zlib114.zip".
390 If the zipfile cannot be opened (file doesn't exist or in not valid), the
391 return value is NULL.
392 Else, the return value is a unzFile Handle, usable with other function
393 of this unzip package.
395 extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def)
396 const char *path;
397 zlib_filefunc_def* pzlib_filefunc_def;
399 unz_s us;
400 unz_s *s;
401 uLong central_pos,uL;
403 uLong number_disk; /* number of the current dist, used for
404 spaning ZIP, unsupported, always 0*/
405 uLong number_disk_with_CD; /* number the the disk with central dir, used
406 for spaning ZIP, unsupported, always 0*/
407 uLong number_entry_CD; /* total number of entries in
408 the central dir
409 (same than number_entry on nospan) */
411 int err=UNZ_OK;
413 if (unz_copyright[0]!=' ')
414 return NULL;
416 if (pzlib_filefunc_def==NULL)
417 fill_fopen_filefunc(&us.z_filefunc);
418 else
419 us.z_filefunc = *pzlib_filefunc_def;
421 us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque,
422 path,
423 ZLIB_FILEFUNC_MODE_READ |
424 ZLIB_FILEFUNC_MODE_EXISTING);
425 if (us.filestream==NULL)
426 return NULL;
428 central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);
429 if (central_pos==0)
430 err=UNZ_ERRNO;
432 if (ZSEEK(us.z_filefunc, us.filestream,
433 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
434 err=UNZ_ERRNO;
436 /* the signature, already checked */
437 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
438 err=UNZ_ERRNO;
440 /* number of this disk */
441 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
442 err=UNZ_ERRNO;
444 /* number of the disk with the start of the central directory */
445 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
446 err=UNZ_ERRNO;
448 /* total number of entries in the central dir on this disk */
449 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
450 err=UNZ_ERRNO;
452 /* total number of entries in the central dir */
453 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
454 err=UNZ_ERRNO;
456 if ((number_entry_CD!=us.gi.number_entry) ||
457 (number_disk_with_CD!=0) ||
458 (number_disk!=0))
459 err=UNZ_BADZIPFILE;
461 /* size of the central directory */
462 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
463 err=UNZ_ERRNO;
465 /* offset of start of central directory with respect to the
466 starting disk number */
467 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
468 err=UNZ_ERRNO;
470 /* zipfile comment length */
471 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
472 err=UNZ_ERRNO;
474 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
475 (err==UNZ_OK))
476 err=UNZ_BADZIPFILE;
478 if (err!=UNZ_OK)
480 ZCLOSE(us.z_filefunc, us.filestream);
481 return NULL;
484 us.byte_before_the_zipfile = central_pos -
485 (us.offset_central_dir+us.size_central_dir);
486 us.central_pos = central_pos;
487 us.pfile_in_zip_read = NULL;
488 us.encrypted = 0;
491 s=(unz_s*)ALLOC(sizeof(unz_s));
492 *s=us;
493 unzGoToFirstFile((unzFile)s);
494 return (unzFile)s;
498 extern unzFile ZEXPORT unzOpen (path)
499 const char *path;
501 return unzOpen2(path, NULL);
505 Close a ZipFile opened with unzipOpen.
506 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
507 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
508 return UNZ_OK if there is no problem. */
509 extern int ZEXPORT unzClose (file)
510 unzFile file;
512 unz_s* s;
513 if (file==NULL)
514 return UNZ_PARAMERROR;
515 s=(unz_s*)file;
517 if (s->pfile_in_zip_read!=NULL)
518 unzCloseCurrentFile(file);
520 ZCLOSE(s->z_filefunc, s->filestream);
521 TRYFREE(s);
522 return UNZ_OK;
527 Write info about the ZipFile in the *pglobal_info structure.
528 No preparation of the structure is needed
529 return UNZ_OK if there is no problem. */
530 extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
531 unzFile file;
532 unz_global_info *pglobal_info;
534 unz_s* s;
535 if (file==NULL)
536 return UNZ_PARAMERROR;
537 s=(unz_s*)file;
538 *pglobal_info=s->gi;
539 return UNZ_OK;
544 Translate date/time from Dos format to tm_unz (readable more easilty)
546 local void unzlocal_DosDateToTmuDate (uLong ulDosDate, tm_unz *ptm)
548 uLong uDate;
549 uDate = (uLong)(ulDosDate>>16);
550 ptm->tm_mday = (uInt)(uDate&0x1f) ;
551 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
552 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
554 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
555 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
556 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
560 Get Info about the current file in the zipfile, with internal only info
562 local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
563 unz_file_info *pfile_info,
564 unz_file_info_internal
565 *pfile_info_internal,
566 char *szFileName,
567 uLong fileNameBufferSize,
568 void *extraField,
569 uLong extraFieldBufferSize,
570 char *szComment,
571 uLong commentBufferSize));
573 local int unzlocal_GetCurrentFileInfoInternal (file,
574 pfile_info,
575 pfile_info_internal,
576 szFileName, fileNameBufferSize,
577 extraField, extraFieldBufferSize,
578 szComment, commentBufferSize)
579 unzFile file;
580 unz_file_info *pfile_info;
581 unz_file_info_internal *pfile_info_internal;
582 char *szFileName;
583 uLong fileNameBufferSize;
584 void *extraField;
585 uLong extraFieldBufferSize;
586 char *szComment;
587 uLong commentBufferSize;
589 unz_s* s;
590 unz_file_info file_info;
591 unz_file_info_internal file_info_internal;
592 int err=UNZ_OK;
593 uLong uMagic;
594 long lSeek=0;
596 if (file==NULL)
597 return UNZ_PARAMERROR;
598 s=(unz_s*)file;
599 if (ZSEEK(s->z_filefunc, s->filestream,
600 s->pos_in_central_dir+s->byte_before_the_zipfile,
601 ZLIB_FILEFUNC_SEEK_SET)!=0)
602 err=UNZ_ERRNO;
605 /* we check the magic */
606 if (err==UNZ_OK) {
607 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
608 err=UNZ_ERRNO;
609 else if (uMagic!=0x02014b50)
610 err=UNZ_BADZIPFILE;
613 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
614 err=UNZ_ERRNO;
616 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
617 err=UNZ_ERRNO;
619 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
620 err=UNZ_ERRNO;
622 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
623 err=UNZ_ERRNO;
625 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
626 err=UNZ_ERRNO;
628 unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
630 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
631 err=UNZ_ERRNO;
633 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
634 err=UNZ_ERRNO;
636 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
637 err=UNZ_ERRNO;
639 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
640 err=UNZ_ERRNO;
642 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
643 err=UNZ_ERRNO;
645 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
646 err=UNZ_ERRNO;
648 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
649 err=UNZ_ERRNO;
651 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
652 err=UNZ_ERRNO;
654 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
655 err=UNZ_ERRNO;
657 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
658 err=UNZ_ERRNO;
660 lSeek+=file_info.size_filename;
661 if ((err==UNZ_OK) && (szFileName!=NULL))
663 uLong uSizeRead ;
664 if (file_info.size_filename<fileNameBufferSize)
666 *(szFileName+file_info.size_filename)='\0';
667 uSizeRead = file_info.size_filename;
669 else
670 uSizeRead = fileNameBufferSize;
672 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
673 if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
674 err=UNZ_ERRNO;
675 lSeek -= uSizeRead;
679 if ((err==UNZ_OK) && (extraField!=NULL))
681 uLong uSizeRead ;
682 if (file_info.size_file_extra<extraFieldBufferSize)
683 uSizeRead = file_info.size_file_extra;
684 else
685 uSizeRead = extraFieldBufferSize;
687 if (lSeek!=0) {
688 if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
689 lSeek=0;
690 else
691 err=UNZ_ERRNO;
694 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
695 if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)
696 err=UNZ_ERRNO;
697 lSeek += file_info.size_file_extra - uSizeRead;
699 else
700 lSeek+=file_info.size_file_extra;
703 if ((err==UNZ_OK) && (szComment!=NULL))
705 uLong uSizeRead ;
706 if (file_info.size_file_comment<commentBufferSize)
708 *(szComment+file_info.size_file_comment)='\0';
709 uSizeRead = file_info.size_file_comment;
711 else
712 uSizeRead = commentBufferSize;
714 if (lSeek!=0) {
715 if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
716 lSeek=0;
717 else
718 err=UNZ_ERRNO;
721 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
722 if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
723 err=UNZ_ERRNO;
724 lSeek+=file_info.size_file_comment - uSizeRead;
726 else
727 lSeek+=file_info.size_file_comment;
729 if ((err==UNZ_OK) && (pfile_info!=NULL))
730 *pfile_info=file_info;
732 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
733 *pfile_info_internal=file_info_internal;
735 return err;
741 Write info about the ZipFile in the *pglobal_info structure.
742 No preparation of the structure is needed
743 return UNZ_OK if there is no problem.
745 extern int ZEXPORT unzGetCurrentFileInfo (file,
746 pfile_info,
747 szFileName, fileNameBufferSize,
748 extraField, extraFieldBufferSize,
749 szComment, commentBufferSize)
750 unzFile file;
751 unz_file_info *pfile_info;
752 char *szFileName;
753 uLong fileNameBufferSize;
754 void *extraField;
755 uLong extraFieldBufferSize;
756 char *szComment;
757 uLong commentBufferSize;
759 return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
760 szFileName,fileNameBufferSize,
761 extraField,extraFieldBufferSize,
762 szComment,commentBufferSize);
766 Set the current file of the zipfile to the first file.
767 return UNZ_OK if there is no problem
769 extern int ZEXPORT unzGoToFirstFile (file)
770 unzFile file;
772 int err=UNZ_OK;
773 unz_s* s;
774 if (file==NULL)
775 return UNZ_PARAMERROR;
776 s=(unz_s*)file;
777 s->pos_in_central_dir=s->offset_central_dir;
778 s->num_file=0;
779 err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
780 &s->cur_file_info_internal,
781 NULL,0,NULL,0,NULL,0);
782 s->current_file_ok = (err == UNZ_OK);
783 return err;
787 Set the current file of the zipfile to the next file.
788 return UNZ_OK if there is no problem
789 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
791 extern int ZEXPORT unzGoToNextFile (file)
792 unzFile file;
794 unz_s* s;
795 int err;
797 if (file==NULL)
798 return UNZ_PARAMERROR;
799 s=(unz_s*)file;
800 if (!s->current_file_ok)
801 return UNZ_END_OF_LIST_OF_FILE;
802 if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
803 if (s->num_file+1==s->gi.number_entry)
804 return UNZ_END_OF_LIST_OF_FILE;
806 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
807 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
808 s->num_file++;
809 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
810 &s->cur_file_info_internal,
811 NULL,0,NULL,0,NULL,0);
812 s->current_file_ok = (err == UNZ_OK);
813 return err;
818 Try locate the file szFileName in the zipfile.
819 For the iCaseSensitivity signification, see unzipStringFileNameCompare
821 return value :
822 UNZ_OK if the file is found. It becomes the current file.
823 UNZ_END_OF_LIST_OF_FILE if the file is not found
825 extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
826 unzFile file;
827 const char *szFileName;
828 int iCaseSensitivity;
830 unz_s* s;
831 int err;
833 /* We remember the 'current' position in the file so that we can jump
834 * back there if we fail.
836 unz_file_info cur_file_infoSaved;
837 unz_file_info_internal cur_file_info_internalSaved;
838 uLong num_fileSaved;
839 uLong pos_in_central_dirSaved;
842 if (file==NULL)
843 return UNZ_PARAMERROR;
845 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
846 return UNZ_PARAMERROR;
848 s=(unz_s*)file;
849 if (!s->current_file_ok)
850 return UNZ_END_OF_LIST_OF_FILE;
852 /* Save the current state */
853 num_fileSaved = s->num_file;
854 pos_in_central_dirSaved = s->pos_in_central_dir;
855 cur_file_infoSaved = s->cur_file_info;
856 cur_file_info_internalSaved = s->cur_file_info_internal;
858 err = unzGoToFirstFile(file);
860 while (err == UNZ_OK)
862 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
863 err = unzGetCurrentFileInfo(file,NULL,
864 szCurrentFileName,sizeof(szCurrentFileName)-1,
865 NULL,0,NULL,0);
866 if (err == UNZ_OK)
868 if (unzStringFileNameCompare(szCurrentFileName,
869 szFileName,iCaseSensitivity)==0)
870 return UNZ_OK;
871 err = unzGoToNextFile(file);
875 /* We failed, so restore the state of the 'current file' to where we
876 * were.
878 s->num_file = num_fileSaved ;
879 s->pos_in_central_dir = pos_in_central_dirSaved ;
880 s->cur_file_info = cur_file_infoSaved;
881 s->cur_file_info_internal = cur_file_info_internalSaved;
882 return err;
887 ///////////////////////////////////////////
888 // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
889 // I need random access
891 // Further optimization could be realized by adding an ability
892 // to cache the directory in memory. The goal being a single
893 // comprehensive file read to put the file I need in a memory.
897 typedef struct unz_file_pos_s
899 uLong pos_in_zip_directory; // offset in file
900 uLong num_of_file; // # of file
901 } unz_file_pos;
904 extern int ZEXPORT unzGetFilePos(file, file_pos)
905 unzFile file;
906 unz_file_pos* file_pos;
908 unz_s* s;
910 if (file==NULL || file_pos==NULL)
911 return UNZ_PARAMERROR;
912 s=(unz_s*)file;
913 if (!s->current_file_ok)
914 return UNZ_END_OF_LIST_OF_FILE;
916 file_pos->pos_in_zip_directory = s->pos_in_central_dir;
917 file_pos->num_of_file = s->num_file;
919 return UNZ_OK;
922 extern int ZEXPORT unzGoToFilePos(file, file_pos)
923 unzFile file;
924 unz_file_pos* file_pos;
926 unz_s* s;
927 int err;
929 if (file==NULL || file_pos==NULL)
930 return UNZ_PARAMERROR;
931 s=(unz_s*)file;
933 /* jump to the right spot */
934 s->pos_in_central_dir = file_pos->pos_in_zip_directory;
935 s->num_file = file_pos->num_of_file;
937 /* set the current file */
938 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
939 &s->cur_file_info_internal,
940 NULL,0,NULL,0,NULL,0);
941 /* return results */
942 s->current_file_ok = (err == UNZ_OK);
943 return err;
947 // Unzip Helper Functions - should be here?
948 ///////////////////////////////////////////
952 Read the local header of the current zipfile
953 Check the coherency of the local header and info in the end of central
954 directory about this file
955 store in *piSizeVar the size of extra info in local header
956 (filename and size of extra field data)
958 local int unzlocal_CheckCurrentFileCoherencyHeader (unz_s *s, uInt *piSizeVar,
959 uLong *poffset_local_extrafield,
960 uInt *psize_local_extrafield)
962 uLong uMagic,uData,uFlags;
963 uLong size_filename;
964 uLong size_extra_field;
965 int err=UNZ_OK;
967 *piSizeVar = 0;
968 *poffset_local_extrafield = 0;
969 *psize_local_extrafield = 0;
971 if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
972 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
973 return UNZ_ERRNO;
976 if (err==UNZ_OK) {
977 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
978 err=UNZ_ERRNO;
979 else if (uMagic!=0x04034b50)
980 err=UNZ_BADZIPFILE;
983 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
984 err=UNZ_ERRNO;
986 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
987 err=UNZ_BADZIPFILE;
989 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
990 err=UNZ_ERRNO;
992 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
993 err=UNZ_ERRNO;
994 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
995 err=UNZ_BADZIPFILE;
997 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
998 (s->cur_file_info.compression_method!=Z_DEFLATED))
999 err=UNZ_BADZIPFILE;
1001 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
1002 err=UNZ_ERRNO;
1004 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
1005 err=UNZ_ERRNO;
1006 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
1007 ((uFlags & 8)==0))
1008 err=UNZ_BADZIPFILE;
1010 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
1011 err=UNZ_ERRNO;
1012 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
1013 ((uFlags & 8)==0))
1014 err=UNZ_BADZIPFILE;
1016 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
1017 err=UNZ_ERRNO;
1018 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
1019 ((uFlags & 8)==0))
1020 err=UNZ_BADZIPFILE;
1023 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
1024 err=UNZ_ERRNO;
1025 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
1026 err=UNZ_BADZIPFILE;
1028 *piSizeVar += (uInt)size_filename;
1030 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
1031 err=UNZ_ERRNO;
1032 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
1033 SIZEZIPLOCALHEADER + size_filename;
1034 *psize_local_extrafield = (uInt)size_extra_field;
1036 *piSizeVar += (uInt)size_extra_field;
1038 return err;
1042 Open for reading data the current file in the zipfile.
1043 If there is no error and the file is opened, the return value is UNZ_OK.
1045 extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
1046 unzFile file;
1047 int* method;
1048 int* level;
1049 int raw;
1050 const char* password;
1052 int err=UNZ_OK;
1053 uInt iSizeVar;
1054 unz_s* s;
1055 file_in_zip_read_info_s* pfile_in_zip_read_info;
1056 uLong offset_local_extrafield; /* offset of the local extra field */
1057 uInt size_local_extrafield; /* size of the local extra field */
1058 # ifndef NOUNCRYPT
1059 char source[12];
1060 # else
1061 if (password != NULL)
1062 return UNZ_PARAMERROR;
1063 # endif
1065 if (file==NULL)
1066 return UNZ_PARAMERROR;
1067 s=(unz_s*)file;
1068 if (!s->current_file_ok)
1069 return UNZ_PARAMERROR;
1071 if (s->pfile_in_zip_read != NULL)
1072 unzCloseCurrentFile(file);
1074 if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
1075 &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1076 return UNZ_BADZIPFILE;
1078 pfile_in_zip_read_info = (file_in_zip_read_info_s*)
1079 ALLOC(sizeof(file_in_zip_read_info_s));
1080 if (pfile_in_zip_read_info==NULL)
1081 return UNZ_INTERNALERROR;
1083 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1084 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1085 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1086 pfile_in_zip_read_info->pos_local_extrafield=0;
1087 pfile_in_zip_read_info->raw=raw;
1089 if (pfile_in_zip_read_info->read_buffer==NULL)
1091 TRYFREE(pfile_in_zip_read_info);
1092 return UNZ_INTERNALERROR;
1095 pfile_in_zip_read_info->stream_initialised=0;
1097 if (method!=NULL)
1098 *method = (int)s->cur_file_info.compression_method;
1100 if (level!=NULL)
1102 *level = 6;
1103 switch (s->cur_file_info.flag & 0x06)
1105 case 6 : *level = 1; break;
1106 case 4 : *level = 2; break;
1107 case 2 : *level = 9; break;
1111 if ((s->cur_file_info.compression_method!=0) &&
1112 (s->cur_file_info.compression_method!=Z_DEFLATED))
1113 err=UNZ_BADZIPFILE;
1115 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1116 pfile_in_zip_read_info->crc32=0;
1117 pfile_in_zip_read_info->compression_method =
1118 s->cur_file_info.compression_method;
1119 pfile_in_zip_read_info->filestream=s->filestream;
1120 pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
1121 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1123 pfile_in_zip_read_info->stream.total_out = 0;
1125 if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
1126 (!raw))
1128 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1129 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1130 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1131 pfile_in_zip_read_info->stream.next_in = (voidpf)0;
1132 pfile_in_zip_read_info->stream.avail_in = 0;
1134 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1135 if (err == Z_OK)
1136 pfile_in_zip_read_info->stream_initialised=1;
1137 else
1139 TRYFREE(pfile_in_zip_read_info);
1140 return err;
1142 /* windowBits is passed < 0 to tell that there is no zlib header.
1143 * Note that in this case inflate *requires* an extra "dummy" byte
1144 * after the compressed stream in order to complete decompression and
1145 * return Z_STREAM_END.
1146 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1147 * size of both compressed and uncompressed data
1150 pfile_in_zip_read_info->rest_read_compressed =
1151 s->cur_file_info.compressed_size ;
1152 pfile_in_zip_read_info->rest_read_uncompressed =
1153 s->cur_file_info.uncompressed_size ;
1156 pfile_in_zip_read_info->pos_in_zipfile =
1157 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1158 iSizeVar;
1160 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1162 s->pfile_in_zip_read = pfile_in_zip_read_info;
1164 # ifndef NOUNCRYPT
1165 if (password != NULL)
1167 int i;
1168 s->pcrc_32_tab = get_crc_table();
1169 init_keys(password,s->keys,s->pcrc_32_tab);
1170 if (ZSEEK(s->z_filefunc, s->filestream,
1171 s->pfile_in_zip_read->pos_in_zipfile +
1172 s->pfile_in_zip_read->byte_before_the_zipfile,
1173 SEEK_SET)!=0)
1174 return UNZ_INTERNALERROR;
1175 if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
1176 return UNZ_INTERNALERROR;
1178 for (i = 0; i<12; i++)
1179 zdecode(s->keys,s->pcrc_32_tab,source[i]);
1181 s->pfile_in_zip_read->pos_in_zipfile+=12;
1182 s->encrypted=1;
1184 # endif
1187 return UNZ_OK;
1190 extern int ZEXPORT unzOpenCurrentFile (file)
1191 unzFile file;
1193 return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
1196 extern int ZEXPORT unzOpenCurrentFilePassword (file, password)
1197 unzFile file;
1198 const char* password;
1200 return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
1203 extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw)
1204 unzFile file;
1205 int* method;
1206 int* level;
1207 int raw;
1209 return unzOpenCurrentFile3(file, method, level, raw, NULL);
1213 Read bytes from the current file.
1214 buf contain buffer where data must be copied
1215 len the size of buf.
1217 return the number of byte copied if somes bytes are copied
1218 return 0 if the end of file was reached
1219 return <0 with error code if there is an error
1220 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1222 extern int ZEXPORT unzReadCurrentFile (file, buf, len)
1223 unzFile file;
1224 voidp buf;
1225 unsigned len;
1227 int err=UNZ_OK;
1228 uInt iRead = 0;
1229 unz_s* s;
1230 file_in_zip_read_info_s* pfile_in_zip_read_info;
1231 if (file==NULL)
1232 return UNZ_PARAMERROR;
1233 s=(unz_s*)file;
1234 pfile_in_zip_read_info=s->pfile_in_zip_read;
1236 if (pfile_in_zip_read_info==NULL)
1237 return UNZ_PARAMERROR;
1240 if ((pfile_in_zip_read_info->read_buffer == NULL))
1241 return UNZ_END_OF_LIST_OF_FILE;
1242 if (len==0)
1243 return 0;
1245 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1247 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1249 if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
1250 (!(pfile_in_zip_read_info->raw)))
1251 pfile_in_zip_read_info->stream.avail_out =
1252 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1254 if ((len>pfile_in_zip_read_info->rest_read_compressed+
1255 pfile_in_zip_read_info->stream.avail_in) &&
1256 (pfile_in_zip_read_info->raw))
1257 pfile_in_zip_read_info->stream.avail_out =
1258 (uInt)pfile_in_zip_read_info->rest_read_compressed+
1259 pfile_in_zip_read_info->stream.avail_in;
1261 while (pfile_in_zip_read_info->stream.avail_out>0)
1263 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1264 (pfile_in_zip_read_info->rest_read_compressed>0))
1266 uInt uReadThis = UNZ_BUFSIZE;
1267 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1268 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1269 if (uReadThis == 0)
1270 return UNZ_EOF;
1271 if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1272 pfile_in_zip_read_info->filestream,
1273 pfile_in_zip_read_info->pos_in_zipfile +
1274 pfile_in_zip_read_info->byte_before_the_zipfile,
1275 ZLIB_FILEFUNC_SEEK_SET)!=0)
1276 return UNZ_ERRNO;
1277 if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1278 pfile_in_zip_read_info->filestream,
1279 pfile_in_zip_read_info->read_buffer,
1280 uReadThis)!=uReadThis)
1281 return UNZ_ERRNO;
1284 # ifndef NOUNCRYPT
1285 if(s->encrypted)
1287 uInt i;
1288 for(i=0;i<uReadThis;i++)
1289 pfile_in_zip_read_info->read_buffer[i] =
1290 zdecode(s->keys,s->pcrc_32_tab,
1291 pfile_in_zip_read_info->read_buffer[i]);
1293 # endif
1296 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1298 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1300 pfile_in_zip_read_info->stream.next_in =
1301 (Bytef*)pfile_in_zip_read_info->read_buffer;
1302 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1305 if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
1307 uInt uDoCopy,i ;
1309 if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
1310 (pfile_in_zip_read_info->rest_read_compressed == 0))
1311 return (iRead==0) ? UNZ_EOF : iRead;
1313 if (pfile_in_zip_read_info->stream.avail_out <
1314 pfile_in_zip_read_info->stream.avail_in)
1315 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1316 else
1317 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1319 for (i=0;i<uDoCopy;i++)
1320 *(pfile_in_zip_read_info->stream.next_out+i) =
1321 *(pfile_in_zip_read_info->stream.next_in+i);
1323 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1324 pfile_in_zip_read_info->stream.next_out,
1325 uDoCopy);
1326 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1327 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1328 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1329 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1330 pfile_in_zip_read_info->stream.next_in += uDoCopy;
1331 pfile_in_zip_read_info->stream.total_out += uDoCopy;
1332 iRead += uDoCopy;
1334 else
1336 uLong uTotalOutBefore,uTotalOutAfter;
1337 const Bytef *bufBefore;
1338 uLong uOutThis;
1339 int flush=Z_SYNC_FLUSH;
1341 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1342 bufBefore = pfile_in_zip_read_info->stream.next_out;
1345 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1346 pfile_in_zip_read_info->stream.avail_out) &&
1347 (pfile_in_zip_read_info->rest_read_compressed == 0))
1348 flush = Z_FINISH;
1350 err=inflate(&pfile_in_zip_read_info->stream,flush);
1352 if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
1353 err = Z_DATA_ERROR;
1355 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1356 uOutThis = uTotalOutAfter-uTotalOutBefore;
1358 pfile_in_zip_read_info->crc32 =
1359 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1360 (uInt)(uOutThis));
1362 pfile_in_zip_read_info->rest_read_uncompressed -=
1363 uOutThis;
1365 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1367 if (err==Z_STREAM_END)
1368 return (iRead==0) ? UNZ_EOF : iRead;
1369 if (err!=Z_OK)
1370 break;
1374 if (err==Z_OK)
1375 return iRead;
1376 return err;
1381 Give the current position in uncompressed data
1383 extern z_off_t ZEXPORT unztell (file)
1384 unzFile file;
1386 unz_s* s;
1387 file_in_zip_read_info_s* pfile_in_zip_read_info;
1388 if (file==NULL)
1389 return UNZ_PARAMERROR;
1390 s=(unz_s*)file;
1391 pfile_in_zip_read_info=s->pfile_in_zip_read;
1393 if (pfile_in_zip_read_info==NULL)
1394 return UNZ_PARAMERROR;
1396 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1401 return 1 if the end of file was reached, 0 elsewhere
1403 extern int ZEXPORT unzeof (file)
1404 unzFile file;
1406 unz_s* s;
1407 file_in_zip_read_info_s* pfile_in_zip_read_info;
1408 if (file==NULL)
1409 return UNZ_PARAMERROR;
1410 s=(unz_s*)file;
1411 pfile_in_zip_read_info=s->pfile_in_zip_read;
1413 if (pfile_in_zip_read_info==NULL)
1414 return UNZ_PARAMERROR;
1416 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1417 return 1;
1418 else
1419 return 0;
1425 Read extra field from the current file (opened by unzOpenCurrentFile)
1426 This is the local-header version of the extra field (sometimes, there is
1427 more info in the local-header version than in the central-header)
1429 if buf==NULL, it return the size of the local extra field that can be read
1431 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1432 buf.
1433 the return value is the number of bytes copied in buf, or (if <0)
1434 the error code
1436 extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
1437 unzFile file;
1438 voidp buf;
1439 unsigned len;
1441 unz_s* s;
1442 file_in_zip_read_info_s* pfile_in_zip_read_info;
1443 uInt read_now;
1444 uLong size_to_read;
1446 if (file==NULL)
1447 return UNZ_PARAMERROR;
1448 s=(unz_s*)file;
1449 pfile_in_zip_read_info=s->pfile_in_zip_read;
1451 if (pfile_in_zip_read_info==NULL)
1452 return UNZ_PARAMERROR;
1454 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1455 pfile_in_zip_read_info->pos_local_extrafield);
1457 if (buf==NULL)
1458 return (int)size_to_read;
1460 if (len>size_to_read)
1461 read_now = (uInt)size_to_read;
1462 else
1463 read_now = (uInt)len ;
1465 if (read_now==0)
1466 return 0;
1468 if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1469 pfile_in_zip_read_info->filestream,
1470 pfile_in_zip_read_info->offset_local_extrafield +
1471 pfile_in_zip_read_info->pos_local_extrafield,
1472 ZLIB_FILEFUNC_SEEK_SET)!=0)
1473 return UNZ_ERRNO;
1475 if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1476 pfile_in_zip_read_info->filestream,
1477 buf,read_now)!=read_now)
1478 return UNZ_ERRNO;
1480 return (int)read_now;
1484 Close the file in zip opened with unzipOpenCurrentFile
1485 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1487 extern int ZEXPORT unzCloseCurrentFile (file)
1488 unzFile file;
1490 int err=UNZ_OK;
1492 unz_s* s;
1493 file_in_zip_read_info_s* pfile_in_zip_read_info;
1494 if (file==NULL)
1495 return UNZ_PARAMERROR;
1496 s=(unz_s*)file;
1497 pfile_in_zip_read_info=s->pfile_in_zip_read;
1499 if (pfile_in_zip_read_info==NULL)
1500 return UNZ_PARAMERROR;
1503 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
1504 (!pfile_in_zip_read_info->raw))
1506 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1507 err=UNZ_CRCERROR;
1511 TRYFREE(pfile_in_zip_read_info->read_buffer);
1512 pfile_in_zip_read_info->read_buffer = NULL;
1513 if (pfile_in_zip_read_info->stream_initialised)
1514 inflateEnd(&pfile_in_zip_read_info->stream);
1516 pfile_in_zip_read_info->stream_initialised = 0;
1517 TRYFREE(pfile_in_zip_read_info);
1519 s->pfile_in_zip_read=NULL;
1521 return err;
1526 Get the global comment string of the ZipFile, in the szComment buffer.
1527 uSizeBuf is the size of the szComment buffer.
1528 return the number of byte copied or an error code <0
1530 extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
1531 unzFile file;
1532 char *szComment;
1533 uLong uSizeBuf;
1535 unz_s* s;
1536 uLong uReadThis ;
1537 if (file==NULL)
1538 return UNZ_PARAMERROR;
1539 s=(unz_s*)file;
1541 uReadThis = uSizeBuf;
1542 if (uReadThis>s->gi.size_comment)
1543 uReadThis = s->gi.size_comment;
1545 if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
1546 return UNZ_ERRNO;
1548 if (uReadThis>0)
1550 *szComment='\0';
1551 if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
1552 return UNZ_ERRNO;
1555 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1556 *(szComment+s->gi.size_comment)='\0';
1557 return (int)uReadThis;
1560 /* Additions by RX '2004 */
1561 extern uLong ZEXPORT unzGetOffset (file)
1562 unzFile file;
1564 unz_s* s;
1566 if (file==NULL)
1567 return UNZ_PARAMERROR;
1568 s=(unz_s*)file;
1569 if (!s->current_file_ok)
1570 return 0;
1571 if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
1572 if (s->num_file==s->gi.number_entry)
1573 return 0;
1574 return s->pos_in_central_dir;
1577 extern int ZEXPORT unzSetOffset (file, pos)
1578 unzFile file;
1579 uLong pos;
1581 unz_s* s;
1582 int err;
1584 if (file==NULL)
1585 return UNZ_PARAMERROR;
1586 s=(unz_s*)file;
1588 s->pos_in_central_dir = pos;
1589 s->num_file = s->gi.number_entry; /* hack */
1590 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1591 &s->cur_file_info_internal,
1592 NULL,0,NULL,0,NULL,0);
1593 s->current_file_ok = (err == UNZ_OK);
1594 return err;