3 This file was altered for needs of wxWidgets. 
   8 /* unzip.c -- IO on .zip files using zlib 
   9    Version 0.15 beta, Mar 19th, 1998, 
  11    Read unzip.h for more info 
  15 #include "wx/platform.h" 
  17 #if wxUSE_ZLIB && wxUSE_ZIPSTREAM 
  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 
  29 #if defined(__WXMSW__) && !defined(__WX_SETUP_H__) && !defined(wxUSE_ZLIB_H_IN_PATH) 
  30    #include "../zlib/zlib.h" 
  36 /* Not the right solution (paths in makefiles) but... */ 
  38 #include "../common/unzip.h" 
  58 /* compile with -Dlocal if your debugger can't find static symbols */ 
  62 #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \ 
  63                       !defined(CASESENSITIVITYDEFAULT_NO) 
  64 #define CASESENSITIVITYDEFAULT_NO 
  69 #define UNZ_BUFSIZE (16384) 
  72 #ifndef UNZ_MAXFILENAMEINZIP 
  73 #define UNZ_MAXFILENAMEINZIP (256) 
  77 # define ALLOC(size) (malloc(size)) 
  80 # define TRYFREE(p) {if (p) free(p);} 
  83 #define SIZECENTRALDIRITEM (0x2e) 
  84 #define SIZEZIPLOCALHEADER (0x1e) 
  87 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ 
 101 const char unz_copyright
[] = 
 102    " unzip 0.15 Copyright 1998 Gilles Vollant "; 
 104 /* unz_file_info_interntal contain internal info about a file in zipfile*/ 
 105 typedef struct unz_file_info_internal_s
 
 107     uLong offset_curfile
;/* relative offset of local header 4 bytes */ 
 108 } unz_file_info_internal
; 
 111 /* file_in_zip_read_info_s contain internal information about a file in zipfile, 
 112     when reading and decompress it */ 
 115         char  *read_buffer
;         /* internal buffer for compressed data */ 
 116         z_stream stream
;            /* zLib stream structure for inflate */ 
 118         uLong pos_in_zipfile
;       /* position in byte on the zipfile, for fseek*/ 
 119         uLong stream_initialised
;   /* flag set if stream structure is initialised*/ 
 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*/ 
 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)*/ 
 132 } file_in_zip_read_info_s
; 
 135 /* unz_s contain internal information about the zipfile 
 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*/ 
 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 */ 
 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*/ 
 153     file_in_zip_read_info_s
* pfile_in_zip_read
; /* structure about the current 
 154                                             file if we are decompressing it */ 
 157 #if defined (__VISAGECPP__) || defined(__BORLANDC__) 
 158 /* VA always requires prototypes */ 
 159 int unzlocal_CheckCurrentFileCoherencyHeader (unz_s
*, uInt
*, uLong
*, uInt
*); 
 162 /* disable warnings about K&R declarations until the end of file */ 
 164 #pragma warning(disable:4131) 
 167 /* =========================================================================== 
 168      Read a byte from a gz_stream; update next_in and avail_in. Return EOF 
 170    IN assertion: the stream s has been sucessfully opened for reading. 
 174 local 
int unzlocal_getByte(fin
,pi
) 
 179         int err 
= fread(&c
, 1, 1, fin
); 
 195 /* =========================================================================== 
 196    Reads a long in LSB order from the given gz_stream. Sets 
 198 local 
int unzlocal_getShort (fin
,pX
) 
 206     err 
= unzlocal_getByte(fin
,&i
); 
 210         err 
= unzlocal_getByte(fin
,&i
); 
 220 local 
int unzlocal_getLong (fin
,pX
) 
 228     err 
= unzlocal_getByte(fin
,&i
); 
 232         err 
= unzlocal_getByte(fin
,&i
); 
 236         err 
= unzlocal_getByte(fin
,&i
); 
 240         err 
= unzlocal_getByte(fin
,&i
); 
 251 /* My own strcmpi / strcasecmp */ 
 252 local 
int strcmpcasenosensitive_internal (fileName1
,fileName2
) 
 253         const char* fileName1
; 
 254         const char* fileName2
; 
 258                 char c1
=*(fileName1
++); 
 259                 char c2
=*(fileName2
++); 
 260                 if ((c1
>='a') && (c1
<='z')) 
 262                 if ((c2
>='a') && (c2
<='z')) 
 265                         return ((c2
=='\0') ? 0 : -1); 
 276 #ifdef  CASESENSITIVITYDEFAULT_NO 
 277 #define CASESENSITIVITYDEFAULTVALUE 2 
 279 #define CASESENSITIVITYDEFAULTVALUE 1 
 282 #ifndef STRCMPCASENOSENTIVEFUNCTION 
 283 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal 
 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 
 291    If iCaseSenisivity = 0, case sensitivity is defaut of your operating system 
 292         (like 1 on Unix, 2 on Windows) 
 295 extern int ZEXPORT 
