Second attempt to fix compilation of dvdread (I don't really like this but it might...
[vlc/asuraparaju-public.git] / libs / unzip / unzip.c
blob72f2dff331f2982f1f9459de48e73a6c871ab78b
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 "zlib.h"
39 #include "unzip.h"
41 #ifdef STDC
42 # include <stddef.h>
43 # include <string.h>
44 # include <stdlib.h>
45 #endif
46 #ifdef NO_ERRNO_H
47 extern int errno;
48 #else
49 # include <errno.h>
50 #endif
52 #include <assert.h>
54 #ifndef local
55 # define local static
56 #endif
57 /* compile with -Dlocal if your debugger can't find static symbols */
60 #ifndef CASESENSITIVITYDEFAULT_NO
61 # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
62 # define CASESENSITIVITYDEFAULT_NO
63 # endif
64 #endif
67 #ifndef UNZ_BUFSIZE
68 #define UNZ_BUFSIZE (16384)
69 #endif
71 #ifndef UNZ_MAXFILENAMEINZIP
72 #define UNZ_MAXFILENAMEINZIP (256)
73 #endif
75 #ifndef ALLOC
76 # define ALLOC(size) (malloc(size))
77 #endif
78 #ifndef TRYFREE
79 # define TRYFREE(p) {free(p);}
80 #endif
82 #define SIZECENTRALDIRITEM (0x2e)
83 #define SIZEZIPLOCALHEADER (0x1e)
88 const char unz_copyright[] =
89 " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
91 /* unz_file_info_interntal contain internal info about a file in zipfile*/
92 typedef struct unz_file_info_internal_s
94 uLong offset_curfile;/* relative offset of local header 4 bytes */
95 } unz_file_info_internal;
98 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
99 when reading and decompress it */
100 typedef struct
102 char *read_buffer; /* internal buffer for compressed data */
103 z_stream stream; /* zLib stream structure for inflate */
105 uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
106 uLong stream_initialised; /* flag set if stream structure is initialised*/
108 uLong offset_local_extrafield;/* offset of the local extra field */
109 uInt size_local_extrafield;/* size of the local extra field */
110 uLong pos_local_extrafield; /* position in the local extra field in read*/
112 uLong crc32; /* crc32 of all data uncompressed */
113 uLong crc32_wait; /* crc32 we must obtain after decompress all */
114 uLong rest_read_compressed; /* number of byte to be decompressed */
115 uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
116 zlib_filefunc_def z_filefunc;
117 voidpf filestream; /* io structore of the zipfile */
118 uLong compression_method; /* compression method (0==store) */
119 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
120 int raw;
121 } file_in_zip_read_info_s;
124 /* unz_s contain internal information about the zipfile
126 typedef struct
128 zlib_filefunc_def z_filefunc;
129 voidpf filestream; /* io structore of the zipfile */
130 unz_global_info gi; /* public global information */
131 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
132 uLong num_file; /* number of the current file in the zipfile*/
133 uLong pos_in_central_dir; /* pos of the current file in the central dir*/
134 uLong current_file_ok; /* flag about the usability of the current file*/
135 uLong central_pos; /* position of the beginning of the central dir*/
137 uLong size_central_dir; /* size of the central directory */
138 uLong offset_central_dir; /* offset of start of central directory with
139 respect to the starting disk number */
141 unz_file_info cur_file_info; /* public info about the current file in zip*/
142 unz_file_info_internal cur_file_info_internal; /* private info about it*/
143 file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
144 file if we are decompressing it */
145 int encrypted;
146 # ifndef NOUNCRYPT
147 unsigned long keys[3]; /* keys defining the pseudo-random sequence */
148 const unsigned long* pcrc_32_tab;
149 # endif
150 } unz_s;
153 #ifndef NOUNCRYPT
154 #include "crypt.h"
155 #endif
157 /* ===========================================================================
158 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
159 for end of file.
160 IN assertion: the stream s has been sucessfully opened for reading.
164 local int unzlocal_getByte OF((
165 const zlib_filefunc_def* pzlib_filefunc_def,
166 voidpf filestream,
167 int *pi));
169 local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi)
170 const zlib_filefunc_def* pzlib_filefunc_def;
171 voidpf filestream;
172 int *pi;
174 unsigned char c;
175 int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
176 if (err==1)
178 *pi = (int)c;
179 return UNZ_OK;
181 else
183 if (ZERROR(*pzlib_filefunc_def,filestream))
184 return UNZ_ERRNO;
185 else
186 return UNZ_EOF;
191 /* ===========================================================================
192 Reads a long in LSB order from the given gz_stream. Sets
194 local int unzlocal_getShort OF((
195 const zlib_filefunc_def* pzlib_filefunc_def,
196 voidpf filestream,
197 uLong *pX));
199 local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
200 const zlib_filefunc_def* pzlib_filefunc_def;
201 voidpf filestream;
202 uLong *pX;
204 uLong x ;
205 int i = 0;
206 int err;
208 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
209 x = (uLong)i;
211 if (err==UNZ_OK)
212 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
213 x += ((uLong)i)<<8;
215 if (err==UNZ_OK)
216 *pX = x;
217 else
218 *pX = 0;
219 return err;
222 local int unzlocal_getLong OF((
223 const zlib_filefunc_def* pzlib_filefunc_def,
224 voidpf filestream,
225 uLong *pX));
227 local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
228 const zlib_filefunc_def* pzlib_filefunc_def;
229 voidpf filestream;
230 uLong *pX;
232 uLong x ;
233 int i = 0;
234 int err;
236 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
237 x = (uLong)i;
239 if (err==UNZ_OK)
240 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
241 x += ((uLong)i)<<8;
243 if (err==UNZ_OK)
244 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
245 x += ((uLong)i)<<16;
247 if (err==UNZ_OK)
248 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
249 x += ((uLong)i)<<24;
251 if (err==UNZ_OK)
252 *pX = x;
253 else
254 *pX = 0;
255 return err;
259 /* My own strcmpi / strcasecmp */
260 local int strcmpcasenosensitive_internal (fileName1,fileName2)
261 const char* fileName1;
262 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 (ulDosDate, ptm)
547 uLong ulDosDate;
548 tm_unz* ptm;
550 uLong uDate;
551 uDate = (uLong)(ulDosDate>>16);
552 ptm->tm_mday = (uInt)(uDate&0x1f) ;
553 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
554 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
556 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
557 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
558 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
562 Get Info about the current file in the zipfile, with internal only info
564 local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
565 unz_file_info *pfile_info,
566 unz_file_info_internal
567 *pfile_info_internal,
568 char *szFileName,
569 uLong fileNameBufferSize,
570 void *extraField,
571 uLong extraFieldBufferSize,
572 char *szComment,
573 uLong commentBufferSize));
575 local int unzlocal_GetCurrentFileInfoInternal (file,
576 pfile_info,
577 pfile_info_internal,
578 szFileName, fileNameBufferSize,
579 extraField, extraFieldBufferSize,
580 szComment, commentBufferSize)
581 unzFile file;
582 unz_file_info *pfile_info;
583 unz_file_info_internal *pfile_info_internal;
584 char *szFileName;
585 uLong fileNameBufferSize;
586 void *extraField;
587 uLong extraFieldBufferSize;
588 char *szComment;
589 uLong commentBufferSize;
591 unz_s* s;
592 unz_file_info file_info;
593 unz_file_info_internal file_info_internal;
594 int err=UNZ_OK;
595 uLong uMagic;
596 long lSeek=0;
598 if (file==NULL)
599 return UNZ_PARAMERROR;
600 s=(unz_s*)file;
601 if (ZSEEK(s->z_filefunc, s->filestream,
602 s->pos_in_central_dir+s->byte_before_the_zipfile,
603 ZLIB_FILEFUNC_SEEK_SET)!=0)
604 err=UNZ_ERRNO;
607 /* we check the magic */
608 if (err==UNZ_OK)
610 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
611 err=UNZ_ERRNO;
612 else if (uMagic!=0x02014b50)
613 err=UNZ_BADZIPFILE;
616 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
617 err=UNZ_ERRNO;
619 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
620 err=UNZ_ERRNO;
622 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
623 err=UNZ_ERRNO;
625 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
626 err=UNZ_ERRNO;
628 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
629 err=UNZ_ERRNO;
631 unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
633 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
634 err=UNZ_ERRNO;
636 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
637 err=UNZ_ERRNO;
639 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
640 err=UNZ_ERRNO;
642 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
643 err=UNZ_ERRNO;
645 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
646 err=UNZ_ERRNO;
648 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
649 err=UNZ_ERRNO;
651 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
652 err=UNZ_ERRNO;
654 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
655 err=UNZ_ERRNO;
657 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
658 err=UNZ_ERRNO;
660 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
661 err=UNZ_ERRNO;
663 lSeek+=file_info.size_filename;
664 if ((err==UNZ_OK) && (szFileName!=NULL))
666 uLong uSizeRead ;
667 if (file_info.size_filename<fileNameBufferSize)
669 *(szFileName+file_info.size_filename)='\0';
670 uSizeRead = file_info.size_filename;
672 else
673 uSizeRead = fileNameBufferSize;
675 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
676 if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
677 err=UNZ_ERRNO;
678 lSeek -= uSizeRead;
682 if ((err==UNZ_OK) && (extraField!=NULL))
684 uLong uSizeRead ;
685 if (file_info.size_file_extra<extraFieldBufferSize)
686 uSizeRead = file_info.size_file_extra;
687 else
688 uSizeRead = extraFieldBufferSize;
690 if (lSeek!=0)
692 if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
693 lSeek=0;
694 else
695 err=UNZ_ERRNO;
697 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
698 if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)
699 err=UNZ_ERRNO;
700 lSeek += file_info.size_file_extra - uSizeRead;
702 else
703 lSeek+=file_info.size_file_extra;
706 if ((err==UNZ_OK) && (szComment!=NULL))
708 uLong uSizeRead ;
709 if (file_info.size_file_comment<commentBufferSize)
711 *(szComment+file_info.size_file_comment)='\0';
712 uSizeRead = file_info.size_file_comment;
714 else
715 uSizeRead = commentBufferSize;
717 if (lSeek!=0)
719 if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
720 lSeek=0;
721 else
722 err=UNZ_ERRNO;
724 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
725 if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
726 err=UNZ_ERRNO;
727 lSeek+=file_info.size_file_comment - uSizeRead;
729 else
730 lSeek+=file_info.size_file_comment;
732 if ((err==UNZ_OK) && (pfile_info!=NULL))
733 *pfile_info=file_info;
735 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
736 *pfile_info_internal=file_info_internal;
738 return err;
744 Write info about the ZipFile in the *pglobal_info structure.
745 No preparation of the structure is needed
746 return UNZ_OK if there is no problem.
748 extern int ZEXPORT unzGetCurrentFileInfo (file,
749 pfile_info,
750 szFileName, fileNameBufferSize,
751 extraField, extraFieldBufferSize,
752 szComment, commentBufferSize)
753 unzFile file;
754 unz_file_info *pfile_info;
755 char *szFileName;
756 uLong fileNameBufferSize;
757 void *extraField;
758 uLong extraFieldBufferSize;
759 char *szComment;
760 uLong commentBufferSize;
762 return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
763 szFileName,fileNameBufferSize,
764 extraField,extraFieldBufferSize,
765 szComment,commentBufferSize);
769 Set the current file of the zipfile to the first file.
770 return UNZ_OK if there is no problem
772 extern int ZEXPORT unzGoToFirstFile (file)
773 unzFile file;
775 int err=UNZ_OK;
776 unz_s* s;
777 if (file==NULL)
778 return UNZ_PARAMERROR;
779 s=(unz_s*)file;
780 s->pos_in_central_dir=s->offset_central_dir;
781 s->num_file=0;
782 err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
783 &s->cur_file_info_internal,
784 NULL,0,NULL,0,NULL,0);
785 s->current_file_ok = (err == UNZ_OK);
786 return err;
790 Set the current file of the zipfile to the next file.
791 return UNZ_OK if there is no problem
792 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
794 extern int ZEXPORT unzGoToNextFile (file)
795 unzFile file;
797 unz_s* s;
798 int err;
800 if (file==NULL)
801 return UNZ_PARAMERROR;
802 s=(unz_s*)file;
803 if (!s->current_file_ok)
804 return UNZ_END_OF_LIST_OF_FILE;
805 if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
806 if (s->num_file+1==s->gi.number_entry)
807 return UNZ_END_OF_LIST_OF_FILE;
809 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
810 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
811 s->num_file++;
812 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
813 &s->cur_file_info_internal,
814 NULL,0,NULL,0,NULL,0);
815 s->current_file_ok = (err == UNZ_OK);
816 return err;
821 Try locate the file szFileName in the zipfile.
822 For the iCaseSensitivity signification, see unzipStringFileNameCompare
824 return value :
825 UNZ_OK if the file is found. It becomes the current file.
826 UNZ_END_OF_LIST_OF_FILE if the file is not found
828 extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
829 unzFile file;
830 const char *szFileName;
831 int iCaseSensitivity;
833 unz_s* s;
834 int err;
836 /* We remember the 'current' position in the file so that we can jump
837 * back there if we fail.
839 unz_file_info cur_file_infoSaved;
840 unz_file_info_internal cur_file_info_internalSaved;
841 uLong num_fileSaved;
842 uLong pos_in_central_dirSaved;
845 if (file==NULL)
846 return UNZ_PARAMERROR;
848 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
849 return UNZ_PARAMERROR;
851 s=(unz_s*)file;
852 if (!s->current_file_ok)
853 return UNZ_END_OF_LIST_OF_FILE;
855 /* Save the current state */
856 num_fileSaved = s->num_file;
857 pos_in_central_dirSaved = s->pos_in_central_dir;
858 cur_file_infoSaved = s->cur_file_info;
859 cur_file_info_internalSaved = s->cur_file_info_internal;
861 err = unzGoToFirstFile(file);
863 while (err == UNZ_OK)
865 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
866 err = unzGetCurrentFileInfo(file,NULL,
867 szCurrentFileName,sizeof(szCurrentFileName)-1,
868 NULL,0,NULL,0);
869 if (err == UNZ_OK)
871 if (unzStringFileNameCompare(szCurrentFileName,
872 szFileName,iCaseSensitivity)==0)
873 return UNZ_OK;
874 err = unzGoToNextFile(file);
878 /* We failed, so restore the state of the 'current file' to where we
879 * were.
881 s->num_file = num_fileSaved ;
882 s->pos_in_central_dir = pos_in_central_dirSaved ;
883 s->cur_file_info = cur_file_infoSaved;
884 s->cur_file_info_internal = cur_file_info_internalSaved;
885 return err;
890 ///////////////////////////////////////////
891 // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
892 // I need random access
894 // Further optimization could be realized by adding an ability
895 // to cache the directory in memory. The goal being a single
896 // comprehensive file read to put the file I need in a memory.
900 typedef struct unz_file_pos_s
902 uLong pos_in_zip_directory; // offset in file
903 uLong num_of_file; // # of file
904 } unz_file_pos;
907 extern int ZEXPORT unzGetFilePos(file, file_pos)
908 unzFile file;
909 unz_file_pos* file_pos;
911 unz_s* s;
913 if (file==NULL || file_pos==NULL)
914 return UNZ_PARAMERROR;
915 s=(unz_s*)file;
916 if (!s->current_file_ok)
917 return UNZ_END_OF_LIST_OF_FILE;
919 file_pos->pos_in_zip_directory = s->pos_in_central_dir;
920 file_pos->num_of_file = s->num_file;
922 return UNZ_OK;
925 extern int ZEXPORT unzGoToFilePos(file, file_pos)
926 unzFile file;
927 unz_file_pos* file_pos;
929 unz_s* s;
930 int err;
932 if (file==NULL || file_pos==NULL)
933 return UNZ_PARAMERROR;
934 s=(unz_s*)file;
936 /* jump to the right spot */
937 s->pos_in_central_dir = file_pos->pos_in_zip_directory;
938 s->num_file = file_pos->num_of_file;
940 /* set the current file */
941 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
942 &s->cur_file_info_internal,
943 NULL,0,NULL,0,NULL,0);
944 /* return results */
945 s->current_file_ok = (err == UNZ_OK);
946 return err;
950 // Unzip Helper Functions - should be here?
951 ///////////////////////////////////////////
955 Read the local header of the current zipfile
956 Check the coherency of the local header and info in the end of central
957 directory about this file
958 store in *piSizeVar the size of extra info in local header
959 (filename and size of extra field data)
961 local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
962 poffset_local_extrafield,
963 psize_local_extrafield)
964 unz_s* s;
965 uInt* piSizeVar;
966 uLong *poffset_local_extrafield;
967 uInt *psize_local_extrafield;
969 uLong uMagic,uData,uFlags;
970 uLong size_filename;
971 uLong size_extra_field;
972 int err=UNZ_OK;
974 *piSizeVar = 0;
975 *poffset_local_extrafield = 0;
976 *psize_local_extrafield = 0;
978 if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
979 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
980 return UNZ_ERRNO;
983 if (err==UNZ_OK)
985 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
986 err=UNZ_ERRNO;
987 else if (uMagic!=0x04034b50)
988 err=UNZ_BADZIPFILE;
990 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
991 err=UNZ_ERRNO;
993 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
994 err=UNZ_BADZIPFILE;
996 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
997 err=UNZ_ERRNO;
999 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1000 err=UNZ_ERRNO;
1001 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
1002 err=UNZ_BADZIPFILE;
1004 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
1005 (s->cur_file_info.compression_method!=Z_DEFLATED))
1006 err=UNZ_BADZIPFILE;
1008 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
1009 err=UNZ_ERRNO;
1011 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
1012 err=UNZ_ERRNO;
1013 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
1014 ((uFlags & 8)==0))
1015 err=UNZ_BADZIPFILE;
1017 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
1018 err=UNZ_ERRNO;
1019 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
1020 ((uFlags & 8)==0))
1021 err=UNZ_BADZIPFILE;
1023 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
1024 err=UNZ_ERRNO;
1025 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
1026 ((uFlags & 8)==0))
1027 err=UNZ_BADZIPFILE;
1030 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
1031 err=UNZ_ERRNO;
1032 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
1033 err=UNZ_BADZIPFILE;
1035 *piSizeVar += (uInt)size_filename;
1037 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
1038 err=UNZ_ERRNO;
1039 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
1040 SIZEZIPLOCALHEADER + size_filename;
1041 *psize_local_extrafield = (uInt)size_extra_field;
1043 *piSizeVar += (uInt)size_extra_field;
1045 return err;
1049 Open for reading data the current file in the zipfile.
1050 If there is no error and the file is opened, the return value is UNZ_OK.
1052 extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
1053 unzFile file;
1054 int* method;
1055 int* level;
1056 int raw;
1057 const char* password;
1059 int err=UNZ_OK;
1060 uInt iSizeVar;
1061 unz_s* s;
1062 file_in_zip_read_info_s* pfile_in_zip_read_info;
1063 uLong offset_local_extrafield; /* offset of the local extra field */
1064 uInt size_local_extrafield; /* size of the local extra field */
1065 # ifndef NOUNCRYPT
1066 char source[12];
1067 # else
1068 if (password != NULL)
1069 return UNZ_PARAMERROR;
1070 # endif
1072 if (file==NULL)
1073 return UNZ_PARAMERROR;
1074 s=(unz_s*)file;
1075 if (!s->current_file_ok)
1076 return UNZ_PARAMERROR;
1078 if (s->pfile_in_zip_read != NULL)
1079 unzCloseCurrentFile(file);
1081 if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
1082 &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1083 return UNZ_BADZIPFILE;
1085 pfile_in_zip_read_info = (file_in_zip_read_info_s*)
1086 ALLOC(sizeof(file_in_zip_read_info_s));
1087 if (pfile_in_zip_read_info==NULL)
1088 return UNZ_INTERNALERROR;
1090 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1091 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1092 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1093 pfile_in_zip_read_info->pos_local_extrafield=0;
1094 pfile_in_zip_read_info->raw=raw;
1096 if (pfile_in_zip_read_info->read_buffer==NULL)
1098 TRYFREE(pfile_in_zip_read_info);
1099 return UNZ_INTERNALERROR;
1102 pfile_in_zip_read_info->stream_initialised=0;
1104 if (method!=NULL)
1105 *method = (int)s->cur_file_info.compression_method;
1107 if (level!=NULL)
1109 *level = 6;
1110 switch (s->cur_file_info.flag & 0x06)
1112 case 6 : *level = 1; break;
1113 case 4 : *level = 2; break;
1114 case 2 : *level = 9; break;
1118 if ((s->cur_file_info.compression_method!=0) &&
1119 (s->cur_file_info.compression_method!=Z_DEFLATED))
1120 err=UNZ_BADZIPFILE;
1122 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1123 pfile_in_zip_read_info->crc32=0;
1124 pfile_in_zip_read_info->compression_method =
1125 s->cur_file_info.compression_method;
1126 pfile_in_zip_read_info->filestream=s->filestream;
1127 pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
1128 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1130 pfile_in_zip_read_info->stream.total_out = 0;
1132 if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
1133 (!raw))
1135 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1136 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1137 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1138 pfile_in_zip_read_info->stream.next_in = (voidpf)0;
1139 pfile_in_zip_read_info->stream.avail_in = 0;
1141 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1142 if (err == Z_OK)
1143 pfile_in_zip_read_info->stream_initialised=1;
1144 else
1146 TRYFREE(pfile_in_zip_read_info);
1147 return err;
1149 /* windowBits is passed < 0 to tell that there is no zlib header.
1150 * Note that in this case inflate *requires* an extra "dummy" byte
1151 * after the compressed stream in order to complete decompression and
1152 * return Z_STREAM_END.
1153 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1154 * size of both compressed and uncompressed data
1157 pfile_in_zip_read_info->rest_read_compressed =
1158 s->cur_file_info.compressed_size ;
1159 pfile_in_zip_read_info->rest_read_uncompressed =
1160 s->cur_file_info.uncompressed_size ;
1163 pfile_in_zip_read_info->pos_in_zipfile =
1164 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1165 iSizeVar;
1167 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1169 s->pfile_in_zip_read = pfile_in_zip_read_info;
1171 # ifndef NOUNCRYPT
1172 if (password != NULL)
1174 int i;
1175 s->pcrc_32_tab = get_crc_table();
1176 init_keys(password,s->keys,s->pcrc_32_tab);
1177 if (ZSEEK(s->z_filefunc, s->filestream,
1178 s->pfile_in_zip_read->pos_in_zipfile +
1179 s->pfile_in_zip_read->byte_before_the_zipfile,
1180 SEEK_SET)!=0)
1181 return UNZ_INTERNALERROR;
1182 if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
1183 return UNZ_INTERNALERROR;
1185 for (i = 0; i<12; i++)
1186 zdecode(s->keys,s->pcrc_32_tab,source[i]);
1188 s->pfile_in_zip_read->pos_in_zipfile+=12;
1189 s->encrypted=1;
1191 # endif
1194 return UNZ_OK;
1197 extern int ZEXPORT unzOpenCurrentFile (file)
1198 unzFile file;
1200 return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
1203 extern int ZEXPORT unzOpenCurrentFilePassword (file, password)
1204 unzFile file;
1205 const char* password;
1207 return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
1210 extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw)
1211 unzFile file;
1212 int* method;
1213 int* level;
1214 int raw;
1216 return unzOpenCurrentFile3(file, method, level, raw, NULL);
1220 Read bytes from the current file.
1221 buf contain buffer where data must be copied
1222 len the size of buf.
1224 return the number of byte copied if somes bytes are copied
1225 return 0 if the end of file was reached
1226 return <0 with error code if there is an error
1227 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1229 extern int ZEXPORT unzReadCurrentFile (file, buf, len)
1230 unzFile file;
1231 voidp buf;
1232 unsigned len;
1234 int err=UNZ_OK;
1235 uInt iRead = 0;
1236 unz_s* s;
1237 file_in_zip_read_info_s* pfile_in_zip_read_info;
1238 if (file==NULL)
1239 return UNZ_PARAMERROR;
1240 s=(unz_s*)file;
1241 pfile_in_zip_read_info=s->pfile_in_zip_read;
1243 if (pfile_in_zip_read_info==NULL)
1244 return UNZ_PARAMERROR;
1247 if ((pfile_in_zip_read_info->read_buffer == NULL))
1248 return UNZ_END_OF_LIST_OF_FILE;
1249 if (len==0)
1250 return 0;
1252 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1254 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1256 if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
1257 (!(pfile_in_zip_read_info->raw)))
1258 pfile_in_zip_read_info->stream.avail_out =
1259 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1261 if ((len>pfile_in_zip_read_info->rest_read_compressed+
1262 pfile_in_zip_read_info->stream.avail_in) &&
1263 (pfile_in_zip_read_info->raw))
1264 pfile_in_zip_read_info->stream.avail_out =
1265 (uInt)pfile_in_zip_read_info->rest_read_compressed+
1266 pfile_in_zip_read_info->stream.avail_in;
1268 while (pfile_in_zip_read_info->stream.avail_out>0)
1270 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1271 (pfile_in_zip_read_info->rest_read_compressed>0))
1273 uInt uReadThis = UNZ_BUFSIZE;
1274 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1275 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1276 if (uReadThis == 0)
1277 return UNZ_EOF;
1278 if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1279 pfile_in_zip_read_info->filestream,
1280 pfile_in_zip_read_info->pos_in_zipfile +
1281 pfile_in_zip_read_info->byte_before_the_zipfile,
1282 ZLIB_FILEFUNC_SEEK_SET)!=0)
1283 return UNZ_ERRNO;
1284 if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1285 pfile_in_zip_read_info->filestream,
1286 pfile_in_zip_read_info->read_buffer,
1287 uReadThis)!=uReadThis)
1288 return UNZ_ERRNO;
1291 # ifndef NOUNCRYPT
1292 if(s->encrypted)
1294 uInt i;
1295 for(i=0;i<uReadThis;i++)
1296 pfile_in_zip_read_info->read_buffer[i] =
1297 zdecode(s->keys,s->pcrc_32_tab,
1298 pfile_in_zip_read_info->read_buffer[i]);
1300 # endif
1303 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1305 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1307 pfile_in_zip_read_info->stream.next_in =
1308 (Bytef*)pfile_in_zip_read_info->read_buffer;
1309 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1312 if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
1314 uInt uDoCopy,i ;
1316 if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
1317 (pfile_in_zip_read_info->rest_read_compressed == 0))
1318 return (iRead==0) ? UNZ_EOF : iRead;
1320 if (pfile_in_zip_read_info->stream.avail_out <
1321 pfile_in_zip_read_info->stream.avail_in)
1322 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1323 else
1324 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1326 for (i=0;i<uDoCopy;i++)
1327 *(pfile_in_zip_read_info->stream.next_out+i) =
1328 *(pfile_in_zip_read_info->stream.next_in+i);
1330 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1331 pfile_in_zip_read_info->stream.next_out,
1332 uDoCopy);
1333 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1334 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1335 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1336 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1337 pfile_in_zip_read_info->stream.next_in += uDoCopy;
1338 pfile_in_zip_read_info->stream.total_out += uDoCopy;
1339 iRead += uDoCopy;
1341 else
1343 uLong uTotalOutBefore,uTotalOutAfter;
1344 const Bytef *bufBefore;
1345 uLong uOutThis;
1346 int flush=Z_SYNC_FLUSH;
1348 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1349 bufBefore = pfile_in_zip_read_info->stream.next_out;
1352 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1353 pfile_in_zip_read_info->stream.avail_out) &&
1354 (pfile_in_zip_read_info->rest_read_compressed == 0))
1355 flush = Z_FINISH;
1357 err=inflate(&pfile_in_zip_read_info->stream,flush);
1359 if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
1360 err = Z_DATA_ERROR;
1362 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1363 uOutThis = uTotalOutAfter-uTotalOutBefore;
1365 pfile_in_zip_read_info->crc32 =
1366 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1367 (uInt)(uOutThis));
1369 pfile_in_zip_read_info->rest_read_uncompressed -=
1370 uOutThis;
1372 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1374 if (err==Z_STREAM_END)
1375 return (iRead==0) ? UNZ_EOF : iRead;
1376 if (err!=Z_OK)
1377 break;
1381 if (err==Z_OK)
1382 return iRead;
1383 return err;
1388 Give the current position in uncompressed data
1390 extern z_off_t ZEXPORT unztell (file)
1391 unzFile file;
1393 unz_s* s;
1394 file_in_zip_read_info_s* pfile_in_zip_read_info;
1395 if (file==NULL)
1396 return UNZ_PARAMERROR;
1397 s=(unz_s*)file;
1398 pfile_in_zip_read_info=s->pfile_in_zip_read;
1400 if (pfile_in_zip_read_info==NULL)
1401 return UNZ_PARAMERROR;
1403 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1408 return 1 if the end of file was reached, 0 elsewhere
1410 extern int ZEXPORT unzeof (file)
1411 unzFile file;
1413 unz_s* s;
1414 file_in_zip_read_info_s* pfile_in_zip_read_info;
1415 if (file==NULL)
1416 return UNZ_PARAMERROR;
1417 s=(unz_s*)file;
1418 pfile_in_zip_read_info=s->pfile_in_zip_read;
1420 if (pfile_in_zip_read_info==NULL)
1421 return UNZ_PARAMERROR;
1423 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1424 return 1;
1425 else
1426 return 0;
1432 Read extra field from the current file (opened by unzOpenCurrentFile)
1433 This is the local-header version of the extra field (sometimes, there is
1434 more info in the local-header version than in the central-header)
1436 if buf==NULL, it return the size of the local extra field that can be read
1438 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1439 buf.
1440 the return value is the number of bytes copied in buf, or (if <0)
1441 the error code
1443 extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
1444 unzFile file;
1445 voidp buf;
1446 unsigned len;
1448 unz_s* s;
1449 file_in_zip_read_info_s* pfile_in_zip_read_info;
1450 uInt read_now;
1451 uLong size_to_read;
1453 if (file==NULL)
1454 return UNZ_PARAMERROR;
1455 s=(unz_s*)file;
1456 pfile_in_zip_read_info=s->pfile_in_zip_read;
1458 if (pfile_in_zip_read_info==NULL)
1459 return UNZ_PARAMERROR;
1461 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1462 pfile_in_zip_read_info->pos_local_extrafield);
1464 if (buf==NULL)
1465 return (int)size_to_read;
1467 if (len>size_to_read)
1468 read_now = (uInt)size_to_read;
1469 else
1470 read_now = (uInt)len ;
1472 if (read_now==0)
1473 return 0;
1475 if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1476 pfile_in_zip_read_info->filestream,
1477 pfile_in_zip_read_info->offset_local_extrafield +
1478 pfile_in_zip_read_info->pos_local_extrafield,
1479 ZLIB_FILEFUNC_SEEK_SET)!=0)
1480 return UNZ_ERRNO;
1482 if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1483 pfile_in_zip_read_info->filestream,
1484 buf,read_now)!=read_now)
1485 return UNZ_ERRNO;
1487 return (int)read_now;
1491 Close the file in zip opened with unzipOpenCurrentFile
1492 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1494 extern int ZEXPORT unzCloseCurrentFile (file)
1495 unzFile file;
1497 int err=UNZ_OK;
1499 unz_s* s;
1500 file_in_zip_read_info_s* pfile_in_zip_read_info;
1501 if (file==NULL)
1502 return UNZ_PARAMERROR;
1503 s=(unz_s*)file;
1504 pfile_in_zip_read_info=s->pfile_in_zip_read;
1506 if (pfile_in_zip_read_info==NULL)
1507 return UNZ_PARAMERROR;
1510 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
1511 (!pfile_in_zip_read_info->raw))
1513 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1514 err=UNZ_CRCERROR;
1518 TRYFREE(pfile_in_zip_read_info->read_buffer);
1519 pfile_in_zip_read_info->read_buffer = NULL;
1520 if (pfile_in_zip_read_info->stream_initialised)
1521 inflateEnd(&pfile_in_zip_read_info->stream);
1523 pfile_in_zip_read_info->stream_initialised = 0;
1524 TRYFREE(pfile_in_zip_read_info);
1526 s->pfile_in_zip_read=NULL;
1528 return err;
1533 Get the global comment string of the ZipFile, in the szComment buffer.
1534 uSizeBuf is the size of the szComment buffer.
1535 return the number of byte copied or an error code <0
1537 extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
1538 unzFile file;
1539 char *szComment;
1540 uLong uSizeBuf;
1542 unz_s* s;
1543 uLong uReadThis ;
1544 if (file==NULL)
1545 return UNZ_PARAMERROR;
1546 s=(unz_s*)file;
1548 uReadThis = uSizeBuf;
1549 if (uReadThis>s->gi.size_comment)
1550 uReadThis = s->gi.size_comment;
1552 if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
1553 return UNZ_ERRNO;
1555 if (uReadThis>0)
1557 *szComment='\0';
1558 if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
1559 return UNZ_ERRNO;
1562 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1563 *(szComment+s->gi.size_comment)='\0';
1564 return (int)uReadThis;
1567 /* Additions by RX '2004 */
1568 extern uLong ZEXPORT unzGetOffset (file)
1569 unzFile file;
1571 unz_s* s;
1573 if (file==NULL)
1574 return UNZ_PARAMERROR;
1575 s=(unz_s*)file;
1576 if (!s->current_file_ok)
1577 return 0;
1578 if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
1579 if (s->num_file==s->gi.number_entry)
1580 return 0;
1581 return s->pos_in_central_dir;
1584 extern int ZEXPORT unzSetOffset (file, pos)
1585 unzFile file;
1586 uLong pos;
1588 unz_s* s;
1589 int err;
1591 if (file==NULL)
1592 return UNZ_PARAMERROR;
1593 s=(unz_s*)file;
1595 s->pos_in_central_dir = pos;
1596 s->num_file = s->gi.number_entry; /* hack */
1597 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1598 &s->cur_file_info_internal,
1599 NULL,0,NULL,0,NULL,0);
1600 s->current_file_ok = (err == UNZ_OK);
1601 return err;