]> git.saurik.com Git - wxWidgets.git/blame - src/common/unzip.c
fixed rounding errors in variable status bar panes widths computation (patch 1030021)
[wxWidgets.git] / src / common / unzip.c
CommitLineData
076bae67
VS
1/*
2
77ffb593 3This file was altered for needs of wxWidgets.
076bae67
VS
4$Id$
5
6*/
7
913df6f2 8/* unzip.c -- IO on .zip files using zlib
5526e819
VS
9 Version 0.15 beta, Mar 19th, 1998,
10
11 Read unzip.h for more info
076bae67 12
5526e819
VS
13*/
14
78340847 15#include "wx/platform.h"
d78b3d64
VS
16
17#if wxUSE_ZLIB && wxUSE_ZIPSTREAM
5526e819
VS
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
f783e7ac
VZ
22/*
23#include "zlib.h"
24 normally, the compiler options should contain -I../zlib, but it is
25 apparently not the case for all MSW makefiles and so, unless we use
26 configure (which defines __WX_SETUP_H__) or it is explicitly overridden by
27 the user (who can define wxUSE_ZLIB_H_IN_PATH), we hardcode the path here
28*/
ac2834ab
GT
29#if defined(__WXMSW__) && !defined(__WX_SETUP_H__) && !defined(wxUSE_ZLIB_H_IN_PATH)
30 #include "../zlib/zlib.h"
ac2834ab
GT
31#else
32 #include "zlib.h"
33#endif
34
ea4f5235
JS
35
36/* Not the right solution (paths in makefiles) but... */
37#ifdef __BORLANDC__
38#include "../common/unzip.h"
39#else
5526e819 40#include "unzip.h"
ea4f5235 41#endif
5526e819
VS
42
43#ifdef STDC
44# include <stddef.h>
45# include <string.h>
46# include <stdlib.h>
47#endif
48#ifdef NO_ERRNO_H
49 extern int errno;
50#else
51# include <errno.h>
52#endif
53
54
55#ifndef local
56# define local static
57#endif
58/* compile with -Dlocal if your debugger can't find static symbols */
59
60
61
62#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
63 !defined(CASESENSITIVITYDEFAULT_NO)
64#define CASESENSITIVITYDEFAULT_NO
65#endif
66
67
68#ifndef UNZ_BUFSIZE
69#define UNZ_BUFSIZE (16384)
70#endif
71
72#ifndef UNZ_MAXFILENAMEINZIP
73#define UNZ_MAXFILENAMEINZIP (256)
74#endif
75
76#ifndef ALLOC
77# define ALLOC(size) (malloc(size))
78#endif
79#ifndef TRYFREE
80# define TRYFREE(p) {if (p) free(p);}
81#endif
82
83#define SIZECENTRALDIRITEM (0x2e)
84#define SIZEZIPLOCALHEADER (0x1e)
85
86
87/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
88
89#ifndef SEEK_CUR
90#define SEEK_CUR 1
91#endif
92
93#ifndef SEEK_END
94#define SEEK_END 2
95#endif
96
97#ifndef SEEK_SET
98#define SEEK_SET 0
99#endif
100
101const char unz_copyright[] =
102 " unzip 0.15 Copyright 1998 Gilles Vollant ";
103
104/* unz_file_info_interntal contain internal info about a file in zipfile*/
105typedef struct unz_file_info_internal_s
106{
107 uLong offset_curfile;/* relative offset of local header 4 bytes */
108} unz_file_info_internal;
109
110
111/* file_in_zip_read_info_s contain internal information about a file in zipfile,
112 when reading and decompress it */
113typedef struct
114{
f5ad07e2
WS
115 char *read_buffer; /* internal buffer for compressed data */
116 z_stream stream; /* zLib stream structure for inflate */
117
118 uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
119 uLong stream_initialised; /* flag set if stream structure is initialised*/
120
121 uLong offset_local_extrafield;/* offset of the local extra field */
122 uInt size_local_extrafield;/* size of the local extra field */
123 uLong pos_local_extrafield; /* position in the local extra field in read*/
124
125 uLong crc32; /* crc32 of all data uncompressed */
126 uLong crc32_wait; /* crc32 we must obtain after decompress all */
127 uLong rest_read_compressed; /* number of byte to be decompressed */
128 uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
129 FILE* file; /* io structore of the zipfile */
130 uLong compression_method; /* compression method (0==store) */
131 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
5526e819
VS
132} file_in_zip_read_info_s;
133
134
135/* unz_s contain internal information about the zipfile
136*/
137typedef struct
138{
f5ad07e2
WS
139 FILE* file; /* io structore of the zipfile */
140 unz_global_info gi; /* public global information */
141 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
142 uLong num_file; /* number of the current file in the zipfile*/
143 uLong pos_in_central_dir; /* pos of the current file in the central dir*/
144 uLong current_file_ok; /* flag about the usability of the current file*/
145 uLong central_pos; /* position of the beginning of the central dir*/
146
147 uLong size_central_dir; /* size of the central directory */
148 uLong offset_central_dir; /* offset of start of central directory with
149 respect to the starting disk number */
150
151 unz_file_info cur_file_info; /* public info about the current file in zip*/
152 unz_file_info_internal cur_file_info_internal; /* private info about it*/
5526e819 153 file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
f5ad07e2 154 file if we are decompressing it */
5526e819
VS
155} unz_s;
156
c0bcc480 157#if defined (__VISAGECPP__) || defined(__BORLANDC__)
866592d8 158/* VA always requires prototypes */
913df6f2
DW
159int unzlocal_CheckCurrentFileCoherencyHeader (unz_s*, uInt*, uLong*, uInt*);
160#endif
5526e819 161
3ca6a5f0
BP
162/* disable warnings about K&R declarations until the end of file */
163#ifdef _MSC_VER
164#pragma warning(disable:4131)
165#endif /* VC++ */
166
5526e819
VS
167/* ===========================================================================
168 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
169 for end of file.
170 IN assertion: the stream s has been sucessfully opened for reading.
171*/
172
173
174local int unzlocal_getByte(fin,pi)
f5ad07e2
WS
175 FILE *fin;
176 int *pi;
5526e819
VS
177{
178 unsigned char c;
f5ad07e2 179 int err = fread(&c, 1, 1, fin);
5526e819
VS
180 if (err==1)
181 {
182 *pi = (int)c;
183 return UNZ_OK;
184 }
185 else
186 {
913df6f2 187 if (ferror(fin))
5526e819
VS
188 return UNZ_ERRNO;
189 else
190 return UNZ_EOF;
191 }
192}
193
194
195/* ===========================================================================
913df6f2 196 Reads a long in LSB order from the given gz_stream. Sets
5526e819
VS
197*/
198local int unzlocal_getShort (fin,pX)
f5ad07e2 199 FILE* fin;
5526e819
VS
200 uLong *pX;
201{
202 uLong x ;
203 int i;
204 int err;
205
206 err = unzlocal_getByte(fin,&i);
207 x = (uLong)i;
913df6f2 208
5526e819
VS
209 if (err==UNZ_OK)
210 err = unzlocal_getByte(fin,&i);
211 x += ((uLong)i)<<8;
913df6f2 212
5526e819
VS
213 if (err==UNZ_OK)
214 *pX = x;
215 else
216 *pX = 0;
217 return err;
218}
219
220local int unzlocal_getLong (fin,pX)
f5ad07e2 221 FILE* fin;
5526e819
VS
222 uLong *pX;
223{
224 uLong x ;
225 int i;
226 int err;
227
228 err = unzlocal_getByte(fin,&i);
229 x = (uLong)i;
913df6f2 230
5526e819
VS
231 if (err==UNZ_OK)
232 err = unzlocal_getByte(fin,&i);
233 x += ((uLong)i)<<8;
234
235 if (err==UNZ_OK)
236 err = unzlocal_getByte(fin,&i);
237 x += ((uLong)i)<<16;
238
239 if (err==UNZ_OK)
240 err = unzlocal_getByte(fin,&i);
241 x += ((uLong)i)<<24;
913df6f2 242
5526e819
VS
243 if (err==UNZ_OK)
244 *pX = x;
245 else
246 *pX = 0;
247 return err;
248}
249
250
251/* My own strcmpi / strcasecmp */
252local int strcmpcasenosensitive_internal (fileName1,fileName2)
f5ad07e2
WS
253 const char* fileName1;
254 const char* fileName2;
5526e819 255{
f5ad07e2
WS
256 for (;;)
257 {
258 char c1=*(fileName1++);
259 char c2=*(fileName2++);
260 if ((c1>='a') && (c1<='z'))
261 c1 -= 0x20;
262 if ((c2>='a') && (c2<='z'))
263 c2 -= 0x20;
264 if (c1=='\0')
265 return ((c2=='\0') ? 0 : -1);
266 if (c2=='\0')
267 return 1;
268 if (c1<c2)
269 return -1;
270 if (c1>c2)
271 return 1;
272 }
5526e819
VS
273}
274
275
276#ifdef CASESENSITIVITYDEFAULT_NO
277#define CASESENSITIVITYDEFAULTVALUE 2
278#else
279#define CASESENSITIVITYDEFAULTVALUE 1
280#endif
281
282#ifndef STRCMPCASENOSENTIVEFUNCTION
283#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
284#endif
285
913df6f2 286/*
5526e819
VS
287 Compare two filename (fileName1,fileName2).
288 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
289 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
290 or strcasecmp)
291 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
292 (like 1 on Unix, 2 on Windows)
293
294*/
295extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
f5ad07e2
WS
296 const char* fileName1;
297 const char* fileName2;
298 int iCaseSensitivity;
5526e819 299{
f5ad07e2
WS
300 if (iCaseSensitivity==0)
301 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
5526e819 302
f5ad07e2
WS
303 if (iCaseSensitivity==1)
304 return strcmp(fileName1,fileName2);
5526e819 305
f5ad07e2 306 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
913df6f2 307}
5526e819
VS
308
309#define BUFREADCOMMENT (0x400)
310
311/*
312 Locate the Central directory of a zipfile (at the end, just before
313 the global comment)
314*/
315local uLong unzlocal_SearchCentralDir(fin)
f5ad07e2 316 FILE *fin;
5526e819 317{
f5ad07e2
WS
318 unsigned char* buf;
319 uLong uSizeFile;
320 uLong uBackRead;
321 uLong uMaxBack=0xffff; /* maximum size of global comment */
322 uLong uPosFound=0;
9e279f14 323
f5ad07e2
WS
324 if (fseek(fin,0,SEEK_END) != 0)
325 return 0;
5526e819
VS
326
327
f5ad07e2 328 uSizeFile = ftell( fin );
9e279f14 329
f5ad07e2
WS
330 if (uMaxBack>uSizeFile)
331 uMaxBack = uSizeFile;
5526e819 332
f5ad07e2
WS
333 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
334 if (buf==NULL)
335 return 0;
5526e819 336
f5ad07e2
WS
337 uBackRead = 4;
338 while (uBackRead<uMaxBack)
339 {
340 uLong uReadSize,uReadPos ;
341 int i;
342 if (uBackRead+BUFREADCOMMENT>uMaxBack)
343 uBackRead = uMaxBack;
344 else
345 uBackRead+=BUFREADCOMMENT;
346 uReadPos = uSizeFile-uBackRead ;
9e279f14 347
f5ad07e2 348 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
5526e819 349 (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
f5ad07e2
WS
350 if (fseek(fin,uReadPos,SEEK_SET)!=0)
351 break;
5526e819 352
f5ad07e2
WS
353 if (fread(buf,(uInt)uReadSize,1,fin)!=1)
354 break;
5526e819
VS
355
356 for (i=(int)uReadSize-3; (i--)>0;)
f5ad07e2
WS
357 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
358 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
359 {
360 uPosFound = uReadPos+i;
361 break;
362 }
363
364 if (uPosFound!=0)
365 break;
366 }
367 TRYFREE(buf);
368 return uPosFound;
5526e819
VS
369}
370
371/*
372 Open a Zip file. path contain the full pathname (by example,
373 on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
f5ad07e2
WS
374 "zlib/zlib109.zip".
375 If the zipfile cannot be opened (file don't exist or in not valid), the
376 return value is NULL.
5526e819 377 Else, the return value is a unzFile Handle, usable with other function
f5ad07e2 378 of this unzip package.
5526e819
VS
379*/
380extern unzFile ZEXPORT unzOpen (path)
f5ad07e2 381 const char *path;
5526e819 382{
f5ad07e2
WS
383 unz_s us;
384 unz_s *s;
385 uLong central_pos,uL;
386 FILE * fin ;
5526e819 387
f5ad07e2
WS
388 uLong number_disk; /* number of the current dist, used for
389 spaning ZIP, unsupported, always 0*/
390 uLong number_disk_with_CD; /* number the the disk with central dir, used
391 for spaning ZIP, unsupported, always 0*/
392 uLong number_entry_CD; /* total number of entries in
393 the central dir
394 (same than number_entry on nospan) */
5526e819 395
f5ad07e2 396 int err=UNZ_OK;
5526e819
VS
397
398 if (unz_copyright[0]!=' ')
399 return NULL;
400
401 fin=fopen(path,"rb");
f352dd54 402
f5ad07e2
WS
403 if (fin==NULL)
404 return NULL;
405
406 central_pos = unzlocal_SearchCentralDir(fin);
407 if (central_pos==0)
408 err=UNZ_ERRNO;
409
410 if (fseek(fin,central_pos,SEEK_SET)!=0)
411 err=UNZ_ERRNO;
412
413 /* the signature, already checked */
414 if (unzlocal_getLong(fin,&uL)!=UNZ_OK)
415 err=UNZ_ERRNO;
416
417 /* number of this disk */
418 if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK)
419 err=UNZ_ERRNO;
420
421 /* number of the disk with the start of the central directory */
422 if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK)
423 err=UNZ_ERRNO;
424
425 /* total number of entries in the central dir on this disk */
426 if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK)
427 err=UNZ_ERRNO;
428
429 /* total number of entries in the central dir */
430 if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK)
431 err=UNZ_ERRNO;
432
433 if ((number_entry_CD!=us.gi.number_entry) ||
434 (number_disk_with_CD!=0) ||
435 (number_disk!=0))
436 err=UNZ_BADZIPFILE;
437
438 /* size of the central directory */
439 if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK)
440 err=UNZ_ERRNO;
441
442 /* offset of start of central directory with respect to the
443 starting disk number */
444 if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK)
445 err=UNZ_ERRNO;
446
447 /* zipfile comment length */
448 if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK)
449 err=UNZ_ERRNO;
450
451 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
452 (err==UNZ_OK))
453 err=UNZ_BADZIPFILE;
454
455 if (err!=UNZ_OK)
456 {
457 fclose(fin);
458 return NULL;
459 }
460 us.file=fin;
461 us.byte_before_the_zipfile = central_pos -
462 (us.offset_central_dir+us.size_central_dir);
463 us.central_pos = central_pos;
5526e819 464 us.pfile_in_zip_read = NULL;
9e279f14 465
5526e819 466
f5ad07e2
WS
467 s=(unz_s*)ALLOC(sizeof(unz_s));
468 *s=us;
469 unzGoToFirstFile((unzFile)s);
470 return (unzFile)s;
5526e819
VS
471}
472
473
474/*
475 Close a ZipFile opened with unzipOpen.
476 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
477 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
478 return UNZ_OK if there is no problem. */
479extern int ZEXPORT unzClose (file)
f5ad07e2 480 unzFile file;
5526e819 481{
f5ad07e2
WS
482 unz_s* s;
483 if (file==NULL)
484 return UNZ_PARAMERROR;
485 s=(unz_s*)file;
5526e819
VS
486
487 if (s->pfile_in_zip_read!=NULL)
488 unzCloseCurrentFile(file);
489
f5ad07e2
WS
490 fclose(s->file);
491 TRYFREE(s);
492 return UNZ_OK;
5526e819
VS
493}
494
495
496/*
497 Write info about the ZipFile in the *pglobal_info structure.
498 No preparation of the structure is needed
499 return UNZ_OK if there is no problem. */
500extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
f5ad07e2
WS
501 unzFile file;
502 unz_global_info *pglobal_info;
5526e819 503{
f5ad07e2
WS
504 unz_s* s;
505 if (file==NULL)
506 return UNZ_PARAMERROR;
507 s=(unz_s*)file;
508 *pglobal_info=s->gi;
509 return UNZ_OK;
5526e819
VS
510}
511
512
513/*
514 Translate date/time from Dos format to tm_unz (readable more easilty)
515*/
516local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
517 uLong ulDosDate;
518 tm_unz* ptm;
519{
520 uLong uDate;
521 uDate = (uLong)(ulDosDate>>16);
522 ptm->tm_mday = (uInt)(uDate&0x1f) ;
523 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
524 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
525
526 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
527 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
528 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
529}
530
531/*
532 Get Info about the current file in the zipfile, with internal only info
533*/
534local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
535 unz_file_info *pfile_info,
913df6f2 536 unz_file_info_internal
5526e819
VS
537 *pfile_info_internal,
538 char *szFileName,
f5ad07e2 539 uLong fileNameBufferSize,
5526e819 540 void *extraField,
f5ad07e2 541 uLong extraFieldBufferSize,
5526e819 542 char *szComment,
f5ad07e2 543 uLong commentBufferSize));
5526e819
VS
544
545local int unzlocal_GetCurrentFileInfoInternal (file,
546 pfile_info,
547 pfile_info_internal,
548 szFileName, fileNameBufferSize,
549 extraField, extraFieldBufferSize,
550 szComment, commentBufferSize)
f5ad07e2
WS
551 unzFile file;
552 unz_file_info *pfile_info;
553 unz_file_info_internal *pfile_info_internal;
554 char *szFileName;
555 uLong fileNameBufferSize;
556 void *extraField;
557 uLong extraFieldBufferSize;
558 char *szComment;
559 uLong commentBufferSize;
5526e819 560{
f5ad07e2
WS
561 unz_s* s;
562 unz_file_info file_info;
563 unz_file_info_internal file_info_internal;
564 int err=UNZ_OK;
565 uLong uMagic;
566 long lSeek=0;
567
568 if (file==NULL)
569 return UNZ_PARAMERROR;
570 s=(unz_s*)file;
571 if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0)
572 err=UNZ_ERRNO;
573
574
575 /* we check the magic */
576 if (err==UNZ_OK)
f6bcfd97 577 {
f5ad07e2
WS
578 if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
579 err=UNZ_ERRNO;
580 else if (uMagic!=0x02014b50)
581 err=UNZ_BADZIPFILE;
f6bcfd97 582 }
5526e819 583
f5ad07e2
WS
584 if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK)
585 err=UNZ_ERRNO;
5526e819 586
f5ad07e2
WS
587 if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK)
588 err=UNZ_ERRNO;
5526e819 589
f5ad07e2
WS
590 if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK)
591 err=UNZ_ERRNO;
5526e819 592
f5ad07e2
WS
593 if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK)
594 err=UNZ_ERRNO;
5526e819 595
f5ad07e2
WS
596 if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK)
597 err=UNZ_ERRNO;
5526e819
VS
598
599 unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
600
f5ad07e2
WS
601 if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK)
602 err=UNZ_ERRNO;
603
604 if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK)
605 err=UNZ_ERRNO;
5526e819 606
f5ad07e2
WS
607 if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK)
608 err=UNZ_ERRNO;
5526e819 609
f5ad07e2
WS
610 if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK)
611 err=UNZ_ERRNO;
5526e819 612
f5ad07e2
WS
613 if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK)
614 err=UNZ_ERRNO;
5526e819 615
f5ad07e2
WS
616 if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK)
617 err=UNZ_ERRNO;
5526e819 618
f5ad07e2
WS
619 if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK)
620 err=UNZ_ERRNO;
5526e819 621
f5ad07e2
WS
622 if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK)
623 err=UNZ_ERRNO;
5526e819 624
f5ad07e2
WS
625 if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK)
626 err=UNZ_ERRNO;
627
628 if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK)
629 err=UNZ_ERRNO;
630
631 lSeek+=file_info.size_filename;
632 if ((err==UNZ_OK) && (szFileName!=NULL))
633 {
634 uLong uSizeRead ;
635 if (file_info.size_filename<fileNameBufferSize)
636 {
637 *(szFileName+file_info.size_filename)='\0';
638 uSizeRead = file_info.size_filename;
639 }
640 else
641 uSizeRead = fileNameBufferSize;
5526e819 642
f5ad07e2
WS
643 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
644 if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1)
645 err=UNZ_ERRNO;
646 lSeek -= uSizeRead;
647 }
5526e819 648
5526e819 649
f5ad07e2
WS
650 if ((err==UNZ_OK) && (extraField!=NULL))
651 {
652 uLong uSizeRead ;
653 if (file_info.size_file_extra<extraFieldBufferSize)
654 uSizeRead = file_info.size_file_extra;
655 else
656 uSizeRead = extraFieldBufferSize;
5526e819 657
f5ad07e2
WS
658 if (lSeek!=0)
659 {
660 if (fseek(s->file,lSeek,SEEK_CUR)==0)
661 lSeek=0;
662 else
663 err=UNZ_ERRNO;
664 }
5526e819 665
f5ad07e2
WS
666 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
667 if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1)
668 err=UNZ_ERRNO;
669 lSeek += file_info.size_file_extra - uSizeRead;
670 }
671 else
672 lSeek+=file_info.size_file_extra;
9e279f14 673
5526e819 674
f5ad07e2
WS
675 if ((err==UNZ_OK) && (szComment!=NULL))
676 {
677 uLong uSizeRead ;
678 if (file_info.size_file_comment<commentBufferSize)
f6bcfd97 679 {
f5ad07e2
WS
680 *(szComment+file_info.size_file_comment)='\0';
681 uSizeRead = file_info.size_file_comment;
f6bcfd97 682 }
f5ad07e2
WS
683 else
684 uSizeRead = commentBufferSize;
f6bcfd97 685
f5ad07e2 686 if (lSeek!=0)
f6bcfd97 687 {
f5ad07e2
WS
688 if (fseek(s->file,lSeek,SEEK_CUR)!=0)
689 err=UNZ_ERRNO;
690#ifdef __WXDEBUG__
691 // lSeek is not used later in the code so update it only for debug purposes
692 else
693 lSeek=0;
694#endif
f6bcfd97
BP
695 }
696
f5ad07e2
WS
697 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
698 if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1)
699 err=UNZ_ERRNO;
700#ifdef __WXDEBUG__
701 // lSeek is not used later in the code so update it only for debug purposes
702 lSeek+=file_info.size_file_comment - uSizeRead;
703#endif
704 }
705#ifdef __WXDEBUG__
706 else
707 {
708 // lSeek is not used later in the code so update it only for debug purposes
709 lSeek+=file_info.size_file_comment;
710 }
711#endif
5526e819 712
f5ad07e2
WS
713 if ((err==UNZ_OK) && (pfile_info!=NULL))
714 *pfile_info=file_info;
5526e819 715
f5ad07e2
WS
716 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
717 *pfile_info_internal=file_info_internal;
5526e819 718
f5ad07e2 719 return err;
5526e819
VS
720}
721
722
723
724/*
725 Write info about the ZipFile in the *pglobal_info structure.
726 No preparation of the structure is needed
727 return UNZ_OK if there is no problem.
728*/
729extern int ZEXPORT unzGetCurrentFileInfo (file,
730 pfile_info,
731 szFileName, fileNameBufferSize,
732 extraField, extraFieldBufferSize,
733 szComment, commentBufferSize)
f5ad07e2
WS
734 unzFile file;
735 unz_file_info *pfile_info;
736 char *szFileName;
737 uLong fileNameBufferSize;
738 void *extraField;
739 uLong extraFieldBufferSize;
740 char *szComment;
741 uLong commentBufferSize;
5526e819 742{
f5ad07e2
WS
743 return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
744 szFileName,fileNameBufferSize,
745 extraField,extraFieldBufferSize,
746 szComment,commentBufferSize);
5526e819
VS
747}
748
749/*
750 Set the current file of the zipfile to the first file.
751 return UNZ_OK if there is no problem
752*/
753extern int ZEXPORT unzGoToFirstFile (file)
f5ad07e2 754 unzFile file;
5526e819 755{
f5ad07e2
WS
756 int err;
757 unz_s* s;
758 if (file==NULL)
759 return UNZ_PARAMERROR;
760 s=(unz_s*)file;
761 s->pos_in_central_dir=s->offset_central_dir;
762 s->num_file=0;
763 err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
764 &s->cur_file_info_internal,
765 NULL,0,NULL,0,NULL,0);
766 s->current_file_ok = (err == UNZ_OK);
767 return err;
5526e819
VS
768}
769
770
771/*
772 Set the current file of the zipfile to the next file.
773 return UNZ_OK if there is no problem
774 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
775*/
776extern int ZEXPORT unzGoToNextFile (file)
f5ad07e2 777 unzFile file;
5526e819 778{
f5ad07e2
WS
779 unz_s* s;
780 int err;
781
782 if (file==NULL)
783 return UNZ_PARAMERROR;
784 s=(unz_s*)file;
785 if (!s->current_file_ok)
786 return UNZ_END_OF_LIST_OF_FILE;
787 if (s->num_file+1==s->gi.number_entry)
788 return UNZ_END_OF_LIST_OF_FILE;
789
790 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
791 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
792 s->num_file++;
793 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
794 &s->cur_file_info_internal,
795 NULL,0,NULL,0,NULL,0);
796 s->current_file_ok = (err == UNZ_OK);
797 return err;
5526e819
VS
798}
799
800
801/*
802 Try locate the file szFileName in the zipfile.
803 For the iCaseSensitivity signification, see unzipStringFileNameCompare
804
805 return value :
806 UNZ_OK if the file is found. It becomes the current file.
807 UNZ_END_OF_LIST_OF_FILE if the file is not found
808*/
809extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
f5ad07e2
WS
810 unzFile file;
811 const char *szFileName;
812 int iCaseSensitivity;
5526e819 813{
f5ad07e2
WS
814 unz_s* s;
815 int err;
6ecb30a3
VS
816 const char *c;
817 char *c2;
818 char szFileName2[UNZ_MAXFILENAMEINZIP+1];
19193a2c 819
f5ad07e2
WS
820 uLong num_fileSaved;
821 uLong pos_in_central_dirSaved;
5526e819 822
19193a2c 823 for (c = szFileName, c2 = szFileName2; *c != '\0'; c++, c2++)
6ecb30a3
VS
824 if (*c == '\\') *c2 = '/';
825 else *c2 = *c;
826 *c2 = '\0';
9e279f14 827
f5ad07e2
WS
828 if (file==NULL)
829 return UNZ_PARAMERROR;
5526e819
VS
830
831 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
832 return UNZ_PARAMERROR;
833
f5ad07e2
WS
834 s=(unz_s*)file;
835 if (!s->current_file_ok)
836 return UNZ_END_OF_LIST_OF_FILE;
5526e819 837
f5ad07e2
WS
838 num_fileSaved = s->num_file;
839 pos_in_central_dirSaved = s->pos_in_central_dir;
5526e819 840
f5ad07e2 841 err = unzGoToFirstFile(file);
5526e819 842
f5ad07e2
WS
843 while (err == UNZ_OK)
844 {
845 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
846 unzGetCurrentFileInfo(file,NULL,
847 szCurrentFileName,sizeof(szCurrentFileName)-1,
848 NULL,0,NULL,0);
6ecb30a3 849 for (c2 = szCurrentFileName; *c2 != '\0'; c2++) if (*c2 == '\\') *c2 = '/';
f5ad07e2
WS
850 if (unzStringFileNameCompare(szCurrentFileName,
851 szFileName2,iCaseSensitivity)==0)
852 return UNZ_OK;
853 err = unzGoToNextFile(file);
854 }
855
856 s->num_file = num_fileSaved ;
857 s->pos_in_central_dir = pos_in_central_dirSaved ;
858 return err;
5526e819
VS
859}
860
861
862/*
863 Read the local header of the current zipfile
864 Check the coherency of the local header and info in the end of central
865 directory about this file
866 store in *piSizeVar the size of extra info in local header
867 (filename and size of extra field data)
868*/
869local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
f5ad07e2
WS
870 poffset_local_extrafield,
871 psize_local_extrafield)
872 unz_s* s;
873 uInt* piSizeVar;
874 uLong *poffset_local_extrafield;
875 uInt *psize_local_extrafield;
5526e819 876{
f5ad07e2
WS
877 uLong uMagic,uData,uFlags;
878 uLong size_filename;
879 uLong size_extra_field;
880 int err=UNZ_OK;
5526e819 881
f5ad07e2
WS
882 *piSizeVar = 0;
883 *poffset_local_extrafield = 0;
884 *psize_local_extrafield = 0;
5526e819 885
f5ad07e2
WS
886 if (fseek(s->file,s->cur_file_info_internal.offset_curfile +
887 s->byte_before_the_zipfile,SEEK_SET)!=0)
888 return UNZ_ERRNO;
5526e819
VS
889
890
f5ad07e2 891 if (err==UNZ_OK)
f6bcfd97 892 {
f5ad07e2
WS
893 if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
894 err=UNZ_ERRNO;
895 else if (uMagic!=0x04034b50)
896 err=UNZ_BADZIPFILE;
f6bcfd97 897 }
5526e819 898
f5ad07e2
WS
899 if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
900 err=UNZ_ERRNO;
5526e819 901/*
f5ad07e2
WS
902 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
903 err=UNZ_BADZIPFILE;
5526e819 904*/
f5ad07e2
WS
905 if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK)
906 err=UNZ_ERRNO;
5526e819 907
f5ad07e2
WS
908 if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
909 err=UNZ_ERRNO;
910 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
911 err=UNZ_BADZIPFILE;
5526e819
VS
912
913 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
914 (s->cur_file_info.compression_method!=Z_DEFLATED))
915 err=UNZ_BADZIPFILE;
916
f5ad07e2
WS
917 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */
918 err=UNZ_ERRNO;
5526e819 919
f5ad07e2
WS
920 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */
921 err=UNZ_ERRNO;
922 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
923 ((uFlags & 8)==0))
924 err=UNZ_BADZIPFILE;
5526e819 925
f5ad07e2
WS
926 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */
927 err=UNZ_ERRNO;
928 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
929 ((uFlags & 8)==0))
930 err=UNZ_BADZIPFILE;
5526e819 931
f5ad07e2
WS
932 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */
933 err=UNZ_ERRNO;
934 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
935 ((uFlags & 8)==0))
936 err=UNZ_BADZIPFILE;
5526e819
VS
937
938
f5ad07e2
WS
939 if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK)
940 err=UNZ_ERRNO;
941 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
942 err=UNZ_BADZIPFILE;
5526e819 943
f5ad07e2 944 *piSizeVar += (uInt)size_filename;
5526e819 945
f5ad07e2
WS
946 if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK)
947 err=UNZ_ERRNO;
948 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
949 SIZEZIPLOCALHEADER + size_filename;
950 *psize_local_extrafield = (uInt)size_extra_field;
5526e819 951
f5ad07e2 952 *piSizeVar += (uInt)size_extra_field;
5526e819 953
f5ad07e2 954 return err;
5526e819 955}
9e279f14 956
5526e819
VS
957/*
958 Open for reading data the current file in the zipfile.
959 If there is no error and the file is opened, the return value is UNZ_OK.
960*/
961extern int ZEXPORT unzOpenCurrentFile (file)
f5ad07e2 962 unzFile file;
5526e819 963{
f5ad07e2
WS
964 int err
965#ifdef __WXDEBUG__
966 =UNZ_OK
967#endif
968 ;
969 int Store;
970 uInt iSizeVar;
971 unz_s* s;
972 file_in_zip_read_info_s* pfile_in_zip_read_info;
973 uLong offset_local_extrafield; /* offset of the local extra field */
974 uInt size_local_extrafield; /* size of the local extra field */
975
976 if (file==NULL)
977 return UNZ_PARAMERROR;
978 s=(unz_s*)file;
979 if (!s->current_file_ok)
980 return UNZ_PARAMERROR;
5526e819
VS
981
982 if (s->pfile_in_zip_read != NULL)
983 unzCloseCurrentFile(file);
984
f5ad07e2
WS
985 if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
986 &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
987 return UNZ_BADZIPFILE;
5526e819 988
f5ad07e2
WS
989 pfile_in_zip_read_info = (file_in_zip_read_info_s*)
990 ALLOC(sizeof(file_in_zip_read_info_s));
991 if (pfile_in_zip_read_info==NULL)
992 return UNZ_INTERNALERROR;
5526e819 993
f5ad07e2
WS
994 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
995 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
996 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
997 pfile_in_zip_read_info->pos_local_extrafield=0;
5526e819 998
f5ad07e2
WS
999 if (pfile_in_zip_read_info->read_buffer==NULL)
1000 {
1001 TRYFREE(pfile_in_zip_read_info);
1002 return UNZ_INTERNALERROR;
1003 }
5526e819 1004
f5ad07e2 1005 pfile_in_zip_read_info->stream_initialised=0;
9e279f14 1006
f5ad07e2
WS
1007#ifdef __WXDEBUG__
1008 if ((s->cur_file_info.compression_method!=0) &&
5526e819 1009 (s->cur_file_info.compression_method!=Z_DEFLATED))
f5ad07e2
WS
1010 err=UNZ_BADZIPFILE;
1011#endif
1012 Store = s->cur_file_info.compression_method==0;
5526e819 1013
f5ad07e2
WS
1014 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1015 pfile_in_zip_read_info->crc32=0;
1016 pfile_in_zip_read_info->compression_method =
5526e819 1017 s->cur_file_info.compression_method;
f5ad07e2
WS
1018 pfile_in_zip_read_info->file=s->file;
1019 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
5526e819
VS
1020
1021 pfile_in_zip_read_info->stream.total_out = 0;
1022
f5ad07e2
WS
1023 if (!Store)
1024 {
1025 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1026 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1027 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
913df6f2 1028
f5ad07e2
WS
1029 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1030 if (err == Z_OK)
1031 pfile_in_zip_read_info->stream_initialised=1;
5526e819
VS
1032 /* windowBits is passed < 0 to tell that there is no zlib header.
1033 * Note that in this case inflate *requires* an extra "dummy" byte
1034 * after the compressed stream in order to complete decompression and
913df6f2
DW
1035 * return Z_STREAM_END.
1036 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
5526e819
VS
1037 * size of both compressed and uncompressed data
1038 */
f5ad07e2
WS
1039 }
1040 pfile_in_zip_read_info->rest_read_compressed =
5526e819 1041 s->cur_file_info.compressed_size ;
f5ad07e2 1042 pfile_in_zip_read_info->rest_read_uncompressed =
5526e819
VS
1043 s->cur_file_info.uncompressed_size ;
1044
9e279f14 1045
f5ad07e2 1046 pfile_in_zip_read_info->pos_in_zipfile =
913df6f2 1047 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
f5ad07e2 1048 iSizeVar;
9e279f14 1049
f5ad07e2 1050 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
5526e819
VS
1051
1052
f5ad07e2 1053 s->pfile_in_zip_read = pfile_in_zip_read_info;
5526e819
VS
1054 return UNZ_OK;
1055}
1056
1057
1058/*
1059 Read bytes from the current file.
1060 buf contain buffer where data must be copied
1061 len the size of buf.
1062
1063 return the number of byte copied if somes bytes are copied
1064 return 0 if the end of file was reached
1065 return <0 with error code if there is an error
1066 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1067*/
1068extern int ZEXPORT unzReadCurrentFile (file, buf, len)
f5ad07e2
WS
1069 unzFile file;
1070 voidp buf;
1071 unsigned len;
5526e819 1072{
f5ad07e2
WS
1073 int err=UNZ_OK;
1074 uInt iRead = 0;
1075 unz_s* s;
1076 file_in_zip_read_info_s* pfile_in_zip_read_info;
1077 if (file==NULL)
1078 return UNZ_PARAMERROR;
1079 s=(unz_s*)file;
5526e819
VS
1080 pfile_in_zip_read_info=s->pfile_in_zip_read;
1081
f5ad07e2
WS
1082 if (pfile_in_zip_read_info==NULL)
1083 return UNZ_PARAMERROR;
5526e819
VS
1084
1085
f5ad07e2
WS
1086 if ((pfile_in_zip_read_info->read_buffer == NULL))
1087 return UNZ_END_OF_LIST_OF_FILE;
1088 if (len==0)
1089 return 0;
5526e819 1090
f5ad07e2 1091 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
5526e819 1092
f5ad07e2 1093 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
9e279f14 1094
f5ad07e2
WS
1095 if (len>pfile_in_zip_read_info->rest_read_uncompressed)
1096 pfile_in_zip_read_info->stream.avail_out =
1097 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
5526e819 1098
f5ad07e2
WS
1099 while (pfile_in_zip_read_info->stream.avail_out>0)
1100 {
1101 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
5526e819 1102 (pfile_in_zip_read_info->rest_read_compressed>0))
f5ad07e2
WS
1103 {
1104 uInt uReadThis = UNZ_BUFSIZE;
1105 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1106 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1107 if (uReadThis == 0)
1108 return UNZ_EOF;
1109 if (fseek(pfile_in_zip_read_info->file,
913df6f2 1110 pfile_in_zip_read_info->pos_in_zipfile +
5526e819 1111 pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0)
f5ad07e2
WS
1112 return UNZ_ERRNO;
1113 if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1,
5526e819 1114 pfile_in_zip_read_info->file)!=1)
f5ad07e2
WS
1115 return UNZ_ERRNO;
1116 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
5526e819 1117
f5ad07e2 1118 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
9e279f14 1119
f5ad07e2 1120 pfile_in_zip_read_info->stream.next_in =
5526e819 1121 (Bytef*)pfile_in_zip_read_info->read_buffer;
f5ad07e2
WS
1122 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1123 }
5526e819 1124
f5ad07e2
WS
1125 if (pfile_in_zip_read_info->compression_method==0)
1126 {
1127 uInt uDoCopy,i ;
1128 if (pfile_in_zip_read_info->stream.avail_out <
5526e819 1129 pfile_in_zip_read_info->stream.avail_in)
f5ad07e2
WS
1130 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1131 else
1132 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
9e279f14 1133
f5ad07e2
WS
1134 for (i=0;i<uDoCopy;i++)
1135 *(pfile_in_zip_read_info->stream.next_out+i) =
5526e819 1136 *(pfile_in_zip_read_info->stream.next_in+i);
9e279f14 1137
f5ad07e2
WS
1138 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1139 pfile_in_zip_read_info->stream.next_out,
1140 uDoCopy);
1141 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1142 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1143 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1144 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1145 pfile_in_zip_read_info->stream.next_in += uDoCopy;
5526e819 1146 pfile_in_zip_read_info->stream.total_out += uDoCopy;
f5ad07e2
WS
1147 iRead += uDoCopy;
1148 }
1149 else
1150 {
1151 uLong uTotalOutBefore,uTotalOutAfter;
1152 const Bytef *bufBefore;
1153 uLong uOutThis;
1154 int flush=Z_SYNC_FLUSH;
1155
1156 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1157 bufBefore = pfile_in_zip_read_info->stream.next_out;
1158
1159 /*
1160 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1161 pfile_in_zip_read_info->stream.avail_out) &&
1162 (pfile_in_zip_read_info->rest_read_compressed == 0))
1163 flush = Z_FINISH;
1164 */
1165 err=inflate(&pfile_in_zip_read_info->stream,flush);
1166
1167 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1168 uOutThis = uTotalOutAfter-uTotalOutBefore;
1169
1170 pfile_in_zip_read_info->crc32 =
5526e819
VS
1171 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1172 (uInt)(uOutThis));
1173
f5ad07e2 1174 pfile_in_zip_read_info->rest_read_uncompressed -=
5526e819
VS
1175 uOutThis;
1176
f5ad07e2 1177 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
913df6f2 1178
f5ad07e2
WS
1179 if (err==Z_STREAM_END)
1180 return (iRead==0) ? UNZ_EOF : iRead;
1181 if (err!=Z_OK)
1182 break;
1183 }
1184 }
5526e819 1185
f5ad07e2
WS
1186 if (err==Z_OK)
1187 return iRead;
1188 return err;
5526e819
VS
1189}
1190
1191
1192/*
1193 Give the current position in uncompressed data
1194*/
1195extern z_off_t ZEXPORT unztell (file)
f5ad07e2 1196 unzFile file;
5526e819 1197{
f5ad07e2
WS
1198 unz_s* s;
1199 file_in_zip_read_info_s* pfile_in_zip_read_info;
1200 if (file==NULL)
1201 return UNZ_PARAMERROR;
1202 s=(unz_s*)file;
5526e819
VS
1203 pfile_in_zip_read_info=s->pfile_in_zip_read;
1204
f5ad07e2
WS
1205 if (pfile_in_zip_read_info==NULL)
1206 return UNZ_PARAMERROR;
5526e819 1207
f5ad07e2 1208 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
5526e819
VS
1209}
1210
1211
1212/*
913df6f2 1213 return 1 if the end of file was reached, 0 elsewhere
5526e819
VS
1214*/
1215extern int ZEXPORT unzeof (file)
f5ad07e2 1216 unzFile file;
5526e819 1217{
f5ad07e2
WS
1218 unz_s* s;
1219 file_in_zip_read_info_s* pfile_in_zip_read_info;
1220 if (file==NULL)
1221 return UNZ_PARAMERROR;
1222 s=(unz_s*)file;
5526e819
VS
1223 pfile_in_zip_read_info=s->pfile_in_zip_read;
1224
f5ad07e2
WS
1225 if (pfile_in_zip_read_info==NULL)
1226 return UNZ_PARAMERROR;
9e279f14 1227
f5ad07e2
WS
1228 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1229 return 1;
1230 else
1231 return 0;
5526e819
VS
1232}
1233
1234
1235
1236/*
1237 Read extra field from the current file (opened by unzOpenCurrentFile)
1238 This is the local-header version of the extra field (sometimes, there is
1239 more info in the local-header version than in the central-header)
1240
1241 if buf==NULL, it return the size of the local extra field that can be read
1242
1243 if buf!=NULL, len is the size of the buffer, the extra header is copied in
f5ad07e2 1244 buf.
913df6f2 1245 the return value is the number of bytes copied in buf, or (if <0)
f5ad07e2 1246 the error code
5526e819
VS
1247*/
1248extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
f5ad07e2
WS
1249 unzFile file;
1250 voidp buf;
1251 unsigned len;
5526e819 1252{
f5ad07e2
WS
1253 unz_s* s;
1254 file_in_zip_read_info_s* pfile_in_zip_read_info;
1255 uInt read_now;
1256 uLong size_to_read;
1257
1258 if (file==NULL)
1259 return UNZ_PARAMERROR;
1260 s=(unz_s*)file;
5526e819
VS
1261 pfile_in_zip_read_info=s->pfile_in_zip_read;
1262
f5ad07e2
WS
1263 if (pfile_in_zip_read_info==NULL)
1264 return UNZ_PARAMERROR;
5526e819 1265
f5ad07e2
WS
1266 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1267 pfile_in_zip_read_info->pos_local_extrafield);
5526e819 1268
f5ad07e2
WS
1269 if (buf==NULL)
1270 return (int)size_to_read;
9e279f14 1271
f5ad07e2
WS
1272 if (len>size_to_read)
1273 read_now = (uInt)size_to_read;
1274 else
1275 read_now = (uInt)len ;
5526e819 1276
f5ad07e2
WS
1277 if (read_now==0)
1278 return 0;
9e279f14 1279
f5ad07e2 1280 if (fseek(pfile_in_zip_read_info->file,
913df6f2 1281 pfile_in_zip_read_info->offset_local_extrafield +
f5ad07e2
WS
1282 pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0)
1283 return UNZ_ERRNO;
5526e819 1284
f5ad07e2
WS
1285 if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1)
1286 return UNZ_ERRNO;
5526e819 1287
f5ad07e2 1288 return (int)read_now;
5526e819
VS
1289}
1290
1291/*
1292 Close the file in zip opened with unzipOpenCurrentFile
1293 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1294*/
1295extern int ZEXPORT unzCloseCurrentFile (file)
f5ad07e2 1296 unzFile file;
5526e819 1297{
f5ad07e2 1298 int err=UNZ_OK;
5526e819 1299
f5ad07e2
WS
1300 unz_s* s;
1301 file_in_zip_read_info_s* pfile_in_zip_read_info;
1302 if (file==NULL)
1303 return UNZ_PARAMERROR;
1304 s=(unz_s*)file;
5526e819
VS
1305 pfile_in_zip_read_info=s->pfile_in_zip_read;
1306
f5ad07e2
WS
1307 if (pfile_in_zip_read_info==NULL)
1308 return UNZ_PARAMERROR;
5526e819
VS
1309
1310
f5ad07e2
WS
1311 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1312 {
1313 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1314 err=UNZ_CRCERROR;
1315 }
5526e819
VS
1316
1317
f5ad07e2
WS
1318 TRYFREE(pfile_in_zip_read_info->read_buffer);
1319 pfile_in_zip_read_info->read_buffer = NULL;
1320 if (pfile_in_zip_read_info->stream_initialised)
1321 inflateEnd(&pfile_in_zip_read_info->stream);
5526e819 1322
f5ad07e2
WS
1323 pfile_in_zip_read_info->stream_initialised = 0;
1324 TRYFREE(pfile_in_zip_read_info);
5526e819
VS
1325
1326 s->pfile_in_zip_read=NULL;
1327
f5ad07e2 1328 return err;
5526e819
VS
1329}
1330
1331
1332/*
1333 Get the global comment string of the ZipFile, in the szComment buffer.
1334 uSizeBuf is the size of the szComment buffer.
1335 return the number of byte copied or an error code <0
1336*/
1337extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
f5ad07e2
WS
1338 unzFile file;
1339 char *szComment;
1340 uLong uSizeBuf;
5526e819 1341{
f5ad07e2
WS
1342 unz_s* s;
1343 uLong uReadThis ;
1344 if (file==NULL)
1345 return UNZ_PARAMERROR;
1346 s=(unz_s*)file;
5526e819 1347
f5ad07e2
WS
1348 uReadThis = uSizeBuf;
1349 if (uReadThis>s->gi.size_comment)
1350 uReadThis = s->gi.size_comment;
5526e819 1351
f5ad07e2
WS
1352 if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0)
1353 return UNZ_ERRNO;
5526e819 1354
f5ad07e2 1355 if (uReadThis>0)
5526e819
VS
1356 {
1357 *szComment='\0';
f5ad07e2
WS
1358 if (fread(szComment,(uInt)uReadThis,1,s->file)!=1)
1359 return UNZ_ERRNO;
5526e819
VS
1360 }
1361
f5ad07e2
WS
1362 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1363 *(szComment+s->gi.size_comment)='\0';
1364 return (int)uReadThis;
5526e819 1365}
d78b3d64 1366
a1b82138
VZ
1367#else
1368
866592d8 1369/* the file shouldn't be empty, som compilers don't like it */
a1b82138
VZ
1370static const int dummyVariableInUnzip = 17;
1371
866592d8 1372#endif /* wxUSE_ZLIB && wxUSE_ZIPSTREAM */