unzStringFileNameCompare (fileName1
,fileName2
,iCaseSensitivity
) 
 296         const char* fileName1
; 
 297         const char* fileName2
; 
 298         int iCaseSensitivity
; 
 300         if (iCaseSensitivity
==0) 
 301                 iCaseSensitivity
=CASESENSITIVITYDEFAULTVALUE
; 
 303         if (iCaseSensitivity
==1) 
 304                 return strcmp(fileName1
,fileName2
); 
 306         return STRCMPCASENOSENTIVEFUNCTION(fileName1
,fileName2
); 
 309 #define BUFREADCOMMENT (0x400) 
 312   Locate the Central directory of a zipfile (at the end, just before 
 315 local uLong 
unzlocal_SearchCentralDir(fin
) 
 321         uLong uMaxBack
=0xffff; /* maximum size of global comment */ 
 324         if (fseek(fin
,0,SEEK_END
) != 0) 
 328         uSizeFile 
= ftell( fin 
); 
 330         if (uMaxBack
>uSizeFile
) 
 331                 uMaxBack 
= uSizeFile
; 
 333         buf 
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4); 
 338         while (uBackRead
<uMaxBack
) 
 340                 uLong uReadSize
,uReadPos 
; 
 342                 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
) 
 343                         uBackRead 
= uMaxBack
; 
 345                         uBackRead
+=BUFREADCOMMENT
; 
 346                 uReadPos 
= uSizeFile
-uBackRead 
; 
 348                 uReadSize 
= ((BUFREADCOMMENT
+4) < (uSizeFile
-uReadPos
)) ? 
 349                      (BUFREADCOMMENT
+4) : (uSizeFile
-uReadPos
); 
 350                 if (fseek(fin
,uReadPos
,SEEK_SET
)!=0) 
 353                 if (fread(buf
,(uInt
)uReadSize
,1,fin
)!=1) 
 356                 for (i
=(int)uReadSize
-3; (i
--)>0;) 
 357                         if (((*(buf
+i
))==0x50) && ((*(buf
+i
+1))==0x4b) && 
 358                                 ((*(buf
+i
+2))==0x05) && ((*(buf
+i
+3))==0x06)) 
 360                                 uPosFound 
= uReadPos
+i
; 
 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 
 375          If the zipfile cannot be opened (file don't exist or in not valid), the 
 376            return value is NULL. 
 377      Else, the return value is a unzFile Handle, usable with other function 
 378            of this unzip package. 
 380 extern unzFile ZEXPORT 
unzOpen (path
) 
 385         uLong central_pos
,uL
; 
 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 
 394                                        (same than number_entry on nospan) */ 
 398     if (unz_copyright
[0]!=' ') 
 401     fin
=fopen(path
,"rb"); 
 406         central_pos 
= unzlocal_SearchCentralDir(fin
); 
 410         if (fseek(fin
,central_pos
,SEEK_SET
)!=0) 
 413         /* the signature, already checked */ 
 414         if (unzlocal_getLong(fin
,&uL
)!=UNZ_OK
) 
 417         /* number of this disk */ 
 418         if (unzlocal_getShort(fin
,&number_disk
)!=UNZ_OK
) 
 421         /* number of the disk with the start of the central directory */ 
 422         if (unzlocal_getShort(fin
,&number_disk_with_CD
)!=UNZ_OK
) 
 425         /* total number of entries in the central dir on this disk */ 
 426         if (unzlocal_getShort(fin
,&us
.gi
.number_entry
)!=UNZ_OK
) 
 429         /* total number of entries in the central dir */ 
 430         if (unzlocal_getShort(fin
,&number_entry_CD
)!=UNZ_OK
) 
 433         if ((number_entry_CD
!=us
.gi
.number_entry
) || 
 434                 (number_disk_with_CD
!=0) || 
 438         /* size of the central directory */ 
 439         if (unzlocal_getLong(fin
,&us
.size_central_dir
)!=UNZ_OK
) 
 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
) 
 447         /* zipfile comment length */ 
 448         if (unzlocal_getShort(fin
,&us
.gi
.size_comment
)!=UNZ_OK
) 
 451         if ((central_pos
<us
.offset_central_dir
+us
.size_central_dir
) && 
 461         us
.byte_before_the_zipfile 
= central_pos 
- 
 462                                     (us
.offset_central_dir
+us
.size_central_dir
); 
 463         us
.central_pos 
= central_pos
; 
 464     us
.pfile_in_zip_read 
= NULL
; 
 467         s
=(unz_s
*)ALLOC(sizeof(unz_s
)); 
 469         unzGoToFirstFile((unzFile
)s
); 
 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. */ 
 479 extern int ZEXPORT 
unzClose (file
) 
 484                 return UNZ_PARAMERROR
; 
 487     if (s
->pfile_in_zip_read
!=NULL
) 
 488         unzCloseCurrentFile(file
); 
 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. */ 
 500 extern int ZEXPORT 
unzGetGlobalInfo (file
,pglobal_info
) 
 502         unz_global_info 
*pglobal_info
; 
 506                 return UNZ_PARAMERROR
; 
 514    Translate date/time from Dos format to tm_unz (readable more easilty) 
 516 local 
void unzlocal_DosDateToTmuDate (ulDosDate
, ptm
) 
 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) ; 
 526     ptm
->tm_hour 
= (uInt
) ((ulDosDate 
&0xF800)/0x800); 
 527     ptm
->tm_min 
=  (uInt
) ((ulDosDate
&0x7E0)/0x20) ; 
 528     ptm
->tm_sec 
=  (uInt
) (2*(ulDosDate
&0x1f)) ; 
 532   Get Info about the current file in the zipfile, with internal only info 
 534 local 
int unzlocal_GetCurrentFileInfoInternal 
OF((unzFile file
, 
 535                                                   unz_file_info 
*pfile_info
, 
 536                                                   unz_file_info_internal
 
 537                                                   *pfile_info_internal
, 
 539                                                                                                   uLong fileNameBufferSize
, 
 541                                                                                                   uLong extraFieldBufferSize
, 
 543                                                                                                   uLong commentBufferSize
)); 
 545 local 
int unzlocal_GetCurrentFileInfoInternal (file
, 
 548                                               szFileName
, fileNameBufferSize
, 
 549                                               extraField
, extraFieldBufferSize
, 
 550                                               szComment
,  commentBufferSize
) 
 552         unz_file_info 
*pfile_info
; 
 553         unz_file_info_internal 
*pfile_info_internal
; 
 555         uLong fileNameBufferSize
; 
 557         uLong extraFieldBufferSize
; 
 559         uLong commentBufferSize
; 
 562         unz_file_info file_info
; 
 563         unz_file_info_internal file_info_internal
; 
 569                 return UNZ_PARAMERROR
; 
 571         if (fseek(s
->file
,s
->pos_in_central_dir
+s
->byte_before_the_zipfile
,SEEK_SET
)!=0) 
 575         /* we check the magic */ 
 578                 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
) 
 580                 else if (uMagic
!=0x02014b50) 
 584         if (unzlocal_getShort(s
->file
,&file_info
.version
) != UNZ_OK
) 
 587         if (unzlocal_getShort(s
->file
,&file_info
.version_needed
) != UNZ_OK
) 
 590         if (unzlocal_getShort(s
->file
,&file_info
.flag
) != UNZ_OK
) 
 593         if (unzlocal_getShort(s
->file
,&file_info
.compression_method
) != UNZ_OK
) 
 596         if (unzlocal_getLong(s
->file
,&file_info
.dosDate
) != UNZ_OK
) 
 599     unzlocal_DosDateToTmuDate(file_info
.dosDate
,&file_info
.tmu_date
); 
 601         if (unzlocal_getLong(s
->file
,&file_info
.crc
) != UNZ_OK
) 
 604         if (unzlocal_getLong(s
->file
,&file_info
.compressed_size
) != UNZ_OK
) 
 607         if (unzlocal_getLong(s
->file
,&file_info
.uncompressed_size
) != UNZ_OK
) 
 610         if (unzlocal_getShort(s
->file
,&file_info
.size_filename
) != UNZ_OK
) 
 613         if (unzlocal_getShort(s
->file
,&file_info
.size_file_extra
) != UNZ_OK
) 
 616         if (unzlocal_getShort(s
->file
,&file_info
.size_file_comment
) != UNZ_OK
) 
 619         if (unzlocal_getShort(s
->file
,&file_info
.disk_num_start
) != UNZ_OK
) 
 622         if (unzlocal_getShort(s
->file
,&file_info
.internal_fa
) != UNZ_OK
) 
 625         if (unzlocal_getLong(s
->file
,&file_info
.external_fa
) != UNZ_OK
) 
 628         if (unzlocal_getLong(s
->file
,&file_info_internal
.offset_curfile
) != UNZ_OK
) 
 631         lSeek
+=file_info
.size_filename
; 
 632         if ((err
==UNZ_OK
) && (szFileName
!=NULL
)) 
 635                 if (file_info
.size_filename
<fileNameBufferSize
) 
 637                         *(szFileName
+file_info
.size_filename
)='\0'; 
 638                         uSizeRead 
= file_info
.size_filename
; 
 641                         uSizeRead 
= fileNameBufferSize
; 
 643                 if ((file_info
.size_filename
>0) && (fileNameBufferSize
>0)) 
 644                         if (fread(szFileName
,(uInt
)uSizeRead
,1,s
->file
)!=1) 
 650         if ((err
==UNZ_OK
) && (extraField
!=NULL
)) 
 653                 if (file_info
.size_file_extra
<extraFieldBufferSize
) 
 654                         uSizeRead 
= file_info
.size_file_extra
; 
 656                         uSizeRead 
= extraFieldBufferSize
; 
 660                         if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0) 
 666                 if ((file_info
.size_file_extra
>0) && (extraFieldBufferSize
>0)) 
 667                         if (fread(extraField
,(uInt
)uSizeRead
,1,s
->file
)!=1) 
 669                 lSeek 
+= file_info
.size_file_extra 
- uSizeRead
; 
 672                 lSeek
+=file_info
.size_file_extra
; 
 675         if ((err
==UNZ_OK
) && (szComment
!=NULL
)) 
 678                 if (file_info
.size_file_comment
<commentBufferSize
) 
 680                         *(szComment
+file_info
.size_file_comment
)='\0'; 
 681                         uSizeRead 
= file_info
.size_file_comment
; 
 684                         uSizeRead 
= commentBufferSize
; 
 688                         if (fseek(s
->file
,lSeek
,SEEK_CUR
)==0) 
 694                 if ((file_info
.size_file_comment
>0) && (commentBufferSize
>0)) 
 695                         if (fread(szComment
,(uInt
)uSizeRead
,1,s
->file
)!=1) 
 697                 lSeek
+=file_info
.size_file_comment 
- uSizeRead
; 
 700                 lSeek
+=file_info
.size_file_comment
; 
 702         if ((err
==UNZ_OK
) && (pfile_info
!=NULL
)) 
 703                 *pfile_info
=file_info
; 
 705         if ((err
==UNZ_OK
) && (pfile_info_internal
!=NULL
)) 
 706                 *pfile_info_internal
=file_info_internal
; 
 714   Write info about the ZipFile in the *pglobal_info structure. 
 715   No preparation of the structure is needed 
 716   return UNZ_OK if there is no problem. 
 718 extern int ZEXPORT 
unzGetCurrentFileInfo (file
, 
 720                                                   szFileName
, fileNameBufferSize
, 
 721                                                   extraField
, extraFieldBufferSize
, 
 722                                                   szComment
,  commentBufferSize
) 
 724         unz_file_info 
*pfile_info
; 
 726         uLong fileNameBufferSize
; 
 728         uLong extraFieldBufferSize
; 
 730         uLong commentBufferSize
; 
 732         return unzlocal_GetCurrentFileInfoInternal(file
,pfile_info
,NULL
, 
 733                                                                                                 szFileName
,fileNameBufferSize
, 
 734                                                                                                 extraField
,extraFieldBufferSize
, 
 735                                                                                                 szComment
,commentBufferSize
); 
 739   Set the current file of the zipfile to the first file. 
 740   return UNZ_OK if there is no problem 
 742 extern int ZEXPORT 
unzGoToFirstFile (file
) 
 748                 return UNZ_PARAMERROR
; 
 750         s
->pos_in_central_dir
=s
->offset_central_dir
; 
 752         err
=unzlocal_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
, 
 753                                                                                          &s
->cur_file_info_internal
, 
 754                                                                                          NULL
,0,NULL
,0,NULL
,0); 
 755         s
->current_file_ok 
= (err 
== UNZ_OK
); 
 761   Set the current file of the zipfile to the next file. 
 762   return UNZ_OK if there is no problem 
 763   return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. 
 765 extern int ZEXPORT 
unzGoToNextFile (file
) 
 772                 return UNZ_PARAMERROR
; 
 774         if (!s
->current_file_ok
) 
 775                 return UNZ_END_OF_LIST_OF_FILE
; 
 776         if (s
->num_file
+1==s
->gi
.number_entry
) 
 777                 return UNZ_END_OF_LIST_OF_FILE
; 
 779         s
->pos_in_central_dir 
+= SIZECENTRALDIRITEM 
+ s
->cur_file_info
.size_filename 
+ 
 780                         s
->cur_file_info
.size_file_extra 
+ s
->cur_file_info
.size_file_comment 
; 
 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
); 
 791   Try locate the file szFileName in the zipfile. 
 792   For the iCaseSensitivity signification, see unzipStringFileNameCompare 
 795   UNZ_OK if the file is found. It becomes the current file. 
 796   UNZ_END_OF_LIST_OF_FILE if the file is not found 
 798 extern int ZEXPORT 
unzLocateFile (file
, szFileName
, iCaseSensitivity
) 
 800         const char *szFileName
; 
 801         int iCaseSensitivity
; 
 807     char szFileName2
[UNZ_MAXFILENAMEINZIP
+1]; 
 810         uLong pos_in_central_dirSaved
; 
 812     for (c 
= szFileName
, c2 
= szFileName2
; *c 
!= '\0'; c
++, c2
++) 
 813         if (*c 
== '\\') *c2 
= '/'; 
 818                 return UNZ_PARAMERROR
; 
 820     if (strlen(szFileName
)>=UNZ_MAXFILENAMEINZIP
) 
 821         return UNZ_PARAMERROR
; 
 824         if (!s
->current_file_ok
) 
 825                 return UNZ_END_OF_LIST_OF_FILE
; 
 827         num_fileSaved 
= s
->num_file
; 
 828         pos_in_central_dirSaved 
= s
->pos_in_central_dir
; 
 830         err 
= unzGoToFirstFile(file
); 
 832         while (err 
== UNZ_OK
) 
 834                 char szCurrentFileName
[UNZ_MAXFILENAMEINZIP
+1]; 
 835                 unzGetCurrentFileInfo(file
,NULL
, 
 836                                                                 szCurrentFileName
,sizeof(szCurrentFileName
)-1, 
 838         for (c2 
= szCurrentFileName
; *c2 
!= '\0'; c2
++) if (*c2 
== '\\') *c2 
= '/'; 
 839                 if (unzStringFileNameCompare(szCurrentFileName
, 
 840                                                                                 szFileName2
,iCaseSensitivity
)==0) 
 842                 err 
= unzGoToNextFile(file
); 
 845         s
->num_file 
= num_fileSaved 
; 
 846         s
->pos_in_central_dir 
= pos_in_central_dirSaved 
; 
 852   Read the local header of the current zipfile 
 853   Check the coherency of the local header and info in the end of central 
 854         directory about this file 
 855   store in *piSizeVar the size of extra info in local header 
 856         (filename and size of extra field data) 
 858 local 
int unzlocal_CheckCurrentFileCoherencyHeader (s
,piSizeVar
, 
 859                                                                                                         poffset_local_extrafield
, 
 860                                                                                                         psize_local_extrafield
) 
 863         uLong 
*poffset_local_extrafield
; 
 864         uInt  
*psize_local_extrafield
; 
 866         uLong uMagic
,uData
,uFlags
; 
 868         uLong size_extra_field
; 
 872         *poffset_local_extrafield 
= 0; 
 873         *psize_local_extrafield 
= 0; 
 875         if (fseek(s
->file
,s
->cur_file_info_internal
.offset_curfile 
+ 
 876                                                                 s
->byte_before_the_zipfile
,SEEK_SET
)!=0) 
 882                 if (unzlocal_getLong(s
->file
,&uMagic
) != UNZ_OK
) 
 884                 else if (uMagic
!=0x04034b50) 
 888         if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
) 
 891         else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) 
 894         if (unzlocal_getShort(s
->file
,&uFlags
) != UNZ_OK
) 
 897         if (unzlocal_getShort(s
->file
,&uData
) != UNZ_OK
) 
 899         else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compression_method
)) 
 902     if ((err
==UNZ_OK
) && (s
->cur_file_info
.compression_method
!=0) && 
 903                          (s
->cur_file_info
.compression_method
!=Z_DEFLATED
)) 
 906         if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* date/time */ 
 909         if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* crc */ 
 911         else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.crc
) && 
 915         if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size compr */ 
 917         else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compressed_size
) && 
 921         if (unzlocal_getLong(s
->file
,&uData
) != UNZ_OK
) /* size uncompr */ 
 923         else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.uncompressed_size
) && 
 928         if (unzlocal_getShort(s
->file
,&size_filename
) != UNZ_OK
) 
 930         else if ((err
==UNZ_OK
) && (size_filename
!=s
->cur_file_info
.size_filename
)) 
 933         *piSizeVar 
+= (uInt
)size_filename
; 
 935         if (unzlocal_getShort(s
->file
,&size_extra_field
) != UNZ_OK
) 
 937         *poffset_local_extrafield
= s
->cur_file_info_internal
.offset_curfile 
+ 
 938                                                                         SIZEZIPLOCALHEADER 
+ size_filename
; 
 939         *psize_local_extrafield 
= (uInt
)size_extra_field
; 
 941         *piSizeVar 
+= (uInt
)size_extra_field
; 
 947   Open for reading data the current file in the zipfile. 
 948   If there is no error and the file is opened, the return value is UNZ_OK. 
 950 extern int ZEXPORT 
unzOpenCurrentFile (file
) 
 957         file_in_zip_read_info_s
* pfile_in_zip_read_info
; 
 958         uLong offset_local_extrafield
;  /* offset of the local extra field */ 
 959         uInt  size_local_extrafield
;    /* size of the local extra field */ 
 962                 return UNZ_PARAMERROR
; 
 964         if (!s
->current_file_ok
) 
 965                 return UNZ_PARAMERROR
; 
 967     if (s
->pfile_in_zip_read 
!= NULL
) 
 968         unzCloseCurrentFile(file
); 
 970         if (unzlocal_CheckCurrentFileCoherencyHeader(s
,&iSizeVar
, 
 971                                 &offset_local_extrafield
,&size_local_extrafield
)!=UNZ_OK
) 
 972                 return UNZ_BADZIPFILE
; 
 974         pfile_in_zip_read_info 
= (file_in_zip_read_info_s
*) 
 975                                                                             ALLOC(sizeof(file_in_zip_read_info_s
)); 
 976         if (pfile_in_zip_read_info
==NULL
) 
 977                 return UNZ_INTERNALERROR
; 
 979         pfile_in_zip_read_info
->read_buffer
=(char*)ALLOC(UNZ_BUFSIZE
); 
 980         pfile_in_zip_read_info
->offset_local_extrafield 
= offset_local_extrafield
; 
 981         pfile_in_zip_read_info
->size_local_extrafield 
= size_local_extrafield
; 
 982         pfile_in_zip_read_info
->pos_local_extrafield
=0; 
 984         if (pfile_in_zip_read_info
->read_buffer
==NULL
) 
 986                 TRYFREE(pfile_in_zip_read_info
); 
 987                 return UNZ_INTERNALERROR
; 
 990         pfile_in_zip_read_info
->stream_initialised
=0; 
 992         if ((s
->cur_file_info
.compression_method
!=0) && 
 993         (s
->cur_file_info
.compression_method
!=Z_DEFLATED
)) 
 995         Store 
= s
->cur_file_info
.compression_method
==0; 
 997         pfile_in_zip_read_info
->crc32_wait
=s
->cur_file_info
.crc
; 
 998         pfile_in_zip_read_info
->crc32
=0; 
 999         pfile_in_zip_read_info
->compression_method 
= 
1000             s
->cur_file_info
.compression_method
; 
1001         pfile_in_zip_read_info
->file
=s
->file
; 
1002         pfile_in_zip_read_info
->byte_before_the_zipfile
=s
->byte_before_the_zipfile
; 
1004     pfile_in_zip_read_info
->stream
.total_out 
= 0; 
1008           pfile_in_zip_read_info
->stream
.zalloc 
= (alloc_func
)0; 
1009           pfile_in_zip_read_info
->stream
.zfree 
= (free_func
)0; 
1010           pfile_in_zip_read_info
->stream
.opaque 
= (voidpf
)0; 
1012           err
=inflateInit2(&pfile_in_zip_read_info
->stream
, -MAX_WBITS
); 
1014             pfile_in_zip_read_info
->stream_initialised
=1; 
1015         /* windowBits is passed < 0 to tell that there is no zlib header. 
1016          * Note that in this case inflate *requires* an extra "dummy" byte 
1017          * after the compressed stream in order to complete decompression and 
1018          * return Z_STREAM_END. 
1019          * In unzip, i don't wait absolutely Z_STREAM_END because I known the 
1020          * size of both compressed and uncompressed data 
1023         pfile_in_zip_read_info
->rest_read_compressed 
= 
1024             s
->cur_file_info
.compressed_size 
; 
1025         pfile_in_zip_read_info
->rest_read_uncompressed 
= 
1026             s
->cur_file_info
.uncompressed_size 
; 
1029         pfile_in_zip_read_info
->pos_in_zipfile 
= 
1030             s
->cur_file_info_internal
.offset_curfile 
+ SIZEZIPLOCALHEADER 
+ 
1033         pfile_in_zip_read_info
->stream
.avail_in 
= (uInt
)0; 
1036         s
->pfile_in_zip_read 
= pfile_in_zip_read_info
; 
1042   Read bytes from the current file. 
1043   buf contain buffer where data must be copied 
1044   len the size of buf. 
1046   return the number of byte copied if somes bytes are copied 
1047   return 0 if the end of file was reached 
1048   return <0 with error code if there is an error 
1049     (UNZ_ERRNO for IO error, or zLib error for uncompress error) 
1051 extern int ZEXPORT 
unzReadCurrentFile  (file
, buf
, len
) 
1059         file_in_zip_read_info_s
* pfile_in_zip_read_info
; 
1061                 return UNZ_PARAMERROR
; 
1063     pfile_in_zip_read_info
=s
->pfile_in_zip_read
; 
1065         if (pfile_in_zip_read_info
==NULL
) 
1066                 return UNZ_PARAMERROR
; 
1069         if ((pfile_in_zip_read_info
->read_buffer 
== NULL
)) 
1070                 return UNZ_END_OF_LIST_OF_FILE
; 
1074         pfile_in_zip_read_info
->stream
.next_out 
= (Bytef
*)buf
; 
1076         pfile_in_zip_read_info
->stream
.avail_out 
= (uInt
)len
; 
1078         if (len
>pfile_in_zip_read_info
->rest_read_uncompressed
) 
1079                 pfile_in_zip_read_info
->stream
.avail_out 
= 
1080                   (uInt
)pfile_in_zip_read_info
->rest_read_uncompressed
; 
1082         while (pfile_in_zip_read_info
->stream
.avail_out
>0) 
1084                 if ((pfile_in_zip_read_info
->stream
.avail_in
==0) && 
1085             (pfile_in_zip_read_info
->rest_read_compressed
>0)) 
1087                         uInt uReadThis 
= UNZ_BUFSIZE
; 
1088                         if (pfile_in_zip_read_info
->rest_read_compressed
<uReadThis
) 
1089                                 uReadThis 
= (uInt
)pfile_in_zip_read_info
->rest_read_compressed
; 
1092                         if (fseek(pfile_in_zip_read_info
->file
, 
1093                       pfile_in_zip_read_info
->pos_in_zipfile 
+ 
1094                          pfile_in_zip_read_info
->byte_before_the_zipfile
,SEEK_SET
)!=0) 
1096                         if (fread(pfile_in_zip_read_info
->read_buffer
,uReadThis
,1, 
1097                          pfile_in_zip_read_info
->file
)!=1) 
1099                         pfile_in_zip_read_info
->pos_in_zipfile 
+= uReadThis
; 
1101                         pfile_in_zip_read_info
->rest_read_compressed
-=uReadThis
; 
1103                         pfile_in_zip_read_info
->stream
.next_in 
= 
1104                 (Bytef
*)pfile_in_zip_read_info
->read_buffer
; 
1105                         pfile_in_zip_read_info
->stream
.avail_in 
= (uInt
)uReadThis
; 
1108                 if (pfile_in_zip_read_info
->compression_method
==0) 
1111                         if (pfile_in_zip_read_info
->stream
.avail_out 
< 
1112                             pfile_in_zip_read_info
->stream
.avail_in
) 
1113                                 uDoCopy 
= pfile_in_zip_read_info
->stream
.avail_out 
; 
1115                                 uDoCopy 
= pfile_in_zip_read_info
->stream
.avail_in 
; 
1117                         for (i
=0;i
<uDoCopy
;i
++) 
1118                                 *(pfile_in_zip_read_info
->stream
.next_out
+i
) = 
1119                         *(pfile_in_zip_read_info
->stream
.next_in
+i
); 
1121                         pfile_in_zip_read_info
->crc32 
= crc32(pfile_in_zip_read_info
->crc32
, 
1122                                                                 pfile_in_zip_read_info
->stream
.next_out
, 
1124                         pfile_in_zip_read_info
->rest_read_uncompressed
-=uDoCopy
; 
1125                         pfile_in_zip_read_info
->stream
.avail_in 
-= uDoCopy
; 
1126                         pfile_in_zip_read_info
->stream
.avail_out 
-= uDoCopy
; 
1127                         pfile_in_zip_read_info
->stream
.next_out 
+= uDoCopy
; 
1128                         pfile_in_zip_read_info
->stream
.next_in 
+= uDoCopy
; 
1129             pfile_in_zip_read_info
->stream
.total_out 
+= uDoCopy
; 
1134                         uLong uTotalOutBefore
,uTotalOutAfter
; 
1135                         const Bytef 
*bufBefore
; 
1137                         int flush
=Z_SYNC_FLUSH
; 
1139                         uTotalOutBefore 
= pfile_in_zip_read_info
->stream
.total_out
; 
1140                         bufBefore 
= pfile_in_zip_read_info
->stream
.next_out
; 
1143                         if ((pfile_in_zip_read_info->rest_read_uncompressed == 
1144                                  pfile_in_zip_read_info->stream.avail_out) && 
1145                                 (pfile_in_zip_read_info->rest_read_compressed == 0)) 
1148                         err
=inflate(&pfile_in_zip_read_info
->stream
,flush
); 
1150                         uTotalOutAfter 
= pfile_in_zip_read_info
->stream
.total_out
; 
1151                         uOutThis 
= uTotalOutAfter
-uTotalOutBefore
; 
1153                         pfile_in_zip_read_info
->crc32 
= 
1154                 crc32(pfile_in_zip_read_info
->crc32
,bufBefore
, 
1157                         pfile_in_zip_read_info
->rest_read_uncompressed 
-= 
1160                         iRead 
+= (uInt
)(uTotalOutAfter 
- uTotalOutBefore
); 
1162                         if (err
==Z_STREAM_END
) 
1163                                 return (iRead
==0) ? UNZ_EOF 
: iRead
; 
1176   Give the current position in uncompressed data 
1178 extern z_off_t ZEXPORT 
unztell (file
) 
1182         file_in_zip_read_info_s
* pfile_in_zip_read_info
; 
1184                 return UNZ_PARAMERROR
; 
1186     pfile_in_zip_read_info
=s
->pfile_in_zip_read
; 
1188         if (pfile_in_zip_read_info
==NULL
) 
1189                 return UNZ_PARAMERROR
; 
1191         return (z_off_t
)pfile_in_zip_read_info
->stream
.total_out
; 
1196   return 1 if the end of file was reached, 0 elsewhere 
1198 extern int ZEXPORT 
unzeof (file
) 
1202         file_in_zip_read_info_s
* pfile_in_zip_read_info
; 
1204                 return UNZ_PARAMERROR
; 
1206     pfile_in_zip_read_info
=s
->pfile_in_zip_read
; 
1208         if (pfile_in_zip_read_info
==NULL
) 
1209                 return UNZ_PARAMERROR
; 
1211         if (pfile_in_zip_read_info
->rest_read_uncompressed 
== 0) 
1220   Read extra field from the current file (opened by unzOpenCurrentFile) 
1221   This is the local-header version of the extra field (sometimes, there is 
1222     more info in the local-header version than in the central-header) 
1224   if buf==NULL, it return the size of the local extra field that can be read 
1226   if buf!=NULL, len is the size of the buffer, the extra header is copied in 
1228   the return value is the number of bytes copied in buf, or (if <0) 
1231 extern int ZEXPORT 
unzGetLocalExtrafield (file
,buf
,len
) 
1237         file_in_zip_read_info_s
* pfile_in_zip_read_info
; 
1242                 return UNZ_PARAMERROR
; 
1244     pfile_in_zip_read_info
=s
->pfile_in_zip_read
; 
1246         if (pfile_in_zip_read_info
==NULL
) 
1247                 return UNZ_PARAMERROR
; 
1249         size_to_read 
= (pfile_in_zip_read_info
->size_local_extrafield 
- 
1250                                 pfile_in_zip_read_info
->pos_local_extrafield
); 
1253                 return (int)size_to_read
; 
1255         if (len
>size_to_read
) 
1256                 read_now 
= (uInt
)size_to_read
; 
1258                 read_now 
= (uInt
)len 
; 
1263         if (fseek(pfile_in_zip_read_info
->file
, 
1264               pfile_in_zip_read_info
->offset_local_extrafield 
+ 
1265                           pfile_in_zip_read_info
->pos_local_extrafield
,SEEK_SET
)!=0) 
1268         if (fread(buf
,(uInt
)size_to_read
,1,pfile_in_zip_read_info
->file
)!=1) 
1271         return (int)read_now
; 
1275   Close the file in zip opened with unzipOpenCurrentFile 
1276   Return UNZ_CRCERROR if all the file was read but the CRC is not good 
1278 extern int ZEXPORT 
unzCloseCurrentFile (file
) 
1284         file_in_zip_read_info_s
* pfile_in_zip_read_info
; 
1286                 return UNZ_PARAMERROR
; 
1288     pfile_in_zip_read_info
=s
->pfile_in_zip_read
; 
1290         if (pfile_in_zip_read_info
==NULL
) 
1291                 return UNZ_PARAMERROR
; 
1294         if (pfile_in_zip_read_info
->rest_read_uncompressed 
== 0) 
1296                 if (pfile_in_zip_read_info
->crc32 
!= pfile_in_zip_read_info
->crc32_wait
) 
1301         TRYFREE(pfile_in_zip_read_info
->read_buffer
); 
1302         pfile_in_zip_read_info
->read_buffer 
= NULL
; 
1303         if (pfile_in_zip_read_info
->stream_initialised
) 
1304                 inflateEnd(&pfile_in_zip_read_info
->stream
); 
1306         pfile_in_zip_read_info
->stream_initialised 
= 0; 
1307         TRYFREE(pfile_in_zip_read_info
); 
1309     s
->pfile_in_zip_read
=NULL
; 
1316   Get the global comment string of the ZipFile, in the szComment buffer. 
1317   uSizeBuf is the size of the szComment buffer. 
1318   return the number of byte copied or an error code <0 
1320 extern int ZEXPORT 
unzGetGlobalComment (file
, szComment
, uSizeBuf
) 
1328                 return UNZ_PARAMERROR
; 
1331         uReadThis 
= uSizeBuf
; 
1332         if (uReadThis
>s
->gi
.size_comment
) 
1333                 uReadThis 
= s
->gi
.size_comment
; 
1335         if (fseek(s
->file
,s
->central_pos
+22,SEEK_SET
)!=0) 
1341           if (fread(szComment
,(uInt
)uReadThis
,1,s
->file
)!=1) 
1345         if ((szComment 
!= NULL
) && (uSizeBuf 
> s
->gi
.size_comment
)) 
1346                 *(szComment
+s
->gi
.size_comment
)='\0'; 
1347         return (int)uReadThis
; 
1352 /* the file shouldn't be empty, som compilers don't like it */ 
1353 static const int dummyVariableInUnzip 
= 17; 
1355 #endif /* wxUSE_ZLIB && wxUSE_ZIPSTREAM */