summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog21
-rw-r--r--Makefile2
-rw-r--r--Makefile.in2
-rw-r--r--README4
-rw-r--r--as400/zlib.inc10
-rw-r--r--contrib/README.contrib4
-rw-r--r--contrib/asm586/match.S718
-rw-r--r--contrib/asm686/match.S656
-rw-r--r--contrib/infback9/infback9.h8
-rw-r--r--contrib/infback9/inftree9.c6
-rw-r--r--contrib/masm686/match.asm821
-rw-r--r--contrib/masmx64/bld_ml64.bat2
-rw-r--r--contrib/masmx64/gvmat64.asm464
-rw-r--r--contrib/masmx64/gvmat64.objbin0 -> 4155 bytes
-rw-r--r--contrib/masmx64/inffas8664.c186
-rw-r--r--contrib/masmx64/inffasx64.asm392
-rw-r--r--contrib/masmx64/inffasx64.objbin0 -> 5913 bytes
-rw-r--r--contrib/masmx64/readme.txt28
-rw-r--r--contrib/masmx86/bld_ml32.bat2
-rw-r--r--contrib/masmx86/gvmat32.asm1881
-rw-r--r--contrib/masmx86/gvmat32c.c268
-rw-r--r--contrib/masmx86/inffas32.asm2119
-rw-r--r--contrib/minizip/ChangeLogUnzip130
-rw-r--r--contrib/minizip/Makefile50
-rw-r--r--contrib/minizip/crypt.h264
-rw-r--r--contrib/minizip/ioapi.c354
-rw-r--r--contrib/minizip/ioapi.h150
-rw-r--r--contrib/minizip/iowin32.c540
-rw-r--r--contrib/minizip/iowin32.h42
-rw-r--r--contrib/minizip/miniunz.c1170
-rw-r--r--contrib/minizip/minizip.c840
-rw-r--r--contrib/minizip/mztools.c562
-rw-r--r--contrib/minizip/mztools.h62
-rw-r--r--contrib/minizip/unzip.c3193
-rw-r--r--contrib/minizip/unzip.h706
-rw-r--r--contrib/minizip/zip.c2407
-rw-r--r--contrib/minizip/zip.h469
-rw-r--r--contrib/testzlib/rdtsc64.asm18
-rw-r--r--contrib/testzlib/rdtsc64.objbin0 -> 744 bytes
-rw-r--r--contrib/testzlib/testzlib.c407
-rw-r--r--contrib/testzlib/testzlib.txt10
-rw-r--r--contrib/testzlib/testzlib8.sln32
-rw-r--r--contrib/testzlib/testzlib8.vcproj638
-rw-r--r--contrib/vstudio/vc7/gvmat32.objbin10143 -> 10241 bytes
-rw-r--r--contrib/vstudio/vc7/inffas32.objbin14899 -> 14893 bytes
-rw-r--r--contrib/vstudio/vc7/zlib.rc6
-rw-r--r--crc32.c6
-rw-r--r--deflate.c27
-rw-r--r--examples/README.examples8
-rw-r--r--examples/gun.c692
-rw-r--r--examples/zlib_how.html5
-rw-r--r--examples/zpipe.c2
-rw-r--r--gzio.c29
-rw-r--r--inflate.c12
-rw-r--r--inftrees.c8
-rw-r--r--minigzip.c4
-rw-r--r--qnx/package.qpg10
-rw-r--r--win32/zlib1.rc8
-rw-r--r--zconf.h8
-rw-r--r--zconf.in.h8
-rw-r--r--zlib.34
-rw-r--r--zlib.h37
-rw-r--r--zutil.h10
63 files changed, 11616 insertions, 8906 deletions
diff --git a/ChangeLog b/ChangeLog
index d162e90..855303b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,27 @@
1 1
2 ChangeLog file for zlib 2 ChangeLog file for zlib
3 3
4Changes in 1.2.2.3 (27 May 2005)
5- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile
6- Typecast fread() return values in gzio.c [Vollant]
7- Remove trailing space in minigzip.c outmode (VC++ can't deal with it)
8- Fix crc check bug in gzread() after gzungetc() [Heiner]
9- Add the deflateTune() function to adjust internal compression parameters
10- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack)
11- Remove an incorrect assertion in examples/zpipe.c
12- Add C++ wrapper in infback9.h [Donais]
13- Fix bug in inflateCopy() when decoding fixed codes
14- Note in zlib.h how much deflateSetDictionary() actually uses
15- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used)
16- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer]
17- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer]
18- Add gzdirect() function to indicate transparent reads
19- Update contrib/minizip [Vollant]
20- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer]
21- Add casts in crc32.c to avoid warnings [Oberhumer]
22- Add contrib/masmx64 [Vollant]
23- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant]
24
4Changes in 1.2.2.2 (30 December 2004) 25Changes in 1.2.2.2 (30 December 2004)
5- Replace structure assignments in deflate.c and inflate.c with zmemcpy to 26- Replace structure assignments in deflate.c and inflate.c with zmemcpy to
6 avoid implicit memcpy calls (portability for no-library compilation) 27 avoid implicit memcpy calls (portability for no-library compilation)
diff --git a/Makefile b/Makefile
index 29f53de..535779d 100644
--- a/Makefile
+++ b/Makefile
@@ -30,7 +30,7 @@ CPP=$(CC) -E
30 30
31LIBS=libz.a 31LIBS=libz.a
32SHAREDLIB=libz.so 32SHAREDLIB=libz.so
33SHAREDLIBV=libz.so.1.2.2.2 33SHAREDLIBV=libz.so.1.2.2.3
34SHAREDLIBM=libz.so.1 34SHAREDLIBM=libz.so.1
35 35
36AR=ar rc 36AR=ar rc
diff --git a/Makefile.in b/Makefile.in
index 29f53de..535779d 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -30,7 +30,7 @@ CPP=$(CC) -E
30 30
31LIBS=libz.a 31LIBS=libz.a
32SHAREDLIB=libz.so 32SHAREDLIB=libz.so
33SHAREDLIBV=libz.so.1.2.2.2 33SHAREDLIBV=libz.so.1.2.2.3
34SHAREDLIBM=libz.so.1 34SHAREDLIBM=libz.so.1
35 35
36AR=ar rc 36AR=ar rc
diff --git a/README b/README
index e91a7a4..9bba2e4 100644
--- a/README
+++ b/README
@@ -1,6 +1,6 @@
1ZLIB DATA COMPRESSION LIBRARY 1ZLIB DATA COMPRESSION LIBRARY
2 2
3zlib 1.2.2.2 is a general purpose data compression library. All the code is 3zlib 1.2.2.3 is a general purpose data compression library. All the code is
4thread safe. The data format used by the zlib library is described by RFCs 4thread safe. The data format used by the zlib library is described by RFCs
5(Request for Comments) 1950 to 1952 in the files 5(Request for Comments) 1950 to 1952 in the files
6http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) 6http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
@@ -33,7 +33,7 @@ Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
33issue of Dr. Dobb's Journal; a copy of the article is available in 33issue of Dr. Dobb's Journal; a copy of the article is available in
34http://dogma.net/markn/articles/zlibtool/zlibtool.htm 34http://dogma.net/markn/articles/zlibtool/zlibtool.htm
35 35
36The changes made in version 1.2.2.2 are documented in the file ChangeLog. 36The changes made in version 1.2.2.3 are documented in the file ChangeLog.
37 37
38Unsupported third party contributions are provided in directory "contrib". 38Unsupported third party contributions are provided in directory "contrib".
39 39
diff --git a/as400/zlib.inc b/as400/zlib.inc
index 04c3309..2905ee0 100644
--- a/as400/zlib.inc
+++ b/as400/zlib.inc
@@ -1,7 +1,7 @@
1 * ZLIB.INC - Interface to the general purpose compression library 1 * ZLIB.INC - Interface to the general purpose compression library
2 * 2 *
3 * ILE RPG400 version by Patrick Monnerat, DATASPHERE. 3 * ILE RPG400 version by Patrick Monnerat, DATASPHERE.
4 * Version 1.2.2.2 4 * Version 1.2.2.3
5 * 5 *
6 * 6 *
7 * WARNING: 7 * WARNING:
@@ -20,8 +20,12 @@
20 * Constants 20 * Constants
21 ************************************************************************** 21 **************************************************************************
22 * 22 *
23 D ZLIB_VERSION C '1.2.2.2' Header's version 23 * Versioning information.
24 D ZLIB_VERNUM C X'1222' 24 *
25 D ZLIB_VERSION C '1.2.2.3'
26 D ZLIB_VERNUM C X'1223'
27 *
28 * Other equates.
25 * 29 *
26 D Z_NO_FLUSH C 0 30 D Z_NO_FLUSH C 0
27 D Z_SYNC_FLUSH C 2 31 D Z_SYNC_FLUSH C 2
diff --git a/contrib/README.contrib b/contrib/README.contrib
index 732d48c..20afc62 100644
--- a/contrib/README.contrib
+++ b/contrib/README.contrib
@@ -42,6 +42,10 @@ masm686/ by Dan Higdon <hdan@kinesoft.com>
42 and Chuck Walbourn <chuckw@kinesoft.com> 42 and Chuck Walbourn <chuckw@kinesoft.com>
43 asm code for Pentium Pro/PII, using the MASM syntax 43 asm code for Pentium Pro/PII, using the MASM syntax
44 44
45masmx64/ by Gilles Vollant <info@winimage.com>
46 x86 64-bit (AMD64 and Intel EM64t) code for x64 assembler to
47 replace longest_match() and inflate_fast()
48
45masmx86/ by Gilles Vollant <info@winimage.com> 49masmx86/ by Gilles Vollant <info@winimage.com>
46 x86 asm code to replace longest_match() and inflate_fast(), 50 x86 asm code to replace longest_match() and inflate_fast(),
47 for Visual C++ and MASM 51 for Visual C++ and MASM
diff --git a/contrib/asm586/match.S b/contrib/asm586/match.S
index 8f16140..371c9a0 100644
--- a/contrib/asm586/match.S
+++ b/contrib/asm586/match.S
@@ -1,354 +1,364 @@
1/* match.s -- Pentium-optimized version of longest_match() 1/* match.s -- Pentium-optimized version of longest_match()
2 * Written for zlib 1.1.2 2 * Written for zlib 1.1.2
3 * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com> 3 * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
4 * 4 *
5 * This is free software; you can redistribute it and/or modify it 5 * This is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License. 6 * under the terms of the GNU General Public License.
7 */ 7 */
8 8
9#ifndef NO_UNDERLINE 9#ifndef NO_UNDERLINE
10#define match_init _match_init 10#define match_init _match_init
11#define longest_match _longest_match 11#define longest_match _longest_match
12#endif 12#endif
13 13
14#define MAX_MATCH (258) 14#define MAX_MATCH (258)
15#define MIN_MATCH (3) 15#define MIN_MATCH (3)
16#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1) 16#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
17#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7) 17#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
18 18
19/* stack frame offsets */ 19/* stack frame offsets */
20 20
21#define wmask 0 /* local copy of s->wmask */ 21#define wmask 0 /* local copy of s->wmask */
22#define window 4 /* local copy of s->window */ 22#define window 4 /* local copy of s->window */
23#define windowbestlen 8 /* s->window + bestlen */ 23#define windowbestlen 8 /* s->window + bestlen */
24#define chainlenscanend 12 /* high word: current chain len */ 24#define chainlenscanend 12 /* high word: current chain len */
25 /* low word: last bytes sought */ 25 /* low word: last bytes sought */
26#define scanstart 16 /* first two bytes of string */ 26#define scanstart 16 /* first two bytes of string */
27#define scanalign 20 /* dword-misalignment of string */ 27#define scanalign 20 /* dword-misalignment of string */
28#define nicematch 24 /* a good enough match size */ 28#define nicematch 24 /* a good enough match size */
29#define bestlen 28 /* size of best match so far */ 29#define bestlen 28 /* size of best match so far */
30#define scan 32 /* ptr to string wanting match */ 30#define scan 32 /* ptr to string wanting match */
31 31
32#define LocalVarsSize (36) 32#define LocalVarsSize (36)
33/* saved ebx 36 */ 33/* saved ebx 36 */
34/* saved edi 40 */ 34/* saved edi 40 */
35/* saved esi 44 */ 35/* saved esi 44 */
36/* saved ebp 48 */ 36/* saved ebp 48 */
37/* return address 52 */ 37/* return address 52 */
38#define deflatestate 56 /* the function arguments */ 38#define deflatestate 56 /* the function arguments */
39#define curmatch 60 39#define curmatch 60
40 40
41/* Offsets for fields in the deflate_state structure. These numbers 41/* Offsets for fields in the deflate_state structure. These numbers
42 * are calculated from the definition of deflate_state, with the 42 * are calculated from the definition of deflate_state, with the
43 * assumption that the compiler will dword-align the fields. (Thus, 43 * assumption that the compiler will dword-align the fields. (Thus,
44 * changing the definition of deflate_state could easily cause this 44 * changing the definition of deflate_state could easily cause this
45 * program to crash horribly, without so much as a warning at 45 * program to crash horribly, without so much as a warning at
46 * compile time. Sigh.) 46 * compile time. Sigh.)
47 */ 47 */
48#define dsWSize 36 48
49#define dsWMask 44 49/* All the +zlib1222add offsets are due to the addition of fields
50#define dsWindow 48 50 * in zlib in the deflate_state structure since the asm code was first written
51#define dsPrev 56 51 * (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
52#define dsMatchLen 88 52 * (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
53#define dsPrevMatch 92 53 * if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
54#define dsStrStart 100 54 */
55#define dsMatchStart 104 55
56#define dsLookahead 108 56#define zlib1222add (8)
57#define dsPrevLen 112 57
58#define dsMaxChainLen 116 58#define dsWSize (36+zlib1222add)
59#define dsGoodMatch 132 59#define dsWMask (44+zlib1222add)
60#define dsNiceMatch 136 60#define dsWindow (48+zlib1222add)
61 61#define dsPrev (56+zlib1222add)
62 62#define dsMatchLen (88+zlib1222add)
63.file "match.S" 63#define dsPrevMatch (92+zlib1222add)
64 64#define dsStrStart (100+zlib1222add)
65.globl match_init, longest_match 65#define dsMatchStart (104+zlib1222add)
66 66#define dsLookahead (108+zlib1222add)
67.text 67#define dsPrevLen (112+zlib1222add)
68 68#define dsMaxChainLen (116+zlib1222add)
69/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */ 69#define dsGoodMatch (132+zlib1222add)
70 70#define dsNiceMatch (136+zlib1222add)
71longest_match: 71
72 72
73/* Save registers that the compiler may be using, and adjust %esp to */ 73.file "match.S"
74/* make room for our stack frame. */ 74
75 75.globl match_init, longest_match
76 pushl %ebp 76
77 pushl %edi 77.text
78 pushl %esi 78
79 pushl %ebx 79/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
80 subl $LocalVarsSize, %esp 80
81 81longest_match:
82/* Retrieve the function arguments. %ecx will hold cur_match */ 82
83/* throughout the entire function. %edx will hold the pointer to the */ 83/* Save registers that the compiler may be using, and adjust %esp to */
84/* deflate_state structure during the function's setup (before */ 84/* make room for our stack frame. */
85/* entering the main loop). */ 85
86 86 pushl %ebp
87 movl deflatestate(%esp), %edx 87 pushl %edi
88 movl curmatch(%esp), %ecx 88 pushl %esi
89 89 pushl %ebx
90/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */ 90 subl $LocalVarsSize, %esp
91 91
92 movl dsNiceMatch(%edx), %eax 92/* Retrieve the function arguments. %ecx will hold cur_match */
93 movl dsLookahead(%edx), %ebx 93/* throughout the entire function. %edx will hold the pointer to the */
94 cmpl %eax, %ebx 94/* deflate_state structure during the function's setup (before */
95 jl LookaheadLess 95/* entering the main loop). */
96 movl %eax, %ebx 96
97LookaheadLess: movl %ebx, nicematch(%esp) 97 movl deflatestate(%esp), %edx
98 98 movl curmatch(%esp), %ecx
99/* register Bytef *scan = s->window + s->strstart; */ 99
100 100/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
101 movl dsWindow(%edx), %esi 101
102 movl %esi, window(%esp) 102 movl dsNiceMatch(%edx), %eax
103 movl dsStrStart(%edx), %ebp 103 movl dsLookahead(%edx), %ebx
104 lea (%esi,%ebp), %edi 104 cmpl %eax, %ebx
105 movl %edi, scan(%esp) 105 jl LookaheadLess
106 106 movl %eax, %ebx
107/* Determine how many bytes the scan ptr is off from being */ 107LookaheadLess: movl %ebx, nicematch(%esp)
108/* dword-aligned. */ 108
109 109/* register Bytef *scan = s->window + s->strstart; */
110 movl %edi, %eax 110
111 negl %eax 111 movl dsWindow(%edx), %esi
112 andl $3, %eax 112 movl %esi, window(%esp)
113 movl %eax, scanalign(%esp) 113 movl dsStrStart(%edx), %ebp
114 114 lea (%esi,%ebp), %edi
115/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */ 115 movl %edi, scan(%esp)
116/* s->strstart - (IPos)MAX_DIST(s) : NIL; */ 116
117 117/* Determine how many bytes the scan ptr is off from being */
118 movl dsWSize(%edx), %eax 118/* dword-aligned. */
119 subl $MIN_LOOKAHEAD, %eax 119
120 subl %eax, %ebp 120 movl %edi, %eax
121 jg LimitPositive 121 negl %eax
122 xorl %ebp, %ebp 122 andl $3, %eax
123LimitPositive: 123 movl %eax, scanalign(%esp)
124 124
125/* unsigned chain_length = s->max_chain_length; */ 125/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
126/* if (s->prev_length >= s->good_match) { */ 126/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
127/* chain_length >>= 2; */ 127
128/* } */ 128 movl dsWSize(%edx), %eax
129 129 subl $MIN_LOOKAHEAD, %eax
130 movl dsPrevLen(%edx), %eax 130 subl %eax, %ebp
131 movl dsGoodMatch(%edx), %ebx 131 jg LimitPositive
132 cmpl %ebx, %eax 132 xorl %ebp, %ebp
133 movl dsMaxChainLen(%edx), %ebx 133LimitPositive:
134 jl LastMatchGood 134
135 shrl $2, %ebx 135/* unsigned chain_length = s->max_chain_length; */
136LastMatchGood: 136/* if (s->prev_length >= s->good_match) { */
137 137/* chain_length >>= 2; */
138/* chainlen is decremented once beforehand so that the function can */ 138/* } */
139/* use the sign flag instead of the zero flag for the exit test. */ 139
140/* It is then shifted into the high word, to make room for the scanend */ 140 movl dsPrevLen(%edx), %eax
141/* scanend value, which it will always accompany. */ 141 movl dsGoodMatch(%edx), %ebx
142 142 cmpl %ebx, %eax
143 decl %ebx 143 movl dsMaxChainLen(%edx), %ebx
144 shll $16, %ebx 144 jl LastMatchGood
145 145 shrl $2, %ebx
146/* int best_len = s->prev_length; */ 146LastMatchGood:
147 147
148 movl dsPrevLen(%edx), %eax 148/* chainlen is decremented once beforehand so that the function can */
149 movl %eax, bestlen(%esp) 149/* use the sign flag instead of the zero flag for the exit test. */
150 150/* It is then shifted into the high word, to make room for the scanend */
151/* Store the sum of s->window + best_len in %esi locally, and in %esi. */ 151/* scanend value, which it will always accompany. */
152 152
153 addl %eax, %esi 153 decl %ebx
154 movl %esi, windowbestlen(%esp) 154 shll $16, %ebx
155 155
156/* register ush scan_start = *(ushf*)scan; */ 156/* int best_len = s->prev_length; */
157/* register ush scan_end = *(ushf*)(scan+best_len-1); */ 157
158 158 movl dsPrevLen(%edx), %eax
159 movw (%edi), %bx 159 movl %eax, bestlen(%esp)
160 movw %bx, scanstart(%esp) 160
161 movw -1(%edi,%eax), %bx 161/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
162 movl %ebx, chainlenscanend(%esp) 162
163 163 addl %eax, %esi
164/* Posf *prev = s->prev; */ 164 movl %esi, windowbestlen(%esp)
165/* uInt wmask = s->w_mask; */ 165
166 166/* register ush scan_start = *(ushf*)scan; */
167 movl dsPrev(%edx), %edi 167/* register ush scan_end = *(ushf*)(scan+best_len-1); */
168 movl dsWMask(%edx), %edx 168
169 mov %edx, wmask(%esp) 169 movw (%edi), %bx
170 170 movw %bx, scanstart(%esp)
171/* Jump into the main loop. */ 171 movw -1(%edi,%eax), %bx
172 172 movl %ebx, chainlenscanend(%esp)
173 jmp LoopEntry 173
174 174/* Posf *prev = s->prev; */
175.balign 16 175/* uInt wmask = s->w_mask; */
176 176
177/* do { 177 movl dsPrev(%edx), %edi
178 * match = s->window + cur_match; 178 movl dsWMask(%edx), %edx
179 * if (*(ushf*)(match+best_len-1) != scan_end || 179 mov %edx, wmask(%esp)
180 * *(ushf*)match != scan_start) continue; 180
181 * [...] 181/* Jump into the main loop. */
182 * } while ((cur_match = prev[cur_match & wmask]) > limit 182
183 * && --chain_length != 0); 183 jmp LoopEntry
184 * 184
185 * Here is the inner loop of the function. The function will spend the 185.balign 16
186 * majority of its time in this loop, and majority of that time will 186
187 * be spent in the first ten instructions. 187/* do {
188 * 188 * match = s->window + cur_match;
189 * Within this loop: 189 * if (*(ushf*)(match+best_len-1) != scan_end ||
190 * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend) 190 * *(ushf*)match != scan_start) continue;
191 * %ecx = curmatch 191 * [...]
192 * %edx = curmatch & wmask 192 * } while ((cur_match = prev[cur_match & wmask]) > limit
193 * %esi = windowbestlen - i.e., (window + bestlen) 193 * && --chain_length != 0);
194 * %edi = prev 194 *
195 * %ebp = limit 195 * Here is the inner loop of the function. The function will spend the
196 * 196 * majority of its time in this loop, and majority of that time will
197 * Two optimization notes on the choice of instructions: 197 * be spent in the first ten instructions.
198 * 198 *
199 * The first instruction uses a 16-bit address, which costs an extra, 199 * Within this loop:
200 * unpairable cycle. This is cheaper than doing a 32-bit access and 200 * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend)
201 * zeroing the high word, due to the 3-cycle misalignment penalty which 201 * %ecx = curmatch
202 * would occur half the time. This also turns out to be cheaper than 202 * %edx = curmatch & wmask
203 * doing two separate 8-bit accesses, as the memory is so rarely in the 203 * %esi = windowbestlen - i.e., (window + bestlen)
204 * L1 cache. 204 * %edi = prev
205 * 205 * %ebp = limit
206 * The window buffer, however, apparently spends a lot of time in the 206 *
207 * cache, and so it is faster to retrieve the word at the end of the 207 * Two optimization notes on the choice of instructions:
208 * match string with two 8-bit loads. The instructions that test the 208 *
209 * word at the beginning of the match string, however, are executed 209 * The first instruction uses a 16-bit address, which costs an extra,
210 * much less frequently, and there it was cheaper to use 16-bit 210 * unpairable cycle. This is cheaper than doing a 32-bit access and
211 * instructions, which avoided the necessity of saving off and 211 * zeroing the high word, due to the 3-cycle misalignment penalty which
212 * subsequently reloading one of the other registers. 212 * would occur half the time. This also turns out to be cheaper than
213 */ 213 * doing two separate 8-bit accesses, as the memory is so rarely in the
214LookupLoop: 214 * L1 cache.
215 /* 1 U & V */ 215 *
216 movw (%edi,%edx,2), %cx /* 2 U pipe */ 216 * The window buffer, however, apparently spends a lot of time in the
217 movl wmask(%esp), %edx /* 2 V pipe */ 217 * cache, and so it is faster to retrieve the word at the end of the
218 cmpl %ebp, %ecx /* 3 U pipe */ 218 * match string with two 8-bit loads. The instructions that test the
219 jbe LeaveNow /* 3 V pipe */ 219 * word at the beginning of the match string, however, are executed
220 subl $0x00010000, %ebx /* 4 U pipe */ 220 * much less frequently, and there it was cheaper to use 16-bit
221 js LeaveNow /* 4 V pipe */ 221 * instructions, which avoided the necessity of saving off and
222LoopEntry: movb -1(%esi,%ecx), %al /* 5 U pipe */ 222 * subsequently reloading one of the other registers.
223 andl %ecx, %edx /* 5 V pipe */ 223 */
224 cmpb %bl, %al /* 6 U pipe */ 224LookupLoop:
225 jnz LookupLoop /* 6 V pipe */ 225 /* 1 U & V */
226 movb (%esi,%ecx), %ah 226 movw (%edi,%edx,2), %cx /* 2 U pipe */
227 cmpb %bh, %ah 227 movl wmask(%esp), %edx /* 2 V pipe */
228 jnz LookupLoop 228 cmpl %ebp, %ecx /* 3 U pipe */
229 movl window(%esp), %eax 229 jbe LeaveNow /* 3 V pipe */
230 movw (%eax,%ecx), %ax 230 subl $0x00010000, %ebx /* 4 U pipe */
231 cmpw scanstart(%esp), %ax 231 js LeaveNow /* 4 V pipe */
232 jnz LookupLoop 232LoopEntry: movb -1(%esi,%ecx), %al /* 5 U pipe */
233 233 andl %ecx, %edx /* 5 V pipe */
234/* Store the current value of chainlen. */ 234 cmpb %bl, %al /* 6 U pipe */
235 235 jnz LookupLoop /* 6 V pipe */
236 movl %ebx, chainlenscanend(%esp) 236 movb (%esi,%ecx), %ah
237 237 cmpb %bh, %ah
238/* Point %edi to the string under scrutiny, and %esi to the string we */ 238 jnz LookupLoop
239/* are hoping to match it up with. In actuality, %esi and %edi are */ 239 movl window(%esp), %eax
240/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */ 240 movw (%eax,%ecx), %ax
241/* initialized to -(MAX_MATCH_8 - scanalign). */ 241 cmpw scanstart(%esp), %ax
242 242 jnz LookupLoop
243 movl window(%esp), %esi 243
244 movl scan(%esp), %edi 244/* Store the current value of chainlen. */
245 addl %ecx, %esi 245
246 movl scanalign(%esp), %eax 246 movl %ebx, chainlenscanend(%esp)
247 movl $(-MAX_MATCH_8), %edx 247
248 lea MAX_MATCH_8(%edi,%eax), %edi 248/* Point %edi to the string under scrutiny, and %esi to the string we */
249 lea MAX_MATCH_8(%esi,%eax), %esi 249/* are hoping to match it up with. In actuality, %esi and %edi are */
250 250/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
251/* Test the strings for equality, 8 bytes at a time. At the end, 251/* initialized to -(MAX_MATCH_8 - scanalign). */
252 * adjust %edx so that it is offset to the exact byte that mismatched. 252
253 * 253 movl window(%esp), %esi
254 * We already know at this point that the first three bytes of the 254 movl scan(%esp), %edi
255 * strings match each other, and they can be safely passed over before 255 addl %ecx, %esi
256 * starting the compare loop. So what this code does is skip over 0-3 256 movl scanalign(%esp), %eax
257 * bytes, as much as necessary in order to dword-align the %edi 257 movl $(-MAX_MATCH_8), %edx
258 * pointer. (%esi will still be misaligned three times out of four.) 258 lea MAX_MATCH_8(%edi,%eax), %edi
259 * 259 lea MAX_MATCH_8(%esi,%eax), %esi
260 * It should be confessed that this loop usually does not represent 260
261 * much of the total running time. Replacing it with a more 261/* Test the strings for equality, 8 bytes at a time. At the end,
262 * straightforward "rep cmpsb" would not drastically degrade 262 * adjust %edx so that it is offset to the exact byte that mismatched.
263 * performance. 263 *
264 */ 264 * We already know at this point that the first three bytes of the
265LoopCmps: 265 * strings match each other, and they can be safely passed over before
266 movl (%esi,%edx), %eax 266 * starting the compare loop. So what this code does is skip over 0-3
267 movl (%edi,%edx), %ebx 267 * bytes, as much as necessary in order to dword-align the %edi
268 xorl %ebx, %eax 268 * pointer. (%esi will still be misaligned three times out of four.)
269 jnz LeaveLoopCmps 269 *
270 movl 4(%esi,%edx), %eax 270 * It should be confessed that this loop usually does not represent
271 movl 4(%edi,%edx), %ebx 271 * much of the total running time. Replacing it with a more
272 xorl %ebx, %eax 272 * straightforward "rep cmpsb" would not drastically degrade
273 jnz LeaveLoopCmps4 273 * performance.
274 addl $8, %edx 274 */
275 jnz LoopCmps 275LoopCmps:
276 jmp LenMaximum 276 movl (%esi,%edx), %eax
277LeaveLoopCmps4: addl $4, %edx 277 movl (%edi,%edx), %ebx
278LeaveLoopCmps: testl $0x0000FFFF, %eax 278 xorl %ebx, %eax
279 jnz LenLower 279 jnz LeaveLoopCmps
280 addl $2, %edx 280 movl 4(%esi,%edx), %eax
281 shrl $16, %eax 281 movl 4(%edi,%edx), %ebx
282LenLower: subb $1, %al 282 xorl %ebx, %eax
283 adcl $0, %edx 283 jnz LeaveLoopCmps4
284 284 addl $8, %edx
285/* Calculate the length of the match. If it is longer than MAX_MATCH, */ 285 jnz LoopCmps
286/* then automatically accept it as the best possible match and leave. */ 286 jmp LenMaximum
287 287LeaveLoopCmps4: addl $4, %edx
288 lea (%edi,%edx), %eax 288LeaveLoopCmps: testl $0x0000FFFF, %eax
289 movl scan(%esp), %edi 289 jnz LenLower
290 subl %edi, %eax 290 addl $2, %edx
291 cmpl $MAX_MATCH, %eax 291 shrl $16, %eax
292 jge LenMaximum 292LenLower: subb $1, %al
293 293 adcl $0, %edx
294/* If the length of the match is not longer than the best match we */ 294
295/* have so far, then forget it and return to the lookup loop. */ 295/* Calculate the length of the match. If it is longer than MAX_MATCH, */
296 296/* then automatically accept it as the best possible match and leave. */
297 movl deflatestate(%esp), %edx 297
298 movl bestlen(%esp), %ebx 298 lea (%edi,%edx), %eax
299 cmpl %ebx, %eax 299 movl scan(%esp), %edi
300 jg LongerMatch 300 subl %edi, %eax
301 movl chainlenscanend(%esp), %ebx 301 cmpl $MAX_MATCH, %eax
302 movl windowbestlen(%esp), %esi 302 jge LenMaximum
303 movl dsPrev(%edx), %edi 303
304 movl wmask(%esp), %edx 304/* If the length of the match is not longer than the best match we */
305 andl %ecx, %edx 305/* have so far, then forget it and return to the lookup loop. */
306 jmp LookupLoop 306
307 307 movl deflatestate(%esp), %edx
308/* s->match_start = cur_match; */ 308 movl bestlen(%esp), %ebx
309/* best_len = len; */ 309 cmpl %ebx, %eax
310/* if (len >= nice_match) break; */ 310 jg LongerMatch
311/* scan_end = *(ushf*)(scan+best_len-1); */ 311 movl chainlenscanend(%esp), %ebx
312 312 movl windowbestlen(%esp), %esi
313LongerMatch: movl nicematch(%esp), %ebx 313 movl dsPrev(%edx), %edi
314 movl %eax, bestlen(%esp) 314 movl wmask(%esp), %edx
315 movl %ecx, dsMatchStart(%edx) 315 andl %ecx, %edx
316 cmpl %ebx, %eax 316 jmp LookupLoop
317 jge LeaveNow 317
318 movl window(%esp), %esi 318/* s->match_start = cur_match; */
319 addl %eax, %esi 319/* best_len = len; */
320 movl %esi, windowbestlen(%esp) 320/* if (len >= nice_match) break; */
321 movl chainlenscanend(%esp), %ebx 321/* scan_end = *(ushf*)(scan+best_len-1); */
322 movw -1(%edi,%eax), %bx 322
323 movl dsPrev(%edx), %edi 323LongerMatch: movl nicematch(%esp), %ebx
324 movl %ebx, chainlenscanend(%esp) 324 movl %eax, bestlen(%esp)
325 movl wmask(%esp), %edx 325 movl %ecx, dsMatchStart(%edx)
326 andl %ecx, %edx 326 cmpl %ebx, %eax
327 jmp LookupLoop 327 jge LeaveNow
328 328 movl window(%esp), %esi
329/* Accept the current string, with the maximum possible length. */ 329 addl %eax, %esi
330 330 movl %esi, windowbestlen(%esp)
331LenMaximum: movl deflatestate(%esp), %edx 331 movl chainlenscanend(%esp), %ebx
332 movl $MAX_MATCH, bestlen(%esp) 332 movw -1(%edi,%eax), %bx
333 movl %ecx, dsMatchStart(%edx) 333 movl dsPrev(%edx), %edi
334 334 movl %ebx, chainlenscanend(%esp)
335/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */ 335 movl wmask(%esp), %edx
336/* return s->lookahead; */ 336 andl %ecx, %edx
337 337 jmp LookupLoop
338LeaveNow: 338
339 movl deflatestate(%esp), %edx 339/* Accept the current string, with the maximum possible length. */
340 movl bestlen(%esp), %ebx 340
341 movl dsLookahead(%edx), %eax 341LenMaximum: movl deflatestate(%esp), %edx
342 cmpl %eax, %ebx 342 movl $MAX_MATCH, bestlen(%esp)
343 jg LookaheadRet 343 movl %ecx, dsMatchStart(%edx)
344 movl %ebx, %eax 344
345LookaheadRet: 345/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
346 346/* return s->lookahead; */
347/* Restore the stack and return from whence we came. */ 347
348 348LeaveNow:
349 addl $LocalVarsSize, %esp 349 movl deflatestate(%esp), %edx
350 popl %ebx 350 movl bestlen(%esp), %ebx
351 popl %esi 351 movl dsLookahead(%edx), %eax
352 popl %edi 352 cmpl %eax, %ebx
353 popl %ebp 353 jg LookaheadRet
354match_init: ret 354 movl %ebx, %eax
355LookaheadRet:
356
357/* Restore the stack and return from whence we came. */
358
359 addl $LocalVarsSize, %esp
360 popl %ebx
361 popl %esi
362 popl %edi
363 popl %ebp
364match_init: ret
diff --git a/contrib/asm686/match.S b/contrib/asm686/match.S
index 8e86c33..c24be4d 100644
--- a/contrib/asm686/match.S
+++ b/contrib/asm686/match.S
@@ -1,327 +1,329 @@
1/* match.s -- Pentium-Pro-optimized version of longest_match() 1/* match.s -- Pentium-Pro-optimized version of longest_match()
2 * Written for zlib 1.1.2 2 * Written for zlib 1.1.2
3 * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com> 3 * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
4 * 4 *
5 * This is free software; you can redistribute it and/or modify it 5 * This is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License. 6 * under the terms of the GNU General Public License.
7 */ 7 */
8 8
9#ifndef NO_UNDERLINE 9#ifndef NO_UNDERLINE
10#define match_init _match_init 10#define match_init _match_init
11#define longest_match _longest_match 11#define longest_match _longest_match
12#endif 12#endif
13 13
14#define MAX_MATCH (258) 14#define MAX_MATCH (258)
15#define MIN_MATCH (3) 15#define MIN_MATCH (3)
16#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1) 16#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
17#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7) 17#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
18 18
19/* stack frame offsets */ 19/* stack frame offsets */
20 20
21#define chainlenwmask 0 /* high word: current chain len */ 21#define chainlenwmask 0 /* high word: current chain len */
22 /* low word: s->wmask */ 22 /* low word: s->wmask */
23#define window 4 /* local copy of s->window */ 23#define window 4 /* local copy of s->window */
24#define windowbestlen 8 /* s->window + bestlen */ 24#define windowbestlen 8 /* s->window + bestlen */
25#define scanstart 16 /* first two bytes of string */ 25#define scanstart 16 /* first two bytes of string */
26#define scanend 12 /* last two bytes of string */ 26#define scanend 12 /* last two bytes of string */
27#define scanalign 20 /* dword-misalignment of string */ 27#define scanalign 20 /* dword-misalignment of string */
28#define nicematch 24 /* a good enough match size */ 28#define nicematch 24 /* a good enough match size */
29#define bestlen 28 /* size of best match so far */ 29#define bestlen 28 /* size of best match so far */
30#define scan 32 /* ptr to string wanting match */ 30#define scan 32 /* ptr to string wanting match */
31 31
32#define LocalVarsSize (36) 32#define LocalVarsSize (36)
33/* saved ebx 36 */ 33/* saved ebx 36 */
34/* saved edi 40 */ 34/* saved edi 40 */
35/* saved esi 44 */ 35/* saved esi 44 */
36/* saved ebp 48 */ 36/* saved ebp 48 */
37/* return address 52 */ 37/* return address 52 */
38#define deflatestate 56 /* the function arguments */ 38#define deflatestate 56 /* the function arguments */
39#define curmatch 60 39#define curmatch 60
40 40
41/* Offsets for fields in the deflate_state structure. These numbers 41/* All the +zlib1222add offsets are due to the addition of fields
42 * are calculated from the definition of deflate_state, with the 42 * in zlib in the deflate_state structure since the asm code was first written
43 * assumption that the compiler will dword-align the fields. (Thus, 43 * (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
44 * changing the definition of deflate_state could easily cause this 44 * (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
45 * program to crash horribly, without so much as a warning at 45 * if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
46 * compile time. Sigh.) 46 */
47 */ 47
48#define dsWSize 36 48#define zlib1222add (8)
49#define dsWMask 44 49
50#define dsWindow 48 50#define dsWSize (36+zlib1222add)
51#define dsPrev 56 51#define dsWMask (44+zlib1222add)
52#define dsMatchLen 88 52#define dsWindow (48+zlib1222add)
53#define dsPrevMatch 92 53#define dsPrev (56+zlib1222add)
54#define dsStrStart 100 54#define dsMatchLen (88+zlib1222add)
55#define dsMatchStart 104 55#define dsPrevMatch (92+zlib1222add)
56#define dsLookahead 108 56#define dsStrStart (100+zlib1222add)
57#define dsPrevLen 112 57#define dsMatchStart (104+zlib1222add)
58#define dsMaxChainLen 116 58#define dsLookahead (108+zlib1222add)
59#define dsGoodMatch 132 59#define dsPrevLen (112+zlib1222add)
60#define dsNiceMatch 136 60#define dsMaxChainLen (116+zlib1222add)
61 61#define dsGoodMatch (132+zlib1222add)
62 62#define dsNiceMatch (136+zlib1222add)
63.file "match.S" 63
64 64
65.globl match_init, longest_match 65.file "match.S"
66 66
67.text 67.globl match_init, longest_match
68 68
69/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */ 69.text
70 70
71longest_match: 71/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
72 72
73/* Save registers that the compiler may be using, and adjust %esp to */ 73longest_match:
74/* make room for our stack frame. */ 74
75 75/* Save registers that the compiler may be using, and adjust %esp to */
76 pushl %ebp 76/* make room for our stack frame. */
77 pushl %edi 77
78 pushl %esi 78 pushl %ebp
79 pushl %ebx 79 pushl %edi
80 subl $LocalVarsSize, %esp 80 pushl %esi
81 81 pushl %ebx
82/* Retrieve the function arguments. %ecx will hold cur_match */ 82 subl $LocalVarsSize, %esp
83/* throughout the entire function. %edx will hold the pointer to the */ 83
84/* deflate_state structure during the function's setup (before */ 84/* Retrieve the function arguments. %ecx will hold cur_match */
85/* entering the main loop). */ 85/* throughout the entire function. %edx will hold the pointer to the */
86 86/* deflate_state structure during the function's setup (before */
87 movl deflatestate(%esp), %edx 87/* entering the main loop). */
88 movl curmatch(%esp), %ecx 88
89 89 movl deflatestate(%esp), %edx
90/* uInt wmask = s->w_mask; */ 90 movl curmatch(%esp), %ecx
91/* unsigned chain_length = s->max_chain_length; */ 91
92/* if (s->prev_length >= s->good_match) { */ 92/* uInt wmask = s->w_mask; */
93/* chain_length >>= 2; */ 93/* unsigned chain_length = s->max_chain_length; */
94/* } */ 94/* if (s->prev_length >= s->good_match) { */
95 95/* chain_length >>= 2; */
96 movl dsPrevLen(%edx), %eax 96/* } */
97 movl dsGoodMatch(%edx), %ebx 97
98 cmpl %ebx, %eax 98 movl dsPrevLen(%edx), %eax
99 movl dsWMask(%edx), %eax 99 movl dsGoodMatch(%edx), %ebx
100 movl dsMaxChainLen(%edx), %ebx 100 cmpl %ebx, %eax
101 jl LastMatchGood 101 movl dsWMask(%edx), %eax
102 shrl $2, %ebx 102 movl dsMaxChainLen(%edx), %ebx
103LastMatchGood: 103 jl LastMatchGood
104 104 shrl $2, %ebx
105/* chainlen is decremented once beforehand so that the function can */ 105LastMatchGood:
106/* use the sign flag instead of the zero flag for the exit test. */ 106
107/* It is then shifted into the high word, to make room for the wmask */ 107/* chainlen is decremented once beforehand so that the function can */
108/* value, which it will always accompany. */ 108/* use the sign flag instead of the zero flag for the exit test. */
109 109/* It is then shifted into the high word, to make room for the wmask */
110 decl %ebx 110/* value, which it will always accompany. */
111 shll $16, %ebx 111
112 orl %eax, %ebx 112 decl %ebx
113 movl %ebx, chainlenwmask(%esp) 113 shll $16, %ebx
114 114 orl %eax, %ebx
115/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */ 115 movl %ebx, chainlenwmask(%esp)
116 116
117 movl dsNiceMatch(%edx), %eax 117/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
118 movl dsLookahead(%edx), %ebx 118
119 cmpl %eax, %ebx 119 movl dsNiceMatch(%edx), %eax
120 jl LookaheadLess 120 movl dsLookahead(%edx), %ebx
121 movl %eax, %ebx 121 cmpl %eax, %ebx
122LookaheadLess: movl %ebx, nicematch(%esp) 122 jl LookaheadLess
123 123 movl %eax, %ebx
124/* register Bytef *scan = s->window + s->strstart; */ 124LookaheadLess: movl %ebx, nicematch(%esp)
125 125
126 movl dsWindow(%edx), %esi 126/* register Bytef *scan = s->window + s->strstart; */
127 movl %esi, window(%esp) 127
128 movl dsStrStart(%edx), %ebp 128 movl dsWindow(%edx), %esi
129 lea (%esi,%ebp), %edi 129 movl %esi, window(%esp)
130 movl %edi, scan(%esp) 130 movl dsStrStart(%edx), %ebp
131 131 lea (%esi,%ebp), %edi
132/* Determine how many bytes the scan ptr is off from being */ 132 movl %edi, scan(%esp)
133/* dword-aligned. */ 133
134 134/* Determine how many bytes the scan ptr is off from being */
135 movl %edi, %eax 135/* dword-aligned. */
136 negl %eax 136
137 andl $3, %eax 137 movl %edi, %eax
138 movl %eax, scanalign(%esp) 138 negl %eax
139 139 andl $3, %eax
140/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */ 140 movl %eax, scanalign(%esp)
141/* s->strstart - (IPos)MAX_DIST(s) : NIL; */ 141
142 142/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
143 movl dsWSize(%edx), %eax 143/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
144 subl $MIN_LOOKAHEAD, %eax 144
145 subl %eax, %ebp 145 movl dsWSize(%edx), %eax
146 jg LimitPositive 146 subl $MIN_LOOKAHEAD, %eax
147 xorl %ebp, %ebp 147 subl %eax, %ebp
148LimitPositive: 148 jg LimitPositive
149 149 xorl %ebp, %ebp
150/* int best_len = s->prev_length; */ 150LimitPositive:
151 151
152 movl dsPrevLen(%edx), %eax 152/* int best_len = s->prev_length; */
153 movl %eax, bestlen(%esp) 153
154 154 movl dsPrevLen(%edx), %eax
155/* Store the sum of s->window + best_len in %esi locally, and in %esi. */ 155 movl %eax, bestlen(%esp)
156 156
157 addl %eax, %esi 157/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
158 movl %esi, windowbestlen(%esp) 158
159 159 addl %eax, %esi
160/* register ush scan_start = *(ushf*)scan; */ 160 movl %esi, windowbestlen(%esp)
161/* register ush scan_end = *(ushf*)(scan+best_len-1); */ 161
162/* Posf *prev = s->prev; */ 162/* register ush scan_start = *(ushf*)scan; */
163 163/* register ush scan_end = *(ushf*)(scan+best_len-1); */
164 movzwl (%edi), %ebx 164/* Posf *prev = s->prev; */
165 movl %ebx, scanstart(%esp) 165
166 movzwl -1(%edi,%eax), %ebx 166 movzwl (%edi), %ebx
167 movl %ebx, scanend(%esp) 167 movl %ebx, scanstart(%esp)
168 movl dsPrev(%edx), %edi 168 movzwl -1(%edi,%eax), %ebx
169 169 movl %ebx, scanend(%esp)
170/* Jump into the main loop. */ 170 movl dsPrev(%edx), %edi
171 171
172 movl chainlenwmask(%esp), %edx 172/* Jump into the main loop. */
173 jmp LoopEntry 173
174 174 movl chainlenwmask(%esp), %edx
175.balign 16 175 jmp LoopEntry
176 176
177/* do { 177.balign 16
178 * match = s->window + cur_match; 178
179 * if (*(ushf*)(match+best_len-1) != scan_end || 179/* do {
180 * *(ushf*)match != scan_start) continue; 180 * match = s->window + cur_match;
181 * [...] 181 * if (*(ushf*)(match+best_len-1) != scan_end ||
182 * } while ((cur_match = prev[cur_match & wmask]) > limit 182 * *(ushf*)match != scan_start) continue;
183 * && --chain_length != 0); 183 * [...]
184 * 184 * } while ((cur_match = prev[cur_match & wmask]) > limit
185 * Here is the inner loop of the function. The function will spend the 185 * && --chain_length != 0);
186 * majority of its time in this loop, and majority of that time will 186 *
187 * be spent in the first ten instructions. 187 * Here is the inner loop of the function. The function will spend the
188 * 188 * majority of its time in this loop, and majority of that time will
189 * Within this loop: 189 * be spent in the first ten instructions.
190 * %ebx = scanend 190 *
191 * %ecx = curmatch 191 * Within this loop:
192 * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) 192 * %ebx = scanend
193 * %esi = windowbestlen - i.e., (window + bestlen) 193 * %ecx = curmatch
194 * %edi = prev 194 * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
195 * %ebp = limit 195 * %esi = windowbestlen - i.e., (window + bestlen)
196 */ 196 * %edi = prev
197LookupLoop: 197 * %ebp = limit
198 andl %edx, %ecx 198 */
199 movzwl (%edi,%ecx,2), %ecx 199LookupLoop:
200 cmpl %ebp, %ecx 200 andl %edx, %ecx
201 jbe LeaveNow 201 movzwl (%edi,%ecx,2), %ecx
202 subl $0x00010000, %edx 202 cmpl %ebp, %ecx
203 js LeaveNow 203 jbe LeaveNow
204LoopEntry: movzwl -1(%esi,%ecx), %eax 204 subl $0x00010000, %edx
205 cmpl %ebx, %eax 205 js LeaveNow
206 jnz LookupLoop 206LoopEntry: movzwl -1(%esi,%ecx), %eax
207 movl window(%esp), %eax 207 cmpl %ebx, %eax
208 movzwl (%eax,%ecx), %eax 208 jnz LookupLoop
209 cmpl scanstart(%esp), %eax 209 movl window(%esp), %eax
210 jnz LookupLoop 210 movzwl (%eax,%ecx), %eax
211 211 cmpl scanstart(%esp), %eax
212/* Store the current value of chainlen. */ 212 jnz LookupLoop
213 213
214 movl %edx, chainlenwmask(%esp) 214/* Store the current value of chainlen. */
215 215
216/* Point %edi to the string under scrutiny, and %esi to the string we */ 216 movl %edx, chainlenwmask(%esp)
217/* are hoping to match it up with. In actuality, %esi and %edi are */ 217
218/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */ 218/* Point %edi to the string under scrutiny, and %esi to the string we */
219/* initialized to -(MAX_MATCH_8 - scanalign). */ 219/* are hoping to match it up with. In actuality, %esi and %edi are */
220 220/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
221 movl window(%esp), %esi 221/* initialized to -(MAX_MATCH_8 - scanalign). */
222 movl scan(%esp), %edi 222
223 addl %ecx, %esi 223 movl window(%esp), %esi
224 movl scanalign(%esp), %eax 224 movl scan(%esp), %edi
225 movl $(-MAX_MATCH_8), %edx 225 addl %ecx, %esi
226 lea MAX_MATCH_8(%edi,%eax), %edi 226 movl scanalign(%esp), %eax
227 lea MAX_MATCH_8(%esi,%eax), %esi 227 movl $(-MAX_MATCH_8), %edx
228 228 lea MAX_MATCH_8(%edi,%eax), %edi
229/* Test the strings for equality, 8 bytes at a time. At the end, 229 lea MAX_MATCH_8(%esi,%eax), %esi
230 * adjust %edx so that it is offset to the exact byte that mismatched. 230
231 * 231/* Test the strings for equality, 8 bytes at a time. At the end,
232 * We already know at this point that the first three bytes of the 232 * adjust %edx so that it is offset to the exact byte that mismatched.
233 * strings match each other, and they can be safely passed over before 233 *
234 * starting the compare loop. So what this code does is skip over 0-3 234 * We already know at this point that the first three bytes of the
235 * bytes, as much as necessary in order to dword-align the %edi 235 * strings match each other, and they can be safely passed over before
236 * pointer. (%esi will still be misaligned three times out of four.) 236 * starting the compare loop. So what this code does is skip over 0-3
237 * 237 * bytes, as much as necessary in order to dword-align the %edi
238 * It should be confessed that this loop usually does not represent 238 * pointer. (%esi will still be misaligned three times out of four.)
239 * much of the total running time. Replacing it with a more 239 *
240 * straightforward "rep cmpsb" would not drastically degrade 240 * It should be confessed that this loop usually does not represent
241 * performance. 241 * much of the total running time. Replacing it with a more
242 */ 242 * straightforward "rep cmpsb" would not drastically degrade
243LoopCmps: 243 * performance.
244 movl (%esi,%edx), %eax 244 */
245 xorl (%edi,%edx), %eax 245LoopCmps:
246 jnz LeaveLoopCmps 246 movl (%esi,%edx), %eax
247 movl 4(%esi,%edx), %eax 247 xorl (%edi,%edx), %eax
248 xorl 4(%edi,%edx), %eax 248 jnz LeaveLoopCmps
249 jnz LeaveLoopCmps4 249 movl 4(%esi,%edx), %eax
250 addl $8, %edx 250 xorl 4(%edi,%edx), %eax
251 jnz LoopCmps 251 jnz LeaveLoopCmps4
252 jmp LenMaximum 252 addl $8, %edx
253LeaveLoopCmps4: addl $4, %edx 253 jnz LoopCmps
254LeaveLoopCmps: testl $0x0000FFFF, %eax 254 jmp LenMaximum
255 jnz LenLower 255LeaveLoopCmps4: addl $4, %edx
256 addl $2, %edx 256LeaveLoopCmps: testl $0x0000FFFF, %eax
257 shrl $16, %eax 257 jnz LenLower
258LenLower: subb $1, %al 258 addl $2, %edx
259 adcl $0, %edx 259 shrl $16, %eax
260 260LenLower: subb $1, %al
261/* Calculate the length of the match. If it is longer than MAX_MATCH, */ 261 adcl $0, %edx
262/* then automatically accept it as the best possible match and leave. */ 262
263 263/* Calculate the length of the match. If it is longer than MAX_MATCH, */
264 lea (%edi,%edx), %eax 264/* then automatically accept it as the best possible match and leave. */
265 movl scan(%esp), %edi 265
266 subl %edi, %eax 266 lea (%edi,%edx), %eax
267 cmpl $MAX_MATCH, %eax 267 movl scan(%esp), %edi
268 jge LenMaximum 268 subl %edi, %eax
269 269 cmpl $MAX_MATCH, %eax
270/* If the length of the match is not longer than the best match we */ 270 jge LenMaximum
271/* have so far, then forget it and return to the lookup loop. */ 271
272 272/* If the length of the match is not longer than the best match we */
273 movl deflatestate(%esp), %edx 273/* have so far, then forget it and return to the lookup loop. */
274 movl bestlen(%esp), %ebx 274
275 cmpl %ebx, %eax 275 movl deflatestate(%esp), %edx
276 jg LongerMatch 276 movl bestlen(%esp), %ebx
277 movl windowbestlen(%esp), %esi 277 cmpl %ebx, %eax
278 movl dsPrev(%edx), %edi 278 jg LongerMatch
279 movl scanend(%esp), %ebx 279 movl windowbestlen(%esp), %esi
280 movl chainlenwmask(%esp), %edx 280 movl dsPrev(%edx), %edi
281 jmp LookupLoop 281 movl scanend(%esp), %ebx
282 282 movl chainlenwmask(%esp), %edx
283/* s->match_start = cur_match; */ 283 jmp LookupLoop
284/* best_len = len; */ 284
285/* if (len >= nice_match) break; */ 285/* s->match_start = cur_match; */
286/* scan_end = *(ushf*)(scan+best_len-1); */ 286/* best_len = len; */
287 287/* if (len >= nice_match) break; */
288LongerMatch: movl nicematch(%esp), %ebx 288/* scan_end = *(ushf*)(scan+best_len-1); */
289 movl %eax, bestlen(%esp) 289
290 movl %ecx, dsMatchStart(%edx) 290LongerMatch: movl nicematch(%esp), %ebx
291 cmpl %ebx, %eax 291 movl %eax, bestlen(%esp)
292 jge LeaveNow 292 movl %ecx, dsMatchStart(%edx)
293 movl window(%esp), %esi 293 cmpl %ebx, %eax
294 addl %eax, %esi 294 jge LeaveNow
295 movl %esi, windowbestlen(%esp) 295 movl window(%esp), %esi
296 movzwl -1(%edi,%eax), %ebx 296 addl %eax, %esi
297 movl dsPrev(%edx), %edi 297 movl %esi, windowbestlen(%esp)
298 movl %ebx, scanend(%esp) 298 movzwl -1(%edi,%eax), %ebx
299 movl chainlenwmask(%esp), %edx 299 movl dsPrev(%edx), %edi
300 jmp LookupLoop 300 movl %ebx, scanend(%esp)
301 301 movl chainlenwmask(%esp), %edx
302/* Accept the current string, with the maximum possible length. */ 302 jmp LookupLoop
303 303
304LenMaximum: movl deflatestate(%esp), %edx 304/* Accept the current string, with the maximum possible length. */
305 movl $MAX_MATCH, bestlen(%esp) 305
306 movl %ecx, dsMatchStart(%edx) 306LenMaximum: movl deflatestate(%esp), %edx
307 307 movl $MAX_MATCH, bestlen(%esp)
308/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */ 308 movl %ecx, dsMatchStart(%edx)
309/* return s->lookahead; */ 309
310 310/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
311LeaveNow: 311/* return s->lookahead; */
312 movl deflatestate(%esp), %edx 312
313 movl bestlen(%esp), %ebx 313LeaveNow:
314 movl dsLookahead(%edx), %eax 314 movl deflatestate(%esp), %edx
315 cmpl %eax, %ebx 315 movl bestlen(%esp), %ebx
316 jg LookaheadRet 316 movl dsLookahead(%edx), %eax
317 movl %ebx, %eax 317 cmpl %eax, %ebx
318LookaheadRet: 318 jg LookaheadRet
319 319 movl %ebx, %eax
320/* Restore the stack and return from whence we came. */ 320LookaheadRet:
321 321
322 addl $LocalVarsSize, %esp 322/* Restore the stack and return from whence we came. */
323 popl %ebx 323
324 popl %esi 324 addl $LocalVarsSize, %esp
325 popl %edi 325 popl %ebx
326 popl %ebp 326 popl %esi
327match_init: ret 327 popl %edi
328 popl %ebp
329match_init: ret
diff --git a/contrib/infback9/infback9.h b/contrib/infback9/infback9.h
index 10bf58c..1073c0a 100644
--- a/contrib/infback9/infback9.h
+++ b/contrib/infback9/infback9.h
@@ -16,6 +16,10 @@
16 * zlib.h must be included before this header file. 16 * zlib.h must be included before this header file.
17 */ 17 */
18 18
19#ifdef __cplusplus
20extern "C" {
21#endif
22
19ZEXTERN int ZEXPORT inflateBack9 OF((z_stream FAR *strm, 23ZEXTERN int ZEXPORT inflateBack9 OF((z_stream FAR *strm,
20 in_func in, void FAR *in_desc, 24 in_func in, void FAR *in_desc,
21 out_func out, void FAR *out_desc)); 25 out_func out, void FAR *out_desc));
@@ -27,3 +31,7 @@ ZEXTERN int ZEXPORT inflateBack9Init_ OF((z_stream FAR *strm,
27#define inflateBack9Init(strm, window) \ 31#define inflateBack9Init(strm, window) \
28 inflateBack9Init_((strm), (window), \ 32 inflateBack9Init_((strm), (window), \
29 ZLIB_VERSION, sizeof(z_stream)) 33 ZLIB_VERSION, sizeof(z_stream))
34
35#ifdef __cplusplus
36}
37#endif
diff --git a/contrib/infback9/inftree9.c b/contrib/infback9/inftree9.c
index 29bef6a..ac4575c 100644
--- a/contrib/infback9/inftree9.c
+++ b/contrib/infback9/inftree9.c
@@ -1,5 +1,5 @@
1/* inftree9.c -- generate Huffman trees for efficient decoding 1/* inftree9.c -- generate Huffman trees for efficient decoding
2 * Copyright (C) 1995-2003 Mark Adler 2 * Copyright (C) 1995-2005 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
@@ -9,7 +9,7 @@
9#define MAXBITS 15 9#define MAXBITS 15
10 10
11const char inflate9_copyright[] = 11const char inflate9_copyright[] =
12 " inflate9 1.2.2.2 Copyright 1995-2004 Mark Adler "; 12 " inflate9 1.2.2.3 Copyright 1995-2005 Mark Adler ";
13/* 13/*
14 If you use the zlib library in a product, an acknowledgment is welcome 14 If you use the zlib library in a product, an acknowledgment is welcome
15 in the documentation of your product. If for some reason you cannot 15 in the documentation of your product. If for some reason you cannot
@@ -64,7 +64,7 @@ unsigned short FAR *work;
64 static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 64 static const unsigned short lext[31] = { /* Length codes 257..285 extra */
65 128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129, 65 128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129,
66 130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132, 66 130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132,
67 133, 133, 133, 133, 144, 72, 199}; 67 133, 133, 133, 133, 144, 66, 71};
68 static const unsigned short dbase[32] = { /* Distance codes 0..31 base */ 68 static const unsigned short dbase[32] = { /* Distance codes 0..31 base */
69 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 69 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49,
70 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 70 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073,
diff --git a/contrib/masm686/match.asm b/contrib/masm686/match.asm
index 2287804..4b03a71 100644
--- a/contrib/masm686/match.asm
+++ b/contrib/masm686/match.asm
@@ -1,408 +1,413 @@
1 1
2; match.asm -- Pentium-Pro optimized version of longest_match() 2; match.asm -- Pentium-Pro optimized version of longest_match()
3; 3;
4; Updated for zlib 1.1.3 and converted to MASM 6.1x 4; Updated for zlib 1.1.3 and converted to MASM 6.1x
5; Copyright (C) 2000 Dan Higdon <hdan@kinesoft.com> 5; Copyright (C) 2000 Dan Higdon <hdan@kinesoft.com>
6; and Chuck Walbourn <chuckw@kinesoft.com> 6; and Chuck Walbourn <chuckw@kinesoft.com>
7; Corrections by Cosmin Truta <cosmint@cs.ubbcluj.ro> 7; Corrections by Cosmin Truta <cosmint@cs.ubbcluj.ro>
8; 8;
9; This is free software; you can redistribute it and/or modify it 9; This is free software; you can redistribute it and/or modify it
10; under the terms of the GNU General Public License. 10; under the terms of the GNU General Public License.
11 11
12; Based on match.S 12; Based on match.S
13; Written for zlib 1.1.2 13; Written for zlib 1.1.2
14; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com> 14; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
15 15;
16 .686P 16; Modified by Gilles Vollant (2005) for add gzhead and gzindex
17 .MODEL FLAT 17
18 18 .686P
19;=========================================================================== 19 .MODEL FLAT
20; EQUATES 20
21;=========================================================================== 21;===========================================================================
22 22; EQUATES
23MAX_MATCH EQU 258 23;===========================================================================
24MIN_MATCH EQU 3 24
25MIN_LOOKAHEAD EQU (MAX_MATCH + MIN_MATCH + 1) 25MAX_MATCH EQU 258
26MAX_MATCH_8 EQU ((MAX_MATCH + 7) AND (NOT 7)) 26MIN_MATCH EQU 3
27 27MIN_LOOKAHEAD EQU (MAX_MATCH + MIN_MATCH + 1)
28;=========================================================================== 28MAX_MATCH_8 EQU ((MAX_MATCH + 7) AND (NOT 7))
29; STRUCTURES 29
30;=========================================================================== 30;===========================================================================
31 31; STRUCTURES
32; This STRUCT assumes a 4-byte alignment 32;===========================================================================
33 33
34DEFLATE_STATE STRUCT 34; This STRUCT assumes a 4-byte alignment
35ds_strm dd ? 35
36ds_status dd ? 36DEFLATE_STATE STRUCT
37ds_pending_buf dd ? 37ds_strm dd ?
38ds_pending_buf_size dd ? 38ds_status dd ?
39ds_pending_out dd ? 39ds_pending_buf dd ?
40ds_pending dd ? 40ds_pending_buf_size dd ?
41ds_wrap dd ? 41ds_pending_out dd ?
42ds_data_type db ? 42ds_pending dd ?
43ds_method db ? 43ds_wrap dd ?
44 db ? ; padding 44; gzhead and gzindex are added in zlib 1.2.2.2 (see deflate.h)
45 db ? ; padding 45ds_gzhead dd ?
46ds_last_flush dd ? 46ds_gzindex dd ?
47ds_w_size dd ? ; used 47ds_data_type db ?
48ds_w_bits dd ? 48ds_method db ?
49ds_w_mask dd ? ; used 49 db ? ; padding
50ds_window dd ? ; used 50 db ? ; padding
51ds_window_size dd ? 51ds_last_flush dd ?
52ds_prev dd ? ; used 52ds_w_size dd ? ; used
53ds_head dd ? 53ds_w_bits dd ?
54ds_ins_h dd ? 54ds_w_mask dd ? ; used
55ds_hash_size dd ? 55ds_window dd ? ; used
56ds_hash_bits dd ? 56ds_window_size dd ?
57ds_hash_mask dd ? 57ds_prev dd ? ; used
58ds_hash_shift dd ? 58ds_head dd ?
59ds_block_start dd ? 59ds_ins_h dd ?
60ds_match_length dd ? ; used 60ds_hash_size dd ?
61ds_prev_match dd ? ; used 61ds_hash_bits dd ?
62ds_match_available dd ? 62ds_hash_mask dd ?
63ds_strstart dd ? ; used 63ds_hash_shift dd ?
64ds_match_start dd ? ; used 64ds_block_start dd ?
65ds_lookahead dd ? ; used 65ds_match_length dd ? ; used
66ds_prev_length dd ? ; used 66ds_prev_match dd ? ; used
67ds_max_chain_length dd ? ; used 67ds_match_available dd ?
68ds_max_laxy_match dd ? 68ds_strstart dd ? ; used
69ds_level dd ? 69ds_match_start dd ? ; used
70ds_strategy dd ? 70ds_lookahead dd ? ; used
71ds_good_match dd ? ; used 71ds_prev_length dd ? ; used
72ds_nice_match dd ? ; used 72ds_max_chain_length dd ? ; used
73 73ds_max_laxy_match dd ?
74; Don't need anymore of the struct for match 74ds_level dd ?
75DEFLATE_STATE ENDS 75ds_strategy dd ?
76 76ds_good_match dd ? ; used
77;=========================================================================== 77ds_nice_match dd ? ; used
78; CODE 78
79;=========================================================================== 79; Don't need anymore of the struct for match
80_TEXT SEGMENT 80DEFLATE_STATE ENDS
81 81
82;--------------------------------------------------------------------------- 82;===========================================================================
83; match_init 83; CODE
84;--------------------------------------------------------------------------- 84;===========================================================================
85 ALIGN 4 85_TEXT SEGMENT
86PUBLIC _match_init 86
87_match_init PROC 87;---------------------------------------------------------------------------
88 ; no initialization needed 88; match_init
89 ret 89;---------------------------------------------------------------------------
90_match_init ENDP 90 ALIGN 4
91 91PUBLIC _match_init
92;--------------------------------------------------------------------------- 92_match_init PROC
93; uInt longest_match(deflate_state *deflatestate, IPos curmatch) 93 ; no initialization needed
94;--------------------------------------------------------------------------- 94 ret
95 ALIGN 4 95_match_init ENDP
96 96
97PUBLIC _longest_match 97;---------------------------------------------------------------------------
98_longest_match PROC 98; uInt longest_match(deflate_state *deflatestate, IPos curmatch)
99 99;---------------------------------------------------------------------------
100; Since this code uses EBP for a scratch register, the stack frame must 100 ALIGN 4
101; be manually constructed and referenced relative to the ESP register. 101
102 102PUBLIC _longest_match
103; Stack image 103_longest_match PROC
104; Variables 104
105chainlenwmask = 0 ; high word: current chain len 105; Since this code uses EBP for a scratch register, the stack frame must
106 ; low word: s->wmask 106; be manually constructed and referenced relative to the ESP register.
107window = 4 ; local copy of s->window 107
108windowbestlen = 8 ; s->window + bestlen 108; Stack image
109scanend = 12 ; last two bytes of string 109; Variables
110scanstart = 16 ; first two bytes of string 110chainlenwmask = 0 ; high word: current chain len
111scanalign = 20 ; dword-misalignment of string 111 ; low word: s->wmask
112nicematch = 24 ; a good enough match size 112window = 4 ; local copy of s->window
113bestlen = 28 ; size of best match so far 113windowbestlen = 8 ; s->window + bestlen
114scan = 32 ; ptr to string wanting match 114scanend = 12 ; last two bytes of string
115varsize = 36 ; number of bytes (also offset to last saved register) 115scanstart = 16 ; first two bytes of string
116 116scanalign = 20 ; dword-misalignment of string
117; Saved Registers (actually pushed into place) 117nicematch = 24 ; a good enough match size
118ebx_save = 36 118bestlen = 28 ; size of best match so far
119edi_save = 40 119scan = 32 ; ptr to string wanting match
120esi_save = 44 120varsize = 36 ; number of bytes (also offset to last saved register)
121ebp_save = 48 121
122 122; Saved Registers (actually pushed into place)
123; Parameters 123ebx_save = 36
124retaddr = 52 124edi_save = 40
125deflatestate = 56 125esi_save = 44
126curmatch = 60 126ebp_save = 48
127 127
128; Save registers that the compiler may be using 128; Parameters
129 push ebp 129retaddr = 52
130 push edi 130deflatestate = 56
131 push esi 131curmatch = 60
132 push ebx 132
133 133; Save registers that the compiler may be using
134; Allocate local variable space 134 push ebp
135 sub esp,varsize 135 push edi
136 136 push esi
137; Retrieve the function arguments. ecx will hold cur_match 137 push ebx
138; throughout the entire function. edx will hold the pointer to the 138
139; deflate_state structure during the function's setup (before 139; Allocate local variable space
140; entering the main loop). 140 sub esp,varsize
141 141
142 mov edx, [esp+deflatestate] 142; Retrieve the function arguments. ecx will hold cur_match
143ASSUME edx:PTR DEFLATE_STATE 143; throughout the entire function. edx will hold the pointer to the
144 144; deflate_state structure during the function's setup (before
145 mov ecx, [esp+curmatch] 145; entering the main loop).
146 146
147; uInt wmask = s->w_mask; 147 mov edx, [esp+deflatestate]
148; unsigned chain_length = s->max_chain_length; 148ASSUME edx:PTR DEFLATE_STATE
149; if (s->prev_length >= s->good_match) { 149
150; chain_length >>= 2; 150 mov ecx, [esp+curmatch]
151; } 151
152 152; uInt wmask = s->w_mask;
153 mov eax, [edx].ds_prev_length 153; unsigned chain_length = s->max_chain_length;
154 mov ebx, [edx].ds_good_match 154; if (s->prev_length >= s->good_match) {
155 cmp eax, ebx 155; chain_length >>= 2;
156 mov eax, [edx].ds_w_mask 156; }
157 mov ebx, [edx].ds_max_chain_length 157
158 jl SHORT LastMatchGood 158 mov eax, [edx].ds_prev_length
159 shr ebx, 2 159 mov ebx, [edx].ds_good_match
160LastMatchGood: 160 cmp eax, ebx
161 161 mov eax, [edx].ds_w_mask
162; chainlen is decremented once beforehand so that the function can 162 mov ebx, [edx].ds_max_chain_length
163; use the sign flag instead of the zero flag for the exit test. 163 jl SHORT LastMatchGood
164; It is then shifted into the high word, to make room for the wmask 164 shr ebx, 2
165; value, which it will always accompany. 165LastMatchGood:
166 166
167 dec ebx 167; chainlen is decremented once beforehand so that the function can
168 shl ebx, 16 168; use the sign flag instead of the zero flag for the exit test.
169 or ebx, eax 169; It is then shifted into the high word, to make room for the wmask
170 mov [esp+chainlenwmask], ebx 170; value, which it will always accompany.
171 171
172; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; 172 dec ebx
173 173 shl ebx, 16
174 mov eax, [edx].ds_nice_match 174 or ebx, eax
175 mov ebx, [edx].ds_lookahead 175 mov [esp+chainlenwmask], ebx
176 cmp ebx, eax 176
177 jl SHORT LookaheadLess 177; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
178 mov ebx, eax 178
179LookaheadLess: 179 mov eax, [edx].ds_nice_match
180 mov [esp+nicematch], ebx 180 mov ebx, [edx].ds_lookahead
181 181 cmp ebx, eax
182;/* register Bytef *scan = s->window + s->strstart; */ 182 jl SHORT LookaheadLess
183 183 mov ebx, eax
184 mov esi, [edx].ds_window 184LookaheadLess:
185 mov [esp+window], esi 185 mov [esp+nicematch], ebx
186 mov ebp, [edx].ds_strstart 186
187 lea edi, [esi+ebp] 187;/* register Bytef *scan = s->window + s->strstart; */
188 mov [esp+scan],edi 188
189 189 mov esi, [edx].ds_window
190;/* Determine how many bytes the scan ptr is off from being */ 190 mov [esp+window], esi
191;/* dword-aligned. */ 191 mov ebp, [edx].ds_strstart
192 192 lea edi, [esi+ebp]
193 mov eax, edi 193 mov [esp+scan],edi
194 neg eax 194
195 and eax, 3 195;/* Determine how many bytes the scan ptr is off from being */
196 mov [esp+scanalign], eax 196;/* dword-aligned. */
197 197
198;/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */ 198 mov eax, edi
199;/* s->strstart - (IPos)MAX_DIST(s) : NIL; */ 199 neg eax
200 200 and eax, 3
201 mov eax, [edx].ds_w_size 201 mov [esp+scanalign], eax
202 sub eax, MIN_LOOKAHEAD 202
203 sub ebp, eax 203;/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
204 jg SHORT LimitPositive 204;/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
205 xor ebp, ebp 205
206LimitPositive: 206 mov eax, [edx].ds_w_size
207 207 sub eax, MIN_LOOKAHEAD
208;/* int best_len = s->prev_length; */ 208 sub ebp, eax
209 209 jg SHORT LimitPositive
210 mov eax, [edx].ds_prev_length 210 xor ebp, ebp
211 mov [esp+bestlen], eax 211LimitPositive:
212 212
213;/* Store the sum of s->window + best_len in %esi locally, and in %esi. */ 213;/* int best_len = s->prev_length; */
214 214
215 add esi, eax 215 mov eax, [edx].ds_prev_length
216 mov [esp+windowbestlen], esi 216 mov [esp+bestlen], eax
217 217
218;/* register ush scan_start = *(ushf*)scan; */ 218;/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
219;/* register ush scan_end = *(ushf*)(scan+best_len-1); */ 219
220;/* Posf *prev = s->prev; */ 220 add esi, eax
221 221 mov [esp+windowbestlen], esi
222 movzx ebx, WORD PTR[edi] 222
223 mov [esp+scanstart], ebx 223;/* register ush scan_start = *(ushf*)scan; */
224 movzx ebx, WORD PTR[eax+edi-1] 224;/* register ush scan_end = *(ushf*)(scan+best_len-1); */
225 mov [esp+scanend], ebx 225;/* Posf *prev = s->prev; */
226 mov edi, [edx].ds_prev 226
227 227 movzx ebx, WORD PTR[edi]
228;/* Jump into the main loop. */ 228 mov [esp+scanstart], ebx
229 229 movzx ebx, WORD PTR[eax+edi-1]
230 mov edx, [esp+chainlenwmask] 230 mov [esp+scanend], ebx
231 jmp SHORT LoopEntry 231 mov edi, [edx].ds_prev
232 232
233;/* do { 233;/* Jump into the main loop. */
234; * match = s->window + cur_match; 234
235; * if (*(ushf*)(match+best_len-1) != scan_end || 235 mov edx, [esp+chainlenwmask]
236; * *(ushf*)match != scan_start) continue; 236 jmp SHORT LoopEntry
237; * [...] 237
238; * } while ((cur_match = prev[cur_match & wmask]) > limit 238;/* do {
239; * && --chain_length != 0); 239; * match = s->window + cur_match;
240; * 240; * if (*(ushf*)(match+best_len-1) != scan_end ||
241; * Here is the inner loop of the function. The function will spend the 241; * *(ushf*)match != scan_start) continue;
242; * majority of its time in this loop, and majority of that time will 242; * [...]
243; * be spent in the first ten instructions. 243; * } while ((cur_match = prev[cur_match & wmask]) > limit
244; * 244; * && --chain_length != 0);
245; * Within this loop: 245; *
246; * %ebx = scanend 246; * Here is the inner loop of the function. The function will spend the
247; * %ecx = curmatch 247; * majority of its time in this loop, and majority of that time will
248; * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) 248; * be spent in the first ten instructions.
249; * %esi = windowbestlen - i.e., (window + bestlen) 249; *
250; * %edi = prev 250; * Within this loop:
251; * %ebp = limit 251; * %ebx = scanend
252; */ 252; * %ecx = curmatch
253 253; * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
254 ALIGN 4 254; * %esi = windowbestlen - i.e., (window + bestlen)
255LookupLoop: 255; * %edi = prev
256 and ecx, edx 256; * %ebp = limit
257 movzx ecx, WORD PTR[edi+ecx*2] 257; */
258 cmp ecx, ebp 258
259 jbe LeaveNow 259 ALIGN 4
260 sub edx, 000010000H 260LookupLoop:
261 js LeaveNow 261 and ecx, edx
262 262 movzx ecx, WORD PTR[edi+ecx*2]
263LoopEntry: 263 cmp ecx, ebp
264 movzx eax, WORD PTR[esi+ecx-1] 264 jbe LeaveNow
265 cmp eax, ebx 265 sub edx, 000010000H
266 jnz SHORT LookupLoop 266 js LeaveNow
267 267
268 mov eax, [esp+window] 268LoopEntry:
269 movzx eax, WORD PTR[eax+ecx] 269 movzx eax, WORD PTR[esi+ecx-1]
270 cmp eax, [esp+scanstart] 270 cmp eax, ebx
271 jnz SHORT LookupLoop 271 jnz SHORT LookupLoop
272 272
273;/* Store the current value of chainlen. */ 273 mov eax, [esp+window]
274 274 movzx eax, WORD PTR[eax+ecx]
275 mov [esp+chainlenwmask], edx 275 cmp eax, [esp+scanstart]
276 276 jnz SHORT LookupLoop
277;/* Point %edi to the string under scrutiny, and %esi to the string we */ 277
278;/* are hoping to match it up with. In actuality, %esi and %edi are */ 278;/* Store the current value of chainlen. */
279;/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */ 279
280;/* initialized to -(MAX_MATCH_8 - scanalign). */ 280 mov [esp+chainlenwmask], edx
281 281
282 mov esi, [esp+window] 282;/* Point %edi to the string under scrutiny, and %esi to the string we */
283 mov edi, [esp+scan] 283;/* are hoping to match it up with. In actuality, %esi and %edi are */
284 add esi, ecx 284;/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
285 mov eax, [esp+scanalign] 285;/* initialized to -(MAX_MATCH_8 - scanalign). */
286 mov edx, -MAX_MATCH_8 286
287 lea edi, [edi+eax+MAX_MATCH_8] 287 mov esi, [esp+window]
288 lea esi, [esi+eax+MAX_MATCH_8] 288 mov edi, [esp+scan]
289 289 add esi, ecx
290;/* Test the strings for equality, 8 bytes at a time. At the end, 290 mov eax, [esp+scanalign]
291; * adjust %edx so that it is offset to the exact byte that mismatched. 291 mov edx, -MAX_MATCH_8
292; * 292 lea edi, [edi+eax+MAX_MATCH_8]
293; * We already know at this point that the first three bytes of the 293 lea esi, [esi+eax+MAX_MATCH_8]
294; * strings match each other, and they can be safely passed over before 294
295; * starting the compare loop. So what this code does is skip over 0-3 295;/* Test the strings for equality, 8 bytes at a time. At the end,
296; * bytes, as much as necessary in order to dword-align the %edi 296; * adjust %edx so that it is offset to the exact byte that mismatched.
297; * pointer. (%esi will still be misaligned three times out of four.) 297; *
298; * 298; * We already know at this point that the first three bytes of the
299; * It should be confessed that this loop usually does not represent 299; * strings match each other, and they can be safely passed over before
300; * much of the total running time. Replacing it with a more 300; * starting the compare loop. So what this code does is skip over 0-3
301; * straightforward "rep cmpsb" would not drastically degrade 301; * bytes, as much as necessary in order to dword-align the %edi
302; * performance. 302; * pointer. (%esi will still be misaligned three times out of four.)
303; */ 303; *
304 304; * It should be confessed that this loop usually does not represent
305LoopCmps: 305; * much of the total running time. Replacing it with a more
306 mov eax, DWORD PTR[esi+edx] 306; * straightforward "rep cmpsb" would not drastically degrade
307 xor eax, DWORD PTR[edi+edx] 307; * performance.
308 jnz SHORT LeaveLoopCmps 308; */
309 309
310 mov eax, DWORD PTR[esi+edx+4] 310LoopCmps:
311 xor eax, DWORD PTR[edi+edx+4] 311 mov eax, DWORD PTR[esi+edx]
312 jnz SHORT LeaveLoopCmps4 312 xor eax, DWORD PTR[edi+edx]
313 313 jnz SHORT LeaveLoopCmps
314 add edx, 8 314
315 jnz SHORT LoopCmps 315 mov eax, DWORD PTR[esi+edx+4]
316 jmp LenMaximum 316 xor eax, DWORD PTR[edi+edx+4]
317 ALIGN 4 317 jnz SHORT LeaveLoopCmps4
318 318
319LeaveLoopCmps4: 319 add edx, 8
320 add edx, 4 320 jnz SHORT LoopCmps
321 321 jmp LenMaximum
322LeaveLoopCmps: 322 ALIGN 4
323 test eax, 00000FFFFH 323
324 jnz SHORT LenLower 324LeaveLoopCmps4:
325 325 add edx, 4
326 add edx, 2 326
327 shr eax, 16 327LeaveLoopCmps:
328 328 test eax, 00000FFFFH
329LenLower: 329 jnz SHORT LenLower
330 sub al, 1 330
331 adc edx, 0 331 add edx, 2
332 332 shr eax, 16
333;/* Calculate the length of the match. If it is longer than MAX_MATCH, */ 333
334;/* then automatically accept it as the best possible match and leave. */ 334LenLower:
335 335 sub al, 1
336 lea eax, [edi+edx] 336 adc edx, 0
337 mov edi, [esp+scan] 337
338 sub eax, edi 338;/* Calculate the length of the match. If it is longer than MAX_MATCH, */
339 cmp eax, MAX_MATCH 339;/* then automatically accept it as the best possible match and leave. */
340 jge SHORT LenMaximum 340
341 341 lea eax, [edi+edx]
342;/* If the length of the match is not longer than the best match we */ 342 mov edi, [esp+scan]
343;/* have so far, then forget it and return to the lookup loop. */ 343 sub eax, edi
344 344 cmp eax, MAX_MATCH
345 mov edx, [esp+deflatestate] 345 jge SHORT LenMaximum
346 mov ebx, [esp+bestlen] 346
347 cmp eax, ebx 347;/* If the length of the match is not longer than the best match we */
348 jg SHORT LongerMatch 348;/* have so far, then forget it and return to the lookup loop. */
349 mov esi, [esp+windowbestlen] 349
350 mov edi, [edx].ds_prev 350 mov edx, [esp+deflatestate]
351 mov ebx, [esp+scanend] 351 mov ebx, [esp+bestlen]
352 mov edx, [esp+chainlenwmask] 352 cmp eax, ebx
353 jmp LookupLoop 353 jg SHORT LongerMatch
354 ALIGN 4 354 mov esi, [esp+windowbestlen]
355 355 mov edi, [edx].ds_prev
356;/* s->match_start = cur_match; */ 356 mov ebx, [esp+scanend]
357;/* best_len = len; */ 357 mov edx, [esp+chainlenwmask]
358;/* if (len >= nice_match) break; */ 358 jmp LookupLoop
359;/* scan_end = *(ushf*)(scan+best_len-1); */ 359 ALIGN 4
360 360
361LongerMatch: 361;/* s->match_start = cur_match; */
362 mov ebx, [esp+nicematch] 362;/* best_len = len; */
363 mov [esp+bestlen], eax 363;/* if (len >= nice_match) break; */
364 mov [edx].ds_match_start, ecx 364;/* scan_end = *(ushf*)(scan+best_len-1); */
365 cmp eax, ebx 365
366 jge SHORT LeaveNow 366LongerMatch:
367 mov esi, [esp+window] 367 mov ebx, [esp+nicematch]
368 add esi, eax 368 mov [esp+bestlen], eax
369 mov [esp+windowbestlen], esi 369 mov [edx].ds_match_start, ecx
370 movzx ebx, WORD PTR[edi+eax-1] 370 cmp eax, ebx
371 mov edi, [edx].ds_prev 371 jge SHORT LeaveNow
372 mov [esp+scanend], ebx 372 mov esi, [esp+window]
373 mov edx, [esp+chainlenwmask] 373 add esi, eax
374 jmp LookupLoop 374 mov [esp+windowbestlen], esi
375 ALIGN 4 375 movzx ebx, WORD PTR[edi+eax-1]
376 376 mov edi, [edx].ds_prev
377;/* Accept the current string, with the maximum possible length. */ 377 mov [esp+scanend], ebx
378 378 mov edx, [esp+chainlenwmask]
379LenMaximum: 379 jmp LookupLoop
380 mov edx, [esp+deflatestate] 380 ALIGN 4
381 mov DWORD PTR[esp+bestlen], MAX_MATCH 381
382 mov [edx].ds_match_start, ecx 382;/* Accept the current string, with the maximum possible length. */
383 383
384;/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */ 384LenMaximum:
385;/* return s->lookahead; */ 385 mov edx, [esp+deflatestate]
386 386 mov DWORD PTR[esp+bestlen], MAX_MATCH
387LeaveNow: 387 mov [edx].ds_match_start, ecx
388 mov edx, [esp+deflatestate] 388
389 mov ebx, [esp+bestlen] 389;/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
390 mov eax, [edx].ds_lookahead 390;/* return s->lookahead; */
391 cmp ebx, eax 391
392 jg SHORT LookaheadRet 392LeaveNow:
393 mov eax, ebx 393 mov edx, [esp+deflatestate]
394LookaheadRet: 394 mov ebx, [esp+bestlen]
395 395 mov eax, [edx].ds_lookahead
396; Restore the stack and return from whence we came. 396 cmp ebx, eax
397 397 jg SHORT LookaheadRet
398 add esp, varsize 398 mov eax, ebx
399 pop ebx 399LookaheadRet:
400 pop esi 400
401 pop edi 401; Restore the stack and return from whence we came.
402 pop ebp 402
403 ret 403 add esp, varsize
404 404 pop ebx
405_longest_match ENDP 405 pop esi
406 406 pop edi
407_TEXT ENDS 407 pop ebp
408END 408 ret
409
410_longest_match ENDP
411
412_TEXT ENDS
413END
diff --git a/contrib/masmx64/bld_ml64.bat b/contrib/masmx64/bld_ml64.bat
new file mode 100644
index 0000000..8f9343d
--- /dev/null
+++ b/contrib/masmx64/bld_ml64.bat
@@ -0,0 +1,2 @@
1ml64.exe /Flinffasx64 /c /Zi inffasx64.asm
2ml64.exe /Flgvmat64 /c /Zi gvmat64.asm
diff --git a/contrib/masmx64/gvmat64.asm b/contrib/masmx64/gvmat64.asm
new file mode 100644
index 0000000..cee2145
--- /dev/null
+++ b/contrib/masmx64/gvmat64.asm
@@ -0,0 +1,464 @@
1;uInt longest_match_x64(
2; deflate_state *s,
3; IPos cur_match); /* current match */
4
5; gvmat64.asm -- Asm portion of the optimized longest_match for 32 bits x86
6; Copyright (C) 1995-2005 Jean-loup Gailly, Brian Raiter and Gilles Vollant.
7; File written by Gilles Vollant, by modifiying the longest_match
8; from Jean-loup Gailly in deflate.c
9; and modifying asm686 with masm, optimised assembly code from Brian Raiter,
10; written 1998
11; http://www.zlib.net
12; http://www.winimage.com/zLibDll
13; http://www.muppetlabs.com/~breadbox/software/assembly.html
14;
15; to compile this file, I use option
16; ml64.exe /Flgvmat64 /c /Zi gvmat64.asm
17; with Microsoft Macro Assembler (x64) for AMD64
18;
19; ml64.exe is given with Visual Studio 2005, Windows 2003 server DDK
20;
21; (you can get Windows 2003 server DDK with ml64 and cl for AMD64 from
22; http://www.microsoft.com/whdc/devtools/ddk/default.mspx for low price)
23;
24; Be carrefull to adapt zlib1222add below to your version of zLib
25
26
27;uInt longest_match(s, cur_match)
28; deflate_state *s;
29; IPos cur_match; /* current match */
30.code
31longest_match PROC
32
33
34;LocalVarsSize equ 88
35 LocalVarsSize equ 72
36
37; register used : rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12
38; free register : r14,r15
39; register can be saved : rsp
40
41 chainlenwmask equ rsp + 8 - LocalVarsSize ; high word: current chain len
42 ; low word: s->wmask
43;window equ rsp + xx - LocalVarsSize ; local copy of s->window ; stored in r10
44;windowbestlen equ rsp + xx - LocalVarsSize ; s->window + bestlen , use r10+r11
45;scanstart equ rsp + xx - LocalVarsSize ; first two bytes of string ; stored in r12w
46;scanend equ rsp + xx - LocalVarsSize ; last two bytes of string use ebx
47;scanalign equ rsp + xx - LocalVarsSize ; dword-misalignment of string r13
48;bestlen equ rsp + xx - LocalVarsSize ; size of best match so far -> r11d
49;scan equ rsp + xx - LocalVarsSize ; ptr to string wanting match -> r9
50 nicematch equ rsp + 16 - LocalVarsSize ; a good enough match size -> r14
51
52save_rdi equ rsp + 24 - LocalVarsSize
53save_rsi equ rsp + 32 - LocalVarsSize
54save_rbx equ rsp + 40 - LocalVarsSize
55save_rbp equ rsp + 48 - LocalVarsSize
56save_r12 equ rsp + 56 - LocalVarsSize
57save_r13 equ rsp + 64 - LocalVarsSize
58;save_r14 equ rsp + 72 - LocalVarsSize
59;save_r15 equ rsp + 80 - LocalVarsSize
60
61
62
63; all the +4 offsets are due to the addition of pending_buf_size (in zlib
64; in the deflate_state structure since the asm code was first written
65; (if you compile with zlib 1.0.4 or older, remove the +4).
66; Note : these value are good with a 8 bytes boundary pack structure
67
68
69 MAX_MATCH equ 258
70 MIN_MATCH equ 3
71 MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1)
72
73
74;;; Offsets for fields in the deflate_state structure. These numbers
75;;; are calculated from the definition of deflate_state, with the
76;;; assumption that the compiler will dword-align the fields. (Thus,
77;;; changing the definition of deflate_state could easily cause this
78;;; program to crash horribly, without so much as a warning at
79;;; compile time. Sigh.)
80
81; all the +zlib1222add offsets are due to the addition of fields
82; in zlib in the deflate_state structure since the asm code was first written
83; (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
84; (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
85; if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
86
87zlib1222add equ 8
88
89dsWSize equ 56+zlib1222add+(zlib1222add/2)
90dsWMask equ 64+zlib1222add+(zlib1222add/2)
91dsWindow equ 72+zlib1222add
92dsPrev equ 88+zlib1222add
93dsMatchLen equ 128+zlib1222add
94dsPrevMatch equ 132+zlib1222add
95dsStrStart equ 140+zlib1222add
96dsMatchStart equ 144+zlib1222add
97dsLookahead equ 148+zlib1222add
98dsPrevLen equ 152+zlib1222add
99dsMaxChainLen equ 156+zlib1222add
100dsGoodMatch equ 172+zlib1222add
101dsNiceMatch equ 176+zlib1222add
102
103
104; parameter 1 in r8(deflate state s), param 2 in rdx (cur match)
105
106; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and
107; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp
108;
109; All registers must be preserved across the call, except for
110; rax, rcx, rdx, r8, r-9, r10, and r11, which are scratch.
111
112
113
114;;; Save registers that the compiler may be using, and adjust esp to
115;;; make room for our stack frame.
116
117
118;;; Retrieve the function arguments. r8d will hold cur_match
119;;; throughout the entire function. edx will hold the pointer to the
120;;; deflate_state structure during the function's setup (before
121;;; entering the main loop.
122
123; parameter 1 in rcx (deflate_state* s), param 2 in edx -> r8 (cur match)
124
125; this clear high 32 bits of r8, which can be garbage in both r8 and rdx
126
127
128 mov [save_rdi],rdi
129 mov [save_rsi],rsi
130 mov [save_rbx],rbx
131 mov [save_rbp],rbp
132 mov r8d,edx
133 mov [save_r12],r12
134 mov [save_r13],r13
135; mov [save_r14],r14
136; mov [save_r15],r15
137
138
139;;; uInt wmask = s->w_mask;
140;;; unsigned chain_length = s->max_chain_length;
141;;; if (s->prev_length >= s->good_match) {
142;;; chain_length >>= 2;
143;;; }
144
145 mov edi, [rcx + dsPrevLen]
146 mov esi, [rcx + dsGoodMatch]
147 mov eax, [rcx + dsWMask]
148 mov ebx, [rcx + dsMaxChainLen]
149 cmp edi, esi
150 jl LastMatchGood
151 shr ebx, 2
152LastMatchGood:
153
154;;; chainlen is decremented once beforehand so that the function can
155;;; use the sign flag instead of the zero flag for the exit test.
156;;; It is then shifted into the high word, to make room for the wmask
157;;; value, which it will always accompany.
158
159 dec ebx
160 shl ebx, 16
161 or ebx, eax
162 mov [chainlenwmask], ebx
163
164;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
165
166 mov eax, [rcx + dsNiceMatch]
167 mov r10d, [rcx + dsLookahead]
168 cmp r10d, eax
169 cmovnl r10d, eax
170 mov [nicematch],r10d
171LookaheadLess:
172
173;;; register Bytef *scan = s->window + s->strstart;
174
175 mov r10, [rcx + dsWindow]
176 mov ebp, [rcx + dsStrStart]
177 lea r13, [r10 + rbp]
178
179;;; Determine how many bytes the scan ptr is off from being
180;;; dword-aligned.
181
182 mov r9,r13
183 neg r13
184 and r13,3
185
186;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
187;;; s->strstart - (IPos)MAX_DIST(s) : NIL;
188
189 mov eax, [rcx + dsWSize]
190 sub eax, MIN_LOOKAHEAD
191 xor edi,edi
192 sub ebp, eax
193
194 mov r11d, [rcx + dsPrevLen]
195
196 cmovng ebp,edi
197
198;;; int best_len = s->prev_length;
199
200
201;;; Store the sum of s->window + best_len in esi locally, and in esi.
202
203 lea rsi,[r10+r11]
204
205;;; register ush scan_start = *(ushf*)scan;
206;;; register ush scan_end = *(ushf*)(scan+best_len-1);
207;;; Posf *prev = s->prev;
208
209 movzx r12d,word ptr [r9]
210 movzx ebx, word ptr [r9 + r11 - 1]
211 mov rdi, [rcx + dsPrev]
212
213;;; Jump into the main loop.
214
215 mov edx, [chainlenwmask]
216
217 cmp bx,word ptr [rsi + r8 - 1]
218 jz LookupLoopIsZero
219
220LookupLoop1:
221 and r8d, edx
222
223 movzx r8d, word ptr [rdi + r8*2]
224 cmp r8d, ebp
225 jbe LeaveNow
226 sub edx, 00010000h
227 js LeaveNow
228
229LoopEntry1:
230 cmp bx,word ptr [rsi + r8 - 1]
231 jz LookupLoopIsZero
232
233LookupLoop2:
234 and r8d, edx
235
236 movzx r8d, word ptr [rdi + r8*2]
237 cmp r8d, ebp
238 jbe LeaveNow
239 sub edx, 00010000h
240 js LeaveNow
241
242LoopEntry2:
243 cmp bx,word ptr [rsi + r8 - 1]
244 jz LookupLoopIsZero
245
246LookupLoop4:
247 and r8d, edx
248
249 movzx r8d, word ptr [rdi + r8*2]
250 cmp r8d, ebp
251 jbe LeaveNow
252 sub edx, 00010000h
253 js LeaveNow
254
255LoopEntry4:
256
257 cmp bx,word ptr [rsi + r8 - 1]
258 jnz LookupLoop1
259 jmp LookupLoopIsZero
260
261
262;;; do {
263;;; match = s->window + cur_match;
264;;; if (*(ushf*)(match+best_len-1) != scan_end ||
265;;; *(ushf*)match != scan_start) continue;
266;;; [...]
267;;; } while ((cur_match = prev[cur_match & wmask]) > limit
268;;; && --chain_length != 0);
269;;;
270;;; Here is the inner loop of the function. The function will spend the
271;;; majority of its time in this loop, and majority of that time will
272;;; be spent in the first ten instructions.
273;;;
274;;; Within this loop:
275;;; ebx = scanend
276;;; r8d = curmatch
277;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
278;;; esi = windowbestlen - i.e., (window + bestlen)
279;;; edi = prev
280;;; ebp = limit
281
282LookupLoop:
283 and r8d, edx
284
285 movzx r8d, word ptr [rdi + r8*2]
286 cmp r8d, ebp
287 jbe LeaveNow
288 sub edx, 00010000h
289 js LeaveNow
290
291LoopEntry:
292
293 cmp bx,word ptr [rsi + r8 - 1]
294 jnz LookupLoop1
295LookupLoopIsZero:
296 cmp r12w, word ptr [r10 + r8]
297 jnz LookupLoop1
298
299
300;;; Store the current value of chainlen.
301 mov [chainlenwmask], edx
302
303;;; Point edi to the string under scrutiny, and esi to the string we
304;;; are hoping to match it up with. In actuality, esi and edi are
305;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is
306;;; initialized to -(MAX_MATCH_8 - scanalign).
307
308 lea rsi,[r8+r10]
309 mov rdx, 0fffffffffffffef8h; -(MAX_MATCH_8)
310 lea rsi, [rsi + r13 + 0108h] ;MAX_MATCH_8]
311 lea rdi, [r9 + r13 + 0108h] ;MAX_MATCH_8]
312
313 prefetcht1 [rsi+rdx]
314 prefetcht1 [rdi+rdx]
315;;; Test the strings for equality, 8 bytes at a time. At the end,
316;;; adjust edx so that it is offset to the exact byte that mismatched.
317;;;
318;;; We already know at this point that the first three bytes of the
319;;; strings match each other, and they can be safely passed over before
320;;; starting the compare loop. So what this code does is skip over 0-3
321;;; bytes, as much as necessary in order to dword-align the edi
322;;; pointer. (esi will still be misaligned three times out of four.)
323;;;
324;;; It should be confessed that this loop usually does not represent
325;;; much of the total running time. Replacing it with a more
326;;; straightforward "rep cmpsb" would not drastically degrade
327;;; performance.
328
329;LoopCmps:
330; mov eax, [rsi + rdx]
331; xor eax, [rdi + rdx]
332; jnz LeaveLoopCmps
333; mov eax, [rsi + rdx + 4]
334; xor eax, [rdi + rdx + 4]
335; jnz LeaveLoopCmps4
336; add rdx, 8
337; jnz LoopCmps
338; jmp LenMaximum
339;LeaveLoopCmps4: add rdx, 4
340;LeaveLoopCmps: test eax, 0000FFFFh
341; jnz LenLower
342; add rdx, 2
343; shr eax, 16
344;LenLower: sub al, 1
345; adc rdx, 0
346
347
348LoopCmps:
349 mov rax, [rsi + rdx]
350 xor rax, [rdi + rdx]
351 jnz LeaveLoopCmps
352
353 mov rax, [rsi + rdx + 8]
354 xor rax, [rdi + rdx + 8]
355 jnz LeaveLoopCmps8
356
357
358 mov rax, [rsi + rdx + 8+8]
359 xor rax, [rdi + rdx + 8+8]
360 jnz LeaveLoopCmps16
361
362 add rdx,8+8+8
363
364 jmp short LoopCmps
365LeaveLoopCmps16: add rdx,8
366LeaveLoopCmps8: add rdx,8
367LeaveLoopCmps:
368
369 test eax, 0000FFFFh
370 jnz LenLower
371
372 test eax,0ffffffffh
373
374 jnz LenLower32
375
376 add rdx,4
377 shr rax,32
378 or ax,ax
379 jnz LenLower
380
381LenLower32:
382 shr eax,16
383 add rdx,2
384LenLower: sub al, 1
385 adc rdx, 0
386;;; Calculate the length of the match. If it is longer than MAX_MATCH,
387;;; then automatically accept it as the best possible match and leave.
388
389 lea rax, [rdi + rdx]
390 sub rax, r9
391 cmp eax, MAX_MATCH
392 jge LenMaximum
393
394;;; If the length of the match is not longer than the best match we
395;;; have so far, then forget it and return to the lookup loop.
396;///////////////////////////////////
397
398 cmp eax, r11d
399 jg LongerMatch
400
401 lea rsi,[r10+r11]
402
403 mov rdi, [rcx + dsPrev]
404 mov edx, [chainlenwmask]
405 jmp LookupLoop
406
407;;; s->match_start = cur_match;
408;;; best_len = len;
409;;; if (len >= nice_match) break;
410;;; scan_end = *(ushf*)(scan+best_len-1);
411
412LongerMatch:
413 mov r11d, eax
414 mov [rcx + dsMatchStart], r8d
415 cmp eax, [nicematch]
416 jge LeaveNow
417
418 lea rsi,[r10+rax]
419
420 movzx ebx, word ptr [r9 + rax - 1]
421 mov rdi, [rcx + dsPrev]
422 mov edx, [chainlenwmask]
423 jmp LookupLoop
424
425;;; Accept the current string, with the maximum possible length.
426
427LenMaximum:
428 mov r11d,MAX_MATCH
429 mov [rcx + dsMatchStart], r8d
430
431;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
432;;; return s->lookahead;
433
434LeaveNow:
435 mov eax, [rcx + dsLookahead]
436 cmp r11d, eax
437 cmovng eax, r11d
438
439
440;;; Restore the stack and return from whence we came.
441
442
443 mov rsi,[save_rsi]
444 mov rdi,[save_rdi]
445 mov rbx,[save_rbx]
446 mov rbp,[save_rbp]
447 mov r12,[save_r12]
448 mov r13,[save_r13]
449; mov r14,[save_r14]
450; mov r15,[save_r15]
451
452
453 ret 0
454; please don't remove this string !
455; Your can freely use gvmat32 in any free or commercial app if you don't remove the string in the binary!
456 db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998, converted to amd 64 by Gilles Vollant 2005",0dh,0ah,0
457longest_match ENDP
458
459match_init PROC
460 ret 0
461match_init ENDP
462
463
464END
diff --git a/contrib/masmx64/gvmat64.obj b/contrib/masmx64/gvmat64.obj
new file mode 100644
index 0000000..10a73fe
--- /dev/null
+++ b/contrib/masmx64/gvmat64.obj
Binary files differ
diff --git a/contrib/masmx64/inffas8664.c b/contrib/masmx64/inffas8664.c
new file mode 100644
index 0000000..3af764d
--- /dev/null
+++ b/contrib/masmx64/inffas8664.c
@@ -0,0 +1,186 @@
1/* inffas8664.c is a hand tuned assembler version of inffast.c - fast decoding
2 * version for AMD64 on Windows using Microsoft C compiler
3 *
4 * Copyright (C) 1995-2003 Mark Adler
5 * For conditions of distribution and use, see copyright notice in zlib.h
6 *
7 * Copyright (C) 2003 Chris Anderson <christop@charm.net>
8 * Please use the copyright conditions above.
9 *
10 * 2005 - Adaptation to Microsoft C Compiler for AMD64 by Gilles Vollant
11 *
12 * inffas8664.c call function inffas8664fnc in inffasx64.asm
13 * inffasx64.asm is automatically convert from AMD64 portion of inffas86.c
14 *
15 * Dec-29-2003 -- I added AMD64 inflate asm support. This version is also
16 * slightly quicker on x86 systems because, instead of using rep movsb to copy
17 * data, it uses rep movsw, which moves data in 2-byte chunks instead of single
18 * bytes. I've tested the AMD64 code on a Fedora Core 1 + the x86_64 updates
19 * from http://fedora.linux.duke.edu/fc1_x86_64
20 * which is running on an Athlon 64 3000+ / Gigabyte GA-K8VT800M system with
21 * 1GB ram. The 64-bit version is about 4% faster than the 32-bit version,
22 * when decompressing mozilla-source-1.3.tar.gz.
23 *
24 * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from
25 * the gcc -S output of zlib-1.2.0/inffast.c. Zlib-1.2.0 is in beta release at
26 * the moment. I have successfully compiled and tested this code with gcc2.96,
27 * gcc3.2, icc5.0, msvc6.0. It is very close to the speed of inffast.S
28 * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX
29 * enabled. I will attempt to merge the MMX code into this version. Newer
30 * versions of this and inffast.S can be found at
31 * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/
32 *
33 */
34
35#include <stdio.h>
36#include "zutil.h"
37#include "inftrees.h"
38#include "inflate.h"
39#include "inffast.h"
40
41/* Mark Adler's comments from inffast.c: */
42
43/*
44 Decode literal, length, and distance codes and write out the resulting
45 literal and match bytes until either not enough input or output is
46 available, an end-of-block is encountered, or a data error is encountered.
47 When large enough input and output buffers are supplied to inflate(), for
48 example, a 16K input buffer and a 64K output buffer, more than 95% of the
49 inflate execution time is spent in this routine.
50
51 Entry assumptions:
52
53 state->mode == LEN
54 strm->avail_in >= 6
55 strm->avail_out >= 258
56 start >= strm->avail_out
57 state->bits < 8
58
59 On return, state->mode is one of:
60
61 LEN -- ran out of enough output space or enough available input
62 TYPE -- reached end of block code, inflate() to interpret next block
63 BAD -- error in block data
64
65 Notes:
66
67 - The maximum input bits used by a length/distance pair is 15 bits for the
68 length code, 5 bits for the length extra, 15 bits for the distance code,
69 and 13 bits for the distance extra. This totals 48 bits, or six bytes.
70 Therefore if strm->avail_in >= 6, then there is enough input to avoid
71 checking for available input while decoding.
72
73 - The maximum bytes that a single length/distance pair can output is 258
74 bytes, which is the maximum length that can be coded. inflate_fast()
75 requires strm->avail_out >= 258 for each loop to avoid checking for
76 output space.
77 */
78
79
80
81 typedef struct inffast_ar {
82/* 64 32 x86 x86_64 */
83/* ar offset register */
84/* 0 0 */ void *esp; /* esp save */
85/* 8 4 */ void *ebp; /* ebp save */
86/* 16 8 */ unsigned char FAR *in; /* esi rsi local strm->next_in */
87/* 24 12 */ unsigned char FAR *last; /* r9 while in < last */
88/* 32 16 */ unsigned char FAR *out; /* edi rdi local strm->next_out */
89/* 40 20 */ unsigned char FAR *beg; /* inflate()'s init next_out */
90/* 48 24 */ unsigned char FAR *end; /* r10 while out < end */
91/* 56 28 */ unsigned char FAR *window;/* size of window, wsize!=0 */
92/* 64 32 */ code const FAR *lcode; /* ebp rbp local strm->lencode */
93/* 72 36 */ code const FAR *dcode; /* r11 local strm->distcode */
94/* 80 40 */ size_t /*unsigned long */hold; /* edx rdx local strm->hold */
95/* 88 44 */ unsigned bits; /* ebx rbx local strm->bits */
96/* 92 48 */ unsigned wsize; /* window size */
97/* 96 52 */ unsigned write; /* window write index */
98/*100 56 */ unsigned lmask; /* r12 mask for lcode */
99/*104 60 */ unsigned dmask; /* r13 mask for dcode */
100/*108 64 */ unsigned len; /* r14 match length */
101/*112 68 */ unsigned dist; /* r15 match distance */
102/*116 72 */ unsigned status; /* set when state chng*/
103 } type_ar;
104#ifdef ASMINF
105
106void inflate_fast(strm, start)
107z_streamp strm;
108unsigned start; /* inflate()'s starting value for strm->avail_out */
109{
110 struct inflate_state FAR *state;
111 type_ar ar;
112 void inffas8664fnc(struct inffast_ar * par);
113
114
115
116#if (defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )) || (defined(_MSC_VER) && defined(_M_AMD64))
117#define PAD_AVAIL_IN 6
118#define PAD_AVAIL_OUT 258
119#else
120#define PAD_AVAIL_IN 5
121#define PAD_AVAIL_OUT 257
122#endif
123
124 /* copy state to local variables */
125 state = (struct inflate_state FAR *)strm->state;
126
127 ar.in = strm->next_in;
128 ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN);
129 ar.out = strm->next_out;
130 ar.beg = ar.out - (start - strm->avail_out);
131 ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT);
132 ar.wsize = state->wsize;
133 ar.write = state->write;
134 ar.window = state->window;
135 ar.hold = state->hold;
136 ar.bits = state->bits;
137 ar.lcode = state->lencode;
138 ar.dcode = state->distcode;
139 ar.lmask = (1U << state->lenbits) - 1;
140 ar.dmask = (1U << state->distbits) - 1;
141
142 /* decode literals and length/distances until end-of-block or not enough
143 input data or output space */
144
145 /* align in on 1/2 hold size boundary */
146 while (((size_t)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) {
147 ar.hold += (unsigned long)*ar.in++ << ar.bits;
148 ar.bits += 8;
149 }
150
151 inffas8664fnc(&ar);
152
153 if (ar.status > 1) {
154 if (ar.status == 2)
155 strm->msg = "invalid literal/length code";
156 else if (ar.status == 3)
157 strm->msg = "invalid distance code";
158 else
159 strm->msg = "invalid distance too far back";
160 state->mode = BAD;
161 }
162 else if ( ar.status == 1 ) {
163 state->mode = TYPE;
164 }
165
166 /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
167 ar.len = ar.bits >> 3;
168 ar.in -= ar.len;
169 ar.bits -= ar.len << 3;
170 ar.hold &= (1U << ar.bits) - 1;
171
172 /* update state and return */
173 strm->next_in = ar.in;
174 strm->next_out = ar.out;
175 strm->avail_in = (unsigned)(ar.in < ar.last ?
176 PAD_AVAIL_IN + (ar.last - ar.in) :
177 PAD_AVAIL_IN - (ar.in - ar.last));
178 strm->avail_out = (unsigned)(ar.out < ar.end ?
179 PAD_AVAIL_OUT + (ar.end - ar.out) :
180 PAD_AVAIL_OUT - (ar.out - ar.end));
181 state->hold = (unsigned long)ar.hold;
182 state->bits = ar.bits;
183 return;
184}
185
186#endif
diff --git a/contrib/masmx64/inffasx64.asm b/contrib/masmx64/inffasx64.asm
new file mode 100644
index 0000000..b5d93a2
--- /dev/null
+++ b/contrib/masmx64/inffasx64.asm
@@ -0,0 +1,392 @@
1; inffasx64.asm is a hand tuned assembler version of inffast.c - fast decoding
2; version for AMD64 on Windows using Microsoft C compiler
3;
4; inffasx64.asm is automatically convert from AMD64 portion of inffas86.c
5; inffasx64.asm is called by inffas8664.c, which contain more info.
6
7
8; to compile this file, I use option
9; ml64.exe /Flinffasx64 /c /Zi inffasx64.asm
10; with Microsoft Macro Assembler (x64) for AMD64
11;
12; ml64.exe is given with Visual Studio 2005, Windows 2003 server DDK
13;
14; (you can get Windows 2003 server DDK with ml64 and cl.exe for AMD64 from
15; http://www.microsoft.com/whdc/devtools/ddk/default.mspx for low price)
16;
17
18.code
19inffas8664fnc PROC
20
21; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and
22; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp
23;
24; All registers must be preserved across the call, except for
25; rax, rcx, rdx, r8, r-9, r10, and r11, which are scratch.
26
27
28 mov [rsp-8],rsi
29 mov [rsp-16],rdi
30 mov [rsp-24],r12
31 mov [rsp-32],r13
32 mov [rsp-40],r14
33 mov [rsp-48],r15
34 mov [rsp-56],rbx
35
36 mov rax,rcx
37
38 mov [rax+8], rbp ; /* save regs rbp and rsp */
39 mov [rax], rsp
40
41 mov rsp, rax ; /* make rsp point to &ar */
42
43 mov rsi, [rsp+16] ; /* rsi = in */
44 mov rdi, [rsp+32] ; /* rdi = out */
45 mov r9, [rsp+24] ; /* r9 = last */
46 mov r10, [rsp+48] ; /* r10 = end */
47 mov rbp, [rsp+64] ; /* rbp = lcode */
48 mov r11, [rsp+72] ; /* r11 = dcode */
49 mov rdx, [rsp+80] ; /* rdx = hold */
50 mov ebx, [rsp+88] ; /* ebx = bits */
51 mov r12d, [rsp+100] ; /* r12d = lmask */
52 mov r13d, [rsp+104] ; /* r13d = dmask */
53 ; /* r14d = len */
54 ; /* r15d = dist */
55
56
57 cld
58 cmp r10, rdi
59 je L_one_time ; /* if only one decode left */
60 cmp r9, rsi
61
62 jne L_do_loop
63
64
65L_one_time:
66 mov r8, r12 ; /* r8 = lmask */
67 cmp bl, 32
68 ja L_get_length_code_one_time
69
70 lodsd ; /* eax = *(uint *)in++ */
71 mov cl, bl ; /* cl = bits, needs it for shifting */
72 add bl, 32 ; /* bits += 32 */
73 shl rax, cl
74 or rdx, rax ; /* hold |= *((uint *)in)++ << bits */
75 jmp L_get_length_code_one_time
76
77ALIGN 4
78L_while_test:
79 cmp r10, rdi
80 jbe L_break_loop
81 cmp r9, rsi
82 jbe L_break_loop
83
84L_do_loop:
85 mov r8, r12 ; /* r8 = lmask */
86 cmp bl, 32
87 ja L_get_length_code ; /* if (32 < bits) */
88
89 lodsd ; /* eax = *(uint *)in++ */
90 mov cl, bl ; /* cl = bits, needs it for shifting */
91 add bl, 32 ; /* bits += 32 */
92 shl rax, cl
93 or rdx, rax ; /* hold |= *((uint *)in)++ << bits */
94
95L_get_length_code:
96 and r8, rdx ; /* r8 &= hold */
97 mov eax, [rbp+r8*4] ; /* eax = lcode[hold & lmask] */
98
99 mov cl, ah ; /* cl = this.bits */
100 sub bl, ah ; /* bits -= this.bits */
101 shr rdx, cl ; /* hold >>= this.bits */
102
103 test al, al
104 jnz L_test_for_length_base ; /* if (op != 0) 45.7% */
105
106 mov r8, r12 ; /* r8 = lmask */
107 shr eax, 16 ; /* output this.val char */
108 stosb
109
110L_get_length_code_one_time:
111 and r8, rdx ; /* r8 &= hold */
112 mov eax, [rbp+r8*4] ; /* eax = lcode[hold & lmask] */
113
114L_dolen:
115 mov cl, ah ; /* cl = this.bits */
116 sub bl, ah ; /* bits -= this.bits */
117 shr rdx, cl ; /* hold >>= this.bits */
118
119 test al, al
120 jnz L_test_for_length_base ; /* if (op != 0) 45.7% */
121
122 shr eax, 16 ; /* output this.val char */
123 stosb
124 jmp L_while_test
125
126ALIGN 4
127L_test_for_length_base:
128 mov r14d, eax ; /* len = this */
129 shr r14d, 16 ; /* len = this.val */
130 mov cl, al
131
132 test al, 16
133 jz L_test_for_second_level_length ; /* if ((op & 16) == 0) 8% */
134 and cl, 15 ; /* op &= 15 */
135 jz L_decode_distance ; /* if (!op) */
136
137L_add_bits_to_len:
138 sub bl, cl
139 xor eax, eax
140 inc eax
141 shl eax, cl
142 dec eax
143 and eax, edx ; /* eax &= hold */
144 shr rdx, cl
145 add r14d, eax ; /* len += hold & mask[op] */
146
147L_decode_distance:
148 mov r8, r13 ; /* r8 = dmask */
149 cmp bl, 32
150 ja L_get_distance_code ; /* if (32 < bits) */
151
152 lodsd ; /* eax = *(uint *)in++ */
153 mov cl, bl ; /* cl = bits, needs it for shifting */
154 add bl, 32 ; /* bits += 32 */
155 shl rax, cl
156 or rdx, rax ; /* hold |= *((uint *)in)++ << bits */
157
158L_get_distance_code:
159 and r8, rdx ; /* r8 &= hold */
160 mov eax, [r11+r8*4] ; /* eax = dcode[hold & dmask] */
161
162L_dodist:
163 mov r15d, eax ; /* dist = this */
164 shr r15d, 16 ; /* dist = this.val */
165 mov cl, ah
166 sub bl, ah ; /* bits -= this.bits */
167 shr rdx, cl ; /* hold >>= this.bits */
168 mov cl, al ; /* cl = this.op */
169
170 test al, 16 ; /* if ((op & 16) == 0) */
171 jz L_test_for_second_level_dist
172 and cl, 15 ; /* op &= 15 */
173 jz L_check_dist_one
174
175L_add_bits_to_dist:
176 sub bl, cl
177 xor eax, eax
178 inc eax
179 shl eax, cl
180 dec eax ; /* (1 << op) - 1 */
181 and eax, edx ; /* eax &= hold */
182 shr rdx, cl
183 add r15d, eax ; /* dist += hold & ((1 << op) - 1) */
184
185L_check_window:
186 mov r8, rsi ; /* save in so from can use it's reg */
187 mov rax, rdi
188 sub rax, [rsp+40] ; /* nbytes = out - beg */
189
190 cmp eax, r15d
191 jb L_clip_window ; /* if (dist > nbytes) 4.2% */
192
193 mov ecx, r14d ; /* ecx = len */
194 mov rsi, rdi
195 sub rsi, r15 ; /* from = out - dist */
196
197 sar ecx, 1
198 jnc L_copy_two ; /* if len % 2 == 0 */
199
200 rep movsw
201 mov al, [rsi]
202 mov [rdi], al
203 inc rdi
204
205 mov rsi, r8 ; /* move in back to %rsi, toss from */
206 jmp L_while_test
207
208L_copy_two:
209 rep movsw
210 mov rsi, r8 ; /* move in back to %rsi, toss from */
211 jmp L_while_test
212
213ALIGN 4
214L_check_dist_one:
215 cmp r15d, 1 ; /* if dist 1, is a memset */
216 jne L_check_window
217 cmp [rsp+40], rdi ; /* if out == beg, outside window */
218 je L_check_window
219
220 mov ecx, r14d ; /* ecx = len */
221 mov al, [rdi-1]
222 mov ah, al
223
224 sar ecx, 1
225 jnc L_set_two
226 mov [rdi], al
227 inc rdi
228
229L_set_two:
230 rep stosw
231 jmp L_while_test
232
233ALIGN 4
234L_test_for_second_level_length:
235 test al, 64
236 jnz L_test_for_end_of_block ; /* if ((op & 64) != 0) */
237
238 xor eax, eax
239 inc eax
240 shl eax, cl
241 dec eax
242 and eax, edx ; /* eax &= hold */
243 add eax, r14d ; /* eax += len */
244 mov eax, [rbp+rax*4] ; /* eax = lcode[val+(hold&mask[op])]*/
245 jmp L_dolen
246
247ALIGN 4
248L_test_for_second_level_dist:
249 test al, 64
250 jnz L_invalid_distance_code ; /* if ((op & 64) != 0) */
251
252 xor eax, eax
253 inc eax
254 shl eax, cl
255 dec eax
256 and eax, edx ; /* eax &= hold */
257 add eax, r15d ; /* eax += dist */
258 mov eax, [r11+rax*4] ; /* eax = dcode[val+(hold&mask[op])]*/
259 jmp L_dodist
260
261ALIGN 4
262L_clip_window:
263 mov ecx, eax ; /* ecx = nbytes */
264 mov eax, [rsp+92] ; /* eax = wsize, prepare for dist cmp */
265 neg ecx ; /* nbytes = -nbytes */
266
267 cmp eax, r15d
268 jb L_invalid_distance_too_far ; /* if (dist > wsize) */
269
270 add ecx, r15d ; /* nbytes = dist - nbytes */
271 cmp dword ptr [rsp+96], 0
272 jne L_wrap_around_window ; /* if (write != 0) */
273
274 mov rsi, [rsp+56] ; /* from = window */
275 sub eax, ecx ; /* eax -= nbytes */
276 add rsi, rax ; /* from += wsize - nbytes */
277
278 mov eax, r14d ; /* eax = len */
279 cmp r14d, ecx
280 jbe L_do_copy ; /* if (nbytes >= len) */
281
282 sub eax, ecx ; /* eax -= nbytes */
283 rep movsb
284 mov rsi, rdi
285 sub rsi, r15 ; /* from = &out[ -dist ] */
286 jmp L_do_copy
287
288ALIGN 4
289L_wrap_around_window:
290 mov eax, [rsp+96] ; /* eax = write */
291 cmp ecx, eax
292 jbe L_contiguous_in_window ; /* if (write >= nbytes) */
293
294 mov esi, [rsp+92] ; /* from = wsize */
295 add rsi, [rsp+56] ; /* from += window */
296 add rsi, rax ; /* from += write */
297 sub rsi, rcx ; /* from -= nbytes */
298 sub ecx, eax ; /* nbytes -= write */
299
300 mov eax, r14d ; /* eax = len */
301 cmp eax, ecx
302 jbe L_do_copy ; /* if (nbytes >= len) */
303
304 sub eax, ecx ; /* len -= nbytes */
305 rep movsb
306 mov rsi, [rsp+56] ; /* from = window */
307 mov ecx, [rsp+96] ; /* nbytes = write */
308 cmp eax, ecx
309 jbe L_do_copy ; /* if (nbytes >= len) */
310
311 sub eax, ecx ; /* len -= nbytes */
312 rep movsb
313 mov rsi, rdi
314 sub rsi, r15 ; /* from = out - dist */
315 jmp L_do_copy
316
317ALIGN 4
318L_contiguous_in_window:
319 mov rsi, [rsp+56] ; /* rsi = window */
320 add rsi, rax
321 sub rsi, rcx ; /* from += write - nbytes */
322
323 mov eax, r14d ; /* eax = len */
324 cmp eax, ecx
325 jbe L_do_copy ; /* if (nbytes >= len) */
326
327 sub eax, ecx ; /* len -= nbytes */
328 rep movsb
329 mov rsi, rdi
330 sub rsi, r15 ; /* from = out - dist */
331 jmp L_do_copy ; /* if (nbytes >= len) */
332
333ALIGN 4
334L_do_copy:
335 mov ecx, eax ; /* ecx = len */
336 rep movsb
337
338 mov rsi, r8 ; /* move in back to %esi, toss from */
339 jmp L_while_test
340
341L_test_for_end_of_block:
342 test al, 32
343 jz L_invalid_literal_length_code
344 mov dword ptr [rsp+116], 1
345 jmp L_break_loop_with_status
346
347L_invalid_literal_length_code:
348 mov dword ptr [rsp+116], 2
349 jmp L_break_loop_with_status
350
351L_invalid_distance_code:
352 mov dword ptr [rsp+116], 3
353 jmp L_break_loop_with_status
354
355L_invalid_distance_too_far:
356 mov dword ptr [rsp+116], 4
357 jmp L_break_loop_with_status
358
359L_break_loop:
360 mov dword ptr [rsp+116], 0
361
362L_break_loop_with_status:
363; /* put in, out, bits, and hold back into ar and pop esp */
364 mov [rsp+16], rsi ; /* in */
365 mov [rsp+32], rdi ; /* out */
366 mov [rsp+88], ebx ; /* bits */
367 mov [rsp+80], rdx ; /* hold */
368
369 mov rax, [rsp] ; /* restore rbp and rsp */
370 mov rbp, [rsp+8]
371 mov rsp, rax
372
373
374
375 mov rsi,[rsp-8]
376 mov rdi,[rsp-16]
377 mov r12,[rsp-24]
378 mov r13,[rsp-32]
379 mov r14,[rsp-40]
380 mov r15,[rsp-48]
381 mov rbx,[rsp-56]
382
383 ret 0
384; :
385; : "m" (ar)
386; : "memory", "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi",
387; "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
388; );
389
390inffas8664fnc ENDP
391;_TEXT ENDS
392END
diff --git a/contrib/masmx64/inffasx64.obj b/contrib/masmx64/inffasx64.obj
new file mode 100644
index 0000000..8df5d82
--- /dev/null
+++ b/contrib/masmx64/inffasx64.obj
Binary files differ
diff --git a/contrib/masmx64/readme.txt b/contrib/masmx64/readme.txt
new file mode 100644
index 0000000..ee03115
--- /dev/null
+++ b/contrib/masmx64/readme.txt
@@ -0,0 +1,28 @@
1Summary
2-------
3This directory contains ASM implementations of the functions
4longest_match() and inflate_fast(), for 64 bits x86 (both AMD64 and Intel EM64t),
5for use with Microsoft Macro Assembler (x64) for AMD64 and Microsoft C++ 64 bits.
6
7gvmat64.asm is written by Gilles Vollant (2005), by using Brian Raiter 686/32 bits
8 assembly optimized version from Jean-loup Gailly original longest_match function
9
10inffasx64.asm and inffas8664.c were written by Chris Anderson, by optimizing
11 original function from Mark Adler
12
13Use instructions
14----------------
15Copy these files into the zlib source directory.
16
17define ASMV and ASMINF in your project. Include inffas8664.c in your source tree,
18and inffasx64.obj and gvmat64.obj as object to link.
19
20
21Build instructions
22------------------
23run bld_64.bat with Microsoft Macro Assembler (x64) for AMD64 (ml64.exe)
24
25ml64.exe is given with Visual Studio 2005, Windows 2003 server DDK
26
27You can get Windows 2003 server DDK with ml64 and cl for AMD64 from
28 http://www.microsoft.com/whdc/devtools/ddk/default.mspx for low price)
diff --git a/contrib/masmx86/bld_ml32.bat b/contrib/masmx86/bld_ml32.bat
new file mode 100644
index 0000000..99144d0
--- /dev/null
+++ b/contrib/masmx86/bld_ml32.bat
@@ -0,0 +1,2 @@
1ml /coff /Zi /c /Flgvmat32.lst gvmat32.asm
2ml /coff /Zi /c /Flinffas32.lst inffas32.asm
diff --git a/contrib/masmx86/gvmat32.asm b/contrib/masmx86/gvmat32.asm
index e841a7f..874bb2d 100644
--- a/contrib/masmx86/gvmat32.asm
+++ b/contrib/masmx86/gvmat32.asm
@@ -1,909 +1,972 @@
1; 1; gvmat32.asm -- Asm portion of the optimized longest_match for 32 bits x86
2; gvmat32.asm -- Asm portion of the optimized longest_match for 32 bits x86 2; Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant.
3; Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant. 3; File written by Gilles Vollant, by modifiying the longest_match
4; File written by Gilles Vollant, by modifiying the longest_match 4; from Jean-loup Gailly in deflate.c
5; from Jean-loup Gailly in deflate.c 5;
6; It need wmask == 0x7fff 6; http://www.zlib.net
7; (assembly code is faster with a fixed wmask) 7; http://www.winimage.com/zLibDll
8; 8; http://www.muppetlabs.com/~breadbox/software/assembly.html
9; For Visual C++ 4.2 and ML 6.11c (version in directory \MASM611C of Win95 DDK) 9;
10; I compile with : "ml /coff /Zi /c gvmat32.asm" 10; For Visual C++ 4.x and higher and ML 6.x and higher
11; 11; ml.exe is in directory \MASM611C of Win95 DDK
12 12; ml.exe is also distributed in http://www.masm32.com/masmdl.htm
13;uInt longest_match_7fff(s, cur_match) 13; and in VC++2003 toolkit at http://msdn.microsoft.com/visualc/vctoolkit2003/
14; deflate_state *s; 14;
15; IPos cur_match; /* current match */ 15; this file contain two implementation of longest_match
16 16;
17 NbStack equ 76 17; longest_match_7fff : written 1996 by Gilles Vollant optimized for
18 cur_match equ dword ptr[esp+NbStack-0] 18; first Pentium. Assume s->w_mask == 0x7fff
19 str_s equ dword ptr[esp+NbStack-4] 19; longest_match_686 : written by Brian raiter (1998), optimized for Pentium Pro
20; 5 dword on top (ret,ebp,esi,edi,ebx) 20;
21 adrret equ dword ptr[esp+NbStack-8] 21; for using an seembly version of longest_match, you need define ASMV in project
22 pushebp equ dword ptr[esp+NbStack-12] 22; There is two way in using gvmat32.asm
23 pushedi equ dword ptr[esp+NbStack-16] 23;
24 pushesi equ dword ptr[esp+NbStack-20] 24; A) Suggested method
25 pushebx equ dword ptr[esp+NbStack-24] 25; if you want include both longest_match_7fff and longest_match_686
26 26; compile the asm file running
27 chain_length equ dword ptr [esp+NbStack-28] 27; ml /coff /Zi /Flgvmat32.lst /c gvmat32.asm
28 limit equ dword ptr [esp+NbStack-32] 28; and include gvmat32c.c in your project
29 best_len equ dword ptr [esp+NbStack-36] 29; if you have an old cpu (386,486 or first Pentium) and s->w_mask==0x7fff,
30 window equ dword ptr [esp+NbStack-40] 30; longest_match_7fff will be used
31 prev equ dword ptr [esp+NbStack-44] 31; if you have a more modern CPU (Pentium Pro, II and higher)
32 scan_start equ word ptr [esp+NbStack-48] 32; longest_match_686 will be used
33 wmask equ dword ptr [esp+NbStack-52] 33; on old cpu with s->w_mask!=0x7fff, longest_match_686 will be used,
34 match_start_ptr equ dword ptr [esp+NbStack-56] 34; but this is not a sitation you'll find often
35 nice_match equ dword ptr [esp+NbStack-60] 35;
36 scan equ dword ptr [esp+NbStack-64] 36; B) Alternative
37 37; if you are not interresed in old cpu performance and want the smaller
38 windowlen equ dword ptr [esp+NbStack-68] 38; binaries possible
39 match_start equ dword ptr [esp+NbStack-72] 39;
40 strend equ dword ptr [esp+NbStack-76] 40; compile the asm file running
41 NbStackAdd equ (NbStack-24) 41; ml /coff /Zi /c /Flgvmat32.lst /DNOOLDPENTIUMCODE gvmat32.asm
42 42; and do not include gvmat32c.c in your project (ou define also
43 .386p 43; NOOLDPENTIUMCODE)
44 44;
45 name gvmatch 45; note : as I known, longest_match_686 is very faster than longest_match_7fff
46 .MODEL FLAT 46; on pentium Pro/II/III, faster (but less) in P4, but it seem
47 47; longest_match_7fff can be faster (very very litte) on AMD Athlon64/K8
48 48;
49 49; see below : zlib1222add must be adjuster if you use a zlib version < 1.2.2.2
50; all the +addstr offsets are due to the addition of pending_buf_size in zlib 1.04 50
51; and adding gzhead and gzindex in zlib 1.2.2.1 51;uInt longest_match_7fff(s, cur_match)
52; in the deflate_state structure since the asm code was first written 52; deflate_state *s;
53; (if you compile with zlib 1.0.4 or older, set addstr to 0). 53; IPos cur_match; /* current match */
54; (if you compiler with zlib between 1.04 and 1.2.1, set addstr to 4) 54
55; Note : these value are good with a 8 bytes boundary pack structure 55 NbStack equ 76
56 56 cur_match equ dword ptr[esp+NbStack-0]
57 addstr equ 4+8 57 str_s equ dword ptr[esp+NbStack-4]
58 dep_chain_length equ 70h+addstr 58; 5 dword on top (ret,ebp,esi,edi,ebx)
59 dep_window equ 2ch+addstr 59 adrret equ dword ptr[esp+NbStack-8]
60 dep_strstart equ 60h+addstr 60 pushebp equ dword ptr[esp+NbStack-12]
61 dep_prev_length equ 6ch+addstr 61 pushedi equ dword ptr[esp+NbStack-16]
62 dep_nice_match equ 84h+addstr 62 pushesi equ dword ptr[esp+NbStack-20]
63 dep_w_size equ 20h+addstr 63 pushebx equ dword ptr[esp+NbStack-24]
64 dep_prev equ 34h+addstr 64
65 dep_w_mask equ 28h+addstr 65 chain_length equ dword ptr [esp+NbStack-28]
66 dep_good_match equ 80h+addstr 66 limit equ dword ptr [esp+NbStack-32]
67 dep_match_start equ 64h+addstr 67 best_len equ dword ptr [esp+NbStack-36]
68 dep_lookahead equ 68h+addstr 68 window equ dword ptr [esp+NbStack-40]
69 69 prev equ dword ptr [esp+NbStack-44]
70 70 scan_start equ word ptr [esp+NbStack-48]
71_TEXT segment 71 wmask equ dword ptr [esp+NbStack-52]
72 72 match_start_ptr equ dword ptr [esp+NbStack-56]
73IFDEF NOUNDERLINE 73 nice_match equ dword ptr [esp+NbStack-60]
74 public longest_match_7fff 74 scan equ dword ptr [esp+NbStack-64]
75 public longest_match_686 75
76; public match_init 76 windowlen equ dword ptr [esp+NbStack-68]
77ELSE 77 match_start equ dword ptr [esp+NbStack-72]
78 public _longest_match_7fff 78 strend equ dword ptr [esp+NbStack-76]
79 public _longest_match_686 79 NbStackAdd equ (NbStack-24)
80; public _match_init 80
81ENDIF 81 .386p
82 82
83 MAX_MATCH equ 258 83 name gvmatch
84 MIN_MATCH equ 3 84 .MODEL FLAT
85 MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1) 85
86 86
87 87
88 88; all the +zlib1222add offsets are due to the addition of fields
89IFDEF NOUNDERLINE 89; in zlib in the deflate_state structure since the asm code was first written
90;match_init proc near 90; (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
91; ret 91; (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
92;match_init endp 92; if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
93ELSE 93
94;_match_init proc near 94 zlib1222add equ 8
95; ret 95
96;_match_init endp 96; Note : these value are good with a 8 bytes boundary pack structure
97ENDIF 97 dep_chain_length equ 74h+zlib1222add
98 98 dep_window equ 30h+zlib1222add
99 99 dep_strstart equ 64h+zlib1222add
100IFDEF NOUNDERLINE 100 dep_prev_length equ 70h+zlib1222add
101longest_match_7fff proc near 101 dep_nice_match equ 88h+zlib1222add
102ELSE 102 dep_w_size equ 24h+zlib1222add
103_longest_match_7fff proc near 103 dep_prev equ 38h+zlib1222add
104ENDIF 104 dep_w_mask equ 2ch+zlib1222add
105 105 dep_good_match equ 84h+zlib1222add
106 mov edx,[esp+4] 106 dep_match_start equ 68h+zlib1222add
107 107 dep_lookahead equ 6ch+zlib1222add
108 108
109 109
110 push ebp 110_TEXT segment
111 push edi 111
112 push esi 112IFDEF NOUNDERLINE
113 push ebx 113 IFDEF NOOLDPENTIUMCODE
114 114 public longest_match
115 sub esp,NbStackAdd 115 public match_init
116 116 ELSE
117; initialize or check the variables used in match.asm. 117 public longest_match_7fff
118 mov ebp,edx 118 public cpudetect32
119 119 public longest_match_686
120; chain_length = s->max_chain_length 120 ENDIF
121; if (prev_length>=good_match) chain_length >>= 2 121ELSE
122 mov edx,[ebp+dep_chain_length] 122 IFDEF NOOLDPENTIUMCODE
123 mov ebx,[ebp+dep_prev_length] 123 public _longest_match
124 cmp [ebp+dep_good_match],ebx 124 public _match_init
125 ja noshr 125 ELSE
126 shr edx,2 126 public _longest_match_7fff
127noshr: 127 public _cpudetect32
128; we increment chain_length because in the asm, the --chain_lenght is in the beginning of the loop 128 public _longest_match_686
129 inc edx 129 ENDIF
130 mov edi,[ebp+dep_nice_match] 130ENDIF
131 mov chain_length,edx 131
132 mov eax,[ebp+dep_lookahead] 132 MAX_MATCH equ 258
133 cmp eax,edi 133 MIN_MATCH equ 3
134; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; 134 MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1)
135 jae nolookaheadnicematch 135
136 mov edi,eax 136
137nolookaheadnicematch: 137
138; best_len = s->prev_length 138IFNDEF NOOLDPENTIUMCODE
139 mov best_len,ebx 139IFDEF NOUNDERLINE
140 140longest_match_7fff proc near
141; window = s->window 141ELSE
142 mov esi,[ebp+dep_window] 142_longest_match_7fff proc near
143 mov ecx,[ebp+dep_strstart] 143ENDIF
144 mov window,esi 144
145 145 mov edx,[esp+4]
146 mov nice_match,edi 146
147; scan = window + strstart 147
148 add esi,ecx 148
149 mov scan,esi 149 push ebp
150; dx = *window 150 push edi
151 mov dx,word ptr [esi] 151 push esi
152; bx = *(window+best_len-1) 152 push ebx
153 mov bx,word ptr [esi+ebx-1] 153
154 add esi,MAX_MATCH-1 154 sub esp,NbStackAdd
155; scan_start = *scan 155
156 mov scan_start,dx 156; initialize or check the variables used in match.asm.
157; strend = scan + MAX_MATCH-1 157 mov ebp,edx
158 mov strend,esi 158
159; bx = scan_end = *(window+best_len-1) 159; chain_length = s->max_chain_length
160 160; if (prev_length>=good_match) chain_length >>= 2
161; IPos limit = s->strstart > (IPos)MAX_DIST(s) ? 161 mov edx,[ebp+dep_chain_length]
162; s->strstart - (IPos)MAX_DIST(s) : NIL; 162 mov ebx,[ebp+dep_prev_length]
163 163 cmp [ebp+dep_good_match],ebx
164 mov esi,[ebp+dep_w_size] 164 ja noshr
165 sub esi,MIN_LOOKAHEAD 165 shr edx,2
166; here esi = MAX_DIST(s) 166noshr:
167 sub ecx,esi 167; we increment chain_length because in the asm, the --chain_lenght is in the beginning of the loop
168 ja nodist 168 inc edx
169 xor ecx,ecx 169 mov edi,[ebp+dep_nice_match]
170nodist: 170 mov chain_length,edx
171 mov limit,ecx 171 mov eax,[ebp+dep_lookahead]
172 172 cmp eax,edi
173; prev = s->prev 173; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
174 mov edx,[ebp+dep_prev] 174 jae nolookaheadnicematch
175 mov prev,edx 175 mov edi,eax
176 176nolookaheadnicematch:
177; 177; best_len = s->prev_length
178 mov edx,dword ptr [ebp+dep_match_start] 178 mov best_len,ebx
179 mov bp,scan_start 179
180 mov eax,cur_match 180; window = s->window
181 mov match_start,edx 181 mov esi,[ebp+dep_window]
182 182 mov ecx,[ebp+dep_strstart]
183 mov edx,window 183 mov window,esi
184 mov edi,edx 184
185 add edi,best_len 185 mov nice_match,edi
186 mov esi,prev 186; scan = window + strstart
187 dec edi 187 add esi,ecx
188; windowlen = window + best_len -1 188 mov scan,esi
189 mov windowlen,edi 189; dx = *window
190 190 mov dx,word ptr [esi]
191 jmp beginloop2 191; bx = *(window+best_len-1)
192 align 4 192 mov bx,word ptr [esi+ebx-1]
193 193 add esi,MAX_MATCH-1
194; here, in the loop 194; scan_start = *scan
195; eax = ax = cur_match 195 mov scan_start,dx
196; ecx = limit 196; strend = scan + MAX_MATCH-1
197; bx = scan_end 197 mov strend,esi
198; bp = scan_start 198; bx = scan_end = *(window+best_len-1)
199; edi = windowlen (window + best_len -1) 199
200; esi = prev 200; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
201 201; s->strstart - (IPos)MAX_DIST(s) : NIL;
202 202
203;// here; chain_length <=16 203 mov esi,[ebp+dep_w_size]
204normalbeg0add16: 204 sub esi,MIN_LOOKAHEAD
205 add chain_length,16 205; here esi = MAX_DIST(s)
206 jz exitloop 206 sub ecx,esi
207normalbeg0: 207 ja nodist
208 cmp word ptr[edi+eax],bx 208 xor ecx,ecx
209 je normalbeg2noroll 209nodist:
210rcontlabnoroll: 210 mov limit,ecx
211; cur_match = prev[cur_match & wmask] 211
212 and eax,7fffh 212; prev = s->prev
213 mov ax,word ptr[esi+eax*2] 213 mov edx,[ebp+dep_prev]
214; if cur_match > limit, go to exitloop 214 mov prev,edx
215 cmp ecx,eax 215
216 jnb exitloop 216;
217; if --chain_length != 0, go to exitloop 217 mov edx,dword ptr [ebp+dep_match_start]
218 dec chain_length 218 mov bp,scan_start
219 jnz normalbeg0 219 mov eax,cur_match
220 jmp exitloop 220 mov match_start,edx
221 221
222normalbeg2noroll: 222 mov edx,window
223; if (scan_start==*(cur_match+window)) goto normalbeg2 223 mov edi,edx
224 cmp bp,word ptr[edx+eax] 224 add edi,best_len
225 jne rcontlabnoroll 225 mov esi,prev
226 jmp normalbeg2 226 dec edi
227 227; windowlen = window + best_len -1
228contloop3: 228 mov windowlen,edi
229 mov edi,windowlen 229
230 230 jmp beginloop2
231; cur_match = prev[cur_match & wmask] 231 align 4
232 and eax,7fffh 232
233 mov ax,word ptr[esi+eax*2] 233; here, in the loop
234; if cur_match > limit, go to exitloop 234; eax = ax = cur_match
235 cmp ecx,eax 235; ecx = limit
236jnbexitloopshort1: 236; bx = scan_end
237 jnb exitloop 237; bp = scan_start
238; if --chain_length != 0, go to exitloop 238; edi = windowlen (window + best_len -1)
239 239; esi = prev
240 240
241; begin the main loop 241
242beginloop2: 242;// here; chain_length <=16
243 sub chain_length,16+1 243normalbeg0add16:
244; if chain_length <=16, don't use the unrolled loop 244 add chain_length,16
245 jna normalbeg0add16 245 jz exitloop
246 246normalbeg0:
247do16: 247 cmp word ptr[edi+eax],bx
248 cmp word ptr[edi+eax],bx 248 je normalbeg2noroll
249 je normalbeg2dc0 249rcontlabnoroll:
250 250; cur_match = prev[cur_match & wmask]
251maccn MACRO lab 251 and eax,7fffh
252 and eax,7fffh 252 mov ax,word ptr[esi+eax*2]
253 mov ax,word ptr[esi+eax*2] 253; if cur_match > limit, go to exitloop
254 cmp ecx,eax 254 cmp ecx,eax
255 jnb exitloop 255 jnb exitloop
256 cmp word ptr[edi+eax],bx 256; if --chain_length != 0, go to exitloop
257 je lab 257 dec chain_length
258 ENDM 258 jnz normalbeg0
259 259 jmp exitloop
260rcontloop0: 260
261 maccn normalbeg2dc1 261normalbeg2noroll:
262 262; if (scan_start==*(cur_match+window)) goto normalbeg2
263rcontloop1: 263 cmp bp,word ptr[edx+eax]
264 maccn normalbeg2dc2 264 jne rcontlabnoroll
265 265 jmp normalbeg2
266rcontloop2: 266
267 maccn normalbeg2dc3 267contloop3:
268 268 mov edi,windowlen
269rcontloop3: 269
270 maccn normalbeg2dc4 270; cur_match = prev[cur_match & wmask]
271 271 and eax,7fffh
272rcontloop4: 272 mov ax,word ptr[esi+eax*2]
273 maccn normalbeg2dc5 273; if cur_match > limit, go to exitloop
274 274 cmp ecx,eax
275rcontloop5: 275jnbexitloopshort1:
276 maccn normalbeg2dc6 276 jnb exitloop
277 277; if --chain_length != 0, go to exitloop
278rcontloop6: 278
279 maccn normalbeg2dc7 279
280 280; begin the main loop
281rcontloop7: 281beginloop2:
282 maccn normalbeg2dc8 282 sub chain_length,16+1
283 283; if chain_length <=16, don't use the unrolled loop
284rcontloop8: 284 jna normalbeg0add16
285 maccn normalbeg2dc9 285
286 286do16:
287rcontloop9: 287 cmp word ptr[edi+eax],bx
288 maccn normalbeg2dc10 288 je normalbeg2dc0
289 289
290rcontloop10: 290maccn MACRO lab
291 maccn short normalbeg2dc11 291 and eax,7fffh
292 292 mov ax,word ptr[esi+eax*2]
293rcontloop11: 293 cmp ecx,eax
294 maccn short normalbeg2dc12 294 jnb exitloop
295 295 cmp word ptr[edi+eax],bx
296rcontloop12: 296 je lab
297 maccn short normalbeg2dc13 297 ENDM
298 298
299rcontloop13: 299rcontloop0:
300 maccn short normalbeg2dc14 300 maccn normalbeg2dc1
301 301
302rcontloop14: 302rcontloop1:
303 maccn short normalbeg2dc15 303 maccn normalbeg2dc2
304 304
305rcontloop15: 305rcontloop2:
306 and eax,7fffh 306 maccn normalbeg2dc3
307 mov ax,word ptr[esi+eax*2] 307
308 cmp ecx,eax 308rcontloop3:
309 jnb exitloop 309 maccn normalbeg2dc4
310 310
311 sub chain_length,16 311rcontloop4:
312 ja do16 312 maccn normalbeg2dc5
313 jmp normalbeg0add16 313
314 314rcontloop5:
315;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 315 maccn normalbeg2dc6
316 316
317normbeg MACRO rcontlab,valsub 317rcontloop6:
318; if we are here, we know that *(match+best_len-1) == scan_end 318 maccn normalbeg2dc7
319 cmp bp,word ptr[edx+eax] 319
320; if (match != scan_start) goto rcontlab 320rcontloop7:
321 jne rcontlab 321 maccn normalbeg2dc8
322; calculate the good chain_length, and we'll compare scan and match string 322
323 add chain_length,16-valsub 323rcontloop8:
324 jmp iseq 324 maccn normalbeg2dc9
325 ENDM 325
326 326rcontloop9:
327 327 maccn normalbeg2dc10
328normalbeg2dc11: 328
329 normbeg rcontloop11,11 329rcontloop10:
330 330 maccn short normalbeg2dc11
331normalbeg2dc12: 331
332 normbeg short rcontloop12,12 332rcontloop11:
333 333 maccn short normalbeg2dc12
334normalbeg2dc13: 334
335 normbeg short rcontloop13,13 335rcontloop12:
336 336 maccn short normalbeg2dc13
337normalbeg2dc14: 337
338 normbeg short rcontloop14,14 338rcontloop13:
339 339 maccn short normalbeg2dc14
340normalbeg2dc15: 340
341 normbeg short rcontloop15,15 341rcontloop14:
342 342 maccn short normalbeg2dc15
343normalbeg2dc10: 343
344 normbeg rcontloop10,10 344rcontloop15:
345 345 and eax,7fffh
346normalbeg2dc9: 346 mov ax,word ptr[esi+eax*2]
347 normbeg rcontloop9,9 347 cmp ecx,eax
348 348 jnb exitloop
349normalbeg2dc8: 349
350 normbeg rcontloop8,8 350 sub chain_length,16
351 351 ja do16
352normalbeg2dc7: 352 jmp normalbeg0add16
353 normbeg rcontloop7,7 353
354 354;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
355normalbeg2dc6: 355
356 normbeg rcontloop6,6 356normbeg MACRO rcontlab,valsub
357 357; if we are here, we know that *(match+best_len-1) == scan_end
358normalbeg2dc5: 358 cmp bp,word ptr[edx+eax]
359 normbeg rcontloop5,5 359; if (match != scan_start) goto rcontlab
360 360 jne rcontlab
361normalbeg2dc4: 361; calculate the good chain_length, and we'll compare scan and match string
362 normbeg rcontloop4,4 362 add chain_length,16-valsub
363 363 jmp iseq
364normalbeg2dc3: 364 ENDM
365 normbeg rcontloop3,3 365
366 366
367normalbeg2dc2: 367normalbeg2dc11:
368 normbeg rcontloop2,2 368 normbeg rcontloop11,11
369 369
370normalbeg2dc1: 370normalbeg2dc12:
371 normbeg rcontloop1,1 371 normbeg short rcontloop12,12
372 372
373normalbeg2dc0: 373normalbeg2dc13:
374 normbeg rcontloop0,0 374 normbeg short rcontloop13,13
375 375
376 376normalbeg2dc14:
377; we go in normalbeg2 because *(ushf*)(match+best_len-1) == scan_end 377 normbeg short rcontloop14,14
378 378
379normalbeg2: 379normalbeg2dc15:
380 mov edi,window 380 normbeg short rcontloop15,15
381 381
382 cmp bp,word ptr[edi+eax] 382normalbeg2dc10:
383 jne contloop3 ; if *(ushf*)match != scan_start, continue 383 normbeg rcontloop10,10
384 384
385iseq: 385normalbeg2dc9:
386; if we are here, we know that *(match+best_len-1) == scan_end 386 normbeg rcontloop9,9
387; and (match == scan_start) 387
388 388normalbeg2dc8:
389 mov edi,edx 389 normbeg rcontloop8,8
390 mov esi,scan ; esi = scan 390
391 add edi,eax ; edi = window + cur_match = match 391normalbeg2dc7:
392 392 normbeg rcontloop7,7
393 mov edx,[esi+3] ; compare manually dword at match+3 393
394 xor edx,[edi+3] ; and scan +3 394normalbeg2dc6:
395 395 normbeg rcontloop6,6
396 jz begincompare ; if equal, go to long compare 396
397 397normalbeg2dc5:
398; we will determine the unmatch byte and calculate len (in esi) 398 normbeg rcontloop5,5
399 or dl,dl 399
400 je eq1rr 400normalbeg2dc4:
401 mov esi,3 401 normbeg rcontloop4,4
402 jmp trfinval 402
403eq1rr: 403normalbeg2dc3:
404 or dx,dx 404 normbeg rcontloop3,3
405 je eq1 405
406 406normalbeg2dc2:
407 mov esi,4 407 normbeg rcontloop2,2
408 jmp trfinval 408
409eq1: 409normalbeg2dc1:
410 and edx,0ffffffh 410 normbeg rcontloop1,1
411 jz eq11 411
412 mov esi,5 412normalbeg2dc0:
413 jmp trfinval 413 normbeg rcontloop0,0
414eq11: 414
415 mov esi,6 415
416 jmp trfinval 416; we go in normalbeg2 because *(ushf*)(match+best_len-1) == scan_end
417 417
418begincompare: 418normalbeg2:
419 ; here we now scan and match begin same 419 mov edi,window
420 add edi,6 420
421 add esi,6 421 cmp bp,word ptr[edi+eax]
422 mov ecx,(MAX_MATCH-(2+4))/4 ; scan for at most MAX_MATCH bytes 422 jne contloop3 ; if *(ushf*)match != scan_start, continue
423 repe cmpsd ; loop until mismatch 423
424 424iseq:
425 je trfin ; go to trfin if not unmatch 425; if we are here, we know that *(match+best_len-1) == scan_end
426; we determine the unmatch byte 426; and (match == scan_start)
427 sub esi,4 427
428 mov edx,[edi-4] 428 mov edi,edx
429 xor edx,[esi] 429 mov esi,scan ; esi = scan
430 430 add edi,eax ; edi = window + cur_match = match
431 or dl,dl 431
432 jnz trfin 432 mov edx,[esi+3] ; compare manually dword at match+3
433 inc esi 433 xor edx,[edi+3] ; and scan +3
434 434
435 or dx,dx 435 jz begincompare ; if equal, go to long compare
436 jnz trfin 436
437 inc esi 437; we will determine the unmatch byte and calculate len (in esi)
438 438 or dl,dl
439 and edx,0ffffffh 439 je eq1rr
440 jnz trfin 440 mov esi,3
441 inc esi 441 jmp trfinval
442 442eq1rr:
443trfin: 443 or dx,dx
444 sub esi,scan ; esi = len 444 je eq1
445trfinval: 445
446; here we have finised compare, and esi contain len of equal string 446 mov esi,4
447 cmp esi,best_len ; if len > best_len, go newbestlen 447 jmp trfinval
448 ja short newbestlen 448eq1:
449; now we restore edx, ecx and esi, for the big loop 449 and edx,0ffffffh
450 mov esi,prev 450 jz eq11
451 mov ecx,limit 451 mov esi,5
452 mov edx,window 452 jmp trfinval
453 jmp contloop3 453eq11:
454 454 mov esi,6
455newbestlen: 455 jmp trfinval
456 mov best_len,esi ; len become best_len 456
457 457begincompare:
458 mov match_start,eax ; save new position as match_start 458 ; here we now scan and match begin same
459 cmp esi,nice_match ; if best_len >= nice_match, exit 459 add edi,6
460 jae exitloop 460 add esi,6
461 mov ecx,scan 461 mov ecx,(MAX_MATCH-(2+4))/4 ; scan for at most MAX_MATCH bytes
462 mov edx,window ; restore edx=window 462 repe cmpsd ; loop until mismatch
463 add ecx,esi 463
464 add esi,edx 464 je trfin ; go to trfin if not unmatch
465 465; we determine the unmatch byte
466 dec esi 466 sub esi,4
467 mov windowlen,esi ; windowlen = window + best_len-1 467 mov edx,[edi-4]
468 mov bx,[ecx-1] ; bx = *(scan+best_len-1) = scan_end 468 xor edx,[esi]
469 469
470; now we restore ecx and esi, for the big loop : 470 or dl,dl
471 mov esi,prev 471 jnz trfin
472 mov ecx,limit 472 inc esi
473 jmp contloop3 473
474 474 or dx,dx
475exitloop: 475 jnz trfin
476; exit : s->match_start=match_start 476 inc esi
477 mov ebx,match_start 477
478 mov ebp,str_s 478 and edx,0ffffffh
479 mov ecx,best_len 479 jnz trfin
480 mov dword ptr [ebp+dep_match_start],ebx 480 inc esi
481 mov eax,dword ptr [ebp+dep_lookahead] 481
482 cmp ecx,eax 482trfin:
483 ja minexlo 483 sub esi,scan ; esi = len
484 mov eax,ecx 484trfinval:
485minexlo: 485; here we have finised compare, and esi contain len of equal string
486; return min(best_len,s->lookahead) 486 cmp esi,best_len ; if len > best_len, go newbestlen
487 487 ja short newbestlen
488; restore stack and register ebx,esi,edi,ebp 488; now we restore edx, ecx and esi, for the big loop
489 add esp,NbStackAdd 489 mov esi,prev
490 490 mov ecx,limit
491 pop ebx 491 mov edx,window
492 pop esi 492 jmp contloop3
493 pop edi 493
494 pop ebp 494newbestlen:
495 ret 495 mov best_len,esi ; len become best_len
496InfoAuthor: 496
497; please don't remove this string ! 497 mov match_start,eax ; save new position as match_start
498; Your are free use gvmat32 in any fre or commercial apps if you don't remove the string in the binary! 498 cmp esi,nice_match ; if best_len >= nice_match, exit
499 db 0dh,0ah,"GVMat32 optimised assembly code written 1996-98 by Gilles Vollant",0dh,0ah 499 jae exitloop
500 500 mov ecx,scan
501 501 mov edx,window ; restore edx=window
502 502 add ecx,esi
503IFDEF NOUNDERLINE 503 add esi,edx
504longest_match_7fff endp 504
505ELSE 505 dec esi
506_longest_match_7fff endp 506 mov windowlen,esi ; windowlen = window + best_len-1
507ENDIF 507 mov bx,[ecx-1] ; bx = *(scan+best_len-1) = scan_end
508 508
509 509; now we restore ecx and esi, for the big loop :
510IFDEF NOUNDERLINE 510 mov esi,prev
511cpudetect32 proc near 511 mov ecx,limit
512ELSE 512 jmp contloop3
513_cpudetect32 proc near 513
514ENDIF 514exitloop:
515 515; exit : s->match_start=match_start
516 push ebx 516 mov ebx,match_start
517 517 mov ebp,str_s
518 pushfd ; push original EFLAGS 518 mov ecx,best_len
519 pop eax ; get original EFLAGS 519 mov dword ptr [ebp+dep_match_start],ebx
520 mov ecx, eax ; save original EFLAGS 520 mov eax,dword ptr [ebp+dep_lookahead]
521 xor eax, 40000h ; flip AC bit in EFLAGS 521 cmp ecx,eax
522 push eax ; save new EFLAGS value on stack 522 ja minexlo
523 popfd ; replace current EFLAGS value 523 mov eax,ecx
524 pushfd ; get new EFLAGS 524minexlo:
525 pop eax ; store new EFLAGS in EAX 525; return min(best_len,s->lookahead)
526 xor eax, ecx ; can’t toggle AC bit, processor=80386 526
527 jz end_cpu_is_386 ; jump if 80386 processor 527; restore stack and register ebx,esi,edi,ebp
528 push ecx 528 add esp,NbStackAdd
529 popfd ; restore AC bit in EFLAGS first 529
530 530 pop ebx
531 pushfd 531 pop esi
532 pushfd 532 pop edi
533 pop ecx 533 pop ebp
534 534 ret
535 mov eax, ecx ; get original EFLAGS 535InfoAuthor:
536 xor eax, 200000h ; flip ID bit in EFLAGS 536; please don't remove this string !
537 push eax ; save new EFLAGS value on stack 537; Your are free use gvmat32 in any fre or commercial apps if you don't remove the string in the binary!
538 popfd ; replace current EFLAGS value 538 db 0dh,0ah,"GVMat32 optimised assembly code written 1996-98 by Gilles Vollant",0dh,0ah
539 pushfd ; get new EFLAGS 539
540 pop eax ; store new EFLAGS in EAX 540
541 popfd ; restore original EFLAGS 541
542 xor eax, ecx ; can’t toggle ID bit, 542IFDEF NOUNDERLINE
543 je is_old_486 ; processor=old 543longest_match_7fff endp
544 544ELSE
545 mov eax,1 545_longest_match_7fff endp
546 db 0fh,0a2h ;CPUID 546ENDIF
547 547
548exitcpudetect: 548
549 pop ebx 549IFDEF NOUNDERLINE
550 ret 550cpudetect32 proc near
551 551ELSE
552end_cpu_is_386: 552_cpudetect32 proc near
553 mov eax,0300h 553ENDIF
554 jmp exitcpudetect 554
555 555 push ebx
556is_old_486: 556
557 mov eax,0400h 557 pushfd ; push original EFLAGS
558 jmp exitcpudetect 558 pop eax ; get original EFLAGS
559 559 mov ecx, eax ; save original EFLAGS
560IFDEF NOUNDERLINE 560 xor eax, 40000h ; flip AC bit in EFLAGS
561cpudetect32 endp 561 push eax ; save new EFLAGS value on stack
562ELSE 562 popfd ; replace current EFLAGS value
563_cpudetect32 endp 563 pushfd ; get new EFLAGS
564ENDIF 564 pop eax ; store new EFLAGS in EAX
565 565 xor eax, ecx ; can’t toggle AC bit, processor=80386
566 566 jz end_cpu_is_386 ; jump if 80386 processor
567 567 push ecx
568 568 popfd ; restore AC bit in EFLAGS first
569MAX_MATCH equ 258 569
570MIN_MATCH equ 3 570 pushfd
571MIN_LOOKAHEAD equ (MAX_MATCH + MIN_MATCH + 1) 571 pushfd
572MAX_MATCH_8_ equ ((MAX_MATCH + 7) AND 0FFF0h) 572 pop ecx
573 573
574 574 mov eax, ecx ; get original EFLAGS
575;;; stack frame offsets 575 xor eax, 200000h ; flip ID bit in EFLAGS
576 576 push eax ; save new EFLAGS value on stack
577chainlenwmask equ esp + 0 ; high word: current chain len 577 popfd ; replace current EFLAGS value
578 ; low word: s->wmask 578 pushfd ; get new EFLAGS
579window equ esp + 4 ; local copy of s->window 579 pop eax ; store new EFLAGS in EAX
580windowbestlen equ esp + 8 ; s->window + bestlen 580 popfd ; restore original EFLAGS
581scanstart equ esp + 16 ; first two bytes of string 581 xor eax, ecx ; can’t toggle ID bit,
582scanend equ esp + 12 ; last two bytes of string 582 je is_old_486 ; processor=old
583scanalign equ esp + 20 ; dword-misalignment of string 583
584nicematch equ esp + 24 ; a good enough match size 584 mov eax,1
585bestlen equ esp + 28 ; size of best match so far 585 db 0fh,0a2h ;CPUID
586scan equ esp + 32 ; ptr to string wanting match 586
587 587exitcpudetect:
588LocalVarsSize equ 36 588 pop ebx
589; saved ebx byte esp + 36 589 ret
590; saved edi byte esp + 40 590
591; saved esi byte esp + 44 591end_cpu_is_386:
592; saved ebp byte esp + 48 592 mov eax,0300h
593; return address byte esp + 52 593 jmp exitcpudetect
594deflatestate equ esp + 56 ; the function arguments 594
595curmatch equ esp + 60 595is_old_486:
596 596 mov eax,0400h
597;;; Offsets for fields in the deflate_state structure. These numbers 597 jmp exitcpudetect
598;;; are calculated from the definition of deflate_state, with the 598
599;;; assumption that the compiler will dword-align the fields. (Thus, 599IFDEF NOUNDERLINE
600;;; changing the definition of deflate_state could easily cause this 600cpudetect32 endp
601;;; program to crash horribly, without so much as a warning at 601ELSE
602;;; compile time. Sigh.) 602_cpudetect32 endp
603 603ENDIF
604dsWSize equ 36+addstr-4 604ENDIF
605dsWMask equ 44+addstr-4 605
606dsWindow equ 48+addstr-4 606MAX_MATCH equ 258
607dsPrev equ 56+addstr-4 607MIN_MATCH equ 3
608dsMatchLen equ 88+addstr-4 608MIN_LOOKAHEAD equ (MAX_MATCH + MIN_MATCH + 1)
609dsPrevMatch equ 92+addstr-4 609MAX_MATCH_8_ equ ((MAX_MATCH + 7) AND 0FFF0h)
610dsStrStart equ 100+addstr-4 610
611dsMatchStart equ 104+addstr-4 611
612dsLookahead equ 108+addstr-4 612;;; stack frame offsets
613dsPrevLen equ 112+addstr-4 613
614dsMaxChainLen equ 116+addstr-4 614chainlenwmask equ esp + 0 ; high word: current chain len
615dsGoodMatch equ 132+addstr-4 615 ; low word: s->wmask
616dsNiceMatch equ 136+addstr-4 616window equ esp + 4 ; local copy of s->window
617 617windowbestlen equ esp + 8 ; s->window + bestlen
618 618scanstart equ esp + 16 ; first two bytes of string
619;;; match.asm -- Pentium-Pro-optimized version of longest_match() 619scanend equ esp + 12 ; last two bytes of string
620;;; Written for zlib 1.1.2 620scanalign equ esp + 20 ; dword-misalignment of string
621;;; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com> 621nicematch equ esp + 24 ; a good enough match size
622;;; You can look at http://www.muppetlabs.com/~breadbox/software/assembly.html 622bestlen equ esp + 28 ; size of best match so far
623;;; 623scan equ esp + 32 ; ptr to string wanting match
624;;; This is free software; you can redistribute it and/or modify it 624
625;;; under the terms of the GNU General Public License. 625LocalVarsSize equ 36
626 626; saved ebx byte esp + 36
627;GLOBAL _longest_match, _match_init 627; saved edi byte esp + 40
628 628; saved esi byte esp + 44
629 629; saved ebp byte esp + 48
630;SECTION .text 630; return address byte esp + 52
631 631deflatestate equ esp + 56 ; the function arguments
632;;; uInt longest_match(deflate_state *deflatestate, IPos curmatch) 632curmatch equ esp + 60
633 633
634;_longest_match: 634;;; Offsets for fields in the deflate_state structure. These numbers
635IFDEF NOUNDERLINE 635;;; are calculated from the definition of deflate_state, with the
636longest_match_686 proc near 636;;; assumption that the compiler will dword-align the fields. (Thus,
637ELSE 637;;; changing the definition of deflate_state could easily cause this
638_longest_match_686 proc near 638;;; program to crash horribly, without so much as a warning at
639ENDIF 639;;; compile time. Sigh.)
640 640
641 641dsWSize equ 36+zlib1222add
642;;; Save registers that the compiler may be using, and adjust esp to 642dsWMask equ 44+zlib1222add
643;;; make room for our stack frame. 643dsWindow equ 48+zlib1222add
644 644dsPrev equ 56+zlib1222add
645 push ebp 645dsMatchLen equ 88+zlib1222add
646 push edi 646dsPrevMatch equ 92+zlib1222add
647 push esi 647dsStrStart equ 100+zlib1222add
648 push ebx 648dsMatchStart equ 104+zlib1222add
649 sub esp, LocalVarsSize 649dsLookahead equ 108+zlib1222add
650 650dsPrevLen equ 112+zlib1222add
651;;; Retrieve the function arguments. ecx will hold cur_match 651dsMaxChainLen equ 116+zlib1222add
652;;; throughout the entire function. edx will hold the pointer to the 652dsGoodMatch equ 132+zlib1222add
653;;; deflate_state structure during the function's setup (before 653dsNiceMatch equ 136+zlib1222add
654;;; entering the main loop. 654
655 655
656 mov edx, [deflatestate] 656;;; match.asm -- Pentium-Pro-optimized version of longest_match()
657 mov ecx, [curmatch] 657;;; Written for zlib 1.1.2
658 658;;; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
659;;; uInt wmask = s->w_mask; 659;;; You can look at http://www.muppetlabs.com/~breadbox/software/assembly.html
660;;; unsigned chain_length = s->max_chain_length; 660;;;
661;;; if (s->prev_length >= s->good_match) { 661;;; This is free software; you can redistribute it and/or modify it
662;;; chain_length >>= 2; 662;;; under the terms of the GNU General Public License.
663;;; } 663
664 664;GLOBAL _longest_match, _match_init
665 mov eax, [edx + dsPrevLen] 665
666 mov ebx, [edx + dsGoodMatch] 666
667 cmp eax, ebx 667;SECTION .text
668 mov eax, [edx + dsWMask] 668
669 mov ebx, [edx + dsMaxChainLen] 669;;; uInt longest_match(deflate_state *deflatestate, IPos curmatch)
670 jl LastMatchGood 670
671 shr ebx, 2 671;_longest_match:
672LastMatchGood: 672IFDEF NOOLDPENTIUMCODE
673 673 IFDEF NOUNDERLINE
674;;; chainlen is decremented once beforehand so that the function can 674 longest_match proc near
675;;; use the sign flag instead of the zero flag for the exit test. 675 ELSE
676;;; It is then shifted into the high word, to make room for the wmask 676 _longest_match proc near
677;;; value, which it will always accompany. 677 ENDIF
678 678ELSE
679 dec ebx 679 IFDEF NOUNDERLINE
680 shl ebx, 16 680 longest_match_686 proc near
681 or ebx, eax 681 ELSE
682 mov [chainlenwmask], ebx 682 _longest_match_686 proc near
683 683 ENDIF
684;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; 684ENDIF
685 685
686 mov eax, [edx + dsNiceMatch] 686;;; Save registers that the compiler may be using, and adjust esp to
687 mov ebx, [edx + dsLookahead] 687;;; make room for our stack frame.
688 cmp ebx, eax 688
689 jl LookaheadLess 689 push ebp
690 mov ebx, eax 690 push edi
691LookaheadLess: mov [nicematch], ebx 691 push esi
692 692 push ebx
693;;; register Bytef *scan = s->window + s->strstart; 693 sub esp, LocalVarsSize
694 694
695 mov esi, [edx + dsWindow] 695;;; Retrieve the function arguments. ecx will hold cur_match
696 mov [window], esi 696;;; throughout the entire function. edx will hold the pointer to the
697 mov ebp, [edx + dsStrStart] 697;;; deflate_state structure during the function's setup (before
698 lea edi, [esi + ebp] 698;;; entering the main loop.
699 mov [scan], edi 699
700 700 mov edx, [deflatestate]
701;;; Determine how many bytes the scan ptr is off from being 701 mov ecx, [curmatch]
702;;; dword-aligned. 702
703 703;;; uInt wmask = s->w_mask;
704 mov eax, edi 704;;; unsigned chain_length = s->max_chain_length;
705 neg eax 705;;; if (s->prev_length >= s->good_match) {
706 and eax, 3 706;;; chain_length >>= 2;
707 mov [scanalign], eax 707;;; }
708 708
709;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ? 709 mov eax, [edx + dsPrevLen]
710;;; s->strstart - (IPos)MAX_DIST(s) : NIL; 710 mov ebx, [edx + dsGoodMatch]
711 711 cmp eax, ebx
712 mov eax, [edx + dsWSize] 712 mov eax, [edx + dsWMask]
713 sub eax, MIN_LOOKAHEAD 713 mov ebx, [edx + dsMaxChainLen]
714 sub ebp, eax 714 jl LastMatchGood
715 jg LimitPositive 715 shr ebx, 2
716 xor ebp, ebp 716LastMatchGood:
717LimitPositive: 717
718 718;;; chainlen is decremented once beforehand so that the function can
719;;; int best_len = s->prev_length; 719;;; use the sign flag instead of the zero flag for the exit test.
720 720;;; It is then shifted into the high word, to make room for the wmask
721 mov eax, [edx + dsPrevLen] 721;;; value, which it will always accompany.
722 mov [bestlen], eax 722
723 723 dec ebx
724;;; Store the sum of s->window + best_len in esi locally, and in esi. 724 shl ebx, 16
725 725 or ebx, eax
726 add esi, eax 726 mov [chainlenwmask], ebx
727 mov [windowbestlen], esi 727
728 728;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
729;;; register ush scan_start = *(ushf*)scan; 729
730;;; register ush scan_end = *(ushf*)(scan+best_len-1); 730 mov eax, [edx + dsNiceMatch]
731;;; Posf *prev = s->prev; 731 mov ebx, [edx + dsLookahead]
732 732 cmp ebx, eax
733 movzx ebx, word ptr [edi] 733 jl LookaheadLess
734 mov [scanstart], ebx 734 mov ebx, eax
735 movzx ebx, word ptr [edi + eax - 1] 735LookaheadLess: mov [nicematch], ebx
736 mov [scanend], ebx 736
737 mov edi, [edx + dsPrev] 737;;; register Bytef *scan = s->window + s->strstart;
738 738
739;;; Jump into the main loop. 739 mov esi, [edx + dsWindow]
740 740 mov [window], esi
741 mov edx, [chainlenwmask] 741 mov ebp, [edx + dsStrStart]
742 jmp short LoopEntry 742 lea edi, [esi + ebp]
743 743 mov [scan], edi
744align 4 744
745 745;;; Determine how many bytes the scan ptr is off from being
746;;; do { 746;;; dword-aligned.
747;;; match = s->window + cur_match; 747
748;;; if (*(ushf*)(match+best_len-1) != scan_end || 748 mov eax, edi
749;;; *(ushf*)match != scan_start) continue; 749 neg eax
750;;; [...] 750 and eax, 3
751;;; } while ((cur_match = prev[cur_match & wmask]) > limit 751 mov [scanalign], eax
752;;; && --chain_length != 0); 752
753;;; 753;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
754;;; Here is the inner loop of the function. The function will spend the 754;;; s->strstart - (IPos)MAX_DIST(s) : NIL;
755;;; majority of its time in this loop, and majority of that time will 755
756;;; be spent in the first ten instructions. 756 mov eax, [edx + dsWSize]
757;;; 757 sub eax, MIN_LOOKAHEAD
758;;; Within this loop: 758 sub ebp, eax
759;;; ebx = scanend 759 jg LimitPositive
760;;; ecx = curmatch 760 xor ebp, ebp
761;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) 761LimitPositive:
762;;; esi = windowbestlen - i.e., (window + bestlen) 762
763;;; edi = prev 763;;; int best_len = s->prev_length;
764;;; ebp = limit 764
765 765 mov eax, [edx + dsPrevLen]
766LookupLoop: 766 mov [bestlen], eax
767 and ecx, edx 767
768 movzx ecx, word ptr [edi + ecx*2] 768;;; Store the sum of s->window + best_len in esi locally, and in esi.
769 cmp ecx, ebp 769
770 jbe LeaveNow 770 add esi, eax
771 sub edx, 00010000h 771 mov [windowbestlen], esi
772 js LeaveNow 772
773LoopEntry: movzx eax, word ptr [esi + ecx - 1] 773;;; register ush scan_start = *(ushf*)scan;
774 cmp eax, ebx 774;;; register ush scan_end = *(ushf*)(scan+best_len-1);
775 jnz LookupLoop 775;;; Posf *prev = s->prev;
776 mov eax, [window] 776
777 movzx eax, word ptr [eax + ecx] 777 movzx ebx, word ptr [edi]
778 cmp eax, [scanstart] 778 mov [scanstart], ebx
779 jnz LookupLoop 779 movzx ebx, word ptr [edi + eax - 1]
780 780 mov [scanend], ebx
781;;; Store the current value of chainlen. 781 mov edi, [edx + dsPrev]
782 782
783 mov [chainlenwmask], edx 783;;; Jump into the main loop.
784 784
785;;; Point edi to the string under scrutiny, and esi to the string we 785 mov edx, [chainlenwmask]
786;;; are hoping to match it up with. In actuality, esi and edi are 786 jmp short LoopEntry
787;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is 787
788;;; initialized to -(MAX_MATCH_8 - scanalign). 788align 4
789 789
790 mov esi, [window] 790;;; do {
791 mov edi, [scan] 791;;; match = s->window + cur_match;
792 add esi, ecx 792;;; if (*(ushf*)(match+best_len-1) != scan_end ||
793 mov eax, [scanalign] 793;;; *(ushf*)match != scan_start) continue;
794 mov edx, 0fffffef8h; -(MAX_MATCH_8) 794;;; [...]
795 lea edi, [edi + eax + 0108h] ;MAX_MATCH_8] 795;;; } while ((cur_match = prev[cur_match & wmask]) > limit
796 lea esi, [esi + eax + 0108h] ;MAX_MATCH_8] 796;;; && --chain_length != 0);
797 797;;;
798;;; Test the strings for equality, 8 bytes at a time. At the end, 798;;; Here is the inner loop of the function. The function will spend the
799;;; adjust edx so that it is offset to the exact byte that mismatched. 799;;; majority of its time in this loop, and majority of that time will
800;;; 800;;; be spent in the first ten instructions.
801;;; We already know at this point that the first three bytes of the 801;;;
802;;; strings match each other, and they can be safely passed over before 802;;; Within this loop:
803;;; starting the compare loop. So what this code does is skip over 0-3 803;;; ebx = scanend
804;;; bytes, as much as necessary in order to dword-align the edi 804;;; ecx = curmatch
805;;; pointer. (esi will still be misaligned three times out of four.) 805;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
806;;; 806;;; esi = windowbestlen - i.e., (window + bestlen)
807;;; It should be confessed that this loop usually does not represent 807;;; edi = prev
808;;; much of the total running time. Replacing it with a more 808;;; ebp = limit
809;;; straightforward "rep cmpsb" would not drastically degrade 809
810;;; performance. 810LookupLoop:
811 811 and ecx, edx
812LoopCmps: 812 movzx ecx, word ptr [edi + ecx*2]
813 mov eax, [esi + edx] 813 cmp ecx, ebp
814 xor eax, [edi + edx] 814 jbe LeaveNow
815 jnz LeaveLoopCmps 815 sub edx, 00010000h
816 mov eax, [esi + edx + 4] 816 js LeaveNow
817 xor eax, [edi + edx + 4] 817LoopEntry: movzx eax, word ptr [esi + ecx - 1]
818 jnz LeaveLoopCmps4 818 cmp eax, ebx
819 add edx, 8 819 jnz LookupLoop
820 jnz LoopCmps 820 mov eax, [window]
821 jmp short LenMaximum 821 movzx eax, word ptr [eax + ecx]
822LeaveLoopCmps4: add edx, 4 822 cmp eax, [scanstart]
823LeaveLoopCmps: test eax, 0000FFFFh 823 jnz LookupLoop
824 jnz LenLower 824
825 add edx, 2 825;;; Store the current value of chainlen.
826 shr eax, 16 826
827LenLower: sub al, 1 827 mov [chainlenwmask], edx
828 adc edx, 0 828
829 829;;; Point edi to the string under scrutiny, and esi to the string we
830;;; Calculate the length of the match. If it is longer than MAX_MATCH, 830;;; are hoping to match it up with. In actuality, esi and edi are
831;;; then automatically accept it as the best possible match and leave. 831;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is
832 832;;; initialized to -(MAX_MATCH_8 - scanalign).
833 lea eax, [edi + edx] 833
834 mov edi, [scan] 834 mov esi, [window]
835 sub eax, edi 835 mov edi, [scan]
836 cmp eax, MAX_MATCH 836 add esi, ecx
837 jge LenMaximum 837 mov eax, [scanalign]
838 838 mov edx, 0fffffef8h; -(MAX_MATCH_8)
839;;; If the length of the match is not longer than the best match we 839 lea edi, [edi + eax + 0108h] ;MAX_MATCH_8]
840;;; have so far, then forget it and return to the lookup loop. 840 lea esi, [esi + eax + 0108h] ;MAX_MATCH_8]
841 841
842 mov edx, [deflatestate] 842;;; Test the strings for equality, 8 bytes at a time. At the end,
843 mov ebx, [bestlen] 843;;; adjust edx so that it is offset to the exact byte that mismatched.
844 cmp eax, ebx 844;;;
845 jg LongerMatch 845;;; We already know at this point that the first three bytes of the
846 mov esi, [windowbestlen] 846;;; strings match each other, and they can be safely passed over before
847 mov edi, [edx + dsPrev] 847;;; starting the compare loop. So what this code does is skip over 0-3
848 mov ebx, [scanend] 848;;; bytes, as much as necessary in order to dword-align the edi
849 mov edx, [chainlenwmask] 849;;; pointer. (esi will still be misaligned three times out of four.)
850 jmp LookupLoop 850;;;
851 851;;; It should be confessed that this loop usually does not represent
852;;; s->match_start = cur_match; 852;;; much of the total running time. Replacing it with a more
853;;; best_len = len; 853;;; straightforward "rep cmpsb" would not drastically degrade
854;;; if (len >= nice_match) break; 854;;; performance.
855;;; scan_end = *(ushf*)(scan+best_len-1); 855
856 856LoopCmps:
857LongerMatch: mov ebx, [nicematch] 857 mov eax, [esi + edx]
858 mov [bestlen], eax 858 xor eax, [edi + edx]
859 mov [edx + dsMatchStart], ecx 859 jnz LeaveLoopCmps
860 cmp eax, ebx 860 mov eax, [esi + edx + 4]
861 jge LeaveNow 861 xor eax, [edi + edx + 4]
862 mov esi, [window] 862 jnz LeaveLoopCmps4
863 add esi, eax 863 add edx, 8
864 mov [windowbestlen], esi 864 jnz LoopCmps
865 movzx ebx, word ptr [edi + eax - 1] 865 jmp short LenMaximum
866 mov edi, [edx + dsPrev] 866LeaveLoopCmps4: add edx, 4
867 mov [scanend], ebx 867LeaveLoopCmps: test eax, 0000FFFFh
868 mov edx, [chainlenwmask] 868 jnz LenLower
869 jmp LookupLoop 869 add edx, 2
870 870 shr eax, 16
871;;; Accept the current string, with the maximum possible length. 871LenLower: sub al, 1
872 872 adc edx, 0
873LenMaximum: mov edx, [deflatestate] 873
874 mov dword ptr [bestlen], MAX_MATCH 874;;; Calculate the length of the match. If it is longer than MAX_MATCH,
875 mov [edx + dsMatchStart], ecx 875;;; then automatically accept it as the best possible match and leave.
876 876
877;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len; 877 lea eax, [edi + edx]
878;;; return s->lookahead; 878 mov edi, [scan]
879 879 sub eax, edi
880LeaveNow: 880 cmp eax, MAX_MATCH
881 mov edx, [deflatestate] 881 jge LenMaximum
882 mov ebx, [bestlen] 882
883 mov eax, [edx + dsLookahead] 883;;; If the length of the match is not longer than the best match we
884 cmp ebx, eax 884;;; have so far, then forget it and return to the lookup loop.
885 jg LookaheadRet 885
886 mov eax, ebx 886 mov edx, [deflatestate]
887LookaheadRet: 887 mov ebx, [bestlen]
888 888 cmp eax, ebx
889;;; Restore the stack and return from whence we came. 889 jg LongerMatch
890 890 mov esi, [windowbestlen]
891 add esp, LocalVarsSize 891 mov edi, [edx + dsPrev]
892 pop ebx 892 mov ebx, [scanend]
893 pop esi 893 mov edx, [chainlenwmask]
894 pop edi 894 jmp LookupLoop
895 pop ebp 895
896 896;;; s->match_start = cur_match;
897 ret 897;;; best_len = len;
898; please don't remove this string ! 898;;; if (len >= nice_match) break;
899; Your can freely use gvmat32 in any free or commercial app if you don't remove the string in the binary! 899;;; scan_end = *(ushf*)(scan+best_len-1);
900 db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998",0dh,0ah 900
901 901LongerMatch: mov ebx, [nicematch]
902IFDEF NOUNDERLINE 902 mov [bestlen], eax
903longest_match_686 endp 903 mov [edx + dsMatchStart], ecx
904ELSE 904 cmp eax, ebx
905_longest_match_686 endp 905 jge LeaveNow
906ENDIF 906 mov esi, [window]
907 907 add esi, eax
908_TEXT ends 908 mov [windowbestlen], esi
909end 909 movzx ebx, word ptr [edi + eax - 1]
910 mov edi, [edx + dsPrev]
911 mov [scanend], ebx
912 mov edx, [chainlenwmask]
913 jmp LookupLoop
914
915;;; Accept the current string, with the maximum possible length.
916
917LenMaximum: mov edx, [deflatestate]
918 mov dword ptr [bestlen], MAX_MATCH
919 mov [edx + dsMatchStart], ecx
920
921;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
922;;; return s->lookahead;
923
924LeaveNow:
925 mov edx, [deflatestate]
926 mov ebx, [bestlen]
927 mov eax, [edx + dsLookahead]
928 cmp ebx, eax
929 jg LookaheadRet
930 mov eax, ebx
931LookaheadRet:
932
933;;; Restore the stack and return from whence we came.
934
935 add esp, LocalVarsSize
936 pop ebx
937 pop esi
938 pop edi
939 pop ebp
940
941 ret
942; please don't remove this string !
943; Your can freely use gvmat32 in any free or commercial app if you don't remove the string in the binary!
944 db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998",0dh,0ah
945
946
947IFDEF NOOLDPENTIUMCODE
948 IFDEF NOUNDERLINE
949 longest_match endp
950 ELSE
951 _longest_match endp
952 ENDIF
953
954 IFDEF NOUNDERLINE
955 match_init proc near
956 ret
957 match_init endp
958 ELSE
959 _match_init proc near
960 ret
961 _match_init endp
962 ENDIF
963ELSE
964 IFDEF NOUNDERLINE
965 longest_match_686 endp
966 ELSE
967 _longest_match_686 endp
968 ENDIF
969ENDIF
970
971_TEXT ends
972end
diff --git a/contrib/masmx86/gvmat32c.c b/contrib/masmx86/gvmat32c.c
index 9ed25f3..7ad2b27 100644
--- a/contrib/masmx86/gvmat32c.c
+++ b/contrib/masmx86/gvmat32c.c
@@ -1,206 +1,62 @@
1/* gvmat32.c -- C portion of the optimized longest_match for 32 bits x86 1/* gvmat32.c -- C portion of the optimized longest_match for 32 bits x86
2 * Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant. 2 * Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant.
3 * File written by Gilles Vollant, by modifiying the longest_match 3 * File written by Gilles Vollant, by modifiying the longest_match
4 * from Jean-loup Gailly in deflate.c 4 * from Jean-loup Gailly in deflate.c
5 * it prepare all parameters and call the assembly longest_match_gvasm 5 * it prepare all parameters and call the assembly longest_match_gvasm
6 * longest_match execute standard C code is wmask != 0x7fff 6 * longest_match execute standard C code is wmask != 0x7fff
7 * (assembly code is faster with a fixed wmask) 7 * (assembly code is faster with a fixed wmask)
8 * 8 *
9 */ 9 * Read comment at beginning of gvmat32.asm for more information
10 10 */
11#include "deflate.h" 11
12 12#if defined(ASMV) && (!defined(NOOLDPENTIUMCODE))
13#ifdef ASMV 13#include "deflate.h"
14#define NIL 0 14
15 15/* if your C compiler don't add underline before function name,
16#define UNALIGNED_OK 16 define ADD_UNDERLINE_ASMFUNC */
17 17#ifdef ADD_UNDERLINE_ASMFUNC
18 18#define longest_match_7fff _longest_match_7fff
19/* if your C compiler don't add underline before function name, 19#define longest_match_686 _longest_match_686
20 define ADD_UNDERLINE_ASMFUNC */ 20#define cpudetect32 _cpudetect32
21#ifdef ADD_UNDERLINE_ASMFUNC 21#endif
22#define longest_match_7fff _longest_match_7fff 22
23#define longest_match_686 _longest_match_686 23
24#define cpudetect32 _cpudetect32 24unsigned long cpudetect32();
25#endif 25
26 26uInt longest_match_c(
27 27 deflate_state *s,
28 28 IPos cur_match); /* current match */
29void match_init() 29
30{ 30
31} 31uInt longest_match_7fff(
32 32 deflate_state *s,
33unsigned long cpudetect32(); 33 IPos cur_match); /* current match */
34 34
35uInt longest_match_c( 35uInt longest_match_686(
36 deflate_state *s, 36 deflate_state *s,
37 IPos cur_match); /* current match */ 37 IPos cur_match); /* current match */
38 38
39 39
40uInt longest_match_7fff( 40static uInt iIsPPro=2;
41 deflate_state *s, 41
42 IPos cur_match); /* current match */ 42void match_init ()
43 43{
44uInt longest_match_686( 44 iIsPPro = (((cpudetect32()/0x100)&0xf)>=6) ? 1 : 0;
45 deflate_state *s, 45}
46 IPos cur_match); /* current match */ 46
47 47uInt longest_match(
48uInt longest_match( 48 deflate_state *s,
49 deflate_state *s, 49 IPos cur_match) /* current match */
50 IPos cur_match) /* current match */ 50{
51{ 51 if (iIsPPro!=0)
52 static uInt iIsPPro=2; 52 return longest_match_686(s,cur_match);
53 53
54 if ((s->w_mask == 0x7fff) && (iIsPPro==0)) 54 if (s->w_mask != 0x7fff)
55 return longest_match_7fff(s,cur_match); 55 return longest_match_686(s,cur_match);
56 56
57 if (iIsPPro==1) 57 /* now ((s->w_mask == 0x7fff) && (iIsPPro==0)) */
58 return longest_match_686(s,cur_match); 58 return longest_match_7fff(s,cur_match);
59 59}
60 if (iIsPPro==2) 60
61 iIsPPro = (((cpudetect32()/0x100)&0xf)>=6) ? 1 : 0; 61
62 62#endif /* defined(ASMV) && (!defined(NOOLDPENTIUMCODE)) */
63 return longest_match_c(s,cur_match);
64}
65
66
67
68uInt longest_match_c(s, cur_match)
69 deflate_state *s;
70 IPos cur_match; /* current match */
71{
72 unsigned chain_length = s->max_chain_length;/* max hash chain length */
73 register Bytef *scan = s->window + s->strstart; /* current string */
74 register Bytef *match; /* matched string */
75 register int len; /* length of current match */
76 int best_len = s->prev_length; /* best match length so far */
77 int nice_match = s->nice_match; /* stop if match long enough */
78 IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
79 s->strstart - (IPos)MAX_DIST(s) : NIL;
80 /* Stop when cur_match becomes <= limit. To simplify the code,
81 * we prevent matches with the string of window index 0.
82 */
83 Posf *prev = s->prev;
84 uInt wmask = s->w_mask;
85
86#ifdef UNALIGNED_OK
87 /* Compare two bytes at a time. Note: this is not always beneficial.
88 * Try with and without -DUNALIGNED_OK to check.
89 */
90 register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
91 register ush scan_start = *(ushf*)scan;
92 register ush scan_end = *(ushf*)(scan+best_len-1);
93#else
94 register Bytef *strend = s->window + s->strstart + MAX_MATCH;
95 register Byte scan_end1 = scan[best_len-1];
96 register Byte scan_end = scan[best_len];
97#endif
98
99 /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
100 * It is easy to get rid of this optimization if necessary.
101 */
102 Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
103
104 /* Do not waste too much time if we already have a good match: */
105 if (s->prev_length >= s->good_match) {
106 chain_length >>= 2;
107 }
108 /* Do not look for matches beyond the end of the input. This is necessary
109 * to make deflate deterministic.
110 */
111 if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
112
113 Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
114
115 do {
116 Assert(cur_match < s->strstart, "no future");
117 match = s->window + cur_match;
118
119 /* Skip to next match if the match length cannot increase
120 * or if the match length is less than 2:
121 */
122#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
123 /* This code assumes sizeof(unsigned short) == 2. Do not use
124 * UNALIGNED_OK if your compiler uses a different size.
125 */
126 if (*(ushf*)(match+best_len-1) != scan_end ||
127 *(ushf*)match != scan_start) continue;
128
129 /* It is not necessary to compare scan[2] and match[2] since they are
130 * always equal when the other bytes match, given that the hash keys
131 * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
132 * strstart+3, +5, ... up to strstart+257. We check for insufficient
133 * lookahead only every 4th comparison; the 128th check will be made
134 * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
135 * necessary to put more guard bytes at the end of the window, or
136 * to check more often for insufficient lookahead.
137 */
138 Assert(scan[2] == match[2], "scan[2]?");
139 scan++, match++;
140 do {
141 } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
142 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
143 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
144 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
145 scan < strend);
146 /* The funny "do {}" generates better code on most compilers */
147
148 /* Here, scan <= window+strstart+257 */
149 Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
150 if (*scan == *match) scan++;
151
152 len = (MAX_MATCH - 1) - (int)(strend-scan);
153 scan = strend - (MAX_MATCH-1);
154
155#else /* UNALIGNED_OK */
156
157 if (match[best_len] != scan_end ||
158 match[best_len-1] != scan_end1 ||
159 *match != *scan ||
160 *++match != scan[1]) continue;
161
162 /* The check at best_len-1 can be removed because it will be made
163 * again later. (This heuristic is not always a win.)
164 * It is not necessary to compare scan[2] and match[2] since they
165 * are always equal when the other bytes match, given that
166 * the hash keys are equal and that HASH_BITS >= 8.
167 */
168 scan += 2, match++;
169 Assert(*scan == *match, "match[2]?");
170
171 /* We check for insufficient lookahead only every 8th comparison;
172 * the 256th check will be made at strstart+258.
173 */
174 do {
175 } while (*++scan == *++match && *++scan == *++match &&
176 *++scan == *++match && *++scan == *++match &&
177 *++scan == *++match && *++scan == *++match &&
178 *++scan == *++match && *++scan == *++match &&
179 scan < strend);
180
181 Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
182
183 len = MAX_MATCH - (int)(strend - scan);
184 scan = strend - MAX_MATCH;
185
186#endif /* UNALIGNED_OK */
187
188 if (len > best_len) {
189 s->match_start = cur_match;
190 best_len = len;
191 if (len >= nice_match) break;
192#ifdef UNALIGNED_OK
193 scan_end = *(ushf*)(scan+best_len-1);
194#else
195 scan_end1 = scan[best_len-1];
196 scan_end = scan[best_len];
197#endif
198 }
199 } while ((cur_match = prev[cur_match & wmask]) > limit
200 && --chain_length != 0);
201
202 if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
203 return s->lookahead;
204}
205
206#endif /* ASMV */
diff --git a/contrib/masmx86/inffas32.asm b/contrib/masmx86/inffas32.asm
index 531bcef..4a20512 100644
--- a/contrib/masmx86/inffas32.asm
+++ b/contrib/masmx86/inffas32.asm
@@ -1,1036 +1,1083 @@
1; 75 "inffast.S" 1;/* inffas32.asm is a hand tuned assembler version of inffast.c -- fast decoding
2;FILE "inffast.S" 2; *
3 3; * inffas32.asm is derivated from inffas86.c, with translation of assembly code
4;;;GLOBAL _inflate_fast 4; *
5 5; * Copyright (C) 1995-2003 Mark Adler
6;;;SECTION .text 6; * For conditions of distribution and use, see copyright notice in zlib.h
7 7; *
8 8; * Copyright (C) 2003 Chris Anderson <christop@charm.net>
9 9; * Please use the copyright conditions above.
10 .586p 10; *
11 .mmx 11; * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from
12 12; * the gcc -S output of zlib-1.2.0/inffast.c. Zlib-1.2.0 is in beta release at
13 name inflate_fast_x86 13; * the moment. I have successfully compiled and tested this code with gcc2.96,
14 .MODEL FLAT 14; * gcc3.2, icc5.0, msvc6.0. It is very close to the speed of inffast.S
15 15; * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX
16_DATA segment 16; * enabled. I will attempt to merge the MMX code into this version. Newer
17inflate_fast_use_mmx: 17; * versions of this and inffast.S can be found at
18 dd 1 18; * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/
19 19; *
20 20; * 2005 : modification by Gilles Vollant
21_TEXT segment 21; */
22PUBLIC _inflate_fast 22; For Visual C++ 4.x and higher and ML 6.x and higher
23 23; ml.exe is in directory \MASM611C of Win95 DDK
24ALIGN 4 24; ml.exe is also distributed in http://www.masm32.com/masmdl.htm
25_inflate_fast: 25; and in VC++2003 toolkit at http://msdn.microsoft.com/visualc/vctoolkit2003/
26 jmp inflate_fast_entry 26;
27 27;
28 28; compile with command line option
29 29; ml /coff /Zi /c /Flinffas32.lst inffas32.asm
30ALIGN 4 30
31 db 'Fast decoding Code from Chris Anderson' 31; if you define NO_GZIP (see inflate.h), compile with
32 db 0 32; ml /coff /Zi /c /Flinffas32.lst /DNO_GUNZIP inffas32.asm
33 33
34ALIGN 4 34
35invalid_literal_length_code_msg: 35; zlib122sup is 0 fort zlib 1.2.2.1 and lower
36 db 'invalid literal/length code' 36; zlib122sup is 8 fort zlib 1.2.2.2 and more (with addition of dmax and head
37 db 0 37; in inflate_state in inflate.h)
38 38zlib1222sup equ 8
39ALIGN 4 39
40invalid_distance_code_msg: 40
41 db 'invalid distance code' 41IFDEF GUNZIP
42 db 0 42 INFLATE_MODE_TYPE equ 11
43 43 INFLATE_MODE_BAD equ 26
44ALIGN 4 44ELSE
45invalid_distance_too_far_msg: 45 IFNDEF NO_GUNZIP
46 db 'invalid distance too far back' 46 INFLATE_MODE_TYPE equ 11
47 db 0 47 INFLATE_MODE_BAD equ 26
48 48 ELSE
49 49 INFLATE_MODE_TYPE equ 3
50ALIGN 4 50 INFLATE_MODE_BAD equ 17
51inflate_fast_mask: 51 ENDIF
52dd 0 52ENDIF
53dd 1 53
54dd 3 54
55dd 7 55; 75 "inffast.S"
56dd 15 56;FILE "inffast.S"
57dd 31 57
58dd 63 58;;;GLOBAL _inflate_fast
59dd 127 59
60dd 255 60;;;SECTION .text
61dd 511 61
62dd 1023 62
63dd 2047 63
64dd 4095 64 .586p
65dd 8191 65 .mmx
66dd 16383 66
67dd 32767 67 name inflate_fast_x86
68dd 65535 68 .MODEL FLAT
69dd 131071 69
70dd 262143 70_DATA segment
71dd 524287 71inflate_fast_use_mmx:
72dd 1048575 72 dd 1
73dd 2097151 73
74dd 4194303 74
75dd 8388607 75_TEXT segment
76dd 16777215 76PUBLIC _inflate_fast
77dd 33554431 77
78dd 67108863 78ALIGN 4
79dd 134217727 79_inflate_fast:
80dd 268435455 80 jmp inflate_fast_entry
81dd 536870911 81
82dd 1073741823 82
83dd 2147483647 83
84dd 4294967295 84ALIGN 4
85 85 db 'Fast decoding Code from Chris Anderson'
86 86 db 0
87; head was added in zlib 1.2.2.1, so we add addstr 87
88; set addstr to 0 with zlib 1.2.1 of below 88ALIGN 4
89addstr equ 4 89invalid_literal_length_code_msg:
90 90 db 'invalid literal/length code'
91mode_state equ 0 ;/* state->mode */ 91 db 0
92wsize_state equ 32+addstr ;/* state->wsize */ 92
93write_state equ (36+4+addstr) ;/* state->write */ 93ALIGN 4
94window_state equ (40+4+addstr) ;/* state->window */ 94invalid_distance_code_msg:
95hold_state equ (44+4+addstr) ;/* state->hold */ 95 db 'invalid distance code'
96bits_state equ (48+4+addstr) ;/* state->bits */ 96 db 0
97lencode_state equ (64+4+addstr) ;/* state->lencode */ 97
98distcode_state equ (68+4+addstr) ;/* state->distcode */ 98ALIGN 4
99lenbits_state equ (72+4+addstr) ;/* state->lenbits */ 99invalid_distance_too_far_msg:
100distbits_state equ (76+4+addstr) ;/* state->distbits */ 100 db 'invalid distance too far back'
101 101 db 0
102 102
103;;SECTION .text 103
104; 205 "inffast.S" 104ALIGN 4
105;GLOBAL inflate_fast_use_mmx 105inflate_fast_mask:
106 106dd 0
107;SECTION .data 107dd 1
108 108dd 3
109 109dd 7
110; GLOBAL inflate_fast_use_mmx:object 110dd 15
111;.size inflate_fast_use_mmx, 4 111dd 31
112; 226 "inffast.S" 112dd 63
113;SECTION .text 113dd 127
114 114dd 255
115ALIGN 4 115dd 511
116inflate_fast_entry: 116dd 1023
117 push edi 117dd 2047
118 push esi 118dd 4095
119 push ebp 119dd 8191
120 push ebx 120dd 16383
121 pushfd 121dd 32767
122 sub esp,64 122dd 65535
123 cld 123dd 131071
124 124dd 262143
125 125dd 524287
126 126dd 1048575
127 127dd 2097151
128 mov esi, [esp+88] 128dd 4194303
129 mov edi, [esi+28] 129dd 8388607
130 130dd 16777215
131 131dd 33554431
132 132dd 67108863
133 133dd 134217727
134 134dd 268435455
135 135dd 536870911
136 136dd 1073741823
137 mov edx, [esi+4] 137dd 2147483647
138 mov eax, [esi+0] 138dd 4294967295
139 139
140 add edx,eax 140
141 sub edx,11 141mode_state equ 0 ;/* state->mode */
142 142wsize_state equ (32+zlib1222sup) ;/* state->wsize */
143 mov [esp+44],eax 143write_state equ (36+4+zlib1222sup) ;/* state->write */
144 mov [esp+20],edx 144window_state equ (40+4+zlib1222sup) ;/* state->window */
145 145hold_state equ (44+4+zlib1222sup) ;/* state->hold */
146 mov ebp, [esp+92] 146bits_state equ (48+4+zlib1222sup) ;/* state->bits */
147 mov ecx, [esi+16] 147lencode_state equ (64+4+zlib1222sup) ;/* state->lencode */
148 mov ebx, [esi+12] 148distcode_state equ (68+4+zlib1222sup) ;/* state->distcode */
149 149lenbits_state equ (72+4+zlib1222sup) ;/* state->lenbits */
150 sub ebp,ecx 150distbits_state equ (76+4+zlib1222sup) ;/* state->distbits */
151 neg ebp 151
152 add ebp,ebx 152
153 153;;SECTION .text
154 sub ecx,257 154; 205 "inffast.S"
155 add ecx,ebx 155;GLOBAL inflate_fast_use_mmx
156 156
157 mov [esp+60],ebx 157;SECTION .data
158 mov [esp+40],ebp 158
159 mov [esp+16],ecx 159
160; 285 "inffast.S" 160; GLOBAL inflate_fast_use_mmx:object
161 mov eax, [edi+lencode_state] 161;.size inflate_fast_use_mmx, 4
162 mov ecx, [edi+distcode_state] 162; 226 "inffast.S"
163 163;SECTION .text
164 mov [esp+8],eax 164
165 mov [esp+12],ecx 165ALIGN 4
166 166inflate_fast_entry:
167 mov eax,1 167 push edi
168 mov ecx, [edi+lenbits_state] 168 push esi
169 shl eax,cl 169 push ebp
170 dec eax 170 push ebx
171 mov [esp+0],eax 171 pushfd
172 172 sub esp,64
173 mov eax,1 173 cld
174 mov ecx, [edi+distbits_state] 174
175 shl eax,cl 175
176 dec eax 176
177 mov [esp+4],eax 177
178 178 mov esi, [esp+88]
179 mov eax, [edi+wsize_state] 179 mov edi, [esi+28]
180 mov ecx, [edi+write_state] 180
181 mov edx, [edi+window_state] 181
182 182
183 mov [esp+52],eax 183
184 mov [esp+48],ecx 184
185 mov [esp+56],edx 185
186 186
187 mov ebp, [edi+hold_state] 187 mov edx, [esi+4]
188 mov ebx, [edi+bits_state] 188 mov eax, [esi+0]
189; 321 "inffast.S" 189
190 mov esi, [esp+44] 190 add edx,eax
191 mov ecx, [esp+20] 191 sub edx,11
192 cmp ecx,esi 192
193 ja L_align_long 193 mov [esp+44],eax
194 194 mov [esp+20],edx
195 add ecx,11 195
196 sub ecx,esi 196 mov ebp, [esp+92]
197 mov eax,12 197 mov ecx, [esi+16]
198 sub eax,ecx 198 mov ebx, [esi+12]
199 lea edi, [esp+28] 199
200 rep movsb 200 sub ebp,ecx
201 mov ecx,eax 201 neg ebp
202 xor eax,eax 202 add ebp,ebx
203 rep stosb 203
204 lea esi, [esp+28] 204 sub ecx,257
205 mov [esp+20],esi 205 add ecx,ebx
206 jmp L_is_aligned 206
207 207 mov [esp+60],ebx
208 208 mov [esp+40],ebp
209L_align_long: 209 mov [esp+16],ecx
210 test esi,3 210; 285 "inffast.S"
211 jz L_is_aligned 211 mov eax, [edi+lencode_state]
212 xor eax,eax 212 mov ecx, [edi+distcode_state]
213 mov al, [esi] 213
214 inc esi 214 mov [esp+8],eax
215 mov ecx,ebx 215 mov [esp+12],ecx
216 add ebx,8 216
217 shl eax,cl 217 mov eax,1
218 or ebp,eax 218 mov ecx, [edi+lenbits_state]
219 jmp L_align_long 219 shl eax,cl
220 220 dec eax
221L_is_aligned: 221 mov [esp+0],eax
222 mov edi, [esp+60] 222
223; 366 "inffast.S" 223 mov eax,1
224L_check_mmx: 224 mov ecx, [edi+distbits_state]
225 cmp dword ptr [inflate_fast_use_mmx],2 225 shl eax,cl
226 je L_init_mmx 226 dec eax
227 ja L_do_loop 227 mov [esp+4],eax
228 228
229 push eax 229 mov eax, [edi+wsize_state]
230 push ebx 230 mov ecx, [edi+write_state]
231 push ecx 231 mov edx, [edi+window_state]
232 push edx 232
233 pushfd 233 mov [esp+52],eax
234 mov eax, [esp] 234 mov [esp+48],ecx
235 xor dword ptr [esp],0200000h 235 mov [esp+56],edx
236 236
237 237 mov ebp, [edi+hold_state]
238 238 mov ebx, [edi+bits_state]
239 239; 321 "inffast.S"
240 popfd 240 mov esi, [esp+44]
241 pushfd 241 mov ecx, [esp+20]
242 pop edx 242 cmp ecx,esi
243 xor edx,eax 243 ja L_align_long
244 jz L_dont_use_mmx 244
245 xor eax,eax 245 add ecx,11
246 cpuid 246 sub ecx,esi
247 cmp ebx,0756e6547h 247 mov eax,12
248 jne L_dont_use_mmx 248 sub eax,ecx
249 cmp ecx,06c65746eh 249 lea edi, [esp+28]
250 jne L_dont_use_mmx 250 rep movsb
251 cmp edx,049656e69h 251 mov ecx,eax
252 jne L_dont_use_mmx 252 xor eax,eax
253 mov eax,1 253 rep stosb
254 cpuid 254 lea esi, [esp+28]
255 shr eax,8 255 mov [esp+20],esi
256 and eax,15 256 jmp L_is_aligned
257 cmp eax,6 257
258 jne L_dont_use_mmx 258
259 test edx,0800000h 259L_align_long:
260 jnz L_use_mmx 260 test esi,3
261 jmp L_dont_use_mmx 261 jz L_is_aligned
262L_use_mmx: 262 xor eax,eax
263 mov dword ptr [inflate_fast_use_mmx],2 263 mov al, [esi]
264 jmp L_check_mmx_pop 264 inc esi
265L_dont_use_mmx: 265 mov ecx,ebx
266 mov dword ptr [inflate_fast_use_mmx],3 266 add ebx,8
267L_check_mmx_pop: 267 shl eax,cl
268 pop edx 268 or ebp,eax
269 pop ecx 269 jmp L_align_long
270 pop ebx 270
271 pop eax 271L_is_aligned:
272 jmp L_check_mmx 272 mov edi, [esp+60]
273; 426 "inffast.S" 273; 366 "inffast.S"
274ALIGN 4 274L_check_mmx:
275L_do_loop: 275 cmp dword ptr [inflate_fast_use_mmx],2
276; 437 "inffast.S" 276 je L_init_mmx
277 cmp bl,15 277 ja L_do_loop
278 ja L_get_length_code 278
279 279 push eax
280 xor eax,eax 280 push ebx
281 lodsw 281 push ecx
282 mov cl,bl 282 push edx
283 add bl,16 283 pushfd
284 shl eax,cl 284 mov eax, [esp]
285 or ebp,eax 285 xor dword ptr [esp],0200000h
286 286
287L_get_length_code: 287
288 mov edx, [esp+0] 288
289 mov ecx, [esp+8] 289
290 and edx,ebp 290 popfd
291 mov eax, [ecx+edx*4] 291 pushfd
292 292 pop edx
293L_dolen: 293 xor edx,eax
294 294 jz L_dont_use_mmx
295 295 xor eax,eax
296 296 cpuid
297 297 cmp ebx,0756e6547h
298 298 jne L_dont_use_mmx
299 299 cmp ecx,06c65746eh
300 mov cl,ah 300 jne L_dont_use_mmx
301 sub bl,ah 301 cmp edx,049656e69h
302 shr ebp,cl 302 jne L_dont_use_mmx
303 303 mov eax,1
304 304 cpuid
305 305 shr eax,8
306 306 and eax,15
307 307 cmp eax,6
308 308 jne L_dont_use_mmx
309 test al,al 309 test edx,0800000h
310 jnz L_test_for_length_base 310 jnz L_use_mmx
311 311 jmp L_dont_use_mmx
312 shr eax,16 312L_use_mmx:
313 stosb 313 mov dword ptr [inflate_fast_use_mmx],2
314 314 jmp L_check_mmx_pop
315L_while_test: 315L_dont_use_mmx:
316 316 mov dword ptr [inflate_fast_use_mmx],3
317 317L_check_mmx_pop:
318 cmp [esp+16],edi 318 pop edx
319 jbe L_break_loop 319 pop ecx
320 320 pop ebx
321 cmp [esp+20],esi 321 pop eax
322 ja L_do_loop 322 jmp L_check_mmx
323 jmp L_break_loop 323; 426 "inffast.S"
324 324ALIGN 4
325L_test_for_length_base: 325L_do_loop:
326; 502 "inffast.S" 326; 437 "inffast.S"
327 mov edx,eax 327 cmp bl,15
328 shr edx,16 328 ja L_get_length_code
329 mov cl,al 329
330 330 xor eax,eax
331 test al,16 331 lodsw
332 jz L_test_for_second_level_length 332 mov cl,bl
333 and cl,15 333 add bl,16
334 jz L_save_len 334 shl eax,cl
335 cmp bl,cl 335 or ebp,eax
336 jae L_add_bits_to_len 336
337 337L_get_length_code:
338 mov ch,cl 338 mov edx, [esp+0]
339 xor eax,eax 339 mov ecx, [esp+8]
340 lodsw 340 and edx,ebp
341 mov cl,bl 341 mov eax, [ecx+edx*4]
342 add bl,16 342
343 shl eax,cl 343L_dolen:
344 or ebp,eax 344
345 mov cl,ch 345
346 346
347L_add_bits_to_len: 347
348 mov eax,1 348
349 shl eax,cl 349
350 dec eax 350 mov cl,ah
351 sub bl,cl 351 sub bl,ah
352 and eax,ebp 352 shr ebp,cl
353 shr ebp,cl 353
354 add edx,eax 354
355 355
356L_save_len: 356
357 mov [esp+24],edx 357
358 358
359 359 test al,al
360L_decode_distance: 360 jnz L_test_for_length_base
361; 549 "inffast.S" 361
362 cmp bl,15 362 shr eax,16
363 ja L_get_distance_code 363 stosb
364 364
365 xor eax,eax 365L_while_test:
366 lodsw 366
367 mov cl,bl 367
368 add bl,16 368 cmp [esp+16],edi
369 shl eax,cl 369 jbe L_break_loop
370 or ebp,eax 370
371 371 cmp [esp+20],esi
372L_get_distance_code: 372 ja L_do_loop
373 mov edx, [esp+4] 373 jmp L_break_loop
374 mov ecx, [esp+12] 374
375 and edx,ebp 375L_test_for_length_base:
376 mov eax, [ecx+edx*4] 376; 502 "inffast.S"
377 377 mov edx,eax
378 378 shr edx,16
379L_dodist: 379 mov cl,al
380 mov edx,eax 380
381 shr edx,16 381 test al,16
382 mov cl,ah 382 jz L_test_for_second_level_length
383 sub bl,ah 383 and cl,15
384 shr ebp,cl 384 jz L_save_len
385; 584 "inffast.S" 385 cmp bl,cl
386 mov cl,al 386 jae L_add_bits_to_len
387 387
388 test al,16 388 mov ch,cl
389 jz L_test_for_second_level_dist 389 xor eax,eax
390 and cl,15 390 lodsw
391 jz L_check_dist_one 391 mov cl,bl
392 cmp bl,cl 392 add bl,16
393 jae L_add_bits_to_dist 393 shl eax,cl
394 394 or ebp,eax
395 mov ch,cl 395 mov cl,ch
396 xor eax,eax 396
397 lodsw 397L_add_bits_to_len:
398 mov cl,bl 398 mov eax,1
399 add bl,16 399 shl eax,cl
400 shl eax,cl 400 dec eax
401 or ebp,eax 401 sub bl,cl
402 mov cl,ch 402 and eax,ebp
403 403 shr ebp,cl
404L_add_bits_to_dist: 404 add edx,eax
405 mov eax,1 405
406 shl eax,cl 406L_save_len:
407 dec eax 407 mov [esp+24],edx
408 sub bl,cl 408
409 and eax,ebp 409
410 shr ebp,cl 410L_decode_distance:
411 add edx,eax 411; 549 "inffast.S"
412 jmp L_check_window 412 cmp bl,15
413 413 ja L_get_distance_code
414L_check_window: 414
415; 625 "inffast.S" 415 xor eax,eax
416 mov [esp+44],esi 416 lodsw
417 mov eax,edi 417 mov cl,bl
418 sub eax, [esp+40] 418 add bl,16
419 419 shl eax,cl
420 cmp eax,edx 420 or ebp,eax
421 jb L_clip_window 421
422 422L_get_distance_code:
423 mov ecx, [esp+24] 423 mov edx, [esp+4]
424 mov esi,edi 424 mov ecx, [esp+12]
425 sub esi,edx 425 and edx,ebp
426 426 mov eax, [ecx+edx*4]
427 sub ecx,3 427
428 mov al, [esi] 428
429 mov [edi],al 429L_dodist:
430 mov al, [esi+1] 430 mov edx,eax
431 mov dl, [esi+2] 431 shr edx,16
432 add esi,3 432 mov cl,ah
433 mov [edi+1],al 433 sub bl,ah
434 mov [edi+2],dl 434 shr ebp,cl
435 add edi,3 435; 584 "inffast.S"
436 rep movsb 436 mov cl,al
437 437
438 mov esi, [esp+44] 438 test al,16
439 jmp L_while_test 439 jz L_test_for_second_level_dist
440 440 and cl,15
441ALIGN 4 441 jz L_check_dist_one
442L_check_dist_one: 442 cmp bl,cl
443 cmp edx,1 443 jae L_add_bits_to_dist
444 jne L_check_window 444
445 cmp [esp+40],edi 445 mov ch,cl
446 je L_check_window 446 xor eax,eax
447 447 lodsw
448 dec edi 448 mov cl,bl
449 mov ecx, [esp+24] 449 add bl,16
450 mov al, [edi] 450 shl eax,cl
451 sub ecx,3 451 or ebp,eax
452 452 mov cl,ch
453 mov [edi+1],al 453
454 mov [edi+2],al 454L_add_bits_to_dist:
455 mov [edi+3],al 455 mov eax,1
456 add edi,4 456 shl eax,cl
457 rep stosb 457 dec eax
458 458 sub bl,cl
459 jmp L_while_test 459 and eax,ebp
460 460 shr ebp,cl
461ALIGN 4 461 add edx,eax
462L_test_for_second_level_length: 462 jmp L_check_window
463 463
464 464L_check_window:
465 465; 625 "inffast.S"
466 466 mov [esp+44],esi
467 test al,64 467 mov eax,edi
468 jnz L_test_for_end_of_block 468 sub eax, [esp+40]
469 469
470 mov eax,1 470 cmp eax,edx
471 shl eax,cl 471 jb L_clip_window
472 dec eax 472
473 and eax,ebp 473 mov ecx, [esp+24]
474 add eax,edx 474 mov esi,edi
475 mov edx, [esp+8] 475 sub esi,edx
476 mov eax, [edx+eax*4] 476
477 jmp L_dolen 477 sub ecx,3
478 478 mov al, [esi]
479ALIGN 4 479 mov [edi],al
480L_test_for_second_level_dist: 480 mov al, [esi+1]
481 481 mov dl, [esi+2]
482 482 add esi,3
483 483 mov [edi+1],al
484 484 mov [edi+2],dl
485 test al,64 485 add edi,3
486 jnz L_invalid_distance_code 486 rep movsb
487 487
488 mov eax,1 488 mov esi, [esp+44]
489 shl eax,cl 489 jmp L_while_test
490 dec eax 490
491 and eax,ebp 491ALIGN 4
492 add eax,edx 492L_check_dist_one:
493 mov edx, [esp+12] 493 cmp edx,1
494 mov eax, [edx+eax*4] 494 jne L_check_window
495 jmp L_dodist 495 cmp [esp+40],edi
496 496 je L_check_window
497ALIGN 4 497
498L_clip_window: 498 dec edi
499; 721 "inffast.S" 499 mov ecx, [esp+24]
500 mov ecx,eax 500 mov al, [edi]
501 mov eax, [esp+52] 501 sub ecx,3
502 neg ecx 502
503 mov esi, [esp+56] 503 mov [edi+1],al
504 504 mov [edi+2],al
505 cmp eax,edx 505 mov [edi+3],al
506 jb L_invalid_distance_too_far 506 add edi,4
507 507 rep stosb
508 add ecx,edx 508
509 cmp dword ptr [esp+48],0 509 jmp L_while_test
510 jne L_wrap_around_window 510
511 511ALIGN 4
512 sub eax,ecx 512L_test_for_second_level_length:
513 add esi,eax 513
514; 749 "inffast.S" 514
515 mov eax, [esp+24] 515
516 cmp eax,ecx 516
517 jbe L_do_copy1 517 test al,64
518 518 jnz L_test_for_end_of_block
519 sub eax,ecx 519
520 rep movsb 520 mov eax,1
521 mov esi,edi 521 shl eax,cl
522 sub esi,edx 522 dec eax
523 jmp L_do_copy1 523 and eax,ebp
524 524 add eax,edx
525 cmp eax,ecx 525 mov edx, [esp+8]
526 jbe L_do_copy1 526 mov eax, [edx+eax*4]
527 527 jmp L_dolen
528 sub eax,ecx 528
529 rep movsb 529ALIGN 4
530 mov esi,edi 530L_test_for_second_level_dist:
531 sub esi,edx 531
532 jmp L_do_copy1 532
533 533
534L_wrap_around_window: 534
535; 793 "inffast.S" 535 test al,64
536 mov eax, [esp+48] 536 jnz L_invalid_distance_code
537 cmp ecx,eax 537
538 jbe L_contiguous_in_window 538 mov eax,1
539 539 shl eax,cl
540 add esi, [esp+52] 540 dec eax
541 add esi,eax 541 and eax,ebp
542 sub esi,ecx 542 add eax,edx
543 sub ecx,eax 543 mov edx, [esp+12]
544 544 mov eax, [edx+eax*4]
545 545 jmp L_dodist
546 mov eax, [esp+24] 546
547 cmp eax,ecx 547ALIGN 4
548 jbe L_do_copy1 548L_clip_window:
549 549; 721 "inffast.S"
550 sub eax,ecx 550 mov ecx,eax
551 rep movsb 551 mov eax, [esp+52]
552 mov esi, [esp+56] 552 neg ecx
553 mov ecx, [esp+48] 553 mov esi, [esp+56]
554 cmp eax,ecx 554
555 jbe L_do_copy1 555 cmp eax,edx
556 556 jb L_invalid_distance_too_far
557 sub eax,ecx 557
558 rep movsb 558 add ecx,edx
559 mov esi,edi 559 cmp dword ptr [esp+48],0
560 sub esi,edx 560 jne L_wrap_around_window
561 jmp L_do_copy1 561
562 562 sub eax,ecx
563L_contiguous_in_window: 563 add esi,eax
564; 836 "inffast.S" 564; 749 "inffast.S"
565 add esi,eax 565 mov eax, [esp+24]
566 sub esi,ecx 566 cmp eax,ecx
567 567 jbe L_do_copy1
568 568
569 mov eax, [esp+24] 569 sub eax,ecx
570 cmp eax,ecx 570 rep movsb
571 jbe L_do_copy1 571 mov esi,edi
572 572 sub esi,edx
573 sub eax,ecx 573 jmp L_do_copy1
574 rep movsb 574
575 mov esi,edi 575 cmp eax,ecx
576 sub esi,edx 576 jbe L_do_copy1
577 577
578L_do_copy1: 578 sub eax,ecx
579; 862 "inffast.S" 579 rep movsb
580 mov ecx,eax 580 mov esi,edi
581 rep movsb 581 sub esi,edx
582 582 jmp L_do_copy1
583 mov esi, [esp+44] 583
584 jmp L_while_test 584L_wrap_around_window:
585; 878 "inffast.S" 585; 793 "inffast.S"
586ALIGN 4 586 mov eax, [esp+48]
587L_init_mmx: 587 cmp ecx,eax
588 emms 588 jbe L_contiguous_in_window
589 589
590 590 add esi, [esp+52]
591 591 add esi,eax
592 592 sub esi,ecx
593 593 sub ecx,eax
594 movd mm0,ebp 594
595 mov ebp,ebx 595
596; 896 "inffast.S" 596 mov eax, [esp+24]
597 movd mm4,[esp+0] 597 cmp eax,ecx
598 movq mm3,mm4 598 jbe L_do_copy1
599 movd mm5,[esp+4] 599
600 movq mm2,mm5 600 sub eax,ecx
601 pxor mm1,mm1 601 rep movsb
602 mov ebx, [esp+8] 602 mov esi, [esp+56]
603 jmp L_do_loop_mmx 603 mov ecx, [esp+48]
604 604 cmp eax,ecx
605ALIGN 4 605 jbe L_do_copy1
606L_do_loop_mmx: 606
607 psrlq mm0,mm1 607 sub eax,ecx
608 608 rep movsb
609 cmp ebp,32 609 mov esi,edi
610 ja L_get_length_code_mmx 610 sub esi,edx
611 611 jmp L_do_copy1
612 movd mm6,ebp 612
613 movd mm7,[esi] 613L_contiguous_in_window:
614 add esi,4 614; 836 "inffast.S"
615 psllq mm7,mm6 615 add esi,eax
616 add ebp,32 616 sub esi,ecx
617 por mm0,mm7 617
618 618
619L_get_length_code_mmx: 619 mov eax, [esp+24]
620 pand mm4,mm0 620 cmp eax,ecx
621 movd eax,mm4 621 jbe L_do_copy1
622 movq mm4,mm3 622
623 mov eax, [ebx+eax*4] 623 sub eax,ecx
624 624 rep movsb
625L_dolen_mmx: 625 mov esi,edi
626 movzx ecx,ah 626 sub esi,edx
627 movd mm1,ecx 627
628 sub ebp,ecx 628L_do_copy1:
629 629; 862 "inffast.S"
630 test al,al 630 mov ecx,eax
631 jnz L_test_for_length_base_mmx 631 rep movsb
632 632
633 shr eax,16 633 mov esi, [esp+44]
634 stosb 634 jmp L_while_test
635 635; 878 "inffast.S"
636L_while_test_mmx: 636ALIGN 4
637 637L_init_mmx:
638 638 emms
639 cmp [esp+16],edi 639
640 jbe L_break_loop 640
641 641
642 cmp [esp+20],esi 642
643 ja L_do_loop_mmx 643
644 jmp L_break_loop 644 movd mm0,ebp
645 645 mov ebp,ebx
646L_test_for_length_base_mmx: 646; 896 "inffast.S"
647 647 movd mm4,[esp+0]
648 mov edx,eax 648 movq mm3,mm4
649 shr edx,16 649 movd mm5,[esp+4]
650 650 movq mm2,mm5
651 test al,16 651 pxor mm1,mm1
652 jz L_test_for_second_level_length_mmx 652 mov ebx, [esp+8]
653 and eax,15 653 jmp L_do_loop_mmx
654 jz L_decode_distance_mmx 654
655 655ALIGN 4
656 psrlq mm0,mm1 656L_do_loop_mmx:
657 movd mm1,eax 657 psrlq mm0,mm1
658 movd ecx,mm0 658
659 sub ebp,eax 659 cmp ebp,32
660 and ecx, [inflate_fast_mask+eax*4] 660 ja L_get_length_code_mmx
661 add edx,ecx 661
662 662 movd mm6,ebp
663L_decode_distance_mmx: 663 movd mm7,[esi]
664 psrlq mm0,mm1 664 add esi,4
665 665 psllq mm7,mm6
666 cmp ebp,32 666 add ebp,32
667 ja L_get_dist_code_mmx 667 por mm0,mm7
668 668
669 movd mm6,ebp 669L_get_length_code_mmx:
670 movd mm7,[esi] 670 pand mm4,mm0
671 add esi,4 671 movd eax,mm4
672 psllq mm7,mm6 672 movq mm4,mm3
673 add ebp,32 673 mov eax, [ebx+eax*4]
674 por mm0,mm7 674
675 675L_dolen_mmx:
676L_get_dist_code_mmx: 676 movzx ecx,ah
677 mov ebx, [esp+12] 677 movd mm1,ecx
678 pand mm5,mm0 678 sub ebp,ecx
679 movd eax,mm5 679
680 movq mm5,mm2 680 test al,al
681 mov eax, [ebx+eax*4] 681 jnz L_test_for_length_base_mmx
682 682
683L_dodist_mmx: 683 shr eax,16
684 684 stosb
685 movzx ecx,ah 685
686 mov ebx,eax 686L_while_test_mmx:
687 shr ebx,16 687
688 sub ebp,ecx 688
689 movd mm1,ecx 689 cmp [esp+16],edi
690 690 jbe L_break_loop
691 test al,16 691
692 jz L_test_for_second_level_dist_mmx 692 cmp [esp+20],esi
693 and eax,15 693 ja L_do_loop_mmx
694 jz L_check_dist_one_mmx 694 jmp L_break_loop
695 695
696L_add_bits_to_dist_mmx: 696L_test_for_length_base_mmx:
697 psrlq mm0,mm1 697
698 movd mm1,eax 698 mov edx,eax
699 movd ecx,mm0 699 shr edx,16
700 sub ebp,eax 700
701 and ecx, [inflate_fast_mask+eax*4] 701 test al,16
702 add ebx,ecx 702 jz L_test_for_second_level_length_mmx
703 703 and eax,15
704L_check_window_mmx: 704 jz L_decode_distance_mmx
705 mov [esp+44],esi 705
706 mov eax,edi 706 psrlq mm0,mm1
707 sub eax, [esp+40] 707 movd mm1,eax
708 708 movd ecx,mm0
709 cmp eax,ebx 709 sub ebp,eax
710 jb L_clip_window_mmx 710 and ecx, [inflate_fast_mask+eax*4]
711 711 add edx,ecx
712 mov ecx,edx 712
713 mov esi,edi 713L_decode_distance_mmx:
714 sub esi,ebx 714 psrlq mm0,mm1
715 715
716 sub ecx,3 716 cmp ebp,32
717 mov al, [esi] 717 ja L_get_dist_code_mmx
718 mov [edi],al 718
719 mov al, [esi+1] 719 movd mm6,ebp
720 mov dl, [esi+2] 720 movd mm7,[esi]
721 add esi,3 721 add esi,4
722 mov [edi+1],al 722 psllq mm7,mm6
723 mov [edi+2],dl 723 add ebp,32
724 add edi,3 724 por mm0,mm7
725 rep movsb 725
726 726L_get_dist_code_mmx:
727 mov esi, [esp+44] 727 mov ebx, [esp+12]
728 mov ebx, [esp+8] 728 pand mm5,mm0
729 jmp L_while_test_mmx 729 movd eax,mm5
730 730 movq mm5,mm2
731ALIGN 4 731 mov eax, [ebx+eax*4]
732L_check_dist_one_mmx: 732
733 cmp ebx,1 733L_dodist_mmx:
734 jne L_check_window_mmx 734
735 cmp [esp+40],edi 735 movzx ecx,ah
736 je L_check_window_mmx 736 mov ebx,eax
737 737 shr ebx,16
738 dec edi 738 sub ebp,ecx
739 mov ecx,edx 739 movd mm1,ecx
740 mov al, [edi] 740
741 sub ecx,3 741 test al,16
742 742 jz L_test_for_second_level_dist_mmx
743 mov [edi+1],al 743 and eax,15
744 mov [edi+2],al 744 jz L_check_dist_one_mmx
745 mov [edi+3],al 745
746 add edi,4 746L_add_bits_to_dist_mmx:
747 rep stosb 747 psrlq mm0,mm1
748 748 movd mm1,eax
749 mov ebx, [esp+8] 749 movd ecx,mm0
750 jmp L_while_test_mmx 750 sub ebp,eax
751 751 and ecx, [inflate_fast_mask+eax*4]
752ALIGN 4 752 add ebx,ecx
753L_test_for_second_level_length_mmx: 753
754 test al,64 754L_check_window_mmx:
755 jnz L_test_for_end_of_block 755 mov [esp+44],esi
756 756 mov eax,edi
757 and eax,15 757 sub eax, [esp+40]
758 psrlq mm0,mm1 758
759 movd ecx,mm0 759 cmp eax,ebx
760 and ecx, [inflate_fast_mask+eax*4] 760 jb L_clip_window_mmx
761 add ecx,edx 761
762 mov eax, [ebx+ecx*4] 762 mov ecx,edx
763 jmp L_dolen_mmx 763 mov esi,edi
764 764 sub esi,ebx
765ALIGN 4 765
766L_test_for_second_level_dist_mmx: 766 sub ecx,3
767 test al,64 767 mov al, [esi]
768 jnz L_invalid_distance_code 768 mov [edi],al
769 769 mov al, [esi+1]
770 and eax,15 770 mov dl, [esi+2]
771 psrlq mm0,mm1 771 add esi,3
772 movd ecx,mm0 772 mov [edi+1],al
773 and ecx, [inflate_fast_mask+eax*4] 773 mov [edi+2],dl
774 mov eax, [esp+12] 774 add edi,3
775 add ecx,ebx 775 rep movsb
776 mov eax, [eax+ecx*4] 776
777 jmp L_dodist_mmx 777 mov esi, [esp+44]
778 778 mov ebx, [esp+8]
779ALIGN 4 779 jmp L_while_test_mmx
780L_clip_window_mmx: 780
781 781ALIGN 4
782 mov ecx,eax 782L_check_dist_one_mmx:
783 mov eax, [esp+52] 783 cmp ebx,1
784 neg ecx 784 jne L_check_window_mmx
785 mov esi, [esp+56] 785 cmp [esp+40],edi
786 786 je L_check_window_mmx
787 cmp eax,ebx 787
788 jb L_invalid_distance_too_far 788 dec edi
789 789 mov ecx,edx
790 add ecx,ebx 790 mov al, [edi]
791 cmp dword ptr [esp+48],0 791 sub ecx,3
792 jne L_wrap_around_window_mmx 792
793 793 mov [edi+1],al
794 sub eax,ecx 794 mov [edi+2],al
795 add esi,eax 795 mov [edi+3],al
796 796 add edi,4
797 cmp edx,ecx 797 rep stosb
798 jbe L_do_copy1_mmx 798
799 799 mov ebx, [esp+8]
800 sub edx,ecx 800 jmp L_while_test_mmx
801 rep movsb 801
802 mov esi,edi 802ALIGN 4
803 sub esi,ebx 803L_test_for_second_level_length_mmx:
804 jmp L_do_copy1_mmx 804 test al,64
805 805 jnz L_test_for_end_of_block
806 cmp edx,ecx 806
807 jbe L_do_copy1_mmx 807 and eax,15
808 808 psrlq mm0,mm1
809 sub edx,ecx 809 movd ecx,mm0
810 rep movsb 810 and ecx, [inflate_fast_mask+eax*4]
811 mov esi,edi 811 add ecx,edx
812 sub esi,ebx 812 mov eax, [ebx+ecx*4]
813 jmp L_do_copy1_mmx 813 jmp L_dolen_mmx
814 814
815L_wrap_around_window_mmx: 815ALIGN 4
816 816L_test_for_second_level_dist_mmx:
817 mov eax, [esp+48] 817 test al,64
818 cmp ecx,eax 818 jnz L_invalid_distance_code
819 jbe L_contiguous_in_window_mmx 819
820 820 and eax,15
821 add esi, [esp+52] 821 psrlq mm0,mm1
822 add esi,eax 822 movd ecx,mm0
823 sub esi,ecx 823 and ecx, [inflate_fast_mask+eax*4]
824 sub ecx,eax 824 mov eax, [esp+12]
825 825 add ecx,ebx
826 826 mov eax, [eax+ecx*4]
827 cmp edx,ecx 827 jmp L_dodist_mmx
828 jbe L_do_copy1_mmx 828
829 829ALIGN 4
830 sub edx,ecx 830L_clip_window_mmx:
831 rep movsb 831
832 mov esi, [esp+56] 832 mov ecx,eax
833 mov ecx, [esp+48] 833 mov eax, [esp+52]
834 cmp edx,ecx 834 neg ecx
835 jbe L_do_copy1_mmx 835 mov esi, [esp+56]
836 836
837 sub edx,ecx 837 cmp eax,ebx
838 rep movsb 838 jb L_invalid_distance_too_far
839 mov esi,edi 839
840 sub esi,ebx 840 add ecx,ebx
841 jmp L_do_copy1_mmx 841 cmp dword ptr [esp+48],0
842 842 jne L_wrap_around_window_mmx
843L_contiguous_in_window_mmx: 843
844 844 sub eax,ecx
845 add esi,eax 845 add esi,eax
846 sub esi,ecx 846
847 847 cmp edx,ecx
848 848 jbe L_do_copy1_mmx
849 cmp edx,ecx 849
850 jbe L_do_copy1_mmx 850 sub edx,ecx
851 851 rep movsb
852 sub edx,ecx 852 mov esi,edi
853 rep movsb 853 sub esi,ebx
854 mov esi,edi 854 jmp L_do_copy1_mmx
855 sub esi,ebx 855
856 856 cmp edx,ecx
857L_do_copy1_mmx: 857 jbe L_do_copy1_mmx
858 858
859 859 sub edx,ecx
860 mov ecx,edx 860 rep movsb
861 rep movsb 861 mov esi,edi
862 862 sub esi,ebx
863 mov esi, [esp+44] 863 jmp L_do_copy1_mmx
864 mov ebx, [esp+8] 864
865 jmp L_while_test_mmx 865L_wrap_around_window_mmx:
866; 1174 "inffast.S" 866
867L_invalid_distance_code: 867 mov eax, [esp+48]
868 868 cmp ecx,eax
869 869 jbe L_contiguous_in_window_mmx
870 870
871 871 add esi, [esp+52]
872 872 add esi,eax
873 mov ecx, invalid_distance_code_msg 873 sub esi,ecx
874 mov edx,26 874 sub ecx,eax
875 jmp L_update_stream_state 875
876 876
877L_test_for_end_of_block: 877 cmp edx,ecx
878 878 jbe L_do_copy1_mmx
879 879
880 880 sub edx,ecx
881 881 rep movsb
882 882 mov esi, [esp+56]
883 test al,32 883 mov ecx, [esp+48]
884 jz L_invalid_literal_length_code 884 cmp edx,ecx
885 885 jbe L_do_copy1_mmx
886 mov ecx,0 886
887 mov edx,11 887 sub edx,ecx
888 jmp L_update_stream_state 888 rep movsb
889 889 mov esi,edi
890L_invalid_literal_length_code: 890 sub esi,ebx
891 891 jmp L_do_copy1_mmx
892 892
893 893L_contiguous_in_window_mmx:
894 894
895 895 add esi,eax
896 mov ecx, invalid_literal_length_code_msg 896 sub esi,ecx
897 mov edx,26 897
898 jmp L_update_stream_state 898
899 899 cmp edx,ecx
900L_invalid_distance_too_far: 900 jbe L_do_copy1_mmx
901 901
902 902 sub edx,ecx
903 903 rep movsb
904 mov esi, [esp+44] 904 mov esi,edi
905 mov ecx, invalid_distance_too_far_msg 905 sub esi,ebx
906 mov edx,26 906
907 jmp L_update_stream_state 907L_do_copy1_mmx:
908 908
909L_update_stream_state: 909
910 910 mov ecx,edx
911 mov eax, [esp+88] 911 rep movsb
912 test ecx,ecx 912
913 jz L_skip_msg 913 mov esi, [esp+44]
914 mov [eax+24],ecx 914 mov ebx, [esp+8]
915L_skip_msg: 915 jmp L_while_test_mmx
916 mov eax, [eax+28] 916; 1174 "inffast.S"
917 mov [eax+mode_state],edx 917L_invalid_distance_code:
918 jmp L_break_loop 918
919 919
920ALIGN 4 920
921L_break_loop: 921
922; 1243 "inffast.S" 922
923 cmp dword ptr [inflate_fast_use_mmx],2 923 mov ecx, invalid_distance_code_msg
924 jne L_update_next_in 924 mov edx,INFLATE_MODE_BAD
925 925 jmp L_update_stream_state
926 926
927 927L_test_for_end_of_block:
928 mov ebx,ebp 928
929 929
930L_update_next_in: 930
931; 1266 "inffast.S" 931
932 mov eax, [esp+88] 932
933 mov ecx,ebx 933 test al,32
934 mov edx, [eax+28] 934 jz L_invalid_literal_length_code
935 shr ecx,3 935
936 sub esi,ecx 936 mov ecx,0
937 shl ecx,3 937 mov edx,INFLATE_MODE_TYPE
938 sub ebx,ecx 938 jmp L_update_stream_state
939 mov [eax+12],edi 939
940 mov [edx+bits_state],ebx 940L_invalid_literal_length_code:
941 mov ecx,ebx 941
942 942
943 lea ebx, [esp+28] 943
944 cmp [esp+20],ebx 944
945 jne L_buf_not_used 945
946 946 mov ecx, invalid_literal_length_code_msg
947 sub esi,ebx 947 mov edx,INFLATE_MODE_BAD
948 mov ebx, [eax+0] 948 jmp L_update_stream_state
949 mov [esp+20],ebx 949
950 add esi,ebx 950L_invalid_distance_too_far:
951 mov ebx, [eax+4] 951
952 sub ebx,11 952
953 add [esp+20],ebx 953
954 954 mov esi, [esp+44]
955L_buf_not_used: 955 mov ecx, invalid_distance_too_far_msg
956 mov [eax+0],esi 956 mov edx,INFLATE_MODE_BAD
957 957 jmp L_update_stream_state
958 mov ebx,1 958
959 shl ebx,cl 959L_update_stream_state:
960 dec ebx 960
961 961 mov eax, [esp+88]
962 962 test ecx,ecx
963 963 jz L_skip_msg
964 964 mov [eax+24],ecx
965 965L_skip_msg:
966 cmp dword ptr [inflate_fast_use_mmx],2 966 mov eax, [eax+28]
967 jne L_update_hold 967 mov [eax+mode_state],edx
968 968 jmp L_break_loop
969 969
970 970ALIGN 4
971 psrlq mm0,mm1 971L_break_loop:
972 movd ebp,mm0 972; 1243 "inffast.S"
973 973 cmp dword ptr [inflate_fast_use_mmx],2
974 emms 974 jne L_update_next_in
975 975
976L_update_hold: 976
977 977
978 978 mov ebx,ebp
979 979
980 and ebp,ebx 980L_update_next_in:
981 mov [edx+hold_state],ebp 981; 1266 "inffast.S"
982 982 mov eax, [esp+88]
983 983 mov ecx,ebx
984 984 mov edx, [eax+28]
985 985 shr ecx,3
986 mov ebx, [esp+20] 986 sub esi,ecx
987 cmp ebx,esi 987 shl ecx,3
988 jbe L_last_is_smaller 988 sub ebx,ecx
989 989 mov [eax+12],edi
990 sub ebx,esi 990 mov [edx+bits_state],ebx
991 add ebx,11 991 mov ecx,ebx
992 mov [eax+4],ebx 992
993 jmp L_fixup_out 993 lea ebx, [esp+28]
994L_last_is_smaller: 994 cmp [esp+20],ebx
995 sub esi,ebx 995 jne L_buf_not_used
996 neg esi 996
997 add esi,11 997 sub esi,ebx
998 mov [eax+4],esi 998 mov ebx, [eax+0]
999 999 mov [esp+20],ebx
1000 1000 add esi,ebx
1001 1001 mov ebx, [eax+4]
1002 1002 sub ebx,11
1003L_fixup_out: 1003 add [esp+20],ebx
1004 1004
1005 mov ebx, [esp+16] 1005L_buf_not_used:
1006 cmp ebx,edi 1006 mov [eax+0],esi
1007 jbe L_end_is_smaller 1007
1008 1008 mov ebx,1
1009 sub ebx,edi 1009 shl ebx,cl
1010 add ebx,257 1010 dec ebx
1011 mov [eax+16],ebx 1011
1012 jmp L_done 1012
1013L_end_is_smaller: 1013
1014 sub edi,ebx 1014
1015 neg edi 1015
1016 add edi,257 1016 cmp dword ptr [inflate_fast_use_mmx],2
1017 mov [eax+16],edi 1017 jne L_update_hold
1018 1018
1019 1019
1020 1020
1021 1021 psrlq mm0,mm1
1022 1022 movd ebp,mm0
1023L_done: 1023
1024 add esp,64 1024 emms
1025 popfd 1025
1026 pop ebx 1026L_update_hold:
1027 pop ebp 1027
1028 pop esi 1028
1029 pop edi 1029
1030 ret 1030 and ebp,ebx
1031 1031 mov [edx+hold_state],ebp
1032 1032
1033 1033
1034 1034
1035_TEXT ends 1035
1036end 1036 mov ebx, [esp+20]
1037 cmp ebx,esi
1038 jbe L_last_is_smaller
1039
1040 sub ebx,esi
1041 add ebx,11
1042 mov [eax+4],ebx
1043 jmp L_fixup_out
1044L_last_is_smaller:
1045 sub esi,ebx
1046 neg esi
1047 add esi,11
1048 mov [eax+4],esi
1049
1050
1051
1052
1053L_fixup_out:
1054
1055 mov ebx, [esp+16]
1056 cmp ebx,edi
1057 jbe L_end_is_smaller
1058
1059 sub ebx,edi
1060 add ebx,257
1061 mov [eax+16],ebx
1062 jmp L_done
1063L_end_is_smaller:
1064 sub edi,ebx
1065 neg edi
1066 add edi,257
1067 mov [eax+16],edi
1068
1069
1070
1071
1072
1073L_done:
1074 add esp,64
1075 popfd
1076 pop ebx
1077 pop ebp
1078 pop esi
1079 pop edi
1080 ret
1081
1082_TEXT ends
1083end
diff --git a/contrib/minizip/ChangeLogUnzip b/contrib/minizip/ChangeLogUnzip
index 4be4d16..e62af14 100644
--- a/contrib/minizip/ChangeLogUnzip
+++ b/contrib/minizip/ChangeLogUnzip
@@ -1,63 +1,67 @@
1Change in 1.01b (20 may 04) 1Change in 1.01e (12 feb 05)
2- Integrate patch from Debian package (submited by Mark Brown) 2- Fix in zipOpen2 for globalcomment (Rolf Kalbermatter)
3- Add tools mztools from Xavier Roche 3- Fix possible memory leak in unzip.c (Zoran Stevanovic)
4 4
5Change in 1.01 (8 may 04) 5Change in 1.01b (20 may 04)
6- fix buffer overrun risk in unzip.c (Xavier Roche) 6- Integrate patch from Debian package (submited by Mark Brown)
7- fix a minor buffer insecurity in minizip.c (Mike Whittaker) 7- Add tools mztools from Xavier Roche
8 8
9Change in 1.00: (10 sept 03) 9Change in 1.01 (8 may 04)
10- rename to 1.00 10- fix buffer overrun risk in unzip.c (Xavier Roche)
11- cosmetic code change 11- fix a minor buffer insecurity in minizip.c (Mike Whittaker)
12 12
13Change in 0.22: (19 May 03) 13Change in 1.00: (10 sept 03)
14- crypting support (unless you define NOCRYPT) 14- rename to 1.00
15- append file in existing zipfile 15- cosmetic code change
16 16
17Change in 0.21: (10 Mar 03) 17Change in 0.22: (19 May 03)
18- bug fixes 18- crypting support (unless you define NOCRYPT)
19 19- append file in existing zipfile
20Change in 0.17: (27 Jan 02) 20
21- bug fixes 21Change in 0.21: (10 Mar 03)
22 22- bug fixes
23Change in 0.16: (19 Jan 02) 23
24- Support of ioapi for virtualize zip file access 24Change in 0.17: (27 Jan 02)
25 25- bug fixes
26Change in 0.15: (19 Mar 98) 26
27- fix memory leak in minizip.c 27Change in 0.16: (19 Jan 02)
28 28- Support of ioapi for virtualize zip file access
29Change in 0.14: (10 Mar 98) 29
30- fix bugs in minizip.c sample for zipping big file 30Change in 0.15: (19 Mar 98)
31- fix problem in month in date handling 31- fix memory leak in minizip.c
32- fix bug in unzlocal_GetCurrentFileInfoInternal in unzip.c for 32
33 comment handling 33Change in 0.14: (10 Mar 98)
34 34- fix bugs in minizip.c sample for zipping big file
35Change in 0.13: (6 Mar 98) 35- fix problem in month in date handling
36- fix bugs in zip.c 36- fix bug in unzlocal_GetCurrentFileInfoInternal in unzip.c for
37- add real minizip sample 37 comment handling
38 38
39Change in 0.12: (4 Mar 98) 39Change in 0.13: (6 Mar 98)
40- add zip.c and zip.h for creates .zip file 40- fix bugs in zip.c
41- fix change_file_date in miniunz.c for Unix (Jean-loup Gailly) 41- add real minizip sample
42- fix miniunz.c for file without specific record for directory 42
43 43Change in 0.12: (4 Mar 98)
44Change in 0.11: (3 Mar 98) 44- add zip.c and zip.h for creates .zip file
45- fix bug in unzGetCurrentFileInfo for get extra field and comment 45- fix change_file_date in miniunz.c for Unix (Jean-loup Gailly)
46- enhance miniunz sample, remove the bad unztst.c sample 46- fix miniunz.c for file without specific record for directory
47 47
48Change in 0.10: (2 Mar 98) 48Change in 0.11: (3 Mar 98)
49- fix bug in unzReadCurrentFile 49- fix bug in unzGetCurrentFileInfo for get extra field and comment
50- rename unzip* to unz* function and structure 50- enhance miniunz sample, remove the bad unztst.c sample
51- remove Windows-like hungary notation variable name 51
52- modify some structure in unzip.h 52Change in 0.10: (2 Mar 98)
53- add somes comment in source 53- fix bug in unzReadCurrentFile
54- remove unzipGetcCurrentFile function 54- rename unzip* to unz* function and structure
55- replace ZUNZEXPORT by ZEXPORT 55- remove Windows-like hungary notation variable name
56- add unzGetLocalExtrafield for get the local extrafield info 56- modify some structure in unzip.h
57- add a new sample, miniunz.c 57- add somes comment in source
58 58- remove unzipGetcCurrentFile function
59Change in 0.4: (25 Feb 98) 59- replace ZUNZEXPORT by ZEXPORT
60- suppress the type unzipFileInZip. 60- add unzGetLocalExtrafield for get the local extrafield info
61 Only on file in the zipfile can be open at the same time 61- add a new sample, miniunz.c
62- fix somes typo in code 62
63- added tm_unz structure in unzip_file_info (date/time in readable format) 63Change in 0.4: (25 Feb 98)
64- suppress the type unzipFileInZip.
65 Only on file in the zipfile can be open at the same time
66- fix somes typo in code
67- added tm_unz structure in unzip_file_info (date/time in readable format)
diff --git a/contrib/minizip/Makefile b/contrib/minizip/Makefile
index 84eaad2..fbba3ac 100644
--- a/contrib/minizip/Makefile
+++ b/contrib/minizip/Makefile
@@ -1,25 +1,25 @@
1CC=cc 1CC=cc
2CFLAGS=-O -I../.. 2CFLAGS=-O -I../..
3 3
4UNZ_OBJS = miniunz.o unzip.o ioapi.o ../../libz.a 4UNZ_OBJS = miniunz.o unzip.o ioapi.o ../../libz.a
5ZIP_OBJS = minizip.o zip.o ioapi.o ../../libz.a 5ZIP_OBJS = minizip.o zip.o ioapi.o ../../libz.a
6 6
7.c.o: 7.c.o:
8 $(CC) -c $(CFLAGS) $*.c 8 $(CC) -c $(CFLAGS) $*.c
9 9
10all: miniunz minizip 10all: miniunz minizip
11 11
12miniunz: $(UNZ_OBJS) 12miniunz: $(UNZ_OBJS)
13 $(CC) $(CFLAGS) -o $@ $(UNZ_OBJS) 13 $(CC) $(CFLAGS) -o $@ $(UNZ_OBJS)
14 14
15minizip: $(ZIP_OBJS) 15minizip: $(ZIP_OBJS)
16 $(CC) $(CFLAGS) -o $@ $(ZIP_OBJS) 16 $(CC) $(CFLAGS) -o $@ $(ZIP_OBJS)
17 17
18test: miniunz minizip 18test: miniunz minizip
19 ./minizip test readme.txt 19 ./minizip test readme.txt
20 ./miniunz -l test.zip 20 ./miniunz -l test.zip
21 mv readme.txt readme.old 21 mv readme.txt readme.old
22 ./miniunz test.zip 22 ./miniunz test.zip
23 23
24clean: 24clean:
25 /bin/rm -f *.o *~ minizip miniunz 25 /bin/rm -f *.o *~ minizip miniunz
diff --git a/contrib/minizip/crypt.h b/contrib/minizip/crypt.h
index 7f8a634..f14a628 100644
--- a/contrib/minizip/crypt.h
+++ b/contrib/minizip/crypt.h
@@ -1,132 +1,132 @@
1/* crypt.h -- base code for crypt/uncrypt ZIPfile 1/* crypt.h -- base code for crypt/uncrypt ZIPfile
2 2
3 3
4 Version 1.01, May 8th, 2004 4 Version 1.01e, February 12th, 2005
5 5
6 Copyright (C) 1998-2004 Gilles Vollant 6 Copyright (C) 1998-2005 Gilles Vollant
7 7
8 This code is a modified version of crypting code in Infozip distribution 8 This code is a modified version of crypting code in Infozip distribution
9 9
10 The encryption/decryption parts of this source code (as opposed to the 10 The encryption/decryption parts of this source code (as opposed to the
11 non-echoing password parts) were originally written in Europe. The 11 non-echoing password parts) were originally written in Europe. The
12 whole source package can be freely distributed, including from the USA. 12 whole source package can be freely distributed, including from the USA.
13 (Prior to January 2000, re-export from the US was a violation of US law.) 13 (Prior to January 2000, re-export from the US was a violation of US law.)
14 14
15 This encryption code is a direct transcription of the algorithm from 15 This encryption code is a direct transcription of the algorithm from
16 Roger Schlafly, described by Phil Katz in the file appnote.txt. This 16 Roger Schlafly, described by Phil Katz in the file appnote.txt. This
17 file (appnote.txt) is distributed with the PKZIP program (even in the 17 file (appnote.txt) is distributed with the PKZIP program (even in the
18 version without encryption capabilities). 18 version without encryption capabilities).
19 19
20 If you don't need crypting in your application, just define symbols 20 If you don't need crypting in your application, just define symbols
21 NOCRYPT and NOUNCRYPT. 21 NOCRYPT and NOUNCRYPT.
22 22
23 This code support the "Traditional PKWARE Encryption". 23 This code support the "Traditional PKWARE Encryption".
24 24
25 The new AES encryption added on Zip format by Winzip (see the page 25 The new AES encryption added on Zip format by Winzip (see the page
26 http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong 26 http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
27 Encryption is not supported. 27 Encryption is not supported.
28*/ 28*/
29 29
30#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) 30#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
31 31
32/*********************************************************************** 32/***********************************************************************
33 * Return the next byte in the pseudo-random sequence 33 * Return the next byte in the pseudo-random sequence
34 */ 34 */
35static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab) 35static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab)
36{ 36{
37 unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an 37 unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
38 * unpredictable manner on 16-bit systems; not a problem 38 * unpredictable manner on 16-bit systems; not a problem
39 * with any known compiler so far, though */ 39 * with any known compiler so far, though */
40 40
41 temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; 41 temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
42 return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); 42 return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
43} 43}
44 44
45/*********************************************************************** 45/***********************************************************************
46 * Update the encryption keys with the next byte of plain text 46 * Update the encryption keys with the next byte of plain text
47 */ 47 */
48static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c) 48static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c)
49{ 49{
50 (*(pkeys+0)) = CRC32((*(pkeys+0)), c); 50 (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
51 (*(pkeys+1)) += (*(pkeys+0)) & 0xff; 51 (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
52 (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; 52 (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
53 { 53 {
54 register int keyshift = (int)((*(pkeys+1)) >> 24); 54 register int keyshift = (int)((*(pkeys+1)) >> 24);
55 (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); 55 (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
56 } 56 }
57 return c; 57 return c;
58} 58}
59 59
60 60
61/*********************************************************************** 61/***********************************************************************
62 * Initialize the encryption keys and the random header according to 62 * Initialize the encryption keys and the random header according to
63 * the given password. 63 * the given password.
64 */ 64 */
65static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab) 65static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab)
66{ 66{
67 *(pkeys+0) = 305419896L; 67 *(pkeys+0) = 305419896L;
68 *(pkeys+1) = 591751049L; 68 *(pkeys+1) = 591751049L;
69 *(pkeys+2) = 878082192L; 69 *(pkeys+2) = 878082192L;
70 while (*passwd != '\0') { 70 while (*passwd != '\0') {
71 update_keys(pkeys,pcrc_32_tab,(int)*passwd); 71 update_keys(pkeys,pcrc_32_tab,(int)*passwd);
72 passwd++; 72 passwd++;
73 } 73 }
74} 74}
75 75
76#define zdecode(pkeys,pcrc_32_tab,c) \ 76#define zdecode(pkeys,pcrc_32_tab,c) \
77 (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) 77 (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
78 78
79#define zencode(pkeys,pcrc_32_tab,c,t) \ 79#define zencode(pkeys,pcrc_32_tab,c,t) \
80 (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) 80 (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
81 81
82#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED 82#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
83 83
84#define RAND_HEAD_LEN 12 84#define RAND_HEAD_LEN 12
85 /* "last resort" source for second part of crypt seed pattern */ 85 /* "last resort" source for second part of crypt seed pattern */
86# ifndef ZCR_SEED2 86# ifndef ZCR_SEED2
87# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ 87# define ZCR_SEED2 3141592654UL /* use PI as default pattern */
88# endif 88# endif
89 89
90static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting) 90static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting)
91 const char *passwd; /* password string */ 91 const char *passwd; /* password string */
92 unsigned char *buf; /* where to write header */ 92 unsigned char *buf; /* where to write header */
93 int bufSize; 93 int bufSize;
94 unsigned long* pkeys; 94 unsigned long* pkeys;
95 const unsigned long* pcrc_32_tab; 95 const unsigned long* pcrc_32_tab;
96 unsigned long crcForCrypting; 96 unsigned long crcForCrypting;
97{ 97{
98 int n; /* index in random header */ 98 int n; /* index in random header */
99 int t; /* temporary */ 99 int t; /* temporary */
100 int c; /* random byte */ 100 int c; /* random byte */
101 unsigned char header[RAND_HEAD_LEN-2]; /* random header */ 101 unsigned char header[RAND_HEAD_LEN-2]; /* random header */
102 static unsigned calls = 0; /* ensure different random header each time */ 102 static unsigned calls = 0; /* ensure different random header each time */
103 103
104 if (bufSize<RAND_HEAD_LEN) 104 if (bufSize<RAND_HEAD_LEN)
105 return 0; 105 return 0;
106 106
107 /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the 107 /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
108 * output of rand() to get less predictability, since rand() is 108 * output of rand() to get less predictability, since rand() is
109 * often poorly implemented. 109 * often poorly implemented.
110 */ 110 */
111 if (++calls == 1) 111 if (++calls == 1)
112 { 112 {
113 srand((unsigned)(time(NULL) ^ ZCR_SEED2)); 113 srand((unsigned)(time(NULL) ^ ZCR_SEED2));
114 } 114 }
115 init_keys(passwd, pkeys, pcrc_32_tab); 115 init_keys(passwd, pkeys, pcrc_32_tab);
116 for (n = 0; n < RAND_HEAD_LEN-2; n++) 116 for (n = 0; n < RAND_HEAD_LEN-2; n++)
117 { 117 {
118 c = (rand() >> 7) & 0xff; 118 c = (rand() >> 7) & 0xff;
119 header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); 119 header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
120 } 120 }
121 /* Encrypt random header (last two bytes is high word of crc) */ 121 /* Encrypt random header (last two bytes is high word of crc) */
122 init_keys(passwd, pkeys, pcrc_32_tab); 122 init_keys(passwd, pkeys, pcrc_32_tab);
123 for (n = 0; n < RAND_HEAD_LEN-2; n++) 123 for (n = 0; n < RAND_HEAD_LEN-2; n++)
124 { 124 {
125 buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); 125 buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
126 } 126 }
127 buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); 127 buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
128 buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); 128 buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
129 return n; 129 return n;
130} 130}
131 131
132#endif 132#endif
diff --git a/contrib/minizip/ioapi.c b/contrib/minizip/ioapi.c
index c9e69f2..7f20c18 100644
--- a/contrib/minizip/ioapi.c
+++ b/contrib/minizip/ioapi.c
@@ -1,177 +1,177 @@
1/* ioapi.c -- IO base function header for compress/uncompress .zip 1/* ioapi.c -- IO base function header for compress/uncompress .zip
2 files using zlib + zip or unzip API 2 files using zlib + zip or unzip API
3 3
4 Version 1.01, May 8th, 2004 4 Version 1.01e, February 12th, 2005
5 5
6 Copyright (C) 1998-2004 Gilles Vollant 6 Copyright (C) 1998-2005 Gilles Vollant
7*/ 7*/
8 8
9#include <stdio.h> 9#include <stdio.h>
10#include <stdlib.h> 10#include <stdlib.h>
11#include <string.h> 11#include <string.h>
12 12
13#include "zlib.h" 13#include "zlib.h"
14#include "ioapi.h" 14#include "ioapi.h"
15 15
16 16
17 17
18/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ 18/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
19 19
20#ifndef SEEK_CUR 20#ifndef SEEK_CUR
21#define SEEK_CUR 1 21#define SEEK_CUR 1
22#endif 22#endif
23 23
24#ifndef SEEK_END 24#ifndef SEEK_END
25#define SEEK_END 2 25#define SEEK_END 2
26#endif 26#endif
27 27
28#ifndef SEEK_SET 28#ifndef SEEK_SET
29#define SEEK_SET 0 29#define SEEK_SET 0
30#endif 30#endif
31 31
32voidpf ZCALLBACK fopen_file_func OF(( 32voidpf ZCALLBACK fopen_file_func OF((
33 voidpf opaque, 33 voidpf opaque,
34 const char* filename, 34 const char* filename,
35 int mode)); 35 int mode));
36 36
37uLong ZCALLBACK fread_file_func OF(( 37uLong ZCALLBACK fread_file_func OF((
38 voidpf opaque, 38 voidpf opaque,
39 voidpf stream, 39 voidpf stream,
40 void* buf, 40 void* buf,
41 uLong size)); 41 uLong size));
42 42
43uLong ZCALLBACK fwrite_file_func OF(( 43uLong ZCALLBACK fwrite_file_func OF((
44 voidpf opaque, 44 voidpf opaque,
45 voidpf stream, 45 voidpf stream,
46 const void* buf, 46 const void* buf,
47 uLong size)); 47 uLong size));
48 48
49long ZCALLBACK ftell_file_func OF(( 49long ZCALLBACK ftell_file_func OF((
50 voidpf opaque, 50 voidpf opaque,
51 voidpf stream)); 51 voidpf stream));
52 52
53long ZCALLBACK fseek_file_func OF(( 53long ZCALLBACK fseek_file_func OF((
54 voidpf opaque, 54 voidpf opaque,
55 voidpf stream, 55 voidpf stream,
56 uLong offset, 56 uLong offset,
57 int origin)); 57 int origin));
58 58
59int ZCALLBACK fclose_file_func OF(( 59int ZCALLBACK fclose_file_func OF((
60 voidpf opaque, 60 voidpf opaque,
61 voidpf stream)); 61 voidpf stream));
62 62
63int ZCALLBACK ferror_file_func OF(( 63int ZCALLBACK ferror_file_func OF((
64 voidpf opaque, 64 voidpf opaque,
65 voidpf stream)); 65 voidpf stream));
66 66
67 67
68voidpf ZCALLBACK fopen_file_func (opaque, filename, mode) 68voidpf ZCALLBACK fopen_file_func (opaque, filename, mode)
69 voidpf opaque; 69 voidpf opaque;
70 const char* filename; 70 const char* filename;
71 int mode; 71 int mode;
72{ 72{
73 FILE* file = NULL; 73 FILE* file = NULL;
74 const char* mode_fopen = NULL; 74 const char* mode_fopen = NULL;
75 if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) 75 if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
76 mode_fopen = "rb"; 76 mode_fopen = "rb";
77 else 77 else
78 if (mode & ZLIB_FILEFUNC_MODE_EXISTING) 78 if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
79 mode_fopen = "r+b"; 79 mode_fopen = "r+b";
80 else 80 else
81 if (mode & ZLIB_FILEFUNC_MODE_CREATE) 81 if (mode & ZLIB_FILEFUNC_MODE_CREATE)
82 mode_fopen = "wb"; 82 mode_fopen = "wb";
83 83
84 if ((filename!=NULL) && (mode_fopen != NULL)) 84 if ((filename!=NULL) && (mode_fopen != NULL))
85 file = fopen(filename, mode_fopen); 85 file = fopen(filename, mode_fopen);
86 return file; 86 return file;
87} 87}
88 88
89 89
90uLong ZCALLBACK fread_file_func (opaque, stream, buf, size) 90uLong ZCALLBACK fread_file_func (opaque, stream, buf, size)
91 voidpf opaque; 91 voidpf opaque;
92 voidpf stream; 92 voidpf stream;
93 void* buf; 93 void* buf;
94 uLong size; 94 uLong size;
95{ 95{
96 uLong ret; 96 uLong ret;
97 ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); 97 ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
98 return ret; 98 return ret;
99} 99}
100 100
101 101
102uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size) 102uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size)
103 voidpf opaque; 103 voidpf opaque;
104 voidpf stream; 104 voidpf stream;
105 const void* buf; 105 const void* buf;
106 uLong size; 106 uLong size;
107{ 107{
108 uLong ret; 108 uLong ret;
109 ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); 109 ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
110 return ret; 110 return ret;
111} 111}
112 112
113long ZCALLBACK ftell_file_func (opaque, stream) 113long ZCALLBACK ftell_file_func (opaque, stream)
114 voidpf opaque; 114 voidpf opaque;
115 voidpf stream; 115 voidpf stream;
116{ 116{
117 long ret; 117 long ret;
118 ret = ftell((FILE *)stream); 118 ret = ftell((FILE *)stream);
119 return ret; 119 return ret;
120} 120}
121 121
122long ZCALLBACK fseek_file_func (opaque, stream, offset, origin) 122long ZCALLBACK fseek_file_func (opaque, stream, offset, origin)
123 voidpf opaque; 123 voidpf opaque;
124 voidpf stream; 124 voidpf stream;
125 uLong offset; 125 uLong offset;
126 int origin; 126 int origin;
127{ 127{
128 int fseek_origin=0; 128 int fseek_origin=0;
129 long ret; 129 long ret;
130 switch (origin) 130 switch (origin)
131 { 131 {
132 case ZLIB_FILEFUNC_SEEK_CUR : 132 case ZLIB_FILEFUNC_SEEK_CUR :
133 fseek_origin = SEEK_CUR; 133 fseek_origin = SEEK_CUR;
134 break; 134 break;
135 case ZLIB_FILEFUNC_SEEK_END : 135 case ZLIB_FILEFUNC_SEEK_END :
136 fseek_origin = SEEK_END; 136 fseek_origin = SEEK_END;
137 break; 137 break;
138 case ZLIB_FILEFUNC_SEEK_SET : 138 case ZLIB_FILEFUNC_SEEK_SET :
139 fseek_origin = SEEK_SET; 139 fseek_origin = SEEK_SET;
140 break; 140 break;
141 default: return -1; 141 default: return -1;
142 } 142 }
143 ret = 0; 143 ret = 0;
144 fseek((FILE *)stream, offset, fseek_origin); 144 fseek((FILE *)stream, offset, fseek_origin);
145 return ret; 145 return ret;
146} 146}
147 147
148int ZCALLBACK fclose_file_func (opaque, stream) 148int ZCALLBACK fclose_file_func (opaque, stream)
149 voidpf opaque; 149 voidpf opaque;
150 voidpf stream; 150 voidpf stream;
151{ 151{
152 int ret; 152 int ret;
153 ret = fclose((FILE *)stream); 153 ret = fclose((FILE *)stream);
154 return ret; 154 return ret;
155} 155}
156 156
157int ZCALLBACK ferror_file_func (opaque, stream) 157int ZCALLBACK ferror_file_func (opaque, stream)
158 voidpf opaque; 158 voidpf opaque;
159 voidpf stream; 159 voidpf stream;
160{ 160{
161 int ret; 161 int ret;
162 ret = ferror((FILE *)stream); 162 ret = ferror((FILE *)stream);
163 return ret; 163 return ret;
164} 164}
165 165
166void fill_fopen_filefunc (pzlib_filefunc_def) 166void fill_fopen_filefunc (pzlib_filefunc_def)
167 zlib_filefunc_def* pzlib_filefunc_def; 167 zlib_filefunc_def* pzlib_filefunc_def;
168{ 168{
169 pzlib_filefunc_def->zopen_file = fopen_file_func; 169 pzlib_filefunc_def->zopen_file = fopen_file_func;
170 pzlib_filefunc_def->zread_file = fread_file_func; 170 pzlib_filefunc_def->zread_file = fread_file_func;
171 pzlib_filefunc_def->zwrite_file = fwrite_file_func; 171 pzlib_filefunc_def->zwrite_file = fwrite_file_func;
172 pzlib_filefunc_def->ztell_file = ftell_file_func; 172 pzlib_filefunc_def->ztell_file = ftell_file_func;
173 pzlib_filefunc_def->zseek_file = fseek_file_func; 173 pzlib_filefunc_def->zseek_file = fseek_file_func;
174 pzlib_filefunc_def->zclose_file = fclose_file_func; 174 pzlib_filefunc_def->zclose_file = fclose_file_func;
175 pzlib_filefunc_def->zerror_file = ferror_file_func; 175 pzlib_filefunc_def->zerror_file = ferror_file_func;
176 pzlib_filefunc_def->opaque = NULL; 176 pzlib_filefunc_def->opaque = NULL;
177} 177}
diff --git a/contrib/minizip/ioapi.h b/contrib/minizip/ioapi.h
index b761161..e73a3b2 100644
--- a/contrib/minizip/ioapi.h
+++ b/contrib/minizip/ioapi.h
@@ -1,75 +1,75 @@
1/* ioapi.h -- IO base function header for compress/uncompress .zip 1/* ioapi.h -- IO base function header for compress/uncompress .zip
2 files using zlib + zip or unzip API 2 files using zlib + zip or unzip API
3 3
4 Version 1.01, May 8th, 2004 4 Version 1.01e, February 12th, 2005
5 5
6 Copyright (C) 1998-2004 Gilles Vollant 6 Copyright (C) 1998-2005 Gilles Vollant
7*/ 7*/
8 8
9#ifndef _ZLIBIOAPI_H 9#ifndef _ZLIBIOAPI_H
10#define _ZLIBIOAPI_H 10#define _ZLIBIOAPI_H
11 11
12 12
13#define ZLIB_FILEFUNC_SEEK_CUR (1) 13#define ZLIB_FILEFUNC_SEEK_CUR (1)
14#define ZLIB_FILEFUNC_SEEK_END (2) 14#define ZLIB_FILEFUNC_SEEK_END (2)
15#define ZLIB_FILEFUNC_SEEK_SET (0) 15#define ZLIB_FILEFUNC_SEEK_SET (0)
16 16
17#define ZLIB_FILEFUNC_MODE_READ (1) 17#define ZLIB_FILEFUNC_MODE_READ (1)
18#define ZLIB_FILEFUNC_MODE_WRITE (2) 18#define ZLIB_FILEFUNC_MODE_WRITE (2)
19#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) 19#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
20 20
21#define ZLIB_FILEFUNC_MODE_EXISTING (4) 21#define ZLIB_FILEFUNC_MODE_EXISTING (4)
22#define ZLIB_FILEFUNC_MODE_CREATE (8) 22#define ZLIB_FILEFUNC_MODE_CREATE (8)
23 23
24 24
25#ifndef ZCALLBACK 25#ifndef ZCALLBACK
26 26
27#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) 27#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
28#define ZCALLBACK CALLBACK 28#define ZCALLBACK CALLBACK
29#else 29#else
30#define ZCALLBACK 30#define ZCALLBACK
31#endif 31#endif
32#endif 32#endif
33 33
34#ifdef __cplusplus 34#ifdef __cplusplus
35extern "C" { 35extern "C" {
36#endif 36#endif
37 37
38typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); 38typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
39typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); 39typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
40typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); 40typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
41typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); 41typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
42typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); 42typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
43typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); 43typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
44typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); 44typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
45 45
46typedef struct zlib_filefunc_def_s 46typedef struct zlib_filefunc_def_s
47{ 47{
48 open_file_func zopen_file; 48 open_file_func zopen_file;
49 read_file_func zread_file; 49 read_file_func zread_file;
50 write_file_func zwrite_file; 50 write_file_func zwrite_file;
51 tell_file_func ztell_file; 51 tell_file_func ztell_file;
52 seek_file_func zseek_file; 52 seek_file_func zseek_file;
53 close_file_func zclose_file; 53 close_file_func zclose_file;
54 testerror_file_func zerror_file; 54 testerror_file_func zerror_file;
55 voidpf opaque; 55 voidpf opaque;
56} zlib_filefunc_def; 56} zlib_filefunc_def;
57 57
58 58
59 59
60void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); 60void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
61 61
62#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size)) 62#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size))
63#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size)) 63#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size))
64#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream)) 64#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream))
65#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode)) 65#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode))
66#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream)) 66#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream))
67#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream)) 67#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream))
68 68
69 69
70#ifdef __cplusplus 70#ifdef __cplusplus
71} 71}
72#endif 72#endif
73 73
74#endif 74#endif
75 75
diff --git a/contrib/minizip/iowin32.c b/contrib/minizip/iowin32.c
index 940dc0b..694bc03 100644
--- a/contrib/minizip/iowin32.c
+++ b/contrib/minizip/iowin32.c
@@ -1,270 +1,270 @@
1/* iowin32.c -- IO base function header for compress/uncompress .zip 1/* iowin32.c -- IO base function header for compress/uncompress .zip
2 files using zlib + zip or unzip API 2 files using zlib + zip or unzip API
3 This IO API version uses the Win32 API (for Microsoft Windows) 3 This IO API version uses the Win32 API (for Microsoft Windows)
4 4
5 Version 1.01, May 8th, 2004 5 Version 1.01e, February 12th, 2005
6 6
7 Copyright (C) 1998-2004 Gilles Vollant 7 Copyright (C) 1998-2005 Gilles Vollant
8*/ 8*/
9 9
10#include <stdlib.h> 10#include <stdlib.h>
11 11
12#include "zlib.h" 12#include "zlib.h"
13#include "ioapi.h" 13#include "ioapi.h"
14#include "iowin32.h" 14#include "iowin32.h"
15 15
16#ifndef INVALID_HANDLE_VALUE 16#ifndef INVALID_HANDLE_VALUE
17#define INVALID_HANDLE_VALUE (0xFFFFFFFF) 17#define INVALID_HANDLE_VALUE (0xFFFFFFFF)
18#endif 18#endif
19 19
20#ifndef INVALID_SET_FILE_POINTER 20#ifndef INVALID_SET_FILE_POINTER
21#define INVALID_SET_FILE_POINTER ((DWORD)-1) 21#define INVALID_SET_FILE_POINTER ((DWORD)-1)
22#endif 22#endif
23 23
24voidpf ZCALLBACK win32_open_file_func OF(( 24voidpf ZCALLBACK win32_open_file_func OF((
25 voidpf opaque, 25 voidpf opaque,
26 const char* filename, 26 const char* filename,
27 int mode)); 27 int mode));
28 28
29uLong ZCALLBACK win32_read_file_func OF(( 29uLong ZCALLBACK win32_read_file_func OF((
30 voidpf opaque, 30 voidpf opaque,
31 voidpf stream, 31 voidpf stream,
32 void* buf, 32 void* buf,
33 uLong size)); 33 uLong size));
34 34
35uLong ZCALLBACK win32_write_file_func OF(( 35uLong ZCALLBACK win32_write_file_func OF((
36 voidpf opaque, 36 voidpf opaque,
37 voidpf stream, 37 voidpf stream,
38 const void* buf, 38 const void* buf,
39 uLong size)); 39 uLong size));
40 40
41long ZCALLBACK win32_tell_file_func OF(( 41long ZCALLBACK win32_tell_file_func OF((
42 voidpf opaque, 42 voidpf opaque,
43 voidpf stream)); 43 voidpf stream));
44 44
45long ZCALLBACK win32_seek_file_func OF(( 45long ZCALLBACK win32_seek_file_func OF((
46 voidpf opaque, 46 voidpf opaque,
47 voidpf stream, 47 voidpf stream,
48 uLong offset, 48 uLong offset,
49 int origin)); 49 int origin));
50 50
51int ZCALLBACK win32_close_file_func OF(( 51int ZCALLBACK win32_close_file_func OF((
52 voidpf opaque, 52 voidpf opaque,
53 voidpf stream)); 53 voidpf stream));
54 54
55int ZCALLBACK win32_error_file_func OF(( 55int ZCALLBACK win32_error_file_func OF((
56 voidpf opaque, 56 voidpf opaque,
57 voidpf stream)); 57 voidpf stream));
58 58
59typedef struct 59typedef struct
60{ 60{
61 HANDLE hf; 61 HANDLE hf;
62 int error; 62 int error;
63} WIN32FILE_IOWIN; 63} WIN32FILE_IOWIN;
64 64
65voidpf ZCALLBACK win32_open_file_func (opaque, filename, mode) 65voidpf ZCALLBACK win32_open_file_func (opaque, filename, mode)
66 voidpf opaque; 66 voidpf opaque;
67 const char* filename; 67 const char* filename;
68 int mode; 68 int mode;
69{ 69{
70 const char* mode_fopen = NULL; 70 const char* mode_fopen = NULL;
71 DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ; 71 DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
72 HANDLE hFile = 0; 72 HANDLE hFile = 0;
73 voidpf ret=NULL; 73 voidpf ret=NULL;
74 74
75 dwDesiredAccess = dwShareMode = dwFlagsAndAttributes = 0; 75 dwDesiredAccess = dwShareMode = dwFlagsAndAttributes = 0;
76 76
77 if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) 77 if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
78 { 78 {
79 dwDesiredAccess = GENERIC_READ; 79 dwDesiredAccess = GENERIC_READ;
80 dwCreationDisposition = OPEN_EXISTING; 80 dwCreationDisposition = OPEN_EXISTING;
81 dwShareMode = FILE_SHARE_READ; 81 dwShareMode = FILE_SHARE_READ;
82 } 82 }
83 else 83 else
84 if (mode & ZLIB_FILEFUNC_MODE_EXISTING) 84 if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
85 { 85 {
86 dwDesiredAccess = GENERIC_WRITE | GENERIC_READ; 86 dwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
87 dwCreationDisposition = OPEN_EXISTING; 87 dwCreationDisposition = OPEN_EXISTING;
88 } 88 }
89 else 89 else
90 if (mode & ZLIB_FILEFUNC_MODE_CREATE) 90 if (mode & ZLIB_FILEFUNC_MODE_CREATE)
91 { 91 {
92 dwDesiredAccess = GENERIC_WRITE | GENERIC_READ; 92 dwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
93 dwCreationDisposition = CREATE_ALWAYS; 93 dwCreationDisposition = CREATE_ALWAYS;
94 } 94 }
95 95
96 if ((filename!=NULL) && (dwDesiredAccess != 0)) 96 if ((filename!=NULL) && (dwDesiredAccess != 0))
97 hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, 97 hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL,
98 dwCreationDisposition, dwFlagsAndAttributes, NULL); 98 dwCreationDisposition, dwFlagsAndAttributes, NULL);
99 99
100 if (hFile == INVALID_HANDLE_VALUE) 100 if (hFile == INVALID_HANDLE_VALUE)
101 hFile = NULL; 101 hFile = NULL;
102 102
103 if (hFile != NULL) 103 if (hFile != NULL)
104 { 104 {
105 WIN32FILE_IOWIN w32fiow; 105 WIN32FILE_IOWIN w32fiow;
106 w32fiow.hf = hFile; 106 w32fiow.hf = hFile;
107 w32fiow.error = 0; 107 w32fiow.error = 0;
108 ret = malloc(sizeof(WIN32FILE_IOWIN)); 108 ret = malloc(sizeof(WIN32FILE_IOWIN));
109 if (ret==NULL) 109 if (ret==NULL)
110 CloseHandle(hFile); 110 CloseHandle(hFile);
111 else *((WIN32FILE_IOWIN*)ret) = w32fiow; 111 else *((WIN32FILE_IOWIN*)ret) = w32fiow;
112 } 112 }
113 return ret; 113 return ret;
114} 114}
115 115
116 116
117uLong ZCALLBACK win32_read_file_func (opaque, stream, buf, size) 117uLong ZCALLBACK win32_read_file_func (opaque, stream, buf, size)
118 voidpf opaque; 118 voidpf opaque;
119 voidpf stream; 119 voidpf stream;
120 void* buf; 120 void* buf;
121 uLong size; 121 uLong size;
122{ 122{
123 uLong ret=0; 123 uLong ret=0;
124 HANDLE hFile = NULL; 124 HANDLE hFile = NULL;
125 if (stream!=NULL) 125 if (stream!=NULL)
126 hFile = ((WIN32FILE_IOWIN*)stream) -> hf; 126 hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
127 if (hFile != NULL) 127 if (hFile != NULL)
128 if (!ReadFile(hFile, buf, size, &ret, NULL)) 128 if (!ReadFile(hFile, buf, size, &ret, NULL))
129 { 129 {
130 DWORD dwErr = GetLastError(); 130 DWORD dwErr = GetLastError();
131 if (dwErr == ERROR_HANDLE_EOF) 131 if (dwErr == ERROR_HANDLE_EOF)
132 dwErr = 0; 132 dwErr = 0;
133 ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; 133 ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
134 } 134 }
135 135
136 return ret; 136 return ret;
137} 137}
138 138
139 139
140uLong ZCALLBACK win32_write_file_func (opaque, stream, buf, size) 140uLong ZCALLBACK win32_write_file_func (opaque, stream, buf, size)
141 voidpf opaque; 141 voidpf opaque;
142 voidpf stream; 142 voidpf stream;
143 const void* buf; 143 const void* buf;
144 uLong size; 144 uLong size;
145{ 145{
146 uLong ret=0; 146 uLong ret=0;
147 HANDLE hFile = NULL; 147 HANDLE hFile = NULL;
148 if (stream!=NULL) 148 if (stream!=NULL)
149 hFile = ((WIN32FILE_IOWIN*)stream) -> hf; 149 hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
150 150
151 if (hFile !=NULL) 151 if (hFile !=NULL)
152 if (!WriteFile(hFile, buf, size, &ret, NULL)) 152 if (!WriteFile(hFile, buf, size, &ret, NULL))
153 { 153 {
154 DWORD dwErr = GetLastError(); 154 DWORD dwErr = GetLastError();
155 if (dwErr == ERROR_HANDLE_EOF) 155 if (dwErr == ERROR_HANDLE_EOF)
156 dwErr = 0; 156 dwErr = 0;
157 ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; 157 ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
158 } 158 }
159 159
160 return ret; 160 return ret;
161} 161}
162 162
163long ZCALLBACK win32_tell_file_func (opaque, stream) 163long ZCALLBACK win32_tell_file_func (opaque, stream)
164 voidpf opaque; 164 voidpf opaque;
165 voidpf stream; 165 voidpf stream;
166{ 166{
167 long ret=-1; 167 long ret=-1;
168 HANDLE hFile = NULL; 168 HANDLE hFile = NULL;
169 if (stream!=NULL) 169 if (stream!=NULL)
170 hFile = ((WIN32FILE_IOWIN*)stream) -> hf; 170 hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
171 if (hFile != NULL) 171 if (hFile != NULL)
172 { 172 {
173 DWORD dwSet = SetFilePointer(hFile, 0, NULL, FILE_CURRENT); 173 DWORD dwSet = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
174 if (dwSet == INVALID_SET_FILE_POINTER) 174 if (dwSet == INVALID_SET_FILE_POINTER)
175 { 175 {
176 DWORD dwErr = GetLastError(); 176 DWORD dwErr = GetLastError();
177 ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; 177 ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
178 ret = -1; 178 ret = -1;
179 } 179 }
180 else 180 else
181 ret=(long)dwSet; 181 ret=(long)dwSet;
182 } 182 }
183 return ret; 183 return ret;
184} 184}
185 185
186long ZCALLBACK win32_seek_file_func (opaque, stream, offset, origin) 186long ZCALLBACK win32_seek_file_func (opaque, stream, offset, origin)
187 voidpf opaque; 187 voidpf opaque;
188 voidpf stream; 188 voidpf stream;
189 uLong offset; 189 uLong offset;
190 int origin; 190 int origin;
191{ 191{
192 DWORD dwMoveMethod=0xFFFFFFFF; 192 DWORD dwMoveMethod=0xFFFFFFFF;
193 HANDLE hFile = NULL; 193 HANDLE hFile = NULL;
194 194
195 long ret=-1; 195 long ret=-1;
196 if (stream!=NULL) 196 if (stream!=NULL)
197 hFile = ((WIN32FILE_IOWIN*)stream) -> hf; 197 hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
198 switch (origin) 198 switch (origin)
199 { 199 {
200 case ZLIB_FILEFUNC_SEEK_CUR : 200 case ZLIB_FILEFUNC_SEEK_CUR :
201 dwMoveMethod = FILE_CURRENT; 201 dwMoveMethod = FILE_CURRENT;
202 break; 202 break;
203 case ZLIB_FILEFUNC_SEEK_END : 203 case ZLIB_FILEFUNC_SEEK_END :
204 dwMoveMethod = FILE_END; 204 dwMoveMethod = FILE_END;
205 break; 205 break;
206 case ZLIB_FILEFUNC_SEEK_SET : 206 case ZLIB_FILEFUNC_SEEK_SET :
207 dwMoveMethod = FILE_BEGIN; 207 dwMoveMethod = FILE_BEGIN;
208 break; 208 break;
209 default: return -1; 209 default: return -1;
210 } 210 }
211 211
212 if (hFile != NULL) 212 if (hFile != NULL)
213 { 213 {
214 DWORD dwSet = SetFilePointer(hFile, offset, NULL, dwMoveMethod); 214 DWORD dwSet = SetFilePointer(hFile, offset, NULL, dwMoveMethod);
215 if (dwSet == INVALID_SET_FILE_POINTER) 215 if (dwSet == INVALID_SET_FILE_POINTER)
216 { 216 {
217 DWORD dwErr = GetLastError(); 217 DWORD dwErr = GetLastError();
218 ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; 218 ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
219 ret = -1; 219 ret = -1;
220 } 220 }
221 else 221 else
222 ret=0; 222 ret=0;
223 } 223 }
224 return ret; 224 return ret;
225} 225}
226 226
227int ZCALLBACK win32_close_file_func (opaque, stream) 227int ZCALLBACK win32_close_file_func (opaque, stream)
228 voidpf opaque; 228 voidpf opaque;
229 voidpf stream; 229 voidpf stream;
230{ 230{
231 int ret=-1; 231 int ret=-1;
232 232
233 if (stream!=NULL) 233 if (stream!=NULL)
234 { 234 {
235 HANDLE hFile; 235 HANDLE hFile;
236 hFile = ((WIN32FILE_IOWIN*)stream) -> hf; 236 hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
237 if (hFile != NULL) 237 if (hFile != NULL)
238 { 238 {
239 CloseHandle(hFile); 239 CloseHandle(hFile);
240 ret=0; 240 ret=0;
241 } 241 }
242 free(stream); 242 free(stream);
243 } 243 }
244 return ret; 244 return ret;
245} 245}
246 246
247int ZCALLBACK win32_error_file_func (opaque, stream) 247int ZCALLBACK win32_error_file_func (opaque, stream)
248 voidpf opaque; 248 voidpf opaque;
249 voidpf stream; 249 voidpf stream;
250{ 250{
251 int ret=-1; 251 int ret=-1;
252 if (stream!=NULL) 252 if (stream!=NULL)
253 { 253 {
254 ret = ((WIN32FILE_IOWIN*)stream) -> error; 254 ret = ((WIN32FILE_IOWIN*)stream) -> error;
255 } 255 }
256 return ret; 256 return ret;
257} 257}
258 258
259void fill_win32_filefunc (pzlib_filefunc_def) 259void fill_win32_filefunc (pzlib_filefunc_def)
260 zlib_filefunc_def* pzlib_filefunc_def; 260 zlib_filefunc_def* pzlib_filefunc_def;
261{ 261{
262 pzlib_filefunc_def->zopen_file = win32_open_file_func; 262 pzlib_filefunc_def->zopen_file = win32_open_file_func;
263 pzlib_filefunc_def->zread_file = win32_read_file_func; 263 pzlib_filefunc_def->zread_file = win32_read_file_func;
264 pzlib_filefunc_def->zwrite_file = win32_write_file_func; 264 pzlib_filefunc_def->zwrite_file = win32_write_file_func;
265 pzlib_filefunc_def->ztell_file = win32_tell_file_func; 265 pzlib_filefunc_def->ztell_file = win32_tell_file_func;
266 pzlib_filefunc_def->zseek_file = win32_seek_file_func; 266 pzlib_filefunc_def->zseek_file = win32_seek_file_func;
267 pzlib_filefunc_def->zclose_file = win32_close_file_func; 267 pzlib_filefunc_def->zclose_file = win32_close_file_func;
268 pzlib_filefunc_def->zerror_file = win32_error_file_func; 268 pzlib_filefunc_def->zerror_file = win32_error_file_func;
269 pzlib_filefunc_def->opaque=NULL; 269 pzlib_filefunc_def->opaque=NULL;
270} 270}
diff --git a/contrib/minizip/iowin32.h b/contrib/minizip/iowin32.h
index 8774fe7..e9c5f8b 100644
--- a/contrib/minizip/iowin32.h
+++ b/contrib/minizip/iowin32.h
@@ -1,21 +1,21 @@
1/* iowin32.h -- IO base function header for compress/uncompress .zip 1/* iowin32.h -- IO base function header for compress/uncompress .zip
2 files using zlib + zip or unzip API 2 files using zlib + zip or unzip API
3 This IO API version uses the Win32 API (for Microsoft Windows) 3 This IO API version uses the Win32 API (for Microsoft Windows)
4 4
5 Version 1.01, May 8th, 2004 5 Version 1.01e, February 12th, 2005
6 6
7 Copyright (C) 1998-2004 Gilles Vollant 7 Copyright (C) 1998-2005 Gilles Vollant
8*/ 8*/
9 9
10#include <windows.h> 10#include <windows.h>
11 11
12 12
13#ifdef __cplusplus 13#ifdef __cplusplus
14extern "C" { 14extern "C" {
15#endif 15#endif
16 16
17void fill_win32_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); 17void fill_win32_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
18 18
19#ifdef __cplusplus 19#ifdef __cplusplus
20} 20}
21#endif 21#endif
diff --git a/contrib/minizip/miniunz.c b/contrib/minizip/miniunz.c
index a6b06a2..82d8702 100644
--- a/contrib/minizip/miniunz.c
+++ b/contrib/minizip/miniunz.c
@@ -1,585 +1,585 @@
1/* 1/*
2 miniunz.c 2 miniunz.c
3 Version 1.01b, May 30th, 2004 3 Version 1.01e, February 12th, 2005
4 4
5 Copyright (C) 1998-2004 Gilles Vollant 5 Copyright (C) 1998-2005 Gilles Vollant
6*/ 6*/
7 7
8 8
9#include <stdio.h> 9#include <stdio.h>
10#include <stdlib.h> 10#include <stdlib.h>
11#include <string.h> 11#include <string.h>
12#include <time.h> 12#include <time.h>
13#include <errno.h> 13#include <errno.h>
14#include <fcntl.h> 14#include <fcntl.h>
15 15
16#ifdef unix 16#ifdef unix
17# include <unistd.h> 17# include <unistd.h>
18# include <utime.h> 18# include <utime.h>
19#else 19#else
20# include <direct.h> 20# include <direct.h>
21# include <io.h> 21# include <io.h>
22#endif 22#endif
23 23
24#include "unzip.h" 24#include "unzip.h"
25 25
26#define CASESENSITIVITY (0) 26#define CASESENSITIVITY (0)
27#define WRITEBUFFERSIZE (8192) 27#define WRITEBUFFERSIZE (8192)
28#define MAXFILENAME (256) 28#define MAXFILENAME (256)
29 29
30#ifdef WIN32 30#ifdef WIN32
31#define USEWIN32IOAPI 31#define USEWIN32IOAPI
32#include "iowin32.h" 32#include "iowin32.h"
33#endif 33#endif
34/* 34/*
35 mini unzip, demo of unzip package 35 mini unzip, demo of unzip package
36 36
37 usage : 37 usage :
38 Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir] 38 Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir]
39 39
40 list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT 40 list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT
41 if it exists 41 if it exists
42*/ 42*/
43 43
44 44
45/* change_file_date : change the date/time of a file 45/* change_file_date : change the date/time of a file
46 filename : the filename of the file where date/time must be modified 46 filename : the filename of the file where date/time must be modified
47 dosdate : the new date at the MSDos format (4 bytes) 47 dosdate : the new date at the MSDos format (4 bytes)
48 tmu_date : the SAME new date at the tm_unz format */ 48 tmu_date : the SAME new date at the tm_unz format */
49void change_file_date(filename,dosdate,tmu_date) 49void change_file_date(filename,dosdate,tmu_date)
50 const char *filename; 50 const char *filename;
51 uLong dosdate; 51 uLong dosdate;
52 tm_unz tmu_date; 52 tm_unz tmu_date;
53{ 53{
54#ifdef WIN32 54#ifdef WIN32
55 HANDLE hFile; 55 HANDLE hFile;
56 FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite; 56 FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;
57 57
58 hFile = CreateFile(filename,GENERIC_READ | GENERIC_WRITE, 58 hFile = CreateFile(filename,GENERIC_READ | GENERIC_WRITE,
59 0,NULL,OPEN_EXISTING,0,NULL); 59 0,NULL,OPEN_EXISTING,0,NULL);
60 GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite); 60 GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);
61 DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal); 61 DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal);
62 LocalFileTimeToFileTime(&ftLocal,&ftm); 62 LocalFileTimeToFileTime(&ftLocal,&ftm);
63 SetFileTime(hFile,&ftm,&ftLastAcc,&ftm); 63 SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
64 CloseHandle(hFile); 64 CloseHandle(hFile);
65#else 65#else
66#ifdef unix 66#ifdef unix
67 struct utimbuf ut; 67 struct utimbuf ut;
68 struct tm newdate; 68 struct tm newdate;
69 newdate.tm_sec = tmu_date.tm_sec; 69 newdate.tm_sec = tmu_date.tm_sec;
70 newdate.tm_min=tmu_date.tm_min; 70 newdate.tm_min=tmu_date.tm_min;
71 newdate.tm_hour=tmu_date.tm_hour; 71 newdate.tm_hour=tmu_date.tm_hour;
72 newdate.tm_mday=tmu_date.tm_mday; 72 newdate.tm_mday=tmu_date.tm_mday;
73 newdate.tm_mon=tmu_date.tm_mon; 73 newdate.tm_mon=tmu_date.tm_mon;
74 if (tmu_date.tm_year > 1900) 74 if (tmu_date.tm_year > 1900)
75 newdate.tm_year=tmu_date.tm_year - 1900; 75 newdate.tm_year=tmu_date.tm_year - 1900;
76 else 76 else
77 newdate.tm_year=tmu_date.tm_year ; 77 newdate.tm_year=tmu_date.tm_year ;
78 newdate.tm_isdst=-1; 78 newdate.tm_isdst=-1;
79 79
80 ut.actime=ut.modtime=mktime(&newdate); 80 ut.actime=ut.modtime=mktime(&newdate);
81 utime(filename,&ut); 81 utime(filename,&ut);
82#endif 82#endif
83#endif 83#endif
84} 84}
85 85
86 86
87/* mymkdir and change_file_date are not 100 % portable 87/* mymkdir and change_file_date are not 100 % portable
88 As I don't know well Unix, I wait feedback for the unix portion */ 88 As I don't know well Unix, I wait feedback for the unix portion */
89 89
90int mymkdir(dirname) 90int mymkdir(dirname)
91 const char* dirname; 91 const char* dirname;
92{ 92{
93 int ret=0; 93 int ret=0;
94#ifdef WIN32 94#ifdef WIN32
95 ret = mkdir(dirname); 95 ret = mkdir(dirname);
96#else 96#else
97#ifdef unix 97#ifdef unix
98 ret = mkdir (dirname,0775); 98 ret = mkdir (dirname,0775);
99#endif 99#endif
100#endif 100#endif
101 return ret; 101 return ret;
102} 102}
103 103
104int makedir (newdir) 104int makedir (newdir)
105 char *newdir; 105 char *newdir;
106{ 106{
107 char *buffer ; 107 char *buffer ;
108 char *p; 108 char *p;
109 int len = (int)strlen(newdir); 109 int len = (int)strlen(newdir);
110 110
111 if (len <= 0) 111 if (len <= 0)
112 return 0; 112 return 0;
113 113
114 buffer = (char*)malloc(len+1); 114 buffer = (char*)malloc(len+1);
115 strcpy(buffer,newdir); 115 strcpy(buffer,newdir);
116 116
117 if (buffer[len-1] == '/') { 117 if (buffer[len-1] == '/') {
118 buffer[len-1] = '\0'; 118 buffer[len-1] = '\0';
119 } 119 }
120 if (mymkdir(buffer) == 0) 120 if (mymkdir(buffer) == 0)
121 { 121 {
122 free(buffer); 122 free(buffer);
123 return 1; 123 return 1;
124 } 124 }
125 125
126 p = buffer+1; 126 p = buffer+1;
127 while (1) 127 while (1)
128 { 128 {
129 char hold; 129 char hold;
130 130
131 while(*p && *p != '\\' && *p != '/') 131 while(*p && *p != '\\' && *p != '/')
132 p++; 132 p++;
133 hold = *p; 133 hold = *p;
134 *p = 0; 134 *p = 0;
135 if ((mymkdir(buffer) == -1) && (errno == ENOENT)) 135 if ((mymkdir(buffer) == -1) && (errno == ENOENT))
136 { 136 {
137 printf("couldn't create directory %s\n",buffer); 137 printf("couldn't create directory %s\n",buffer);
138 free(buffer); 138 free(buffer);
139 return 0; 139 return 0;
140 } 140 }
141 if (hold == 0) 141 if (hold == 0)
142 break; 142 break;
143 *p++ = hold; 143 *p++ = hold;
144 } 144 }
145 free(buffer); 145 free(buffer);
146 return 1; 146 return 1;
147} 147}
148 148
149void do_banner() 149void do_banner()
150{ 150{
151 printf("MiniUnz 1.01b, demo of zLib + Unz package written by Gilles Vollant\n"); 151 printf("MiniUnz 1.01b, demo of zLib + Unz package written by Gilles Vollant\n");
152 printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n"); 152 printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n");
153} 153}
154 154
155void do_help() 155void do_help()
156{ 156{
157 printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\n\n" \ 157 printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\n\n" \
158 " -e Extract without pathname (junk paths)\n" \ 158 " -e Extract without pathname (junk paths)\n" \
159 " -x Extract with pathname\n" \ 159 " -x Extract with pathname\n" \
160 " -v list files\n" \ 160 " -v list files\n" \
161 " -l list files\n" \ 161 " -l list files\n" \
162 " -d directory to extract into\n" \ 162 " -d directory to extract into\n" \
163 " -o overwrite files without prompting\n" \ 163 " -o overwrite files without prompting\n" \
164 " -p extract crypted file using password\n\n"); 164 " -p extract crypted file using password\n\n");
165} 165}
166 166
167 167
168int do_list(uf) 168int do_list(uf)
169 unzFile uf; 169 unzFile uf;
170{ 170{
171 uLong i; 171 uLong i;
172 unz_global_info gi; 172 unz_global_info gi;
173 int err; 173 int err;
174 174
175 err = unzGetGlobalInfo (uf,&gi); 175 err = unzGetGlobalInfo (uf,&gi);
176 if (err!=UNZ_OK) 176 if (err!=UNZ_OK)
177 printf("error %d with zipfile in unzGetGlobalInfo \n",err); 177 printf("error %d with zipfile in unzGetGlobalInfo \n",err);
178 printf(" Length Method Size Ratio Date Time CRC-32 Name\n"); 178 printf(" Length Method Size Ratio Date Time CRC-32 Name\n");
179 printf(" ------ ------ ---- ----- ---- ---- ------ ----\n"); 179 printf(" ------ ------ ---- ----- ---- ---- ------ ----\n");
180 for (i=0;i<gi.number_entry;i++) 180 for (i=0;i<gi.number_entry;i++)
181 { 181 {
182 char filename_inzip[256]; 182 char filename_inzip[256];
183 unz_file_info file_info; 183 unz_file_info file_info;
184 uLong ratio=0; 184 uLong ratio=0;
185 const char *string_method; 185 const char *string_method;
186 char charCrypt=' '; 186 char charCrypt=' ';
187 err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0); 187 err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
188 if (err!=UNZ_OK) 188 if (err!=UNZ_OK)
189 { 189 {
190 printf("error %d with zipfile in unzGetCurrentFileInfo\n",err); 190 printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
191 break; 191 break;
192 } 192 }
193 if (file_info.uncompressed_size>0) 193 if (file_info.uncompressed_size>0)
194 ratio = (file_info.compressed_size*100)/file_info.uncompressed_size; 194 ratio = (file_info.compressed_size*100)/file_info.uncompressed_size;
195 195
196 /* display a '*' if the file is crypted */ 196 /* display a '*' if the file is crypted */
197 if ((file_info.flag & 1) != 0) 197 if ((file_info.flag & 1) != 0)
198 charCrypt='*'; 198 charCrypt='*';
199 199
200 if (file_info.compression_method==0) 200 if (file_info.compression_method==0)
201 string_method="Stored"; 201 string_method="Stored";
202 else 202 else
203 if (file_info.compression_method==Z_DEFLATED) 203 if (file_info.compression_method==Z_DEFLATED)
204 { 204 {
205 uInt iLevel=(uInt)((file_info.flag & 0x6)/2); 205 uInt iLevel=(uInt)((file_info.flag & 0x6)/2);
206 if (iLevel==0) 206 if (iLevel==0)
207 string_method="Defl:N"; 207 string_method="Defl:N";
208 else if (iLevel==1) 208 else if (iLevel==1)
209 string_method="Defl:X"; 209 string_method="Defl:X";
210 else if ((iLevel==2) || (iLevel==3)) 210 else if ((iLevel==2) || (iLevel==3))
211 string_method="Defl:F"; /* 2:fast , 3 : extra fast*/ 211 string_method="Defl:F"; /* 2:fast , 3 : extra fast*/
212 } 212 }
213 else 213 else
214 string_method="Unkn. "; 214 string_method="Unkn. ";
215 215
216 printf("%7lu %6s%c%7lu %3lu%% %2.2lu-%2.2lu-%2.2lu %2.2lu:%2.2lu %8.8lx %s\n", 216 printf("%7lu %6s%c%7lu %3lu%% %2.2lu-%2.2lu-%2.2lu %2.2lu:%2.2lu %8.8lx %s\n",
217 file_info.uncompressed_size,string_method, 217 file_info.uncompressed_size,string_method,
218 charCrypt, 218 charCrypt,
219 file_info.compressed_size, 219 file_info.compressed_size,
220 ratio, 220 ratio,
221 (uLong)file_info.tmu_date.tm_mon + 1, 221 (uLong)file_info.tmu_date.tm_mon + 1,
222 (uLong)file_info.tmu_date.tm_mday, 222 (uLong)file_info.tmu_date.tm_mday,
223 (uLong)file_info.tmu_date.tm_year % 100, 223 (uLong)file_info.tmu_date.tm_year % 100,
224 (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min, 224 (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min,
225 (uLong)file_info.crc,filename_inzip); 225 (uLong)file_info.crc,filename_inzip);
226 if ((i+1)<gi.number_entry) 226 if ((i+1)<gi.number_entry)
227 { 227 {
228 err = unzGoToNextFile(uf); 228 err = unzGoToNextFile(uf);
229 if (err!=UNZ_OK) 229 if (err!=UNZ_OK)
230 { 230 {
231 printf("error %d with zipfile in unzGoToNextFile\n",err); 231 printf("error %d with zipfile in unzGoToNextFile\n",err);
232 break; 232 break;
233 } 233 }
234 } 234 }
235 } 235 }
236 236
237 return 0; 237 return 0;
238} 238}
239 239
240 240
241int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password) 241int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
242 unzFile uf; 242 unzFile uf;
243 const int* popt_extract_without_path; 243 const int* popt_extract_without_path;
244 int* popt_overwrite; 244 int* popt_overwrite;
245 const char* password; 245 const char* password;
246{ 246{
247 char filename_inzip[256]; 247 char filename_inzip[256];
248 char* filename_withoutpath; 248 char* filename_withoutpath;
249 char* p; 249 char* p;
250 int err=UNZ_OK; 250 int err=UNZ_OK;
251 FILE *fout=NULL; 251 FILE *fout=NULL;
252 void* buf; 252 void* buf;
253 uInt size_buf; 253 uInt size_buf;
254 254
255 unz_file_info file_info; 255 unz_file_info file_info;
256 uLong ratio=0; 256 uLong ratio=0;
257 err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0); 257 err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
258 258
259 if (err!=UNZ_OK) 259 if (err!=UNZ_OK)
260 { 260 {
261 printf("error %d with zipfile in unzGetCurrentFileInfo\n",err); 261 printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
262 return err; 262 return err;
263 } 263 }
264 264
265 size_buf = WRITEBUFFERSIZE; 265 size_buf = WRITEBUFFERSIZE;
266 buf = (void*)malloc(size_buf); 266 buf = (void*)malloc(size_buf);
267 if (buf==NULL) 267 if (buf==NULL)
268 { 268 {
269 printf("Error allocating memory\n"); 269 printf("Error allocating memory\n");
270 return UNZ_INTERNALERROR; 270 return UNZ_INTERNALERROR;
271 } 271 }
272 272
273 p = filename_withoutpath = filename_inzip; 273 p = filename_withoutpath = filename_inzip;
274 while ((*p) != '\0') 274 while ((*p) != '\0')
275 { 275 {
276 if (((*p)=='/') || ((*p)=='\\')) 276 if (((*p)=='/') || ((*p)=='\\'))
277 filename_withoutpath = p+1; 277 filename_withoutpath = p+1;
278 p++; 278 p++;
279 } 279 }
280 280
281 if ((*filename_withoutpath)=='\0') 281 if ((*filename_withoutpath)=='\0')
282 { 282 {
283 if ((*popt_extract_without_path)==0) 283 if ((*popt_extract_without_path)==0)
284 { 284 {
285 printf("creating directory: %s\n",filename_inzip); 285 printf("creating directory: %s\n",filename_inzip);
286 mymkdir(filename_inzip); 286 mymkdir(filename_inzip);
287 } 287 }
288 } 288 }
289 else 289 else
290 { 290 {
291 const char* write_filename; 291 const char* write_filename;
292 int skip=0; 292 int skip=0;
293 293
294 if ((*popt_extract_without_path)==0) 294 if ((*popt_extract_without_path)==0)
295 write_filename = filename_inzip; 295 write_filename = filename_inzip;
296 else 296 else
297 write_filename = filename_withoutpath; 297 write_filename = filename_withoutpath;
298 298
299 err = unzOpenCurrentFilePassword(uf,password); 299 err = unzOpenCurrentFilePassword(uf,password);
300 if (err!=UNZ_OK) 300 if (err!=UNZ_OK)
301 { 301 {
302 printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err); 302 printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);
303 } 303 }
304 304
305 if (((*popt_overwrite)==0) && (err==UNZ_OK)) 305 if (((*popt_overwrite)==0) && (err==UNZ_OK))
306 { 306 {
307 char rep=0; 307 char rep=0;
308 FILE* ftestexist; 308 FILE* ftestexist;
309 ftestexist = fopen(write_filename,"rb"); 309 ftestexist = fopen(write_filename,"rb");
310 if (ftestexist!=NULL) 310 if (ftestexist!=NULL)
311 { 311 {
312 fclose(ftestexist); 312 fclose(ftestexist);
313 do 313 do
314 { 314 {
315 char answer[128]; 315 char answer[128];
316 int ret; 316 int ret;
317 317
318 printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ",write_filename); 318 printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ",write_filename);
319 ret = scanf("%1s",answer); 319 ret = scanf("%1s",answer);
320 if (ret != 1) 320 if (ret != 1)
321 { 321 {
322 exit(EXIT_FAILURE); 322 exit(EXIT_FAILURE);
323 } 323 }
324 rep = answer[0] ; 324 rep = answer[0] ;
325 if ((rep>='a') && (rep<='z')) 325 if ((rep>='a') && (rep<='z'))
326 rep -= 0x20; 326 rep -= 0x20;
327 } 327 }
328 while ((rep!='Y') && (rep!='N') && (rep!='A')); 328 while ((rep!='Y') && (rep!='N') && (rep!='A'));
329 } 329 }
330 330
331 if (rep == 'N') 331 if (rep == 'N')
332 skip = 1; 332 skip = 1;
333 333
334 if (rep == 'A') 334 if (rep == 'A')
335 *popt_overwrite=1; 335 *popt_overwrite=1;
336 } 336 }
337 337
338 if ((skip==0) && (err==UNZ_OK)) 338 if ((skip==0) && (err==UNZ_OK))
339 { 339 {
340 fout=fopen(write_filename,"wb"); 340 fout=fopen(write_filename,"wb");
341 341
342 /* some zipfile don't contain directory alone before file */ 342 /* some zipfile don't contain directory alone before file */
343 if ((fout==NULL) && ((*popt_extract_without_path)==0) && 343 if ((fout==NULL) && ((*popt_extract_without_path)==0) &&
344 (filename_withoutpath!=(char*)filename_inzip)) 344 (filename_withoutpath!=(char*)filename_inzip))
345 { 345 {
346 char c=*(filename_withoutpath-1); 346 char c=*(filename_withoutpath-1);
347 *(filename_withoutpath-1)='\0'; 347 *(filename_withoutpath-1)='\0';
348 makedir(write_filename); 348 makedir(write_filename);
349 *(filename_withoutpath-1)=c; 349 *(filename_withoutpath-1)=c;
350 fout=fopen(write_filename,"wb"); 350 fout=fopen(write_filename,"wb");
351 } 351 }
352 352
353 if (fout==NULL) 353 if (fout==NULL)
354 { 354 {
355 printf("error opening %s\n",write_filename); 355 printf("error opening %s\n",write_filename);
356 } 356 }
357 } 357 }
358 358
359 if (fout!=NULL) 359 if (fout!=NULL)
360 { 360 {
361 printf(" extracting: %s\n",write_filename); 361 printf(" extracting: %s\n",write_filename);
362 362
363 do 363 do
364 { 364 {
365 err = unzReadCurrentFile(uf,buf,size_buf); 365 err = unzReadCurrentFile(uf,buf,size_buf);
366 if (err<0) 366 if (err<0)
367 { 367 {
368 printf("error %d with zipfile in unzReadCurrentFile\n",err); 368 printf("error %d with zipfile in unzReadCurrentFile\n",err);
369 break; 369 break;
370 } 370 }
371 if (err>0) 371 if (err>0)
372 if (fwrite(buf,err,1,fout)!=1) 372 if (fwrite(buf,err,1,fout)!=1)
373 { 373 {
374 printf("error in writing extracted file\n"); 374 printf("error in writing extracted file\n");
375 err=UNZ_ERRNO; 375 err=UNZ_ERRNO;
376 break; 376 break;
377 } 377 }
378 } 378 }
379 while (err>0); 379 while (err>0);
380 if (fout) 380 if (fout)
381 fclose(fout); 381 fclose(fout);
382 382
383 if (err==0) 383 if (err==0)
384 change_file_date(write_filename,file_info.dosDate, 384 change_file_date(write_filename,file_info.dosDate,
385 file_info.tmu_date); 385 file_info.tmu_date);
386 } 386 }
387 387
388 if (err==UNZ_OK) 388 if (err==UNZ_OK)
389 { 389 {
390 err = unzCloseCurrentFile (uf); 390 err = unzCloseCurrentFile (uf);
391 if (err!=UNZ_OK) 391 if (err!=UNZ_OK)
392 { 392 {
393 printf("error %d with zipfile in unzCloseCurrentFile\n",err); 393 printf("error %d with zipfile in unzCloseCurrentFile\n",err);
394 } 394 }
395 } 395 }
396 else 396 else
397 unzCloseCurrentFile(uf); /* don't lose the error */ 397 unzCloseCurrentFile(uf); /* don't lose the error */
398 } 398 }
399 399
400 free(buf); 400 free(buf);
401 return err; 401 return err;
402} 402}
403 403
404 404
405int do_extract(uf,opt_extract_without_path,opt_overwrite,password) 405int do_extract(uf,opt_extract_without_path,opt_overwrite,password)
406 unzFile uf; 406 unzFile uf;
407 int opt_extract_without_path; 407 int opt_extract_without_path;
408 int opt_overwrite; 408 int opt_overwrite;
409 const char* password; 409 const char* password;
410{ 410{
411 uLong i; 411 uLong i;
412 unz_global_info gi; 412 unz_global_info gi;
413 int err; 413 int err;
414 FILE* fout=NULL; 414 FILE* fout=NULL;
415 415
416 err = unzGetGlobalInfo (uf,&gi); 416 err = unzGetGlobalInfo (uf,&gi);
417 if (err!=UNZ_OK) 417 if (err!=UNZ_OK)
418 printf("error %d with zipfile in unzGetGlobalInfo \n",err); 418 printf("error %d with zipfile in unzGetGlobalInfo \n",err);
419 419
420 for (i=0;i<gi.number_entry;i++) 420 for (i=0;i<gi.number_entry;i++)
421 { 421 {
422 if (do_extract_currentfile(uf,&opt_extract_without_path, 422 if (do_extract_currentfile(uf,&opt_extract_without_path,
423 &opt_overwrite, 423 &opt_overwrite,
424 password) != UNZ_OK) 424 password) != UNZ_OK)
425 break; 425 break;
426 426
427 if ((i+1)<gi.number_entry) 427 if ((i+1)<gi.number_entry)
428 { 428 {
429 err = unzGoToNextFile(uf); 429 err = unzGoToNextFile(uf);
430 if (err!=UNZ_OK) 430 if (err!=UNZ_OK)
431 { 431 {
432 printf("error %d with zipfile in unzGoToNextFile\n",err); 432 printf("error %d with zipfile in unzGoToNextFile\n",err);
433 break; 433 break;
434 } 434 }
435 } 435 }
436 } 436 }
437 437
438 return 0; 438 return 0;
439} 439}
440 440
441int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,password) 441int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,password)
442 unzFile uf; 442 unzFile uf;
443 const char* filename; 443 const char* filename;
444 int opt_extract_without_path; 444 int opt_extract_without_path;
445 int opt_overwrite; 445 int opt_overwrite;
446 const char* password; 446 const char* password;
447{ 447{
448 int err = UNZ_OK; 448 int err = UNZ_OK;
449 if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK) 449 if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
450 { 450 {
451 printf("file %s not found in the zipfile\n",filename); 451 printf("file %s not found in the zipfile\n",filename);
452 return 2; 452 return 2;
453 } 453 }
454 454
455 if (do_extract_currentfile(uf,&opt_extract_without_path, 455 if (do_extract_currentfile(uf,&opt_extract_without_path,
456 &opt_overwrite, 456 &opt_overwrite,
457 password) == UNZ_OK) 457 password) == UNZ_OK)
458 return 0; 458 return 0;
459 else 459 else
460 return 1; 460 return 1;
461} 461}
462 462
463 463
464int main(argc,argv) 464int main(argc,argv)
465 int argc; 465 int argc;
466 char *argv[]; 466 char *argv[];
467{ 467{
468 const char *zipfilename=NULL; 468 const char *zipfilename=NULL;
469 const char *filename_to_extract=NULL; 469 const char *filename_to_extract=NULL;
470 const char *password=NULL; 470 const char *password=NULL;
471 char filename_try[MAXFILENAME+16] = ""; 471 char filename_try[MAXFILENAME+16] = "";
472 int i; 472 int i;
473 int opt_do_list=0; 473 int opt_do_list=0;
474 int opt_do_extract=1; 474 int opt_do_extract=1;
475 int opt_do_extract_withoutpath=0; 475 int opt_do_extract_withoutpath=0;
476 int opt_overwrite=0; 476 int opt_overwrite=0;
477 int opt_extractdir=0; 477 int opt_extractdir=0;
478 const char *dirname=NULL; 478 const char *dirname=NULL;
479 unzFile uf=NULL; 479 unzFile uf=NULL;
480 480
481 do_banner(); 481 do_banner();
482 if (argc==1) 482 if (argc==1)
483 { 483 {
484 do_help(); 484 do_help();
485 return 0; 485 return 0;
486 } 486 }
487 else 487 else
488 { 488 {
489 for (i=1;i<argc;i++) 489 for (i=1;i<argc;i++)
490 { 490 {
491 if ((*argv[i])=='-') 491 if ((*argv[i])=='-')
492 { 492 {
493 const char *p=argv[i]+1; 493 const char *p=argv[i]+1;
494 494
495 while ((*p)!='\0') 495 while ((*p)!='\0')
496 { 496 {
497 char c=*(p++);; 497 char c=*(p++);;
498 if ((c=='l') || (c=='L')) 498 if ((c=='l') || (c=='L'))
499 opt_do_list = 1; 499 opt_do_list = 1;
500 if ((c=='v') || (c=='V')) 500 if ((c=='v') || (c=='V'))
501 opt_do_list = 1; 501 opt_do_list = 1;
502 if ((c=='x') || (c=='X')) 502 if ((c=='x') || (c=='X'))
503 opt_do_extract = 1; 503 opt_do_extract = 1;
504 if ((c=='e') || (c=='E')) 504 if ((c=='e') || (c=='E'))
505 opt_do_extract = opt_do_extract_withoutpath = 1; 505 opt_do_extract = opt_do_extract_withoutpath = 1;
506 if ((c=='o') || (c=='O')) 506 if ((c=='o') || (c=='O'))
507 opt_overwrite=1; 507 opt_overwrite=1;
508 if ((c=='d') || (c=='D')) 508 if ((c=='d') || (c=='D'))
509 { 509 {
510 opt_extractdir=1; 510 opt_extractdir=1;
511 dirname=argv[i+1]; 511 dirname=argv[i+1];
512 } 512 }
513 513
514 if (((c=='p') || (c=='P')) && (i+1<argc)) 514 if (((c=='p') || (c=='P')) && (i+1<argc))
515 { 515 {
516 password=argv[i+1]; 516 password=argv[i+1];
517 i++; 517 i++;
518 } 518 }
519 } 519 }
520 } 520 }
521 else 521 else
522 { 522 {
523 if (zipfilename == NULL) 523 if (zipfilename == NULL)
524 zipfilename = argv[i]; 524 zipfilename = argv[i];
525 else if ((filename_to_extract==NULL) && (!opt_extractdir)) 525 else if ((filename_to_extract==NULL) && (!opt_extractdir))
526 filename_to_extract = argv[i] ; 526 filename_to_extract = argv[i] ;
527 } 527 }
528 } 528 }
529 } 529 }
530 530
531 if (zipfilename!=NULL) 531 if (zipfilename!=NULL)
532 { 532 {
533 533
534# ifdef USEWIN32IOAPI 534# ifdef USEWIN32IOAPI
535 zlib_filefunc_def ffunc; 535 zlib_filefunc_def ffunc;
536# endif 536# endif
537 537
538 strncpy(filename_try, zipfilename,MAXFILENAME-1); 538 strncpy(filename_try, zipfilename,MAXFILENAME-1);
539 /* strncpy doesnt append the trailing NULL, of the string is too long. */ 539 /* strncpy doesnt append the trailing NULL, of the string is too long. */
540 filename_try[ MAXFILENAME ] = '\0'; 540 filename_try[ MAXFILENAME ] = '\0';
541 541
542# ifdef USEWIN32IOAPI 542# ifdef USEWIN32IOAPI
543 fill_win32_filefunc(&ffunc); 543 fill_win32_filefunc(&ffunc);
544 uf = unzOpen2(zipfilename,&ffunc); 544 uf = unzOpen2(zipfilename,&ffunc);
545# else 545# else
546 uf = unzOpen(zipfilename); 546 uf = unzOpen(zipfilename);
547# endif 547# endif
548 if (uf==NULL) 548 if (uf==NULL)
549 { 549 {
550 strcat(filename_try,".zip"); 550 strcat(filename_try,".zip");
551# ifdef USEWIN32IOAPI 551# ifdef USEWIN32IOAPI
552 uf = unzOpen2(filename_try,&ffunc); 552 uf = unzOpen2(filename_try,&ffunc);
553# else 553# else
554 uf = unzOpen(filename_try); 554 uf = unzOpen(filename_try);
555# endif 555# endif
556 } 556 }
557 } 557 }
558 558
559 if (uf==NULL) 559 if (uf==NULL)
560 { 560 {
561 printf("Cannot open %s or %s.zip\n",zipfilename,zipfilename); 561 printf("Cannot open %s or %s.zip\n",zipfilename,zipfilename);
562 return 1; 562 return 1;
563 } 563 }
564 printf("%s opened\n",filename_try); 564 printf("%s opened\n",filename_try);
565 565
566 if (opt_do_list==1) 566 if (opt_do_list==1)
567 return do_list(uf); 567 return do_list(uf);
568 else if (opt_do_extract==1) 568 else if (opt_do_extract==1)
569 { 569 {
570 if (opt_extractdir && chdir(dirname)) 570 if (opt_extractdir && chdir(dirname))
571 { 571 {
572 printf("Error changing into %s, aborting\n", dirname); 572 printf("Error changing into %s, aborting\n", dirname);
573 exit(-1); 573 exit(-1);
574 } 574 }
575 575
576 if (filename_to_extract == NULL) 576 if (filename_to_extract == NULL)
577 return do_extract(uf,opt_do_extract_withoutpath,opt_overwrite,password); 577 return do_extract(uf,opt_do_extract_withoutpath,opt_overwrite,password);
578 else 578 else
579 return do_extract_onefile(uf,filename_to_extract, 579 return do_extract_onefile(uf,filename_to_extract,
580 opt_do_extract_withoutpath,opt_overwrite,password); 580 opt_do_extract_withoutpath,opt_overwrite,password);
581 } 581 }
582 unzCloseCurrentFile(uf); 582 unzCloseCurrentFile(uf);
583 583
584 return 0; 584 return 0;
585} 585}
diff --git a/contrib/minizip/minizip.c b/contrib/minizip/minizip.c
index 918c322..70fee02 100644
--- a/contrib/minizip/minizip.c
+++ b/contrib/minizip/minizip.c
@@ -1,420 +1,420 @@
1/* 1/*
2 minizip.c 2 minizip.c
3 Version 1.01b, May 30th, 2004 3 Version 1.01e, February 12th, 2005
4 4
5 Copyright (C) 1998-2004 Gilles Vollant 5 Copyright (C) 1998-2005 Gilles Vollant
6*/ 6*/
7 7
8#include <stdio.h> 8#include <stdio.h>
9#include <stdlib.h> 9#include <stdlib.h>
10#include <string.h> 10#include <string.h>
11#include <time.h> 11#include <time.h>
12#include <errno.h> 12#include <errno.h>
13#include <fcntl.h> 13#include <fcntl.h>
14 14
15#ifdef unix 15#ifdef unix
16# include <unistd.h> 16# include <unistd.h>
17# include <utime.h> 17# include <utime.h>
18# include <sys/types.h> 18# include <sys/types.h>
19# include <sys/stat.h> 19# include <sys/stat.h>
20#else 20#else
21# include <direct.h> 21# include <direct.h>
22# include <io.h> 22# include <io.h>
23#endif 23#endif
24 24
25#include "zip.h" 25#include "zip.h"
26 26
27#ifdef WIN32 27#ifdef WIN32
28#define USEWIN32IOAPI 28#define USEWIN32IOAPI
29#include "iowin32.h" 29#include "iowin32.h"
30#endif 30#endif
31 31
32 32
33 33
34#define WRITEBUFFERSIZE (16384) 34#define WRITEBUFFERSIZE (16384)
35#define MAXFILENAME (256) 35#define MAXFILENAME (256)
36 36
37#ifdef WIN32 37#ifdef WIN32
38uLong filetime(f, tmzip, dt) 38uLong filetime(f, tmzip, dt)
39 char *f; /* name of file to get info on */ 39 char *f; /* name of file to get info on */
40 tm_zip *tmzip; /* return value: access, modific. and creation times */ 40 tm_zip *tmzip; /* return value: access, modific. and creation times */
41 uLong *dt; /* dostime */ 41 uLong *dt; /* dostime */
42{ 42{
43 int ret = 0; 43 int ret = 0;
44 { 44 {
45 FILETIME ftLocal; 45 FILETIME ftLocal;
46 HANDLE hFind; 46 HANDLE hFind;
47 WIN32_FIND_DATA ff32; 47 WIN32_FIND_DATA ff32;
48 48
49 hFind = FindFirstFile(f,&ff32); 49 hFind = FindFirstFile(f,&ff32);
50 if (hFind != INVALID_HANDLE_VALUE) 50 if (hFind != INVALID_HANDLE_VALUE)
51 { 51 {
52 FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal); 52 FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
53 FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0); 53 FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
54 FindClose(hFind); 54 FindClose(hFind);
55 ret = 1; 55 ret = 1;
56 } 56 }
57 } 57 }
58 return ret; 58 return ret;
59} 59}
60#else 60#else
61#ifdef unix 61#ifdef unix
62uLong filetime(f, tmzip, dt) 62uLong filetime(f, tmzip, dt)
63 char *f; /* name of file to get info on */ 63 char *f; /* name of file to get info on */
64 tm_zip *tmzip; /* return value: access, modific. and creation times */ 64 tm_zip *tmzip; /* return value: access, modific. and creation times */
65 uLong *dt; /* dostime */ 65 uLong *dt; /* dostime */
66{ 66{
67 int ret=0; 67 int ret=0;
68 struct stat s; /* results of stat() */ 68 struct stat s; /* results of stat() */
69 struct tm* filedate; 69 struct tm* filedate;
70 time_t tm_t=0; 70 time_t tm_t=0;
71 71
72 if (strcmp(f,"-")!=0) 72 if (strcmp(f,"-")!=0)
73 { 73 {
74 char name[MAXFILENAME+1]; 74 char name[MAXFILENAME+1];
75 int len = strlen(f); 75 int len = strlen(f);
76 if (len > MAXFILENAME) 76 if (len > MAXFILENAME)
77 len = MAXFILENAME; 77 len = MAXFILENAME;
78 78
79 strncpy(name, f,MAXFILENAME-1); 79 strncpy(name, f,MAXFILENAME-1);
80 /* strncpy doesnt append the trailing NULL, of the string is too long. */ 80 /* strncpy doesnt append the trailing NULL, of the string is too long. */
81 name[ MAXFILENAME ] = '\0'; 81 name[ MAXFILENAME ] = '\0';
82 82
83 if (name[len - 1] == '/') 83 if (name[len - 1] == '/')
84 name[len - 1] = '\0'; 84 name[len - 1] = '\0';
85 /* not all systems allow stat'ing a file with / appended */ 85 /* not all systems allow stat'ing a file with / appended */
86 if (stat(name,&s)==0) 86 if (stat(name,&s)==0)
87 { 87 {
88 tm_t = s.st_mtime; 88 tm_t = s.st_mtime;
89 ret = 1; 89 ret = 1;
90 } 90 }
91 } 91 }
92 filedate = localtime(&tm_t); 92 filedate = localtime(&tm_t);
93 93
94 tmzip->tm_sec = filedate->tm_sec; 94 tmzip->tm_sec = filedate->tm_sec;
95 tmzip->tm_min = filedate->tm_min; 95 tmzip->tm_min = filedate->tm_min;
96 tmzip->tm_hour = filedate->tm_hour; 96 tmzip->tm_hour = filedate->tm_hour;
97 tmzip->tm_mday = filedate->tm_mday; 97 tmzip->tm_mday = filedate->tm_mday;
98 tmzip->tm_mon = filedate->tm_mon ; 98 tmzip->tm_mon = filedate->tm_mon ;
99 tmzip->tm_year = filedate->tm_year; 99 tmzip->tm_year = filedate->tm_year;
100 100
101 return ret; 101 return ret;
102} 102}
103#else 103#else
104uLong filetime(f, tmzip, dt) 104uLong filetime(f, tmzip, dt)
105 char *f; /* name of file to get info on */ 105 char *f; /* name of file to get info on */
106 tm_zip *tmzip; /* return value: access, modific. and creation times */ 106 tm_zip *tmzip; /* return value: access, modific. and creation times */
107 uLong *dt; /* dostime */ 107 uLong *dt; /* dostime */
108{ 108{
109 return 0; 109 return 0;
110} 110}
111#endif 111#endif
112#endif 112#endif
113 113
114 114
115 115
116 116
117int check_exist_file(filename) 117int check_exist_file(filename)
118 const char* filename; 118 const char* filename;
119{ 119{
120 FILE* ftestexist; 120 FILE* ftestexist;
121 int ret = 1; 121 int ret = 1;
122 ftestexist = fopen(filename,"rb"); 122 ftestexist = fopen(filename,"rb");
123 if (ftestexist==NULL) 123 if (ftestexist==NULL)
124 ret = 0; 124 ret = 0;
125 else 125 else
126 fclose(ftestexist); 126 fclose(ftestexist);
127 return ret; 127 return ret;
128} 128}
129 129
130void do_banner() 130void do_banner()
131{ 131{
132 printf("MiniZip 1.01b, demo of zLib + Zip package written by Gilles Vollant\n"); 132 printf("MiniZip 1.01b, demo of zLib + Zip package written by Gilles Vollant\n");
133 printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n"); 133 printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n");
134} 134}
135 135
136void do_help() 136void do_help()
137{ 137{
138 printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] file.zip [files_to_add]\n\n" \ 138 printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] file.zip [files_to_add]\n\n" \
139 " -o Overwrite existing file.zip\n" \ 139 " -o Overwrite existing file.zip\n" \
140 " -a Append to existing file.zip\n" \ 140 " -a Append to existing file.zip\n" \
141 " -0 Store only\n" \ 141 " -0 Store only\n" \
142 " -1 Compress faster\n" \ 142 " -1 Compress faster\n" \
143 " -9 Compress better\n\n"); 143 " -9 Compress better\n\n");
144} 144}
145 145
146/* calculate the CRC32 of a file, 146/* calculate the CRC32 of a file,
147 because to encrypt a file, we need known the CRC32 of the file before */ 147 because to encrypt a file, we need known the CRC32 of the file before */
148int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc) 148int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc)
149{ 149{
150 unsigned long calculate_crc=0; 150 unsigned long calculate_crc=0;
151 int err=ZIP_OK; 151 int err=ZIP_OK;
152 FILE * fin = fopen(filenameinzip,"rb"); 152 FILE * fin = fopen(filenameinzip,"rb");
153 unsigned long size_read = 0; 153 unsigned long size_read = 0;
154 unsigned long total_read = 0; 154 unsigned long total_read = 0;
155 if (fin==NULL) 155 if (fin==NULL)
156 { 156 {
157 err = ZIP_ERRNO; 157 err = ZIP_ERRNO;
158 } 158 }
159 159
160 if (err == ZIP_OK) 160 if (err == ZIP_OK)
161 do 161 do
162 { 162 {
163 err = ZIP_OK; 163 err = ZIP_OK;
164 size_read = (int)fread(buf,1,size_buf,fin); 164 size_read = (int)fread(buf,1,size_buf,fin);
165 if (size_read < size_buf) 165 if (size_read < size_buf)
166 if (feof(fin)==0) 166 if (feof(fin)==0)
167 { 167 {
168 printf("error in reading %s\n",filenameinzip); 168 printf("error in reading %s\n",filenameinzip);
169 err = ZIP_ERRNO; 169 err = ZIP_ERRNO;
170 } 170 }
171 171
172 if (size_read>0) 172 if (size_read>0)
173 calculate_crc = crc32(calculate_crc,buf,size_read); 173 calculate_crc = crc32(calculate_crc,buf,size_read);
174 total_read += size_read; 174 total_read += size_read;
175 175
176 } while ((err == ZIP_OK) && (size_read>0)); 176 } while ((err == ZIP_OK) && (size_read>0));
177 177
178 if (fin) 178 if (fin)
179 fclose(fin); 179 fclose(fin);
180 180
181 *result_crc=calculate_crc; 181 *result_crc=calculate_crc;
182 printf("file %s crc %x\n",filenameinzip,calculate_crc); 182 printf("file %s crc %x\n",filenameinzip,calculate_crc);
183 return err; 183 return err;
184} 184}
185 185
186int main(argc,argv) 186int main(argc,argv)
187 int argc; 187 int argc;
188 char *argv[]; 188 char *argv[];
189{ 189{
190 int i; 190 int i;
191 int opt_overwrite=0; 191 int opt_overwrite=0;
192 int opt_compress_level=Z_DEFAULT_COMPRESSION; 192 int opt_compress_level=Z_DEFAULT_COMPRESSION;
193 int zipfilenamearg = 0; 193 int zipfilenamearg = 0;
194 char filename_try[MAXFILENAME+16]; 194 char filename_try[MAXFILENAME+16];
195 int zipok; 195 int zipok;
196 int err=0; 196 int err=0;
197 int size_buf=0; 197 int size_buf=0;
198 void* buf=NULL; 198 void* buf=NULL;
199 const char* password=NULL; 199 const char* password=NULL;
200 200
201 201
202 do_banner(); 202 do_banner();
203 if (argc==1) 203 if (argc==1)
204 { 204 {
205 do_help(); 205 do_help();
206 return 0; 206 return 0;
207 } 207 }
208 else 208 else
209 { 209 {
210 for (i=1;i<argc;i++) 210 for (i=1;i<argc;i++)
211 { 211 {
212 if ((*argv[i])=='-') 212 if ((*argv[i])=='-')
213 { 213 {
214 const char *p=argv[i]+1; 214 const char *p=argv[i]+1;
215 215
216 while ((*p)!='\0') 216 while ((*p)!='\0')
217 { 217 {
218 char c=*(p++);; 218 char c=*(p++);;
219 if ((c=='o') || (c=='O')) 219 if ((c=='o') || (c=='O'))
220 opt_overwrite = 1; 220 opt_overwrite = 1;
221 if ((c=='a') || (c=='A')) 221 if ((c=='a') || (c=='A'))
222 opt_overwrite = 2; 222 opt_overwrite = 2;
223 if ((c>='0') && (c<='9')) 223 if ((c>='0') && (c<='9'))
224 opt_compress_level = c-'0'; 224 opt_compress_level = c-'0';
225 225
226 if (((c=='p') || (c=='P')) && (i+1<argc)) 226 if (((c=='p') || (c=='P')) && (i+1<argc))
227 { 227 {
228 password=argv[i+1]; 228 password=argv[i+1];
229 i++; 229 i++;
230 } 230 }
231 } 231 }
232 } 232 }
233 else 233 else
234 if (zipfilenamearg == 0) 234 if (zipfilenamearg == 0)
235 zipfilenamearg = i ; 235 zipfilenamearg = i ;
236 } 236 }
237 } 237 }
238 238
239 size_buf = WRITEBUFFERSIZE; 239 size_buf = WRITEBUFFERSIZE;
240 buf = (void*)malloc(size_buf); 240 buf = (void*)malloc(size_buf);
241 if (buf==NULL) 241 if (buf==NULL)
242 { 242 {
243 printf("Error allocating memory\n"); 243 printf("Error allocating memory\n");
244 return ZIP_INTERNALERROR; 244 return ZIP_INTERNALERROR;
245 } 245 }
246 246
247 if (zipfilenamearg==0) 247 if (zipfilenamearg==0)
248 zipok=0; 248 zipok=0;
249 else 249 else
250 { 250 {
251 int i,len; 251 int i,len;
252 int dot_found=0; 252 int dot_found=0;
253 253
254 zipok = 1 ; 254 zipok = 1 ;
255 strncpy(filename_try, argv[zipfilenamearg],MAXFILENAME-1); 255 strncpy(filename_try, argv[zipfilenamearg],MAXFILENAME-1);
256 /* strncpy doesnt append the trailing NULL, of the string is too long. */ 256 /* strncpy doesnt append the trailing NULL, of the string is too long. */
257 filename_try[ MAXFILENAME ] = '\0'; 257 filename_try[ MAXFILENAME ] = '\0';
258 258
259 len=(int)strlen(filename_try); 259 len=(int)strlen(filename_try);
260 for (i=0;i<len;i++) 260 for (i=0;i<len;i++)
261 if (filename_try[i]=='.') 261 if (filename_try[i]=='.')
262 dot_found=1; 262 dot_found=1;
263 263
264 if (dot_found==0) 264 if (dot_found==0)
265 strcat(filename_try,".zip"); 265 strcat(filename_try,".zip");
266 266
267 if (opt_overwrite==2) 267 if (opt_overwrite==2)
268 { 268 {
269 /* if the file don't exist, we not append file */ 269 /* if the file don't exist, we not append file */
270 if (check_exist_file(filename_try)==0) 270 if (check_exist_file(filename_try)==0)
271 opt_overwrite=1; 271 opt_overwrite=1;
272 } 272 }
273 else 273 else
274 if (opt_overwrite==0) 274 if (opt_overwrite==0)
275 if (check_exist_file(filename_try)!=0) 275 if (check_exist_file(filename_try)!=0)
276 { 276 {
277 char rep=0; 277 char rep=0;
278 do 278 do
279 { 279 {
280 char answer[128]; 280 char answer[128];
281 int ret; 281 int ret;
282 printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ",filename_try); 282 printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ",filename_try);
283 ret = scanf("%1s",answer); 283 ret = scanf("%1s",answer);
284 if (ret != 1) 284 if (ret != 1)
285 { 285 {
286 exit(EXIT_FAILURE); 286 exit(EXIT_FAILURE);
287 } 287 }
288 rep = answer[0] ; 288 rep = answer[0] ;
289 if ((rep>='a') && (rep<='z')) 289 if ((rep>='a') && (rep<='z'))
290 rep -= 0x20; 290 rep -= 0x20;
291 } 291 }
292 while ((rep!='Y') && (rep!='N') && (rep!='A')); 292 while ((rep!='Y') && (rep!='N') && (rep!='A'));
293 if (rep=='N') 293 if (rep=='N')
294 zipok = 0; 294 zipok = 0;
295 if (rep=='A') 295 if (rep=='A')
296 opt_overwrite = 2; 296 opt_overwrite = 2;
297 } 297 }
298 } 298 }
299 299
300 if (zipok==1) 300 if (zipok==1)
301 { 301 {
302 zipFile zf; 302 zipFile zf;
303 int errclose; 303 int errclose;
304# ifdef USEWIN32IOAPI 304# ifdef USEWIN32IOAPI
305 zlib_filefunc_def ffunc; 305 zlib_filefunc_def ffunc;
306 fill_win32_filefunc(&ffunc); 306 fill_win32_filefunc(&ffunc);
307 zf = zipOpen2(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc); 307 zf = zipOpen2(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc);
308# else 308# else
309 zf = zipOpen(filename_try,(opt_overwrite==2) ? 2 : 0); 309 zf = zipOpen(filename_try,(opt_overwrite==2) ? 2 : 0);
310# endif 310# endif
311 311
312 if (zf == NULL) 312 if (zf == NULL)
313 { 313 {
314 printf("error opening %s\n",filename_try); 314 printf("error opening %s\n",filename_try);
315 err= ZIP_ERRNO; 315 err= ZIP_ERRNO;
316 } 316 }
317 else 317 else
318 printf("creating %s\n",filename_try); 318 printf("creating %s\n",filename_try);
319 319
320 for (i=zipfilenamearg+1;(i<argc) && (err==ZIP_OK);i++) 320 for (i=zipfilenamearg+1;(i<argc) && (err==ZIP_OK);i++)
321 { 321 {
322 if (!((((*(argv[i]))=='-') || ((*(argv[i]))=='/')) && 322 if (!((((*(argv[i]))=='-') || ((*(argv[i]))=='/')) &&
323 ((argv[i][1]=='o') || (argv[i][1]=='O') || 323 ((argv[i][1]=='o') || (argv[i][1]=='O') ||
324 (argv[i][1]=='a') || (argv[i][1]=='A') || 324 (argv[i][1]=='a') || (argv[i][1]=='A') ||
325 (argv[i][1]=='p') || (argv[i][1]=='P') || 325 (argv[i][1]=='p') || (argv[i][1]=='P') ||
326 ((argv[i][1]>='0') || (argv[i][1]<='9'))) && 326 ((argv[i][1]>='0') || (argv[i][1]<='9'))) &&
327 (strlen(argv[i]) == 2))) 327 (strlen(argv[i]) == 2)))
328 { 328 {
329 FILE * fin; 329 FILE * fin;
330 int size_read; 330 int size_read;
331 const char* filenameinzip = argv[i]; 331 const char* filenameinzip = argv[i];
332 zip_fileinfo zi; 332 zip_fileinfo zi;
333 unsigned long crcFile=0; 333 unsigned long crcFile=0;
334 334
335 zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour = 335 zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
336 zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0; 336 zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
337 zi.dosDate = 0; 337 zi.dosDate = 0;
338 zi.internal_fa = 0; 338 zi.internal_fa = 0;
339 zi.external_fa = 0; 339 zi.external_fa = 0;
340 filetime(filenameinzip,&zi.tmz_date,&zi.dosDate); 340 filetime(filenameinzip,&zi.tmz_date,&zi.dosDate);
341 341
342/* 342/*
343 err = zipOpenNewFileInZip(zf,filenameinzip,&zi, 343 err = zipOpenNewFileInZip(zf,filenameinzip,&zi,
344 NULL,0,NULL,0,NULL / * comment * /, 344 NULL,0,NULL,0,NULL / * comment * /,
345 (opt_compress_level != 0) ? Z_DEFLATED : 0, 345 (opt_compress_level != 0) ? Z_DEFLATED : 0,
346 opt_compress_level); 346 opt_compress_level);
347*/ 347*/
348 if ((password != NULL) && (err==ZIP_OK)) 348 if ((password != NULL) && (err==ZIP_OK))
349 err = getFileCrc(filenameinzip,buf,size_buf,&crcFile); 349 err = getFileCrc(filenameinzip,buf,size_buf,&crcFile);
350 350
351 err = zipOpenNewFileInZip3(zf,filenameinzip,&zi, 351 err = zipOpenNewFileInZip3(zf,filenameinzip,&zi,
352 NULL,0,NULL,0,NULL /* comment*/, 352 NULL,0,NULL,0,NULL /* comment*/,
353 (opt_compress_level != 0) ? Z_DEFLATED : 0, 353 (opt_compress_level != 0) ? Z_DEFLATED : 0,
354 opt_compress_level,0, 354 opt_compress_level,0,
355 /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */ 355 /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */
356 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, 356 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
357 password,crcFile); 357 password,crcFile);
358 358
359 if (err != ZIP_OK) 359 if (err != ZIP_OK)
360 printf("error in opening %s in zipfile\n",filenameinzip); 360 printf("error in opening %s in zipfile\n",filenameinzip);
361 else 361 else
362 { 362 {
363 fin = fopen(filenameinzip,"rb"); 363 fin = fopen(filenameinzip,"rb");
364 if (fin==NULL) 364 if (fin==NULL)
365 { 365 {
366 err=ZIP_ERRNO; 366 err=ZIP_ERRNO;
367 printf("error in opening %s for reading\n",filenameinzip); 367 printf("error in opening %s for reading\n",filenameinzip);
368 } 368 }
369 } 369 }
370 370
371 if (err == ZIP_OK) 371 if (err == ZIP_OK)
372 do 372 do
373 { 373 {
374 err = ZIP_OK; 374 err = ZIP_OK;
375 size_read = (int)fread(buf,1,size_buf,fin); 375 size_read = (int)fread(buf,1,size_buf,fin);
376 if (size_read < size_buf) 376 if (size_read < size_buf)
377 if (feof(fin)==0) 377 if (feof(fin)==0)
378 { 378 {
379 printf("error in reading %s\n",filenameinzip); 379 printf("error in reading %s\n",filenameinzip);
380 err = ZIP_ERRNO; 380 err = ZIP_ERRNO;
381 } 381 }
382 382
383 if (size_read>0) 383 if (size_read>0)
384 { 384 {
385 err = zipWriteInFileInZip (zf,buf,size_read); 385 err = zipWriteInFileInZip (zf,buf,size_read);
386 if (err<0) 386 if (err<0)
387 { 387 {
388 printf("error in writing %s in the zipfile\n", 388 printf("error in writing %s in the zipfile\n",
389 filenameinzip); 389 filenameinzip);
390 } 390 }
391 391
392 } 392 }
393 } while ((err == ZIP_OK) && (size_read>0)); 393 } while ((err == ZIP_OK) && (size_read>0));
394 394
395 if (fin) 395 if (fin)
396 fclose(fin); 396 fclose(fin);
397 397
398 if (err<0) 398 if (err<0)
399 err=ZIP_ERRNO; 399 err=ZIP_ERRNO;
400 else 400 else
401 { 401 {
402 err = zipCloseFileInZip(zf); 402 err = zipCloseFileInZip(zf);
403 if (err!=ZIP_OK) 403 if (err!=ZIP_OK)
404 printf("error in closing %s in the zipfile\n", 404 printf("error in closing %s in the zipfile\n",
405 filenameinzip); 405 filenameinzip);
406 } 406 }
407 } 407 }
408 } 408 }
409 errclose = zipClose(zf,NULL); 409 errclose = zipClose(zf,NULL);
410 if (errclose != ZIP_OK) 410 if (errclose != ZIP_OK)
411 printf("error in closing %s\n",filename_try); 411 printf("error in closing %s\n",filename_try);
412 } 412 }
413 else 413 else
414 { 414 {
415 do_help(); 415 do_help();
416 } 416 }
417 417
418 free(buf); 418 free(buf);
419 return 0; 419 return 0;
420} 420}
diff --git a/contrib/minizip/mztools.c b/contrib/minizip/mztools.c
index c1266bc..bc5c798 100644
--- a/contrib/minizip/mztools.c
+++ b/contrib/minizip/mztools.c
@@ -1,281 +1,281 @@
1/* 1/*
2 Additional tools for Minizip 2 Additional tools for Minizip
3 Code: Xavier Roche '2004 3 Code: Xavier Roche '2004
4 License: Same as ZLIB (www.gzip.org) 4 License: Same as ZLIB (www.gzip.org)
5*/ 5*/
6 6
7/* Code */ 7/* Code */
8#include <stdio.h> 8#include <stdio.h>
9#include <stdlib.h> 9#include <stdlib.h>
10#include <string.h> 10#include <string.h>
11#include "zlib.h" 11#include "zlib.h"
12#include "unzip.h" 12#include "unzip.h"
13 13
14#define READ_8(adr) ((unsigned char)*(adr)) 14#define READ_8(adr) ((unsigned char)*(adr))
15#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) ) 15#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) )
16#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) ) 16#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) )
17 17
18#define WRITE_8(buff, n) do { \ 18#define WRITE_8(buff, n) do { \
19 *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \ 19 *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \
20} while(0) 20} while(0)
21#define WRITE_16(buff, n) do { \ 21#define WRITE_16(buff, n) do { \
22 WRITE_8((unsigned char*)(buff), n); \ 22 WRITE_8((unsigned char*)(buff), n); \
23 WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \ 23 WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \
24} while(0) 24} while(0)
25#define WRITE_32(buff, n) do { \ 25#define WRITE_32(buff, n) do { \
26 WRITE_16((unsigned char*)(buff), (n) & 0xffff); \ 26 WRITE_16((unsigned char*)(buff), (n) & 0xffff); \
27 WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \ 27 WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \
28} while(0) 28} while(0)
29 29
30extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered) 30extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered)
31const char* file; 31const char* file;
32const char* fileOut; 32const char* fileOut;
33const char* fileOutTmp; 33const char* fileOutTmp;
34uLong* nRecovered; 34uLong* nRecovered;
35uLong* bytesRecovered; 35uLong* bytesRecovered;
36{ 36{
37 int err = Z_OK; 37 int err = Z_OK;
38 FILE* fpZip = fopen(file, "rb"); 38 FILE* fpZip = fopen(file, "rb");
39 FILE* fpOut = fopen(fileOut, "wb"); 39 FILE* fpOut = fopen(fileOut, "wb");
40 FILE* fpOutCD = fopen(fileOutTmp, "wb"); 40 FILE* fpOutCD = fopen(fileOutTmp, "wb");
41 if (fpZip != NULL && fpOut != NULL) { 41 if (fpZip != NULL && fpOut != NULL) {
42 int entries = 0; 42 int entries = 0;
43 uLong totalBytes = 0; 43 uLong totalBytes = 0;
44 char header[30]; 44 char header[30];
45 char filename[256]; 45 char filename[256];
46 char extra[1024]; 46 char extra[1024];
47 int offset = 0; 47 int offset = 0;
48 int offsetCD = 0; 48 int offsetCD = 0;
49 while ( fread(header, 1, 30, fpZip) == 30 ) { 49 while ( fread(header, 1, 30, fpZip) == 30 ) {
50 int currentOffset = offset; 50 int currentOffset = offset;
51 51
52 /* File entry */ 52 /* File entry */
53 if (READ_32(header) == 0x04034b50) { 53 if (READ_32(header) == 0x04034b50) {
54 unsigned int version = READ_16(header + 4); 54 unsigned int version = READ_16(header + 4);
55 unsigned int gpflag = READ_16(header + 6); 55 unsigned int gpflag = READ_16(header + 6);
56 unsigned int method = READ_16(header + 8); 56 unsigned int method = READ_16(header + 8);
57 unsigned int filetime = READ_16(header + 10); 57 unsigned int filetime = READ_16(header + 10);
58 unsigned int filedate = READ_16(header + 12); 58 unsigned int filedate = READ_16(header + 12);
59 unsigned int crc = READ_32(header + 14); /* crc */ 59 unsigned int crc = READ_32(header + 14); /* crc */
60 unsigned int cpsize = READ_32(header + 18); /* compressed size */ 60 unsigned int cpsize = READ_32(header + 18); /* compressed size */
61 unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */ 61 unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */
62 unsigned int fnsize = READ_16(header + 26); /* file name length */ 62 unsigned int fnsize = READ_16(header + 26); /* file name length */
63 unsigned int extsize = READ_16(header + 28); /* extra field length */ 63 unsigned int extsize = READ_16(header + 28); /* extra field length */
64 filename[0] = extra[0] = '\0'; 64 filename[0] = extra[0] = '\0';
65 65
66 /* Header */ 66 /* Header */
67 if (fwrite(header, 1, 30, fpOut) == 30) { 67 if (fwrite(header, 1, 30, fpOut) == 30) {
68 offset += 30; 68 offset += 30;
69 } else { 69 } else {
70 err = Z_ERRNO; 70 err = Z_ERRNO;
71 break; 71 break;
72 } 72 }
73 73
74 /* Filename */ 74 /* Filename */
75 if (fnsize > 0) { 75 if (fnsize > 0) {
76 if (fread(filename, 1, fnsize, fpZip) == fnsize) { 76 if (fread(filename, 1, fnsize, fpZip) == fnsize) {
77 if (fwrite(filename, 1, fnsize, fpOut) == fnsize) { 77 if (fwrite(filename, 1, fnsize, fpOut) == fnsize) {
78 offset += fnsize; 78 offset += fnsize;
79 } else { 79 } else {
80 err = Z_ERRNO; 80 err = Z_ERRNO;
81 break; 81 break;
82 } 82 }
83 } else { 83 } else {
84 err = Z_ERRNO; 84 err = Z_ERRNO;
85 break; 85 break;
86 } 86 }
87 } else { 87 } else {
88 err = Z_STREAM_ERROR; 88 err = Z_STREAM_ERROR;
89 break; 89 break;
90 } 90 }
91 91
92 /* Extra field */ 92 /* Extra field */
93 if (extsize > 0) { 93 if (extsize > 0) {
94 if (fread(extra, 1, extsize, fpZip) == extsize) { 94 if (fread(extra, 1, extsize, fpZip) == extsize) {
95 if (fwrite(extra, 1, extsize, fpOut) == extsize) { 95 if (fwrite(extra, 1, extsize, fpOut) == extsize) {
96 offset += extsize; 96 offset += extsize;
97 } else { 97 } else {
98 err = Z_ERRNO; 98 err = Z_ERRNO;
99 break; 99 break;
100 } 100 }
101 } else { 101 } else {
102 err = Z_ERRNO; 102 err = Z_ERRNO;
103 break; 103 break;
104 } 104 }
105 } 105 }
106 106
107 /* Data */ 107 /* Data */
108 { 108 {
109 int dataSize = cpsize; 109 int dataSize = cpsize;
110 if (dataSize == 0) { 110 if (dataSize == 0) {
111 dataSize = uncpsize; 111 dataSize = uncpsize;
112 } 112 }
113 if (dataSize > 0) { 113 if (dataSize > 0) {
114 char* data = malloc(dataSize); 114 char* data = malloc(dataSize);
115 if (data != NULL) { 115 if (data != NULL) {
116 if ((int)fread(data, 1, dataSize, fpZip) == dataSize) { 116 if ((int)fread(data, 1, dataSize, fpZip) == dataSize) {
117 if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) { 117 if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) {
118 offset += dataSize; 118 offset += dataSize;
119 totalBytes += dataSize; 119 totalBytes += dataSize;
120 } else { 120 } else {
121 err = Z_ERRNO; 121 err = Z_ERRNO;
122 } 122 }
123 } else { 123 } else {
124 err = Z_ERRNO; 124 err = Z_ERRNO;
125 } 125 }
126 free(data); 126 free(data);
127 if (err != Z_OK) { 127 if (err != Z_OK) {
128 break; 128 break;
129 } 129 }
130 } else { 130 } else {
131 err = Z_MEM_ERROR; 131 err = Z_MEM_ERROR;
132 break; 132 break;
133 } 133 }
134 } 134 }
135 } 135 }
136 136
137 /* Central directory entry */ 137 /* Central directory entry */
138 { 138 {
139 char header[46]; 139 char header[46];
140 char* comment = ""; 140 char* comment = "";
141 int comsize = (int) strlen(comment); 141 int comsize = (int) strlen(comment);
142 WRITE_32(header, 0x02014b50); 142 WRITE_32(header, 0x02014b50);
143 WRITE_16(header + 4, version); 143 WRITE_16(header + 4, version);
144 WRITE_16(header + 6, version); 144 WRITE_16(header + 6, version);
145 WRITE_16(header + 8, gpflag); 145 WRITE_16(header + 8, gpflag);
146 WRITE_16(header + 10, method); 146 WRITE_16(header + 10, method);
147 WRITE_16(header + 12, filetime); 147 WRITE_16(header + 12, filetime);
148 WRITE_16(header + 14, filedate); 148 WRITE_16(header + 14, filedate);
149 WRITE_32(header + 16, crc); 149 WRITE_32(header + 16, crc);
150 WRITE_32(header + 20, cpsize); 150 WRITE_32(header + 20, cpsize);
151 WRITE_32(header + 24, uncpsize); 151 WRITE_32(header + 24, uncpsize);
152 WRITE_16(header + 28, fnsize); 152 WRITE_16(header + 28, fnsize);
153 WRITE_16(header + 30, extsize); 153 WRITE_16(header + 30, extsize);
154 WRITE_16(header + 32, comsize); 154 WRITE_16(header + 32, comsize);
155 WRITE_16(header + 34, 0); /* disk # */ 155 WRITE_16(header + 34, 0); /* disk # */
156 WRITE_16(header + 36, 0); /* int attrb */ 156 WRITE_16(header + 36, 0); /* int attrb */
157 WRITE_32(header + 38, 0); /* ext attrb */ 157 WRITE_32(header + 38, 0); /* ext attrb */
158 WRITE_32(header + 42, currentOffset); 158 WRITE_32(header + 42, currentOffset);
159 /* Header */ 159 /* Header */
160 if (fwrite(header, 1, 46, fpOutCD) == 46) { 160 if (fwrite(header, 1, 46, fpOutCD) == 46) {
161 offsetCD += 46; 161 offsetCD += 46;
162 162
163 /* Filename */ 163 /* Filename */
164 if (fnsize > 0) { 164 if (fnsize > 0) {
165 if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) { 165 if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) {
166 offsetCD += fnsize; 166 offsetCD += fnsize;
167 } else { 167 } else {
168 err = Z_ERRNO; 168 err = Z_ERRNO;
169 break; 169 break;
170 } 170 }
171 } else { 171 } else {
172 err = Z_STREAM_ERROR; 172 err = Z_STREAM_ERROR;
173 break; 173 break;
174 } 174 }
175 175
176 /* Extra field */ 176 /* Extra field */
177 if (extsize > 0) { 177 if (extsize > 0) {
178 if (fwrite(extra, 1, extsize, fpOutCD) == extsize) { 178 if (fwrite(extra, 1, extsize, fpOutCD) == extsize) {
179 offsetCD += extsize; 179 offsetCD += extsize;
180 } else { 180 } else {
181 err = Z_ERRNO; 181 err = Z_ERRNO;
182 break; 182 break;
183 } 183 }
184 } 184 }
185 185
186 /* Comment field */ 186 /* Comment field */
187 if (comsize > 0) { 187 if (comsize > 0) {
188 if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) { 188 if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) {
189 offsetCD += comsize; 189 offsetCD += comsize;
190 } else { 190 } else {
191 err = Z_ERRNO; 191 err = Z_ERRNO;
192 break; 192 break;
193 } 193 }
194 } 194 }
195 195
196 196
197 } else { 197 } else {
198 err = Z_ERRNO; 198 err = Z_ERRNO;
199 break; 199 break;
200 } 200 }
201 } 201 }
202 202
203 /* Success */ 203 /* Success */
204 entries++; 204 entries++;
205 205
206 } else { 206 } else {
207 break; 207 break;
208 } 208 }
209 } 209 }
210 210
211 /* Final central directory */ 211 /* Final central directory */
212 { 212 {
213 int entriesZip = entries; 213 int entriesZip = entries;
214 char header[22]; 214 char header[22];
215 char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools"; 215 char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools";
216 int comsize = (int) strlen(comment); 216 int comsize = (int) strlen(comment);
217 if (entriesZip > 0xffff) { 217 if (entriesZip > 0xffff) {
218 entriesZip = 0xffff; 218 entriesZip = 0xffff;
219 } 219 }
220 WRITE_32(header, 0x06054b50); 220 WRITE_32(header, 0x06054b50);
221 WRITE_16(header + 4, 0); /* disk # */ 221 WRITE_16(header + 4, 0); /* disk # */
222 WRITE_16(header + 6, 0); /* disk # */ 222 WRITE_16(header + 6, 0); /* disk # */
223 WRITE_16(header + 8, entriesZip); /* hack */ 223 WRITE_16(header + 8, entriesZip); /* hack */
224 WRITE_16(header + 10, entriesZip); /* hack */ 224 WRITE_16(header + 10, entriesZip); /* hack */
225 WRITE_32(header + 12, offsetCD); /* size of CD */ 225 WRITE_32(header + 12, offsetCD); /* size of CD */
226 WRITE_32(header + 16, offset); /* offset to CD */ 226 WRITE_32(header + 16, offset); /* offset to CD */
227 WRITE_16(header + 20, comsize); /* comment */ 227 WRITE_16(header + 20, comsize); /* comment */
228 228
229 /* Header */ 229 /* Header */
230 if (fwrite(header, 1, 22, fpOutCD) == 22) { 230 if (fwrite(header, 1, 22, fpOutCD) == 22) {
231 231
232 /* Comment field */ 232 /* Comment field */
233 if (comsize > 0) { 233 if (comsize > 0) {
234 if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) { 234 if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) {
235 err = Z_ERRNO; 235 err = Z_ERRNO;
236 } 236 }
237 } 237 }
238 238
239 } else { 239 } else {
240 err = Z_ERRNO; 240 err = Z_ERRNO;
241 } 241 }
242 } 242 }
243 243
244 /* Final merge (file + central directory) */ 244 /* Final merge (file + central directory) */
245 fclose(fpOutCD); 245 fclose(fpOutCD);
246 if (err == Z_OK) { 246 if (err == Z_OK) {
247 fpOutCD = fopen(fileOutTmp, "rb"); 247 fpOutCD = fopen(fileOutTmp, "rb");
248 if (fpOutCD != NULL) { 248 if (fpOutCD != NULL) {
249 int nRead; 249 int nRead;
250 char buffer[8192]; 250 char buffer[8192];
251 while ( (nRead = fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) { 251 while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) {
252 if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) { 252 if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) {
253 err = Z_ERRNO; 253 err = Z_ERRNO;
254 break; 254 break;
255 } 255 }
256 } 256 }
257 fclose(fpOutCD); 257 fclose(fpOutCD);
258 } 258 }
259 } 259 }
260 260
261 /* Close */ 261 /* Close */
262 fclose(fpZip); 262 fclose(fpZip);
263 fclose(fpOut); 263 fclose(fpOut);
264 264
265 /* Wipe temporary file */ 265 /* Wipe temporary file */
266 (void)remove(fileOutTmp); 266 (void)remove(fileOutTmp);
267 267
268 /* Number of recovered entries */ 268 /* Number of recovered entries */
269 if (err == Z_OK) { 269 if (err == Z_OK) {
270 if (nRecovered != NULL) { 270 if (nRecovered != NULL) {
271 *nRecovered = entries; 271 *nRecovered = entries;
272 } 272 }
273 if (bytesRecovered != NULL) { 273 if (bytesRecovered != NULL) {
274 *bytesRecovered = totalBytes; 274 *bytesRecovered = totalBytes;
275 } 275 }
276 } 276 }
277 } else { 277 } else {
278 err = Z_STREAM_ERROR; 278 err = Z_STREAM_ERROR;
279 } 279 }
280 return err; 280 return err;
281} 281}
diff --git a/contrib/minizip/mztools.h b/contrib/minizip/mztools.h
index 88b3459..82d1597 100644
--- a/contrib/minizip/mztools.h
+++ b/contrib/minizip/mztools.h
@@ -1,31 +1,31 @@
1/* 1/*
2 Additional tools for Minizip 2 Additional tools for Minizip
3 Code: Xavier Roche '2004 3 Code: Xavier Roche '2004
4 License: Same as ZLIB (www.gzip.org) 4 License: Same as ZLIB (www.gzip.org)
5*/ 5*/
6 6
7#ifndef _zip_tools_H 7#ifndef _zip_tools_H
8#define _zip_tools_H 8#define _zip_tools_H
9 9
10#ifdef __cplusplus 10#ifdef __cplusplus
11extern "C" { 11extern "C" {
12#endif 12#endif
13 13
14#ifndef _ZLIB_H 14#ifndef _ZLIB_H
15#include "zlib.h" 15#include "zlib.h"
16#endif 16#endif
17 17
18#include "unzip.h" 18#include "unzip.h"
19 19
20/* Repair a ZIP file (missing central directory) 20/* Repair a ZIP file (missing central directory)
21 file: file to recover 21 file: file to recover
22 fileOut: output file after recovery 22 fileOut: output file after recovery
23 fileOutTmp: temporary file name used for recovery 23 fileOutTmp: temporary file name used for recovery
24*/ 24*/
25extern int ZEXPORT unzRepair(const char* file, 25extern int ZEXPORT unzRepair(const char* file,
26 const char* fileOut, 26 const char* fileOut,
27 const char* fileOutTmp, 27 const char* fileOutTmp,
28 uLong* nRecovered, 28 uLong* nRecovered,
29 uLong* bytesRecovered); 29 uLong* bytesRecovered);
30 30
31#endif 31#endif
diff --git a/contrib/minizip/unzip.c b/contrib/minizip/unzip.c
index e14de9e..3a70629 100644
--- a/contrib/minizip/unzip.c
+++ b/contrib/minizip/unzip.c
@@ -1,1595 +1,1598 @@
1/* unzip.c -- IO for uncompress .zip files using zlib 1/* unzip.c -- IO for uncompress .zip files using zlib
2 Version 1.01d, September 22th, 2004 2 Version 1.01e, February 12th, 2005
3 3
4 Copyright (C) 1998-2004 Gilles Vollant 4 Copyright (C) 1998-2005 Gilles Vollant
5 5
6 Read unzip.h for more info 6 Read unzip.h for more info
7*/ 7*/
8 8
9/* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of 9/* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
10compatibility with older software. The following is from the original crypt.c. Code 10compatibility with older software. The following is from the original crypt.c. Code
11woven in by Terry Thorsen 1/2003. 11woven in by Terry Thorsen 1/2003.
12*/ 12*/
13/* 13/*
14 Copyright (c) 1990-2000 Info-ZIP. All rights reserved. 14 Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
15 15
16 See the accompanying file LICENSE, version 2000-Apr-09 or later 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. 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 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 19 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
20*/ 20*/
21/* 21/*
22 crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] 22 crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
23 23
24 The encryption/decryption parts of this source code (as opposed to the 24 The encryption/decryption parts of this source code (as opposed to the
25 non-echoing password parts) were originally written in Europe. The 25 non-echoing password parts) were originally written in Europe. The
26 whole source package can be freely distributed, including from the USA. 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.) 27 (Prior to January 2000, re-export from the US was a violation of US law.)
28 */ 28 */
29 29
30/* 30/*
31 This encryption code is a direct transcription of the algorithm from 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 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 33 file (appnote.txt) is distributed with the PKZIP program (even in the
34 version without encryption capabilities). 34 version without encryption capabilities).
35 */ 35 */
36 36
37 37
38#include <stdio.h> 38#include <stdio.h>
39#include <stdlib.h> 39#include <stdlib.h>
40#include <string.h> 40#include <string.h>
41#include "zlib.h" 41#include "zlib.h"
42#include "unzip.h" 42#include "unzip.h"
43 43
44#ifdef STDC 44#ifdef STDC
45# include <stddef.h> 45# include <stddef.h>
46# include <string.h> 46# include <string.h>
47# include <stdlib.h> 47# include <stdlib.h>
48#endif 48#endif
49#ifdef NO_ERRNO_H 49#ifdef NO_ERRNO_H
50 extern int errno; 50 extern int errno;
51#else 51#else
52# include <errno.h> 52# include <errno.h>
53#endif 53#endif
54 54
55 55
56#ifndef local 56#ifndef local
57# define local static 57# define local static
58#endif 58#endif
59/* compile with -Dlocal if your debugger can't find static symbols */ 59/* compile with -Dlocal if your debugger can't find static symbols */
60 60
61 61
62#ifndef CASESENSITIVITYDEFAULT_NO 62#ifndef CASESENSITIVITYDEFAULT_NO
63# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) 63# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
64# define CASESENSITIVITYDEFAULT_NO 64# define CASESENSITIVITYDEFAULT_NO
65# endif 65# endif
66#endif 66#endif
67 67
68 68
69#ifndef UNZ_BUFSIZE 69#ifndef UNZ_BUFSIZE
70#define UNZ_BUFSIZE (16384) 70#define UNZ_BUFSIZE (16384)
71#endif 71#endif
72 72
73#ifndef UNZ_MAXFILENAMEINZIP 73#ifndef UNZ_MAXFILENAMEINZIP
74#define UNZ_MAXFILENAMEINZIP (256) 74#define UNZ_MAXFILENAMEINZIP (256)
75#endif 75#endif
76 76
77#ifndef ALLOC 77#ifndef ALLOC
78# define ALLOC(size) (malloc(size)) 78# define ALLOC(size) (malloc(size))
79#endif 79#endif
80#ifndef TRYFREE 80#ifndef TRYFREE
81# define TRYFREE(p) {if (p) free(p);} 81# define TRYFREE(p) {if (p) free(p);}
82#endif 82#endif
83 83
84#define SIZECENTRALDIRITEM (0x2e) 84#define SIZECENTRALDIRITEM (0x2e)
85#define SIZEZIPLOCALHEADER (0x1e) 85#define SIZEZIPLOCALHEADER (0x1e)
86 86
87 87
88 88
89 89
90const char unz_copyright[] = 90const char unz_copyright[] =
91 " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; 91 " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
92 92
93/* unz_file_info_interntal contain internal info about a file in zipfile*/ 93/* unz_file_info_interntal contain internal info about a file in zipfile*/
94typedef struct unz_file_info_internal_s 94typedef struct unz_file_info_internal_s
95{ 95{
96 uLong offset_curfile;/* relative offset of local header 4 bytes */ 96 uLong offset_curfile;/* relative offset of local header 4 bytes */
97} unz_file_info_internal; 97} unz_file_info_internal;
98 98
99 99
100/* file_in_zip_read_info_s contain internal information about a file in zipfile, 100/* file_in_zip_read_info_s contain internal information about a file in zipfile,
101 when reading and decompress it */ 101 when reading and decompress it */
102typedef struct 102typedef struct
103{ 103{
104 char *read_buffer; /* internal buffer for compressed data */ 104 char *read_buffer; /* internal buffer for compressed data */
105 z_stream stream; /* zLib stream structure for inflate */ 105 z_stream stream; /* zLib stream structure for inflate */
106 106
107 uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ 107 uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
108 uLong stream_initialised; /* flag set if stream structure is initialised*/ 108 uLong stream_initialised; /* flag set if stream structure is initialised*/
109 109
110 uLong offset_local_extrafield;/* offset of the local extra field */ 110 uLong offset_local_extrafield;/* offset of the local extra field */
111 uInt size_local_extrafield;/* size of the local extra field */ 111 uInt size_local_extrafield;/* size of the local extra field */
112 uLong pos_local_extrafield; /* position in the local extra field in read*/ 112 uLong pos_local_extrafield; /* position in the local extra field in read*/
113 113
114 uLong crc32; /* crc32 of all data uncompressed */ 114 uLong crc32; /* crc32 of all data uncompressed */
115 uLong crc32_wait; /* crc32 we must obtain after decompress all */ 115 uLong crc32_wait; /* crc32 we must obtain after decompress all */
116 uLong rest_read_compressed; /* number of byte to be decompressed */ 116 uLong rest_read_compressed; /* number of byte to be decompressed */
117 uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/ 117 uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
118 zlib_filefunc_def z_filefunc; 118 zlib_filefunc_def z_filefunc;
119 voidpf filestream; /* io structore of the zipfile */ 119 voidpf filestream; /* io structore of the zipfile */
120 uLong compression_method; /* compression method (0==store) */ 120 uLong compression_method; /* compression method (0==store) */
121 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ 121 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
122 int raw; 122 int raw;
123} file_in_zip_read_info_s; 123} file_in_zip_read_info_s;
124 124
125 125
126/* unz_s contain internal information about the zipfile 126/* unz_s contain internal information about the zipfile
127*/ 127*/
128typedef struct 128typedef struct
129{ 129{
130 zlib_filefunc_def z_filefunc; 130 zlib_filefunc_def z_filefunc;
131 voidpf filestream; /* io structore of the zipfile */ 131 voidpf filestream; /* io structore of the zipfile */
132 unz_global_info gi; /* public global information */ 132 unz_global_info gi; /* public global information */
133 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ 133 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
134 uLong num_file; /* number of the current file in the zipfile*/ 134 uLong num_file; /* number of the current file in the zipfile*/
135 uLong pos_in_central_dir; /* pos of the current file in the central dir*/ 135 uLong pos_in_central_dir; /* pos of the current file in the central dir*/
136 uLong current_file_ok; /* flag about the usability of the current file*/ 136 uLong current_file_ok; /* flag about the usability of the current file*/
137 uLong central_pos; /* position of the beginning of the central dir*/ 137 uLong central_pos; /* position of the beginning of the central dir*/
138 138
139 uLong size_central_dir; /* size of the central directory */ 139 uLong size_central_dir; /* size of the central directory */
140 uLong offset_central_dir; /* offset of start of central directory with 140 uLong offset_central_dir; /* offset of start of central directory with
141 respect to the starting disk number */ 141 respect to the starting disk number */
142 142
143 unz_file_info cur_file_info; /* public info about the current file in zip*/ 143 unz_file_info cur_file_info; /* public info about the current file in zip*/
144 unz_file_info_internal cur_file_info_internal; /* private info about it*/ 144 unz_file_info_internal cur_file_info_internal; /* private info about it*/
145 file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current 145 file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
146 file if we are decompressing it */ 146 file if we are decompressing it */
147 int encrypted; 147 int encrypted;
148# ifndef NOUNCRYPT 148# ifndef NOUNCRYPT
149 unsigned long keys[3]; /* keys defining the pseudo-random sequence */ 149 unsigned long keys[3]; /* keys defining the pseudo-random sequence */
150 const unsigned long* pcrc_32_tab; 150 const unsigned long* pcrc_32_tab;
151# endif 151# endif
152} unz_s; 152} unz_s;
153 153
154 154
155#ifndef NOUNCRYPT 155#ifndef NOUNCRYPT
156#include "crypt.h" 156#include "crypt.h"
157#endif 157#endif
158 158
159/* =========================================================================== 159/* ===========================================================================
160 Read a byte from a gz_stream; update next_in and avail_in. Return EOF 160 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
161 for end of file. 161 for end of file.
162 IN assertion: the stream s has been sucessfully opened for reading. 162 IN assertion: the stream s has been sucessfully opened for reading.
163*/ 163*/
164 164
165 165
166local int unzlocal_getByte OF(( 166local int unzlocal_getByte OF((
167 const zlib_filefunc_def* pzlib_filefunc_def, 167 const zlib_filefunc_def* pzlib_filefunc_def,
168 voidpf filestream, 168 voidpf filestream,
169 int *pi)); 169 int *pi));
170 170
171local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi) 171local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi)
172 const zlib_filefunc_def* pzlib_filefunc_def; 172 const zlib_filefunc_def* pzlib_filefunc_def;
173 voidpf filestream; 173 voidpf filestream;
174 int *pi; 174 int *pi;
175{ 175{
176 unsigned char c; 176 unsigned char c;
177 int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1); 177 int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
178 if (err==1) 178 if (err==1)
179 { 179 {
180 *pi = (int)c; 180 *pi = (int)c;
181 return UNZ_OK; 181 return UNZ_OK;
182 } 182 }
183 else 183 else
184 { 184 {
185 if (ZERROR(*pzlib_filefunc_def,filestream)) 185 if (ZERROR(*pzlib_filefunc_def,filestream))
186 return UNZ_ERRNO; 186 return UNZ_ERRNO;
187 else 187 else
188 return UNZ_EOF; 188 return UNZ_EOF;
189 } 189 }
190} 190}
191 191
192 192
193/* =========================================================================== 193/* ===========================================================================
194 Reads a long in LSB order from the given gz_stream. Sets 194 Reads a long in LSB order from the given gz_stream. Sets
195*/ 195*/
196local int unzlocal_getShort OF(( 196local int unzlocal_getShort OF((
197 const zlib_filefunc_def* pzlib_filefunc_def, 197 const zlib_filefunc_def* pzlib_filefunc_def,
198 voidpf filestream, 198 voidpf filestream,
199 uLong *pX)); 199 uLong *pX));
200 200
201local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX) 201local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
202 const zlib_filefunc_def* pzlib_filefunc_def; 202 const zlib_filefunc_def* pzlib_filefunc_def;
203 voidpf filestream; 203 voidpf filestream;
204 uLong *pX; 204 uLong *pX;
205{ 205{
206 uLong x ; 206 uLong x ;
207 int i; 207 int i;
208 int err; 208 int err;
209 209
210 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); 210 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
211 x = (uLong)i; 211 x = (uLong)i;
212 212
213 if (err==UNZ_OK) 213 if (err==UNZ_OK)
214 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); 214 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
215 x += ((uLong)i)<<8; 215 x += ((uLong)i)<<8;
216 216
217 if (err==UNZ_OK) 217 if (err==UNZ_OK)
218 *pX = x; 218 *pX = x;
219 else 219 else
220 *pX = 0; 220 *pX = 0;
221 return err; 221 return err;
222} 222}
223 223
224local int unzlocal_getLong OF(( 224local int unzlocal_getLong OF((
225 const zlib_filefunc_def* pzlib_filefunc_def, 225 const zlib_filefunc_def* pzlib_filefunc_def,
226 voidpf filestream, 226 voidpf filestream,
227 uLong *pX)); 227 uLong *pX));
228 228
229local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX) 229local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
230 const zlib_filefunc_def* pzlib_filefunc_def; 230 const zlib_filefunc_def* pzlib_filefunc_def;
231 voidpf filestream; 231 voidpf filestream;
232 uLong *pX; 232 uLong *pX;
233{ 233{
234 uLong x ; 234 uLong x ;
235 int i; 235 int i;
236 int err; 236 int err;
237 237
238 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); 238 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
239 x = (uLong)i; 239 x = (uLong)i;
240 240
241 if (err==UNZ_OK) 241 if (err==UNZ_OK)
242 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); 242 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
243 x += ((uLong)i)<<8; 243 x += ((uLong)i)<<8;
244 244
245 if (err==UNZ_OK) 245 if (err==UNZ_OK)
246 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); 246 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
247 x += ((uLong)i)<<16; 247 x += ((uLong)i)<<16;
248 248
249 if (err==UNZ_OK) 249 if (err==UNZ_OK)
250 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); 250 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
251 x += ((uLong)i)<<24; 251 x += ((uLong)i)<<24;
252 252
253 if (err==UNZ_OK) 253 if (err==UNZ_OK)
254 *pX = x; 254 *pX = x;
255 else 255 else
256 *pX = 0; 256 *pX = 0;
257 return err; 257 return err;
258} 258}
259 259
260 260
261/* My own strcmpi / strcasecmp */ 261/* My own strcmpi / strcasecmp */
262local int strcmpcasenosensitive_internal (fileName1,fileName2) 262local int strcmpcasenosensitive_internal (fileName1,fileName2)
263 const char* fileName1; 263 const char* fileName1;
264 const char* fileName2; 264 const char* fileName2;
265{ 265{
266 for (;;) 266 for (;;)
267 { 267 {
268 char c1=*(fileName1++); 268 char c1=*(fileName1++);
269 char c2=*(fileName2++); 269 char c2=*(fileName2++);
270 if ((c1>='a') && (c1<='z')) 270 if ((c1>='a') && (c1<='z'))
271 c1 -= 0x20; 271 c1 -= 0x20;
272 if ((c2>='a') && (c2<='z')) 272 if ((c2>='a') && (c2<='z'))
273 c2 -= 0x20; 273 c2 -= 0x20;
274 if (c1=='\0') 274 if (c1=='\0')
275 return ((c2=='\0') ? 0 : -1); 275 return ((c2=='\0') ? 0 : -1);
276 if (c2=='\0') 276 if (c2=='\0')
277 return 1; 277 return 1;
278 if (c1<c2) 278 if (c1<c2)
279 return -1; 279 return -1;
280 if (c1>c2) 280 if (c1>c2)
281 return 1; 281 return 1;
282 } 282 }
283} 283}
284 284
285 285
286#ifdef CASESENSITIVITYDEFAULT_NO 286#ifdef CASESENSITIVITYDEFAULT_NO
287#define CASESENSITIVITYDEFAULTVALUE 2 287#define CASESENSITIVITYDEFAULTVALUE 2
288#else 288#else
289#define CASESENSITIVITYDEFAULTVALUE 1 289#define CASESENSITIVITYDEFAULTVALUE 1
290#endif 290#endif
291 291
292#ifndef STRCMPCASENOSENTIVEFUNCTION 292#ifndef STRCMPCASENOSENTIVEFUNCTION
293#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal 293#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
294#endif 294#endif
295 295
296/* 296/*
297 Compare two filename (fileName1,fileName2). 297 Compare two filename (fileName1,fileName2).
298 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) 298 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
299 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi 299 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
300 or strcasecmp) 300 or strcasecmp)
301 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system 301 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
302 (like 1 on Unix, 2 on Windows) 302 (like 1 on Unix, 2 on Windows)
303 303
304*/ 304*/
305extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity) 305extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
306 const char* fileName1; 306 const char* fileName1;
307 const char* fileName2; 307 const char* fileName2;
308 int iCaseSensitivity; 308 int iCaseSensitivity;
309{ 309{
310 if (iCaseSensitivity==0) 310 if (iCaseSensitivity==0)
311 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; 311 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
312 312
313 if (iCaseSensitivity==1) 313 if (iCaseSensitivity==1)
314 return strcmp(fileName1,fileName2); 314 return strcmp(fileName1,fileName2);
315 315
316 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); 316 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
317} 317}
318 318
319#ifndef BUFREADCOMMENT 319#ifndef BUFREADCOMMENT
320#define BUFREADCOMMENT (0x400) 320#define BUFREADCOMMENT (0x400)
321#endif 321#endif
322 322
323/* 323/*
324 Locate the Central directory of a zipfile (at the end, just before 324 Locate the Central directory of a zipfile (at the end, just before
325 the global comment) 325 the global comment)
326*/ 326*/
327local uLong unzlocal_SearchCentralDir OF(( 327local uLong unzlocal_SearchCentralDir OF((
328 const zlib_filefunc_def* pzlib_filefunc_def, 328 const zlib_filefunc_def* pzlib_filefunc_def,
329 voidpf filestream)); 329 voidpf filestream));
330 330
331local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream) 331local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream)
332 const zlib_filefunc_def* pzlib_filefunc_def; 332 const zlib_filefunc_def* pzlib_filefunc_def;
333 voidpf filestream; 333 voidpf filestream;
334{ 334{
335 unsigned char* buf; 335 unsigned char* buf;
336 uLong uSizeFile; 336 uLong uSizeFile;
337 uLong uBackRead; 337 uLong uBackRead;
338 uLong uMaxBack=0xffff; /* maximum size of global comment */ 338 uLong uMaxBack=0xffff; /* maximum size of global comment */
339 uLong uPosFound=0; 339 uLong uPosFound=0;
340 340
341 if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) 341 if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
342 return 0; 342 return 0;
343 343
344 344
345 uSizeFile = ZTELL(*pzlib_filefunc_def,filestream); 345 uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
346 346
347 if (uMaxBack>uSizeFile) 347 if (uMaxBack>uSizeFile)
348 uMaxBack = uSizeFile; 348 uMaxBack = uSizeFile;
349 349
350 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); 350 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
351 if (buf==NULL) 351 if (buf==NULL)
352 return 0; 352 return 0;
353 353
354 uBackRead = 4; 354 uBackRead = 4;
355 while (uBackRead<uMaxBack) 355 while (uBackRead<uMaxBack)
356 { 356 {
357 uLong uReadSize,uReadPos ; 357 uLong uReadSize,uReadPos ;
358 int i; 358 int i;
359 if (uBackRead+BUFREADCOMMENT>uMaxBack) 359 if (uBackRead+BUFREADCOMMENT>uMaxBack)
360 uBackRead = uMaxBack; 360 uBackRead = uMaxBack;
361 else 361 else
362 uBackRead+=BUFREADCOMMENT; 362 uBackRead+=BUFREADCOMMENT;
363 uReadPos = uSizeFile-uBackRead ; 363 uReadPos = uSizeFile-uBackRead ;
364 364
365 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? 365 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
366 (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); 366 (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
367 if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) 367 if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
368 break; 368 break;
369 369
370 if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) 370 if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
371 break; 371 break;
372 372
373 for (i=(int)uReadSize-3; (i--)>0;) 373 for (i=(int)uReadSize-3; (i--)>0;)
374 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && 374 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
375 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) 375 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
376 { 376 {
377 uPosFound = uReadPos+i; 377 uPosFound = uReadPos+i;
378 break; 378 break;
379 } 379 }
380 380
381 if (uPosFound!=0) 381 if (uPosFound!=0)
382 break; 382 break;
383 } 383 }
384 TRYFREE(buf); 384 TRYFREE(buf);
385 return uPosFound; 385 return uPosFound;
386} 386}
387 387
388/* 388/*
389 Open a Zip file. path contain the full pathname (by example, 389 Open a Zip file. path contain the full pathname (by example,
390 on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer 390 on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
391 "zlib/zlib114.zip". 391 "zlib/zlib114.zip".
392 If the zipfile cannot be opened (file doesn't exist or in not valid), the 392 If the zipfile cannot be opened (file doesn't exist or in not valid), the
393 return value is NULL. 393 return value is NULL.
394 Else, the return value is a unzFile Handle, usable with other function 394 Else, the return value is a unzFile Handle, usable with other function
395 of this unzip package. 395 of this unzip package.
396*/ 396*/
397extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def) 397extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def)
398 const char *path; 398 const char *path;
399 zlib_filefunc_def* pzlib_filefunc_def; 399 zlib_filefunc_def* pzlib_filefunc_def;
400{ 400{
401 unz_s us; 401 unz_s us;
402 unz_s *s; 402 unz_s *s;
403 uLong central_pos,uL; 403 uLong central_pos,uL;
404 404
405 uLong number_disk; /* number of the current dist, used for 405 uLong number_disk; /* number of the current dist, used for
406 spaning ZIP, unsupported, always 0*/ 406 spaning ZIP, unsupported, always 0*/
407 uLong number_disk_with_CD; /* number the the disk with central dir, used 407 uLong number_disk_with_CD; /* number the the disk with central dir, used
408 for spaning ZIP, unsupported, always 0*/ 408 for spaning ZIP, unsupported, always 0*/
409 uLong number_entry_CD; /* total number of entries in 409 uLong number_entry_CD; /* total number of entries in
410 the central dir 410 the central dir
411 (same than number_entry on nospan) */ 411 (same than number_entry on nospan) */
412 412
413 int err=UNZ_OK; 413 int err=UNZ_OK;
414 414
415 if (unz_copyright[0]!=' ') 415 if (unz_copyright[0]!=' ')
416 return NULL; 416 return NULL;
417 417
418 if (pzlib_filefunc_def==NULL) 418 if (pzlib_filefunc_def==NULL)
419 fill_fopen_filefunc(&us.z_filefunc); 419 fill_fopen_filefunc(&us.z_filefunc);
420 else 420 else
421 us.z_filefunc = *pzlib_filefunc_def; 421 us.z_filefunc = *pzlib_filefunc_def;
422 422
423 us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque, 423 us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque,
424 path, 424 path,
425 ZLIB_FILEFUNC_MODE_READ | 425 ZLIB_FILEFUNC_MODE_READ |
426 ZLIB_FILEFUNC_MODE_EXISTING); 426 ZLIB_FILEFUNC_MODE_EXISTING);
427 if (us.filestream==NULL) 427 if (us.filestream==NULL)
428 return NULL; 428 return NULL;
429 429
430 central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream); 430 central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);
431 if (central_pos==0) 431 if (central_pos==0)
432 err=UNZ_ERRNO; 432 err=UNZ_ERRNO;
433 433
434 if (ZSEEK(us.z_filefunc, us.filestream, 434 if (ZSEEK(us.z_filefunc, us.filestream,
435 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) 435 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
436 err=UNZ_ERRNO; 436 err=UNZ_ERRNO;
437 437
438 /* the signature, already checked */ 438 /* the signature, already checked */
439 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) 439 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
440 err=UNZ_ERRNO; 440 err=UNZ_ERRNO;
441 441
442 /* number of this disk */ 442 /* number of this disk */
443 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) 443 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
444 err=UNZ_ERRNO; 444 err=UNZ_ERRNO;
445 445
446 /* number of the disk with the start of the central directory */ 446 /* number of the disk with the start of the central directory */
447 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) 447 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
448 err=UNZ_ERRNO; 448 err=UNZ_ERRNO;
449 449
450 /* total number of entries in the central dir on this disk */ 450 /* total number of entries in the central dir on this disk */
451 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) 451 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
452 err=UNZ_ERRNO; 452 err=UNZ_ERRNO;
453 453
454 /* total number of entries in the central dir */ 454 /* total number of entries in the central dir */
455 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) 455 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
456 err=UNZ_ERRNO; 456 err=UNZ_ERRNO;
457 457
458 if ((number_entry_CD!=us.gi.number_entry) || 458 if ((number_entry_CD!=us.gi.number_entry) ||
459 (number_disk_with_CD!=0) || 459 (number_disk_with_CD!=0) ||
460 (number_disk!=0)) 460 (number_disk!=0))
461 err=UNZ_BADZIPFILE; 461 err=UNZ_BADZIPFILE;
462 462
463 /* size of the central directory */ 463 /* size of the central directory */
464 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) 464 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
465 err=UNZ_ERRNO; 465 err=UNZ_ERRNO;
466 466
467 /* offset of start of central directory with respect to the 467 /* offset of start of central directory with respect to the
468 starting disk number */ 468 starting disk number */
469 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) 469 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
470 err=UNZ_ERRNO; 470 err=UNZ_ERRNO;
471 471
472 /* zipfile comment length */ 472 /* zipfile comment length */
473 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) 473 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
474 err=UNZ_ERRNO; 474 err=UNZ_ERRNO;
475 475
476 if ((central_pos<us.offset_central_dir+us.size_central_dir) && 476 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
477 (err==UNZ_OK)) 477 (err==UNZ_OK))
478 err=UNZ_BADZIPFILE; 478 err=UNZ_BADZIPFILE;
479 479
480 if (err!=UNZ_OK) 480 if (err!=UNZ_OK)
481 { 481 {
482 ZCLOSE(us.z_filefunc, us.filestream); 482 ZCLOSE(us.z_filefunc, us.filestream);
483 return NULL; 483 return NULL;
484 } 484 }
485 485
486 us.byte_before_the_zipfile = central_pos - 486 us.byte_before_the_zipfile = central_pos -
487 (us.offset_central_dir+us.size_central_dir); 487 (us.offset_central_dir+us.size_central_dir);
488 us.central_pos = central_pos; 488 us.central_pos = central_pos;
489 us.pfile_in_zip_read = NULL; 489 us.pfile_in_zip_read = NULL;
490 us.encrypted = 0; 490 us.encrypted = 0;
491 491
492 492
493 s=(unz_s*)ALLOC(sizeof(unz_s)); 493 s=(unz_s*)ALLOC(sizeof(unz_s));
494 *s=us; 494 *s=us;
495 unzGoToFirstFile((unzFile)s); 495 unzGoToFirstFile((unzFile)s);
496 return (unzFile)s; 496 return (unzFile)s;
497} 497}
498 498
499 499
500extern unzFile ZEXPORT unzOpen (path) 500extern unzFile ZEXPORT unzOpen (path)
501 const char *path; 501 const char *path;
502{ 502{
503 return unzOpen2(path, NULL); 503 return unzOpen2(path, NULL);
504} 504}
505 505
506/* 506/*
507 Close a ZipFile opened with unzipOpen. 507 Close a ZipFile opened with unzipOpen.
508 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later), 508 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
509 these files MUST be closed with unzipCloseCurrentFile before call unzipClose. 509 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
510 return UNZ_OK if there is no problem. */ 510 return UNZ_OK if there is no problem. */
511extern int ZEXPORT unzClose (file) 511extern int ZEXPORT unzClose (file)
512 unzFile file; 512 unzFile file;
513{ 513{
514 unz_s* s; 514 unz_s* s;
515 if (file==NULL) 515 if (file==NULL)
516 return UNZ_PARAMERROR; 516 return UNZ_PARAMERROR;
517 s=(unz_s*)file; 517 s=(unz_s*)file;
518 518
519 if (s->pfile_in_zip_read!=NULL) 519 if (s->pfile_in_zip_read!=NULL)
520 unzCloseCurrentFile(file); 520 unzCloseCurrentFile(file);
521 521
522 ZCLOSE(s->z_filefunc, s->filestream); 522 ZCLOSE(s->z_filefunc, s->filestream);
523 TRYFREE(s); 523 TRYFREE(s);
524 return UNZ_OK; 524 return UNZ_OK;
525} 525}
526 526
527 527
528/* 528/*
529 Write info about the ZipFile in the *pglobal_info structure. 529 Write info about the ZipFile in the *pglobal_info structure.
530 No preparation of the structure is needed 530 No preparation of the structure is needed
531 return UNZ_OK if there is no problem. */ 531 return UNZ_OK if there is no problem. */
532extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info) 532extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
533 unzFile file; 533 unzFile file;
534 unz_global_info *pglobal_info; 534 unz_global_info *pglobal_info;
535{ 535{
536 unz_s* s; 536 unz_s* s;
537 if (file==NULL) 537 if (file==NULL)
538 return UNZ_PARAMERROR; 538 return UNZ_PARAMERROR;
539 s=(unz_s*)file; 539 s=(unz_s*)file;
540 *pglobal_info=s->gi; 540 *pglobal_info=s->gi;
541 return UNZ_OK; 541 return UNZ_OK;
542} 542}
543 543
544 544
545/* 545/*
546 Translate date/time from Dos format to tm_unz (readable more easilty) 546 Translate date/time from Dos format to tm_unz (readable more easilty)
547*/ 547*/
548local void unzlocal_DosDateToTmuDate (ulDosDate, ptm) 548local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
549 uLong ulDosDate; 549 uLong ulDosDate;
550 tm_unz* ptm; 550 tm_unz* ptm;
551{ 551{
552 uLong uDate; 552 uLong uDate;
553 uDate = (uLong)(ulDosDate>>16); 553 uDate = (uLong)(ulDosDate>>16);
554 ptm->tm_mday = (uInt)(uDate&0x1f) ; 554 ptm->tm_mday = (uInt)(uDate&0x1f) ;
555 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; 555 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
556 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; 556 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
557 557
558 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); 558 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
559 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; 559 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
560 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; 560 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
561} 561}
562 562
563/* 563/*
564 Get Info about the current file in the zipfile, with internal only info 564 Get Info about the current file in the zipfile, with internal only info
565*/ 565*/
566local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file, 566local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
567 unz_file_info *pfile_info, 567 unz_file_info *pfile_info,
568 unz_file_info_internal 568 unz_file_info_internal
569 *pfile_info_internal, 569 *pfile_info_internal,
570 char *szFileName, 570 char *szFileName,
571 uLong fileNameBufferSize, 571 uLong fileNameBufferSize,
572 void *extraField, 572 void *extraField,
573 uLong extraFieldBufferSize, 573 uLong extraFieldBufferSize,
574 char *szComment, 574 char *szComment,
575 uLong commentBufferSize)); 575 uLong commentBufferSize));
576 576
577local int unzlocal_GetCurrentFileInfoInternal (file, 577local int unzlocal_GetCurrentFileInfoInternal (file,
578 pfile_info, 578 pfile_info,
579 pfile_info_internal, 579 pfile_info_internal,
580 szFileName, fileNameBufferSize, 580 szFileName, fileNameBufferSize,
581 extraField, extraFieldBufferSize, 581 extraField, extraFieldBufferSize,
582 szComment, commentBufferSize) 582 szComment, commentBufferSize)
583 unzFile file; 583 unzFile file;
584 unz_file_info *pfile_info; 584 unz_file_info *pfile_info;
585 unz_file_info_internal *pfile_info_internal; 585 unz_file_info_internal *pfile_info_internal;
586 char *szFileName; 586 char *szFileName;
587 uLong fileNameBufferSize; 587 uLong fileNameBufferSize;
588 void *extraField; 588 void *extraField;
589 uLong extraFieldBufferSize; 589 uLong extraFieldBufferSize;
590 char *szComment; 590 char *szComment;
591 uLong commentBufferSize; 591 uLong commentBufferSize;
592{ 592{
593 unz_s* s; 593 unz_s* s;
594 unz_file_info file_info; 594 unz_file_info file_info;
595 unz_file_info_internal file_info_internal; 595 unz_file_info_internal file_info_internal;
596 int err=UNZ_OK; 596 int err=UNZ_OK;
597 uLong uMagic; 597 uLong uMagic;
598 long lSeek=0; 598 long lSeek=0;
599 599
600 if (file==NULL) 600 if (file==NULL)
601 return UNZ_PARAMERROR; 601 return UNZ_PARAMERROR;
602 s=(unz_s*)file; 602 s=(unz_s*)file;
603 if (ZSEEK(s->z_filefunc, s->filestream, 603 if (ZSEEK(s->z_filefunc, s->filestream,
604 s->pos_in_central_dir+s->byte_before_the_zipfile, 604 s->pos_in_central_dir+s->byte_before_the_zipfile,
605 ZLIB_FILEFUNC_SEEK_SET)!=0) 605 ZLIB_FILEFUNC_SEEK_SET)!=0)
606 err=UNZ_ERRNO; 606 err=UNZ_ERRNO;
607 607
608 608
609 /* we check the magic */ 609 /* we check the magic */
610 if (err==UNZ_OK) 610 if (err==UNZ_OK)
611 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) 611 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
612 err=UNZ_ERRNO; 612 err=UNZ_ERRNO;
613 else if (uMagic!=0x02014b50) 613 else if (uMagic!=0x02014b50)
614 err=UNZ_BADZIPFILE; 614 err=UNZ_BADZIPFILE;
615 615
616 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) 616 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
617 err=UNZ_ERRNO; 617 err=UNZ_ERRNO;
618 618
619 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) 619 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
620 err=UNZ_ERRNO; 620 err=UNZ_ERRNO;
621 621
622 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) 622 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
623 err=UNZ_ERRNO; 623 err=UNZ_ERRNO;
624 624
625 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) 625 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
626 err=UNZ_ERRNO; 626 err=UNZ_ERRNO;
627 627
628 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) 628 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
629 err=UNZ_ERRNO; 629 err=UNZ_ERRNO;
630 630
631 unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); 631 unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
632 632
633 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) 633 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
634 err=UNZ_ERRNO; 634 err=UNZ_ERRNO;
635 635
636 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) 636 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
637 err=UNZ_ERRNO; 637 err=UNZ_ERRNO;
638 638
639 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) 639 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
640 err=UNZ_ERRNO; 640 err=UNZ_ERRNO;
641 641
642 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) 642 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
643 err=UNZ_ERRNO; 643 err=UNZ_ERRNO;
644 644
645 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) 645 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
646 err=UNZ_ERRNO; 646 err=UNZ_ERRNO;
647 647
648 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) 648 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
649 err=UNZ_ERRNO; 649 err=UNZ_ERRNO;
650 650
651 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) 651 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
652 err=UNZ_ERRNO; 652 err=UNZ_ERRNO;
653 653
654 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) 654 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
655 err=UNZ_ERRNO; 655 err=UNZ_ERRNO;
656 656
657 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) 657 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
658 err=UNZ_ERRNO; 658 err=UNZ_ERRNO;
659 659
660 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) 660 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
661 err=UNZ_ERRNO; 661 err=UNZ_ERRNO;
662 662
663 lSeek+=file_info.size_filename; 663 lSeek+=file_info.size_filename;
664 if ((err==UNZ_OK) && (szFileName!=NULL)) 664 if ((err==UNZ_OK) && (szFileName!=NULL))
665 { 665 {
666 uLong uSizeRead ; 666 uLong uSizeRead ;
667 if (file_info.size_filename<fileNameBufferSize) 667 if (file_info.size_filename<fileNameBufferSize)
668 { 668 {
669 *(szFileName+file_info.size_filename)='\0'; 669 *(szFileName+file_info.size_filename)='\0';
670 uSizeRead = file_info.size_filename; 670 uSizeRead = file_info.size_filename;
671 } 671 }
672 else 672 else
673 uSizeRead = fileNameBufferSize; 673 uSizeRead = fileNameBufferSize;
674 674
675 if ((file_info.size_filename>0) && (fileNameBufferSize>0)) 675 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
676 if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) 676 if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
677 err=UNZ_ERRNO; 677 err=UNZ_ERRNO;
678 lSeek -= uSizeRead; 678 lSeek -= uSizeRead;
679 } 679 }
680 680
681 681
682 if ((err==UNZ_OK) && (extraField!=NULL)) 682 if ((err==UNZ_OK) && (extraField!=NULL))
683 { 683 {
684 uLong uSizeRead ; 684 uLong uSizeRead ;
685 if (file_info.size_file_extra<extraFieldBufferSize) 685 if (file_info.size_file_extra<extraFieldBufferSize)
686 uSizeRead = file_info.size_file_extra; 686 uSizeRead = file_info.size_file_extra;
687 else 687 else
688 uSizeRead = extraFieldBufferSize; 688 uSizeRead = extraFieldBufferSize;
689 689
690 if (lSeek!=0) 690 if (lSeek!=0)
691 if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) 691 if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
692 lSeek=0; 692 lSeek=0;
693 else 693 else
694 err=UNZ_ERRNO; 694 err=UNZ_ERRNO;
695 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) 695 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
696 if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead) 696 if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)
697 err=UNZ_ERRNO; 697 err=UNZ_ERRNO;
698 lSeek += file_info.size_file_extra - uSizeRead; 698 lSeek += file_info.size_file_extra - uSizeRead;
699 } 699 }
700 else 700 else
701 lSeek+=file_info.size_file_extra; 701 lSeek+=file_info.size_file_extra;
702 702
703 703
704 if ((err==UNZ_OK) && (szComment!=NULL)) 704 if ((err==UNZ_OK) && (szComment!=NULL))
705 { 705 {
706 uLong uSizeRead ; 706 uLong uSizeRead ;
707 if (file_info.size_file_comment<commentBufferSize) 707 if (file_info.size_file_comment<commentBufferSize)
708 { 708 {
709 *(szComment+file_info.size_file_comment)='\0'; 709 *(szComment+file_info.size_file_comment)='\0';
710 uSizeRead = file_info.size_file_comment; 710 uSizeRead = file_info.size_file_comment;
711 } 711 }
712 else 712 else
713 uSizeRead = commentBufferSize; 713 uSizeRead = commentBufferSize;
714 714
715 if (lSeek!=0) 715 if (lSeek!=0)
716 if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) 716 if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
717 lSeek=0; 717 lSeek=0;
718 else 718 else
719 err=UNZ_ERRNO; 719 err=UNZ_ERRNO;
720 if ((file_info.size_file_comment>0) && (commentBufferSize>0)) 720 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
721 if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) 721 if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
722 err=UNZ_ERRNO; 722 err=UNZ_ERRNO;
723 lSeek+=file_info.size_file_comment - uSizeRead; 723 lSeek+=file_info.size_file_comment - uSizeRead;
724 } 724 }
725 else 725 else
726 lSeek+=file_info.size_file_comment; 726 lSeek+=file_info.size_file_comment;
727 727
728 if ((err==UNZ_OK) && (pfile_info!=NULL)) 728 if ((err==UNZ_OK) && (pfile_info!=NULL))
729 *pfile_info=file_info; 729 *pfile_info=file_info;
730 730
731 if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) 731 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
732 *pfile_info_internal=file_info_internal; 732 *pfile_info_internal=file_info_internal;
733 733
734 return err; 734 return err;
735} 735}
736 736
737 737
738 738
739/* 739/*
740 Write info about the ZipFile in the *pglobal_info structure. 740 Write info about the ZipFile in the *pglobal_info structure.
741 No preparation of the structure is needed 741 No preparation of the structure is needed
742 return UNZ_OK if there is no problem. 742 return UNZ_OK if there is no problem.
743*/ 743*/
744extern int ZEXPORT unzGetCurrentFileInfo (file, 744extern int ZEXPORT unzGetCurrentFileInfo (file,
745 pfile_info, 745 pfile_info,
746 szFileName, fileNameBufferSize, 746 szFileName, fileNameBufferSize,
747 extraField, extraFieldBufferSize, 747 extraField, extraFieldBufferSize,
748 szComment, commentBufferSize) 748 szComment, commentBufferSize)
749 unzFile file; 749 unzFile file;
750 unz_file_info *pfile_info; 750 unz_file_info *pfile_info;
751 char *szFileName; 751 char *szFileName;
752 uLong fileNameBufferSize; 752 uLong fileNameBufferSize;
753 void *extraField; 753 void *extraField;
754 uLong extraFieldBufferSize; 754 uLong extraFieldBufferSize;
755 char *szComment; 755 char *szComment;
756 uLong commentBufferSize; 756 uLong commentBufferSize;
757{ 757{
758 return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, 758 return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
759 szFileName,fileNameBufferSize, 759 szFileName,fileNameBufferSize,
760 extraField,extraFieldBufferSize, 760 extraField,extraFieldBufferSize,
761 szComment,commentBufferSize); 761 szComment,commentBufferSize);
762} 762}
763 763
764/* 764/*
765 Set the current file of the zipfile to the first file. 765 Set the current file of the zipfile to the first file.
766 return UNZ_OK if there is no problem 766 return UNZ_OK if there is no problem
767*/ 767*/
768extern int ZEXPORT unzGoToFirstFile (file) 768extern int ZEXPORT unzGoToFirstFile (file)
769 unzFile file; 769 unzFile file;
770{ 770{
771 int err=UNZ_OK; 771 int err=UNZ_OK;
772 unz_s* s; 772 unz_s* s;
773 if (file==NULL) 773 if (file==NULL)
774 return UNZ_PARAMERROR; 774 return UNZ_PARAMERROR;
775 s=(unz_s*)file; 775 s=(unz_s*)file;
776 s->pos_in_central_dir=s->offset_central_dir; 776 s->pos_in_central_dir=s->offset_central_dir;
777 s->num_file=0; 777 s->num_file=0;
778 err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, 778 err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
779 &s->cur_file_info_internal, 779 &s->cur_file_info_internal,
780 NULL,0,NULL,0,NULL,0); 780 NULL,0,NULL,0,NULL,0);
781 s->current_file_ok = (err == UNZ_OK); 781 s->current_file_ok = (err == UNZ_OK);
782 return err; 782 return err;
783} 783}
784 784
785/* 785/*
786 Set the current file of the zipfile to the next file. 786 Set the current file of the zipfile to the next file.
787 return UNZ_OK if there is no problem 787 return UNZ_OK if there is no problem
788 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. 788 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
789*/ 789*/
790extern int ZEXPORT unzGoToNextFile (file) 790extern int ZEXPORT unzGoToNextFile (file)
791 unzFile file; 791 unzFile file;
792{ 792{
793 unz_s* s; 793 unz_s* s;
794 int err; 794 int err;
795 795
796 if (file==NULL) 796 if (file==NULL)
797 return UNZ_PARAMERROR; 797 return UNZ_PARAMERROR;
798 s=(unz_s*)file; 798 s=(unz_s*)file;
799 if (!s->current_file_ok) 799 if (!s->current_file_ok)
800 return UNZ_END_OF_LIST_OF_FILE; 800 return UNZ_END_OF_LIST_OF_FILE;
801 if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ 801 if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
802 if (s->num_file+1==s->gi.number_entry) 802 if (s->num_file+1==s->gi.number_entry)
803 return UNZ_END_OF_LIST_OF_FILE; 803 return UNZ_END_OF_LIST_OF_FILE;
804 804
805 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + 805 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
806 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; 806 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
807 s->num_file++; 807 s->num_file++;
808 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, 808 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
809 &s->cur_file_info_internal, 809 &s->cur_file_info_internal,
810 NULL,0,NULL,0,NULL,0); 810 NULL,0,NULL,0,NULL,0);
811 s->current_file_ok = (err == UNZ_OK); 811 s->current_file_ok = (err == UNZ_OK);
812 return err; 812 return err;
813} 813}
814 814
815 815
816/* 816/*
817 Try locate the file szFileName in the zipfile. 817 Try locate the file szFileName in the zipfile.
818 For the iCaseSensitivity signification, see unzipStringFileNameCompare 818 For the iCaseSensitivity signification, see unzipStringFileNameCompare
819 819
820 return value : 820 return value :
821 UNZ_OK if the file is found. It becomes the current file. 821 UNZ_OK if the file is found. It becomes the current file.
822 UNZ_END_OF_LIST_OF_FILE if the file is not found 822 UNZ_END_OF_LIST_OF_FILE if the file is not found
823*/ 823*/
824extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity) 824extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
825 unzFile file; 825 unzFile file;
826 const char *szFileName; 826 const char *szFileName;
827 int iCaseSensitivity; 827 int iCaseSensitivity;
828{ 828{
829 unz_s* s; 829 unz_s* s;
830 int err; 830 int err;
831 831
832 /* We remember the 'current' position in the file so that we can jump 832 /* We remember the 'current' position in the file so that we can jump
833 * back there if we fail. 833 * back there if we fail.
834 */ 834 */
835 unz_file_info cur_file_infoSaved; 835 unz_file_info cur_file_infoSaved;
836 unz_file_info_internal cur_file_info_internalSaved; 836 unz_file_info_internal cur_file_info_internalSaved;
837 uLong num_fileSaved; 837 uLong num_fileSaved;
838 uLong pos_in_central_dirSaved; 838 uLong pos_in_central_dirSaved;
839 839
840 840
841 if (file==NULL) 841 if (file==NULL)
842 return UNZ_PARAMERROR; 842 return UNZ_PARAMERROR;
843 843
844 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) 844 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
845 return UNZ_PARAMERROR; 845 return UNZ_PARAMERROR;
846 846
847 s=(unz_s*)file; 847 s=(unz_s*)file;
848 if (!s->current_file_ok) 848 if (!s->current_file_ok)
849 return UNZ_END_OF_LIST_OF_FILE; 849 return UNZ_END_OF_LIST_OF_FILE;
850 850
851 /* Save the current state */ 851 /* Save the current state */
852 num_fileSaved = s->num_file; 852 num_fileSaved = s->num_file;
853 pos_in_central_dirSaved = s->pos_in_central_dir; 853 pos_in_central_dirSaved = s->pos_in_central_dir;
854 cur_file_infoSaved = s->cur_file_info; 854 cur_file_infoSaved = s->cur_file_info;
855 cur_file_info_internalSaved = s->cur_file_info_internal; 855 cur_file_info_internalSaved = s->cur_file_info_internal;
856 856
857 err = unzGoToFirstFile(file); 857 err = unzGoToFirstFile(file);
858 858
859 while (err == UNZ_OK) 859 while (err == UNZ_OK)
860 { 860 {
861 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; 861 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
862 err = unzGetCurrentFileInfo(file,NULL, 862 err = unzGetCurrentFileInfo(file,NULL,
863 szCurrentFileName,sizeof(szCurrentFileName)-1, 863 szCurrentFileName,sizeof(szCurrentFileName)-1,
864 NULL,0,NULL,0); 864 NULL,0,NULL,0);
865 if (err == UNZ_OK) 865 if (err == UNZ_OK)
866 { 866 {
867 if (unzStringFileNameCompare(szCurrentFileName, 867 if (unzStringFileNameCompare(szCurrentFileName,
868 szFileName,iCaseSensitivity)==0) 868 szFileName,iCaseSensitivity)==0)
869 return UNZ_OK; 869 return UNZ_OK;
870 err = unzGoToNextFile(file); 870 err = unzGoToNextFile(file);
871 } 871 }
872 } 872 }
873 873
874 /* We failed, so restore the state of the 'current file' to where we 874 /* We failed, so restore the state of the 'current file' to where we
875 * were. 875 * were.
876 */ 876 */
877 s->num_file = num_fileSaved ; 877 s->num_file = num_fileSaved ;
878 s->pos_in_central_dir = pos_in_central_dirSaved ; 878 s->pos_in_central_dir = pos_in_central_dirSaved ;
879 s->cur_file_info = cur_file_infoSaved; 879 s->cur_file_info = cur_file_infoSaved;
880 s->cur_file_info_internal = cur_file_info_internalSaved; 880 s->cur_file_info_internal = cur_file_info_internalSaved;
881 return err; 881 return err;
882} 882}
883 883
884 884
885/* 885/*
886/////////////////////////////////////////// 886///////////////////////////////////////////
887// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) 887// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
888// I need random access 888// I need random access
889// 889//
890// Further optimization could be realized by adding an ability 890// Further optimization could be realized by adding an ability
891// to cache the directory in memory. The goal being a single 891// to cache the directory in memory. The goal being a single
892// comprehensive file read to put the file I need in a memory. 892// comprehensive file read to put the file I need in a memory.
893*/ 893*/
894 894
895/* 895/*
896typedef struct unz_file_pos_s 896typedef struct unz_file_pos_s
897{ 897{
898 uLong pos_in_zip_directory; // offset in file 898 uLong pos_in_zip_directory; // offset in file
899 uLong num_of_file; // # of file 899 uLong num_of_file; // # of file
900} unz_file_pos; 900} unz_file_pos;
901*/ 901*/
902 902
903extern int ZEXPORT unzGetFilePos(file, file_pos) 903extern int ZEXPORT unzGetFilePos(file, file_pos)
904 unzFile file; 904 unzFile file;
905 unz_file_pos* file_pos; 905 unz_file_pos* file_pos;
906{ 906{
907 unz_s* s; 907 unz_s* s;
908 908
909 if (file==NULL || file_pos==NULL) 909 if (file==NULL || file_pos==NULL)
910 return UNZ_PARAMERROR; 910 return UNZ_PARAMERROR;
911 s=(unz_s*)file; 911 s=(unz_s*)file;
912 if (!s->current_file_ok) 912 if (!s->current_file_ok)
913 return UNZ_END_OF_LIST_OF_FILE; 913 return UNZ_END_OF_LIST_OF_FILE;
914 914
915 file_pos->pos_in_zip_directory = s->pos_in_central_dir; 915 file_pos->pos_in_zip_directory = s->pos_in_central_dir;
916 file_pos->num_of_file = s->num_file; 916 file_pos->num_of_file = s->num_file;
917 917
918 return UNZ_OK; 918 return UNZ_OK;
919} 919}
920 920
921extern int ZEXPORT unzGoToFilePos(file, file_pos) 921extern int ZEXPORT unzGoToFilePos(file, file_pos)
922 unzFile file; 922 unzFile file;
923 unz_file_pos* file_pos; 923 unz_file_pos* file_pos;
924{ 924{
925 unz_s* s; 925 unz_s* s;
926 int err; 926 int err;
927 927
928 if (file==NULL || file_pos==NULL) 928 if (file==NULL || file_pos==NULL)
929 return UNZ_PARAMERROR; 929 return UNZ_PARAMERROR;
930 s=(unz_s*)file; 930 s=(unz_s*)file;
931 931
932 /* jump to the right spot */ 932 /* jump to the right spot */
933 s->pos_in_central_dir = file_pos->pos_in_zip_directory; 933 s->pos_in_central_dir = file_pos->pos_in_zip_directory;
934 s->num_file = file_pos->num_of_file; 934 s->num_file = file_pos->num_of_file;
935 935
936 /* set the current file */ 936 /* set the current file */
937 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, 937 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
938 &s->cur_file_info_internal, 938 &s->cur_file_info_internal,
939 NULL,0,NULL,0,NULL,0); 939 NULL,0,NULL,0,NULL,0);
940 /* return results */ 940 /* return results */
941 s->current_file_ok = (err == UNZ_OK); 941 s->current_file_ok = (err == UNZ_OK);
942 return err; 942 return err;
943} 943}
944 944
945/* 945/*
946// Unzip Helper Functions - should be here? 946// Unzip Helper Functions - should be here?
947/////////////////////////////////////////// 947///////////////////////////////////////////
948*/ 948*/
949 949
950/* 950/*
951 Read the local header of the current zipfile 951 Read the local header of the current zipfile
952 Check the coherency of the local header and info in the end of central 952 Check the coherency of the local header and info in the end of central
953 directory about this file 953 directory about this file
954 store in *piSizeVar the size of extra info in local header 954 store in *piSizeVar the size of extra info in local header
955 (filename and size of extra field data) 955 (filename and size of extra field data)
956*/ 956*/
957local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar, 957local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
958 poffset_local_extrafield, 958 poffset_local_extrafield,
959 psize_local_extrafield) 959 psize_local_extrafield)
960 unz_s* s; 960 unz_s* s;
961 uInt* piSizeVar; 961 uInt* piSizeVar;
962 uLong *poffset_local_extrafield; 962 uLong *poffset_local_extrafield;
963 uInt *psize_local_extrafield; 963 uInt *psize_local_extrafield;
964{ 964{
965 uLong uMagic,uData,uFlags; 965 uLong uMagic,uData,uFlags;
966 uLong size_filename; 966 uLong size_filename;
967 uLong size_extra_field; 967 uLong size_extra_field;
968 int err=UNZ_OK; 968 int err=UNZ_OK;
969 969
970 *piSizeVar = 0; 970 *piSizeVar = 0;
971 *poffset_local_extrafield = 0; 971 *poffset_local_extrafield = 0;
972 *psize_local_extrafield = 0; 972 *psize_local_extrafield = 0;
973 973
974 if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + 974 if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
975 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) 975 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
976 return UNZ_ERRNO; 976 return UNZ_ERRNO;
977 977
978 978
979 if (err==UNZ_OK) 979 if (err==UNZ_OK)
980 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) 980 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
981 err=UNZ_ERRNO; 981 err=UNZ_ERRNO;
982 else if (uMagic!=0x04034b50) 982 else if (uMagic!=0x04034b50)
983 err=UNZ_BADZIPFILE; 983 err=UNZ_BADZIPFILE;
984 984
985 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) 985 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
986 err=UNZ_ERRNO; 986 err=UNZ_ERRNO;
987/* 987/*
988 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) 988 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
989 err=UNZ_BADZIPFILE; 989 err=UNZ_BADZIPFILE;
990*/ 990*/
991 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) 991 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
992 err=UNZ_ERRNO; 992 err=UNZ_ERRNO;
993 993
994 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) 994 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
995 err=UNZ_ERRNO; 995 err=UNZ_ERRNO;
996 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) 996 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
997 err=UNZ_BADZIPFILE; 997 err=UNZ_BADZIPFILE;
998 998
999 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && 999 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
1000 (s->cur_file_info.compression_method!=Z_DEFLATED)) 1000 (s->cur_file_info.compression_method!=Z_DEFLATED))
1001 err=UNZ_BADZIPFILE; 1001 err=UNZ_BADZIPFILE;
1002 1002
1003 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ 1003 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
1004 err=UNZ_ERRNO; 1004 err=UNZ_ERRNO;
1005 1005
1006 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ 1006 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
1007 err=UNZ_ERRNO; 1007 err=UNZ_ERRNO;
1008 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && 1008 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
1009 ((uFlags & 8)==0)) 1009 ((uFlags & 8)==0))
1010 err=UNZ_BADZIPFILE; 1010 err=UNZ_BADZIPFILE;
1011 1011
1012 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ 1012 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
1013 err=UNZ_ERRNO; 1013 err=UNZ_ERRNO;
1014 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && 1014 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
1015 ((uFlags & 8)==0)) 1015 ((uFlags & 8)==0))
1016 err=UNZ_BADZIPFILE; 1016 err=UNZ_BADZIPFILE;
1017 1017
1018 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ 1018 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
1019 err=UNZ_ERRNO; 1019 err=UNZ_ERRNO;
1020 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && 1020 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
1021 ((uFlags & 8)==0)) 1021 ((uFlags & 8)==0))
1022 err=UNZ_BADZIPFILE; 1022 err=UNZ_BADZIPFILE;
1023 1023
1024 1024
1025 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) 1025 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
1026 err=UNZ_ERRNO; 1026 err=UNZ_ERRNO;
1027 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) 1027 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
1028 err=UNZ_BADZIPFILE; 1028 err=UNZ_BADZIPFILE;
1029 1029
1030 *piSizeVar += (uInt)size_filename; 1030 *piSizeVar += (uInt)size_filename;
1031 1031
1032 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) 1032 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
1033 err=UNZ_ERRNO; 1033 err=UNZ_ERRNO;
1034 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + 1034 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
1035 SIZEZIPLOCALHEADER + size_filename; 1035 SIZEZIPLOCALHEADER + size_filename;
1036 *psize_local_extrafield = (uInt)size_extra_field; 1036 *psize_local_extrafield = (uInt)size_extra_field;
1037 1037
1038 *piSizeVar += (uInt)size_extra_field; 1038 *piSizeVar += (uInt)size_extra_field;
1039 1039
1040 return err; 1040 return err;
1041} 1041}
1042 1042
1043/* 1043/*
1044 Open for reading data the current file in the zipfile. 1044 Open for reading data the current file in the zipfile.
1045 If there is no error and the file is opened, the return value is UNZ_OK. 1045 If there is no error and the file is opened, the return value is UNZ_OK.
1046*/ 1046*/
1047extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password) 1047extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
1048 unzFile file; 1048 unzFile file;
1049 int* method; 1049 int* method;
1050 int* level; 1050 int* level;
1051 int raw; 1051 int raw;
1052 const char* password; 1052 const char* password;
1053{ 1053{
1054 int err=UNZ_OK; 1054 int err=UNZ_OK;
1055 uInt iSizeVar; 1055 uInt iSizeVar;
1056 unz_s* s; 1056 unz_s* s;
1057 file_in_zip_read_info_s* pfile_in_zip_read_info; 1057 file_in_zip_read_info_s* pfile_in_zip_read_info;
1058 uLong offset_local_extrafield; /* offset of the local extra field */ 1058 uLong offset_local_extrafield; /* offset of the local extra field */
1059 uInt size_local_extrafield; /* size of the local extra field */ 1059 uInt size_local_extrafield; /* size of the local extra field */
1060# ifndef NOUNCRYPT 1060# ifndef NOUNCRYPT
1061 char source[12]; 1061 char source[12];
1062# else 1062# else
1063 if (password != NULL) 1063 if (password != NULL)
1064 return UNZ_PARAMERROR; 1064 return UNZ_PARAMERROR;
1065# endif 1065# endif
1066 1066
1067 if (file==NULL) 1067 if (file==NULL)
1068 return UNZ_PARAMERROR; 1068 return UNZ_PARAMERROR;
1069 s=(unz_s*)file; 1069 s=(unz_s*)file;
1070 if (!s->current_file_ok) 1070 if (!s->current_file_ok)
1071 return UNZ_PARAMERROR; 1071 return UNZ_PARAMERROR;
1072 1072
1073 if (s->pfile_in_zip_read != NULL) 1073 if (s->pfile_in_zip_read != NULL)
1074 unzCloseCurrentFile(file); 1074 unzCloseCurrentFile(file);
1075 1075
1076 if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, 1076 if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
1077 &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) 1077 &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1078 return UNZ_BADZIPFILE; 1078 return UNZ_BADZIPFILE;
1079 1079
1080 pfile_in_zip_read_info = (file_in_zip_read_info_s*) 1080 pfile_in_zip_read_info = (file_in_zip_read_info_s*)
1081 ALLOC(sizeof(file_in_zip_read_info_s)); 1081 ALLOC(sizeof(file_in_zip_read_info_s));
1082 if (pfile_in_zip_read_info==NULL) 1082 if (pfile_in_zip_read_info==NULL)
1083 return UNZ_INTERNALERROR; 1083 return UNZ_INTERNALERROR;
1084 1084
1085 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); 1085 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1086 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; 1086 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1087 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; 1087 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1088 pfile_in_zip_read_info->pos_local_extrafield=0; 1088 pfile_in_zip_read_info->pos_local_extrafield=0;
1089 pfile_in_zip_read_info->raw=raw; 1089 pfile_in_zip_read_info->raw=raw;
1090 1090
1091 if (pfile_in_zip_read_info->read_buffer==NULL) 1091 if (pfile_in_zip_read_info->read_buffer==NULL)
1092 { 1092 {
1093 TRYFREE(pfile_in_zip_read_info); 1093 TRYFREE(pfile_in_zip_read_info);
1094 return UNZ_INTERNALERROR; 1094 return UNZ_INTERNALERROR;
1095 } 1095 }
1096 1096
1097 pfile_in_zip_read_info->stream_initialised=0; 1097 pfile_in_zip_read_info->stream_initialised=0;
1098 1098
1099 if (method!=NULL) 1099 if (method!=NULL)
1100 *method = (int)s->cur_file_info.compression_method; 1100 *method = (int)s->cur_file_info.compression_method;
1101 1101
1102 if (level!=NULL) 1102 if (level!=NULL)
1103 { 1103 {
1104 *level = 6; 1104 *level = 6;
1105 switch (s->cur_file_info.flag & 0x06) 1105 switch (s->cur_file_info.flag & 0x06)
1106 { 1106 {
1107 case 6 : *level = 1; break; 1107 case 6 : *level = 1; break;
1108 case 4 : *level = 2; break; 1108 case 4 : *level = 2; break;
1109 case 2 : *level = 9; break; 1109 case 2 : *level = 9; break;
1110 } 1110 }
1111 } 1111 }
1112 1112
1113 if ((s->cur_file_info.compression_method!=0) && 1113 if ((s->cur_file_info.compression_method!=0) &&
1114 (s->cur_file_info.compression_method!=Z_DEFLATED)) 1114 (s->cur_file_info.compression_method!=Z_DEFLATED))
1115 err=UNZ_BADZIPFILE; 1115 err=UNZ_BADZIPFILE;
1116 1116
1117 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; 1117 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1118 pfile_in_zip_read_info->crc32=0; 1118 pfile_in_zip_read_info->crc32=0;
1119 pfile_in_zip_read_info->compression_method = 1119 pfile_in_zip_read_info->compression_method =
1120 s->cur_file_info.compression_method; 1120 s->cur_file_info.compression_method;
1121 pfile_in_zip_read_info->filestream=s->filestream; 1121 pfile_in_zip_read_info->filestream=s->filestream;
1122 pfile_in_zip_read_info->z_filefunc=s->z_filefunc; 1122 pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
1123 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; 1123 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1124 1124
1125 pfile_in_zip_read_info->stream.total_out = 0; 1125 pfile_in_zip_read_info->stream.total_out = 0;
1126 1126
1127 if ((s->cur_file_info.compression_method==Z_DEFLATED) && 1127 if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
1128 (!raw)) 1128 (!raw))
1129 { 1129 {
1130 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; 1130 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1131 pfile_in_zip_read_info->stream.zfree = (free_func)0; 1131 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1132 pfile_in_zip_read_info->stream.opaque = (voidpf)0; 1132 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1133 pfile_in_zip_read_info->stream.next_in = (voidpf)0; 1133 pfile_in_zip_read_info->stream.next_in = (voidpf)0;
1134 pfile_in_zip_read_info->stream.avail_in = 0; 1134 pfile_in_zip_read_info->stream.avail_in = 0;
1135 1135
1136 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); 1136 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1137 if (err == Z_OK) 1137 if (err == Z_OK)
1138 pfile_in_zip_read_info->stream_initialised=1; 1138 pfile_in_zip_read_info->stream_initialised=1;
1139 else 1139 else
1140 return err; 1140 {
1141 /* windowBits is passed < 0 to tell that there is no zlib header. 1141 TRYFREE(pfile_in_zip_read_info);
1142 * Note that in this case inflate *requires* an extra "dummy" byte 1142 return err;
1143 * after the compressed stream in order to complete decompression and 1143 }
1144 * return Z_STREAM_END. 1144 /* windowBits is passed < 0 to tell that there is no zlib header.
1145 * In unzip, i don't wait absolutely Z_STREAM_END because I known the 1145 * Note that in this case inflate *requires* an extra "dummy" byte
1146 * size of both compressed and uncompressed data 1146 * after the compressed stream in order to complete decompression and
1147 */ 1147 * return Z_STREAM_END.
1148 } 1148 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1149 pfile_in_zip_read_info->rest_read_compressed = 1149 * size of both compressed and uncompressed data
1150 s->cur_file_info.compressed_size ; 1150 */
1151 pfile_in_zip_read_info->rest_read_uncompressed = 1151 }
1152 s->cur_file_info.uncompressed_size ; 1152 pfile_in_zip_read_info->rest_read_compressed =
1153 1153 s->cur_file_info.compressed_size ;
1154 1154 pfile_in_zip_read_info->rest_read_uncompressed =
1155 pfile_in_zip_read_info->pos_in_zipfile = 1155 s->cur_file_info.uncompressed_size ;
1156 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + 1156
1157 iSizeVar; 1157
1158 1158 pfile_in_zip_read_info->pos_in_zipfile =
1159 pfile_in_zip_read_info->stream.avail_in = (uInt)0; 1159 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1160 1160 iSizeVar;
1161 s->pfile_in_zip_read = pfile_in_zip_read_info; 1161
1162 1162 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1163# ifndef NOUNCRYPT 1163
1164 if (password != NULL) 1164 s->pfile_in_zip_read = pfile_in_zip_read_info;
1165 { 1165
1166 int i; 1166# ifndef NOUNCRYPT
1167 s->pcrc_32_tab = get_crc_table(); 1167 if (password != NULL)
1168 init_keys(password,s->keys,s->pcrc_32_tab); 1168 {
1169 if (ZSEEK(s->z_filefunc, s->filestream, 1169 int i;
1170 s->pfile_in_zip_read->pos_in_zipfile + 1170 s->pcrc_32_tab = get_crc_table();
1171 s->pfile_in_zip_read->byte_before_the_zipfile, 1171 init_keys(password,s->keys,s->pcrc_32_tab);
1172 SEEK_SET)!=0) 1172 if (ZSEEK(s->z_filefunc, s->filestream,
1173 return UNZ_INTERNALERROR; 1173 s->pfile_in_zip_read->pos_in_zipfile +
1174 if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12) 1174 s->pfile_in_zip_read->byte_before_the_zipfile,
1175 return UNZ_INTERNALERROR; 1175 SEEK_SET)!=0)
1176 1176 return UNZ_INTERNALERROR;
1177 for (i = 0; i<12; i++) 1177 if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
1178 zdecode(s->keys,s->pcrc_32_tab,source[i]); 1178 return UNZ_INTERNALERROR;
1179 1179
1180 s->pfile_in_zip_read->pos_in_zipfile+=12; 1180 for (i = 0; i<12; i++)
1181 s->encrypted=1; 1181 zdecode(s->keys,s->pcrc_32_tab,source[i]);
1182 } 1182
1183# endif 1183 s->pfile_in_zip_read->pos_in_zipfile+=12;
1184 1184 s->encrypted=1;
1185 1185 }
1186 return UNZ_OK; 1186# endif
1187} 1187
1188 1188
1189extern int ZEXPORT unzOpenCurrentFile (file) 1189 return UNZ_OK;
1190 unzFile file; 1190}
1191{ 1191
1192 return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); 1192extern int ZEXPORT unzOpenCurrentFile (file)
1193} 1193 unzFile file;
1194 1194{
1195extern int ZEXPORT unzOpenCurrentFilePassword (file, password) 1195 return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
1196 unzFile file; 1196}
1197 const char* password; 1197
1198{ 1198extern int ZEXPORT unzOpenCurrentFilePassword (file, password)
1199 return unzOpenCurrentFile3(file, NULL, NULL, 0, password); 1199 unzFile file;
1200} 1200 const char* password;
1201 1201{
1202extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw) 1202 return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
1203 unzFile file; 1203}
1204 int* method; 1204
1205 int* level; 1205extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw)
1206 int raw; 1206 unzFile file;
1207{ 1207 int* method;
1208 return unzOpenCurrentFile3(file, method, level, raw, NULL); 1208 int* level;
1209} 1209 int raw;
1210 1210{
1211/* 1211 return unzOpenCurrentFile3(file, method, level, raw, NULL);
1212 Read bytes from the current file. 1212}
1213 buf contain buffer where data must be copied 1213
1214 len the size of buf. 1214/*
1215 1215 Read bytes from the current file.
1216 return the number of byte copied if somes bytes are copied 1216 buf contain buffer where data must be copied
1217 return 0 if the end of file was reached 1217 len the size of buf.
1218 return <0 with error code if there is an error 1218
1219 (UNZ_ERRNO for IO error, or zLib error for uncompress error) 1219 return the number of byte copied if somes bytes are copied
1220*/ 1220 return 0 if the end of file was reached
1221extern int ZEXPORT unzReadCurrentFile (file, buf, len) 1221 return <0 with error code if there is an error
1222 unzFile file; 1222 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1223 voidp buf; 1223*/
1224 unsigned len; 1224extern int ZEXPORT unzReadCurrentFile (file, buf, len)
1225{ 1225 unzFile file;
1226 int err=UNZ_OK; 1226 voidp buf;
1227 uInt iRead = 0; 1227 unsigned len;
1228 unz_s* s; 1228{
1229 file_in_zip_read_info_s* pfile_in_zip_read_info; 1229 int err=UNZ_OK;
1230 if (file==NULL) 1230 uInt iRead = 0;
1231 return UNZ_PARAMERROR; 1231 unz_s* s;
1232 s=(unz_s*)file; 1232 file_in_zip_read_info_s* pfile_in_zip_read_info;
1233 pfile_in_zip_read_info=s->pfile_in_zip_read; 1233 if (file==NULL)
1234 1234 return UNZ_PARAMERROR;
1235 if (pfile_in_zip_read_info==NULL) 1235 s=(unz_s*)file;
1236 return UNZ_PARAMERROR; 1236 pfile_in_zip_read_info=s->pfile_in_zip_read;
1237 1237
1238 1238 if (pfile_in_zip_read_info==NULL)
1239 if ((pfile_in_zip_read_info->read_buffer == NULL)) 1239 return UNZ_PARAMERROR;
1240 return UNZ_END_OF_LIST_OF_FILE; 1240
1241 if (len==0) 1241
1242 return 0; 1242 if ((pfile_in_zip_read_info->read_buffer == NULL))
1243 1243 return UNZ_END_OF_LIST_OF_FILE;
1244 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; 1244 if (len==0)
1245 1245 return 0;
1246 pfile_in_zip_read_info->stream.avail_out = (uInt)len; 1246
1247 1247 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1248 if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && 1248
1249 (!(pfile_in_zip_read_info->raw))) 1249 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1250 pfile_in_zip_read_info->stream.avail_out = 1250
1251 (uInt)pfile_in_zip_read_info->rest_read_uncompressed; 1251 if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
1252 1252 (!(pfile_in_zip_read_info->raw)))
1253 if ((len>pfile_in_zip_read_info->rest_read_compressed+ 1253 pfile_in_zip_read_info->stream.avail_out =
1254 pfile_in_zip_read_info->stream.avail_in) && 1254 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1255 (pfile_in_zip_read_info->raw)) 1255
1256 pfile_in_zip_read_info->stream.avail_out = 1256 if ((len>pfile_in_zip_read_info->rest_read_compressed+
1257 (uInt)pfile_in_zip_read_info->rest_read_compressed+ 1257 pfile_in_zip_read_info->stream.avail_in) &&
1258 pfile_in_zip_read_info->stream.avail_in; 1258 (pfile_in_zip_read_info->raw))
1259 1259 pfile_in_zip_read_info->stream.avail_out =
1260 while (pfile_in_zip_read_info->stream.avail_out>0) 1260 (uInt)pfile_in_zip_read_info->rest_read_compressed+
1261 { 1261 pfile_in_zip_read_info->stream.avail_in;
1262 if ((pfile_in_zip_read_info->stream.avail_in==0) && 1262
1263 (pfile_in_zip_read_info->rest_read_compressed>0)) 1263 while (pfile_in_zip_read_info->stream.avail_out>0)
1264 { 1264 {
1265 uInt uReadThis = UNZ_BUFSIZE; 1265 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1266 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis) 1266 (pfile_in_zip_read_info->rest_read_compressed>0))
1267 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed; 1267 {
1268 if (uReadThis == 0) 1268 uInt uReadThis = UNZ_BUFSIZE;
1269 return UNZ_EOF; 1269 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1270 if (ZSEEK(pfile_in_zip_read_info->z_filefunc, 1270 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1271 pfile_in_zip_read_info->filestream, 1271 if (uReadThis == 0)
1272 pfile_in_zip_read_info->pos_in_zipfile + 1272 return UNZ_EOF;
1273 pfile_in_zip_read_info->byte_before_the_zipfile, 1273 if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1274 ZLIB_FILEFUNC_SEEK_SET)!=0) 1274 pfile_in_zip_read_info->filestream,
1275 return UNZ_ERRNO; 1275 pfile_in_zip_read_info->pos_in_zipfile +
1276 if (ZREAD(pfile_in_zip_read_info->z_filefunc, 1276 pfile_in_zip_read_info->byte_before_the_zipfile,
1277 pfile_in_zip_read_info->filestream, 1277 ZLIB_FILEFUNC_SEEK_SET)!=0)
1278 pfile_in_zip_read_info->read_buffer, 1278 return UNZ_ERRNO;
1279 uReadThis)!=uReadThis) 1279 if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1280 return UNZ_ERRNO; 1280 pfile_in_zip_read_info->filestream,
1281 1281 pfile_in_zip_read_info->read_buffer,
1282 1282 uReadThis)!=uReadThis)
1283# ifndef NOUNCRYPT 1283 return UNZ_ERRNO;
1284 if(s->encrypted) 1284
1285 { 1285
1286 uInt i; 1286# ifndef NOUNCRYPT
1287 for(i=0;i<uReadThis;i++) 1287 if(s->encrypted)
1288 pfile_in_zip_read_info->read_buffer[i] = 1288 {
1289 zdecode(s->keys,s->pcrc_32_tab, 1289 uInt i;
1290 pfile_in_zip_read_info->read_buffer[i]); 1290 for(i=0;i<uReadThis;i++)
1291 } 1291 pfile_in_zip_read_info->read_buffer[i] =
1292# endif 1292 zdecode(s->keys,s->pcrc_32_tab,
1293 1293 pfile_in_zip_read_info->read_buffer[i]);
1294 1294 }
1295 pfile_in_zip_read_info->pos_in_zipfile += uReadThis; 1295# endif
1296 1296
1297 pfile_in_zip_read_info->rest_read_compressed-=uReadThis; 1297
1298 1298 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1299 pfile_in_zip_read_info->stream.next_in = 1299
1300 (Bytef*)pfile_in_zip_read_info->read_buffer; 1300 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1301 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; 1301
1302 } 1302 pfile_in_zip_read_info->stream.next_in =
1303 1303 (Bytef*)pfile_in_zip_read_info->read_buffer;
1304 if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) 1304 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1305 { 1305 }
1306 uInt uDoCopy,i ; 1306
1307 1307 if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
1308 if ((pfile_in_zip_read_info->stream.avail_in == 0) && 1308 {
1309 (pfile_in_zip_read_info->rest_read_compressed == 0)) 1309 uInt uDoCopy,i ;
1310 return (iRead==0) ? UNZ_EOF : iRead; 1310
1311 1311 if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
1312 if (pfile_in_zip_read_info->stream.avail_out < 1312 (pfile_in_zip_read_info->rest_read_compressed == 0))
1313 pfile_in_zip_read_info->stream.avail_in) 1313 return (iRead==0) ? UNZ_EOF : iRead;
1314 uDoCopy = pfile_in_zip_read_info->stream.avail_out ; 1314
1315 else 1315 if (pfile_in_zip_read_info->stream.avail_out <
1316 uDoCopy = pfile_in_zip_read_info->stream.avail_in ; 1316 pfile_in_zip_read_info->stream.avail_in)
1317 1317 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1318 for (i=0;i<uDoCopy;i++) 1318 else
1319 *(pfile_in_zip_read_info->stream.next_out+i) = 1319 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1320 *(pfile_in_zip_read_info->stream.next_in+i); 1320
1321 1321 for (i=0;i<uDoCopy;i++)
1322 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, 1322 *(pfile_in_zip_read_info->stream.next_out+i) =
1323 pfile_in_zip_read_info->stream.next_out, 1323 *(pfile_in_zip_read_info->stream.next_in+i);
1324 uDoCopy); 1324
1325 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; 1325 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1326 pfile_in_zip_read_info->stream.avail_in -= uDoCopy; 1326 pfile_in_zip_read_info->stream.next_out,
1327 pfile_in_zip_read_info->stream.avail_out -= uDoCopy; 1327 uDoCopy);
1328 pfile_in_zip_read_info->stream.next_out += uDoCopy; 1328 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1329 pfile_in_zip_read_info->stream.next_in += uDoCopy; 1329 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1330 pfile_in_zip_read_info->stream.total_out += uDoCopy; 1330 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1331 iRead += uDoCopy; 1331 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1332 } 1332 pfile_in_zip_read_info->stream.next_in += uDoCopy;
1333 else 1333 pfile_in_zip_read_info->stream.total_out += uDoCopy;
1334 { 1334 iRead += uDoCopy;
1335 uLong uTotalOutBefore,uTotalOutAfter; 1335 }
1336 const Bytef *bufBefore; 1336 else
1337 uLong uOutThis; 1337 {
1338 int flush=Z_SYNC_FLUSH; 1338 uLong uTotalOutBefore,uTotalOutAfter;
1339 1339 const Bytef *bufBefore;
1340 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; 1340 uLong uOutThis;
1341 bufBefore = pfile_in_zip_read_info->stream.next_out; 1341 int flush=Z_SYNC_FLUSH;
1342 1342
1343 /* 1343 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1344 if ((pfile_in_zip_read_info->rest_read_uncompressed == 1344 bufBefore = pfile_in_zip_read_info->stream.next_out;
1345 pfile_in_zip_read_info->stream.avail_out) && 1345
1346 (pfile_in_zip_read_info->rest_read_compressed == 0)) 1346 /*
1347 flush = Z_FINISH; 1347 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1348 */ 1348 pfile_in_zip_read_info->stream.avail_out) &&
1349 err=inflate(&pfile_in_zip_read_info->stream,flush); 1349 (pfile_in_zip_read_info->rest_read_compressed == 0))
1350 1350 flush = Z_FINISH;
1351 if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) 1351 */
1352 err = Z_DATA_ERROR; 1352 err=inflate(&pfile_in_zip_read_info->stream,flush);
1353 1353
1354 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; 1354 if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
1355 uOutThis = uTotalOutAfter-uTotalOutBefore; 1355 err = Z_DATA_ERROR;
1356 1356
1357 pfile_in_zip_read_info->crc32 = 1357 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1358 crc32(pfile_in_zip_read_info->crc32,bufBefore, 1358 uOutThis = uTotalOutAfter-uTotalOutBefore;
1359 (uInt)(uOutThis)); 1359
1360 1360 pfile_in_zip_read_info->crc32 =
1361 pfile_in_zip_read_info->rest_read_uncompressed -= 1361 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1362 uOutThis; 1362 (uInt)(uOutThis));
1363 1363
1364 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); 1364 pfile_in_zip_read_info->rest_read_uncompressed -=
1365 1365 uOutThis;
1366 if (err==Z_STREAM_END) 1366
1367 return (iRead==0) ? UNZ_EOF : iRead; 1367 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1368 if (err!=Z_OK) 1368
1369 break; 1369 if (err==Z_STREAM_END)
1370 } 1370 return (iRead==0) ? UNZ_EOF : iRead;
1371 } 1371 if (err!=Z_OK)
1372 1372 break;
1373 if (err==Z_OK) 1373 }
1374 return iRead; 1374 }
1375 return err; 1375
1376} 1376 if (err==Z_OK)
1377 1377 return iRead;
1378 1378 return err;
1379/* 1379}
1380 Give the current position in uncompressed data 1380
1381*/ 1381
1382extern z_off_t ZEXPORT unztell (file) 1382/*
1383 unzFile file; 1383 Give the current position in uncompressed data
1384{ 1384*/
1385 unz_s* s; 1385extern z_off_t ZEXPORT unztell (file)
1386 file_in_zip_read_info_s* pfile_in_zip_read_info; 1386 unzFile file;
1387 if (file==NULL) 1387{
1388 return UNZ_PARAMERROR; 1388 unz_s* s;
1389 s=(unz_s*)file; 1389 file_in_zip_read_info_s* pfile_in_zip_read_info;
1390 pfile_in_zip_read_info=s->pfile_in_zip_read; 1390 if (file==NULL)
1391 1391 return UNZ_PARAMERROR;
1392 if (pfile_in_zip_read_info==NULL) 1392 s=(unz_s*)file;
1393 return UNZ_PARAMERROR; 1393 pfile_in_zip_read_info=s->pfile_in_zip_read;
1394 1394
1395 return (z_off_t)pfile_in_zip_read_info->stream.total_out; 1395 if (pfile_in_zip_read_info==NULL)
1396} 1396 return UNZ_PARAMERROR;
1397 1397
1398 1398 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1399/* 1399}
1400 return 1 if the end of file was reached, 0 elsewhere 1400
1401*/ 1401
1402extern int ZEXPORT unzeof (file) 1402/*
1403 unzFile file; 1403 return 1 if the end of file was reached, 0 elsewhere
1404{ 1404*/
1405 unz_s* s; 1405extern int ZEXPORT unzeof (file)
1406 file_in_zip_read_info_s* pfile_in_zip_read_info; 1406 unzFile file;
1407 if (file==NULL) 1407{
1408 return UNZ_PARAMERROR; 1408 unz_s* s;
1409 s=(unz_s*)file; 1409 file_in_zip_read_info_s* pfile_in_zip_read_info;
1410 pfile_in_zip_read_info=s->pfile_in_zip_read; 1410 if (file==NULL)
1411 1411 return UNZ_PARAMERROR;
1412 if (pfile_in_zip_read_info==NULL) 1412 s=(unz_s*)file;
1413 return UNZ_PARAMERROR; 1413 pfile_in_zip_read_info=s->pfile_in_zip_read;
1414 1414
1415 if (pfile_in_zip_read_info->rest_read_uncompressed == 0) 1415 if (pfile_in_zip_read_info==NULL)
1416 return 1; 1416 return UNZ_PARAMERROR;
1417 else 1417
1418 return 0; 1418 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1419} 1419 return 1;
1420 1420 else
1421 1421 return 0;
1422 1422}
1423/* 1423
1424 Read extra field from the current file (opened by unzOpenCurrentFile) 1424
1425 This is the local-header version of the extra field (sometimes, there is 1425
1426 more info in the local-header version than in the central-header) 1426/*
1427 1427 Read extra field from the current file (opened by unzOpenCurrentFile)
1428 if buf==NULL, it return the size of the local extra field that can be read 1428 This is the local-header version of the extra field (sometimes, there is
1429 1429 more info in the local-header version than in the central-header)
1430 if buf!=NULL, len is the size of the buffer, the extra header is copied in 1430
1431 buf. 1431 if buf==NULL, it return the size of the local extra field that can be read
1432 the return value is the number of bytes copied in buf, or (if <0) 1432
1433 the error code 1433 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1434*/ 1434 buf.
1435extern int ZEXPORT unzGetLocalExtrafield (file,buf,len) 1435 the return value is the number of bytes copied in buf, or (if <0)
1436 unzFile file; 1436 the error code
1437 voidp buf; 1437*/
1438 unsigned len; 1438extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
1439{ 1439 unzFile file;
1440 unz_s* s; 1440 voidp buf;
1441 file_in_zip_read_info_s* pfile_in_zip_read_info; 1441 unsigned len;
1442 uInt read_now; 1442{
1443 uLong size_to_read; 1443 unz_s* s;
1444 1444 file_in_zip_read_info_s* pfile_in_zip_read_info;
1445 if (file==NULL) 1445 uInt read_now;
1446 return UNZ_PARAMERROR; 1446 uLong size_to_read;
1447 s=(unz_s*)file; 1447
1448 pfile_in_zip_read_info=s->pfile_in_zip_read; 1448 if (file==NULL)
1449 1449 return UNZ_PARAMERROR;
1450 if (pfile_in_zip_read_info==NULL) 1450 s=(unz_s*)file;
1451 return UNZ_PARAMERROR; 1451 pfile_in_zip_read_info=s->pfile_in_zip_read;
1452 1452
1453 size_to_read = (pfile_in_zip_read_info->size_local_extrafield - 1453 if (pfile_in_zip_read_info==NULL)
1454 pfile_in_zip_read_info->pos_local_extrafield); 1454 return UNZ_PARAMERROR;
1455 1455
1456 if (buf==NULL) 1456 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1457 return (int)size_to_read; 1457 pfile_in_zip_read_info->pos_local_extrafield);
1458 1458
1459 if (len>size_to_read) 1459 if (buf==NULL)
1460 read_now = (uInt)size_to_read; 1460 return (int)size_to_read;
1461 else 1461
1462 read_now = (uInt)len ; 1462 if (len>size_to_read)
1463 1463 read_now = (uInt)size_to_read;
1464 if (read_now==0) 1464 else
1465 return 0; 1465 read_now = (uInt)len ;
1466 1466
1467 if (ZSEEK(pfile_in_zip_read_info->z_filefunc, 1467 if (read_now==0)
1468 pfile_in_zip_read_info->filestream, 1468 return 0;
1469 pfile_in_zip_read_info->offset_local_extrafield + 1469
1470 pfile_in_zip_read_info->pos_local_extrafield, 1470 if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1471 ZLIB_FILEFUNC_SEEK_SET)!=0) 1471 pfile_in_zip_read_info->filestream,
1472 return UNZ_ERRNO; 1472 pfile_in_zip_read_info->offset_local_extrafield +
1473 1473 pfile_in_zip_read_info->pos_local_extrafield,
1474 if (ZREAD(pfile_in_zip_read_info->z_filefunc, 1474 ZLIB_FILEFUNC_SEEK_SET)!=0)
1475 pfile_in_zip_read_info->filestream, 1475 return UNZ_ERRNO;
1476 buf,read_now)!=read_now) 1476
1477 return UNZ_ERRNO; 1477 if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1478 1478 pfile_in_zip_read_info->filestream,
1479 return (int)read_now; 1479 buf,read_now)!=read_now)
1480} 1480 return UNZ_ERRNO;
1481 1481
1482/* 1482 return (int)read_now;
1483 Close the file in zip opened with unzipOpenCurrentFile 1483}
1484 Return UNZ_CRCERROR if all the file was read but the CRC is not good 1484
1485*/ 1485/*
1486extern int ZEXPORT unzCloseCurrentFile (file) 1486 Close the file in zip opened with unzipOpenCurrentFile
1487 unzFile file; 1487 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1488{ 1488*/
1489 int err=UNZ_OK; 1489extern int ZEXPORT unzCloseCurrentFile (file)
1490 1490 unzFile file;
1491 unz_s* s; 1491{
1492 file_in_zip_read_info_s* pfile_in_zip_read_info; 1492 int err=UNZ_OK;
1493 if (file==NULL) 1493
1494 return UNZ_PARAMERROR; 1494 unz_s* s;
1495 s=(unz_s*)file; 1495 file_in_zip_read_info_s* pfile_in_zip_read_info;
1496 pfile_in_zip_read_info=s->pfile_in_zip_read; 1496 if (file==NULL)
1497 1497 return UNZ_PARAMERROR;
1498 if (pfile_in_zip_read_info==NULL) 1498 s=(unz_s*)file;
1499 return UNZ_PARAMERROR; 1499 pfile_in_zip_read_info=s->pfile_in_zip_read;
1500 1500
1501 1501 if (pfile_in_zip_read_info==NULL)
1502 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && 1502 return UNZ_PARAMERROR;
1503 (!pfile_in_zip_read_info->raw)) 1503
1504 { 1504
1505 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) 1505 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
1506 err=UNZ_CRCERROR; 1506 (!pfile_in_zip_read_info->raw))
1507 } 1507 {
1508 1508 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1509 1509 err=UNZ_CRCERROR;
1510 TRYFREE(pfile_in_zip_read_info->read_buffer); 1510 }
1511 pfile_in_zip_read_info->read_buffer = NULL; 1511
1512 if (pfile_in_zip_read_info->stream_initialised) 1512
1513 inflateEnd(&pfile_in_zip_read_info->stream); 1513 TRYFREE(pfile_in_zip_read_info->read_buffer);
1514 1514 pfile_in_zip_read_info->read_buffer = NULL;
1515 pfile_in_zip_read_info->stream_initialised = 0; 1515 if (pfile_in_zip_read_info->stream_initialised)
1516 TRYFREE(pfile_in_zip_read_info); 1516 inflateEnd(&pfile_in_zip_read_info->stream);
1517 1517
1518 s->pfile_in_zip_read=NULL; 1518 pfile_in_zip_read_info->stream_initialised = 0;
1519 1519 TRYFREE(pfile_in_zip_read_info);
1520 return err; 1520
1521} 1521 s->pfile_in_zip_read=NULL;
1522 1522
1523 1523 return err;
1524/* 1524}
1525 Get the global comment string of the ZipFile, in the szComment buffer. 1525
1526 uSizeBuf is the size of the szComment buffer. 1526
1527 return the number of byte copied or an error code <0 1527/*
1528*/ 1528 Get the global comment string of the ZipFile, in the szComment buffer.
1529extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf) 1529 uSizeBuf is the size of the szComment buffer.
1530 unzFile file; 1530 return the number of byte copied or an error code <0
1531 char *szComment; 1531*/
1532 uLong uSizeBuf; 1532extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
1533{ 1533 unzFile file;
1534 int err=UNZ_OK; 1534 char *szComment;
1535 unz_s* s; 1535 uLong uSizeBuf;
1536 uLong uReadThis ; 1536{
1537 if (file==NULL) 1537 int err=UNZ_OK;
1538 return UNZ_PARAMERROR; 1538 unz_s* s;
1539 s=(unz_s*)file; 1539 uLong uReadThis ;
1540 1540 if (file==NULL)
1541 uReadThis = uSizeBuf; 1541 return UNZ_PARAMERROR;
1542 if (uReadThis>s->gi.size_comment) 1542 s=(unz_s*)file;
1543 uReadThis = s->gi.size_comment; 1543
1544 1544 uReadThis = uSizeBuf;
1545 if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) 1545 if (uReadThis>s->gi.size_comment)
1546 return UNZ_ERRNO; 1546 uReadThis = s->gi.size_comment;
1547 1547
1548 if (uReadThis>0) 1548 if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
1549 { 1549 return UNZ_ERRNO;
1550 *szComment='\0'; 1550
1551 if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) 1551 if (uReadThis>0)
1552 return UNZ_ERRNO; 1552 {
1553 } 1553 *szComment='\0';
1554 1554 if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
1555 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) 1555 return UNZ_ERRNO;
1556 *(szComment+s->gi.size_comment)='\0'; 1556 }
1557 return (int)uReadThis; 1557
1558} 1558 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1559 1559 *(szComment+s->gi.size_comment)='\0';
1560/* Additions by RX '2004 */ 1560 return (int)uReadThis;
1561extern uLong ZEXPORT unzGetOffset (file) 1561}
1562 unzFile file; 1562
1563{ 1563/* Additions by RX '2004 */
1564 unz_s* s; 1564extern uLong ZEXPORT unzGetOffset (file)
1565 1565 unzFile file;
1566 if (file==NULL) 1566{
1567 return UNZ_PARAMERROR; 1567 unz_s* s;
1568 s=(unz_s*)file; 1568
1569 if (!s->current_file_ok) 1569 if (file==NULL)
1570 return 0; 1570 return UNZ_PARAMERROR;
1571 if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) 1571 s=(unz_s*)file;
1572 if (s->num_file==s->gi.number_entry) 1572 if (!s->current_file_ok)
1573 return 0; 1573 return 0;
1574 return s->pos_in_central_dir; 1574 if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
1575} 1575 if (s->num_file==s->gi.number_entry)
1576 1576 return 0;
1577extern int ZEXPORT unzSetOffset (file, pos) 1577 return s->pos_in_central_dir;
1578 unzFile file; 1578}
1579 uLong pos; 1579
1580{ 1580extern int ZEXPORT unzSetOffset (file, pos)
1581 unz_s* s; 1581 unzFile file;
1582 int err; 1582 uLong pos;
1583 1583{
1584 if (file==NULL) 1584 unz_s* s;
1585 return UNZ_PARAMERROR; 1585 int err;
1586 s=(unz_s*)file; 1586
1587 1587 if (file==NULL)
1588 s->pos_in_central_dir = pos; 1588 return UNZ_PARAMERROR;
1589 s->num_file = s->gi.number_entry; /* hack */ 1589 s=(unz_s*)file;
1590 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, 1590
1591 &s->cur_file_info_internal, 1591 s->pos_in_central_dir = pos;
1592 NULL,0,NULL,0,NULL,0); 1592 s->num_file = s->gi.number_entry; /* hack */
1593 s->current_file_ok = (err == UNZ_OK); 1593 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1594 return err; 1594 &s->cur_file_info_internal,
1595} 1595 NULL,0,NULL,0,NULL,0);
1596 s->current_file_ok = (err == UNZ_OK);
1597 return err;
1598}
diff --git a/contrib/minizip/unzip.h b/contrib/minizip/unzip.h
index 0c7c6f1..c3206a0 100644
--- a/contrib/minizip/unzip.h
+++ b/contrib/minizip/unzip.h
@@ -1,352 +1,354 @@
1/* unzip.h -- IO for uncompress .zip files using zlib 1/* unzip.h -- IO for uncompress .zip files using zlib
2 Version 1.01, May 8th, 2004 2 Version 1.01e, February 12th, 2005
3 3
4 Copyright (C) 1998-2004 Gilles Vollant 4 Copyright (C) 1998-2005 Gilles Vollant
5 5
6 This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g 6 This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
7 WinZip, InfoZip tools and compatible. 7 WinZip, InfoZip tools and compatible.
8 Encryption and multi volume ZipFile (span) are not supported. 8
9 Old compressions used by old PKZip 1.x are not supported 9 Multi volume ZipFile (span) are not supported.
10 10 Encryption compatible with pkzip 2.04g only supported
11 11 Old compressions used by old PKZip 1.x are not supported
12 I WAIT FEEDBACK at mail info@winimage.com 12
13 Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution 13
14 14 I WAIT FEEDBACK at mail info@winimage.com
15 Condition of use and distribution are the same than zlib : 15 Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
16 16
17 This software is provided 'as-is', without any express or implied 17 Condition of use and distribution are the same than zlib :
18 warranty. In no event will the authors be held liable for any damages 18
19 arising from the use of this software. 19 This software is provided 'as-is', without any express or implied
20 20 warranty. In no event will the authors be held liable for any damages
21 Permission is granted to anyone to use this software for any purpose, 21 arising from the use of this software.
22 including commercial applications, and to alter it and redistribute it 22
23 freely, subject to the following restrictions: 23 Permission is granted to anyone to use this software for any purpose,
24 24 including commercial applications, and to alter it and redistribute it
25 1. The origin of this software must not be misrepresented; you must not 25 freely, subject to the following restrictions:
26 claim that you wrote the original software. If you use this software 26
27 in a product, an acknowledgment in the product documentation would be 27 1. The origin of this software must not be misrepresented; you must not
28 appreciated but is not required. 28 claim that you wrote the original software. If you use this software
29 2. Altered source versions must be plainly marked as such, and must not be 29 in a product, an acknowledgment in the product documentation would be
30 misrepresented as being the original software. 30 appreciated but is not required.
31 3. This notice may not be removed or altered from any source distribution. 31 2. Altered source versions must be plainly marked as such, and must not be
32 32 misrepresented as being the original software.
33 33 3. This notice may not be removed or altered from any source distribution.
34*/ 34
35 35
36/* for more info about .ZIP format, see 36*/
37 http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip 37
38 http://www.info-zip.org/pub/infozip/doc/ 38/* for more info about .ZIP format, see
39 PkWare has also a specification at : 39 http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip
40 ftp://ftp.pkware.com/probdesc.zip 40 http://www.info-zip.org/pub/infozip/doc/
41*/ 41 PkWare has also a specification at :
42 42 ftp://ftp.pkware.com/probdesc.zip
43#ifndef _unz_H 43*/
44#define _unz_H 44
45 45#ifndef _unz_H
46#ifdef __cplusplus 46#define _unz_H
47extern "C" { 47
48#endif 48#ifdef __cplusplus
49 49extern "C" {
50#ifndef _ZLIB_H 50#endif
51#include "zlib.h" 51
52#endif 52#ifndef _ZLIB_H
53 53#include "zlib.h"
54#ifndef _ZLIBIOAPI_H 54#endif
55#include "ioapi.h" 55
56#endif 56#ifndef _ZLIBIOAPI_H
57 57#include "ioapi.h"
58#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) 58#endif
59/* like the STRICT of WIN32, we define a pointer that cannot be converted 59
60 from (void*) without cast */ 60#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
61typedef struct TagunzFile__ { int unused; } unzFile__; 61/* like the STRICT of WIN32, we define a pointer that cannot be converted
62typedef unzFile__ *unzFile; 62 from (void*) without cast */
63#else 63typedef struct TagunzFile__ { int unused; } unzFile__;
64typedef voidp unzFile; 64typedef unzFile__ *unzFile;
65#endif 65#else
66 66typedef voidp unzFile;
67 67#endif
68#define UNZ_OK (0) 68
69#define UNZ_END_OF_LIST_OF_FILE (-100) 69
70#define UNZ_ERRNO (Z_ERRNO) 70#define UNZ_OK (0)
71#define UNZ_EOF (0) 71#define UNZ_END_OF_LIST_OF_FILE (-100)
72#define UNZ_PARAMERROR (-102) 72#define UNZ_ERRNO (Z_ERRNO)
73#define UNZ_BADZIPFILE (-103) 73#define UNZ_EOF (0)
74#define UNZ_INTERNALERROR (-104) 74#define UNZ_PARAMERROR (-102)
75#define UNZ_CRCERROR (-105) 75#define UNZ_BADZIPFILE (-103)
76 76#define UNZ_INTERNALERROR (-104)
77/* tm_unz contain date/time info */ 77#define UNZ_CRCERROR (-105)
78typedef struct tm_unz_s 78
79{ 79/* tm_unz contain date/time info */
80 uInt tm_sec; /* seconds after the minute - [0,59] */ 80typedef struct tm_unz_s
81 uInt tm_min; /* minutes after the hour - [0,59] */ 81{
82 uInt tm_hour; /* hours since midnight - [0,23] */ 82 uInt tm_sec; /* seconds after the minute - [0,59] */
83 uInt tm_mday; /* day of the month - [1,31] */ 83 uInt tm_min; /* minutes after the hour - [0,59] */
84 uInt tm_mon; /* months since January - [0,11] */ 84 uInt tm_hour; /* hours since midnight - [0,23] */
85 uInt tm_year; /* years - [1980..2044] */ 85 uInt tm_mday; /* day of the month - [1,31] */
86} tm_unz; 86 uInt tm_mon; /* months since January - [0,11] */
87 87 uInt tm_year; /* years - [1980..2044] */
88/* unz_global_info structure contain global data about the ZIPfile 88} tm_unz;
89 These data comes from the end of central dir */ 89
90typedef struct unz_global_info_s 90/* unz_global_info structure contain global data about the ZIPfile
91{ 91 These data comes from the end of central dir */
92 uLong number_entry; /* total number of entries in 92typedef struct unz_global_info_s
93 the central dir on this disk */ 93{
94 uLong size_comment; /* size of the global comment of the zipfile */ 94 uLong number_entry; /* total number of entries in
95} unz_global_info; 95 the central dir on this disk */
96 96 uLong size_comment; /* size of the global comment of the zipfile */
97 97} unz_global_info;
98/* unz_file_info contain information about a file in the zipfile */ 98
99typedef struct unz_file_info_s 99
100{ 100/* unz_file_info contain information about a file in the zipfile */
101 uLong version; /* version made by 2 bytes */ 101typedef struct unz_file_info_s
102 uLong version_needed; /* version needed to extract 2 bytes */ 102{
103 uLong flag; /* general purpose bit flag 2 bytes */ 103 uLong version; /* version made by 2 bytes */
104 uLong compression_method; /* compression method 2 bytes */ 104 uLong version_needed; /* version needed to extract 2 bytes */
105 uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ 105 uLong flag; /* general purpose bit flag 2 bytes */
106 uLong crc; /* crc-32 4 bytes */ 106 uLong compression_method; /* compression method 2 bytes */
107 uLong compressed_size; /* compressed size 4 bytes */ 107 uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
108 uLong uncompressed_size; /* uncompressed size 4 bytes */ 108 uLong crc; /* crc-32 4 bytes */
109 uLong size_filename; /* filename length 2 bytes */ 109 uLong compressed_size; /* compressed size 4 bytes */
110 uLong size_file_extra; /* extra field length 2 bytes */ 110 uLong uncompressed_size; /* uncompressed size 4 bytes */
111 uLong size_file_comment; /* file comment length 2 bytes */ 111 uLong size_filename; /* filename length 2 bytes */
112 112 uLong size_file_extra; /* extra field length 2 bytes */
113 uLong disk_num_start; /* disk number start 2 bytes */ 113 uLong size_file_comment; /* file comment length 2 bytes */
114 uLong internal_fa; /* internal file attributes 2 bytes */ 114
115 uLong external_fa; /* external file attributes 4 bytes */ 115 uLong disk_num_start; /* disk number start 2 bytes */
116 116 uLong internal_fa; /* internal file attributes 2 bytes */
117 tm_unz tmu_date; 117 uLong external_fa; /* external file attributes 4 bytes */
118} unz_file_info; 118
119 119 tm_unz tmu_date;
120extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, 120} unz_file_info;
121 const char* fileName2, 121
122 int iCaseSensitivity)); 122extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
123/* 123 const char* fileName2,
124 Compare two filename (fileName1,fileName2). 124 int iCaseSensitivity));
125 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) 125/*
126 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi 126 Compare two filename (fileName1,fileName2).
127 or strcasecmp) 127 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
128 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system 128 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
129 (like 1 on Unix, 2 on Windows) 129 or strcasecmp)
130*/ 130 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
131 131 (like 1 on Unix, 2 on Windows)
132 132*/
133extern unzFile ZEXPORT unzOpen OF((const char *path)); 133
134/* 134
135 Open a Zip file. path contain the full pathname (by example, 135extern unzFile ZEXPORT unzOpen OF((const char *path));
136 on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer 136/*
137 "zlib/zlib113.zip". 137 Open a Zip file. path contain the full pathname (by example,
138 If the zipfile cannot be opened (file don't exist or in not valid), the 138 on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
139 return value is NULL. 139 "zlib/zlib113.zip".
140 Else, the return value is a unzFile Handle, usable with other function 140 If the zipfile cannot be opened (file don't exist or in not valid), the
141 of this unzip package. 141 return value is NULL.
142*/ 142 Else, the return value is a unzFile Handle, usable with other function
143 143 of this unzip package.
144extern unzFile ZEXPORT unzOpen2 OF((const char *path, 144*/
145 zlib_filefunc_def* pzlib_filefunc_def)); 145
146/* 146extern unzFile ZEXPORT unzOpen2 OF((const char *path,
147 Open a Zip file, like unzOpen, but provide a set of file low level API 147 zlib_filefunc_def* pzlib_filefunc_def));
148 for read/write the zip file (see ioapi.h) 148/*
149*/ 149 Open a Zip file, like unzOpen, but provide a set of file low level API
150 150 for read/write the zip file (see ioapi.h)
151extern int ZEXPORT unzClose OF((unzFile file)); 151*/
152/* 152
153 Close a ZipFile opened with unzipOpen. 153extern int ZEXPORT unzClose OF((unzFile file));
154 If there is files inside the .Zip opened with unzOpenCurrentFile (see later), 154/*
155 these files MUST be closed with unzipCloseCurrentFile before call unzipClose. 155 Close a ZipFile opened with unzipOpen.
156 return UNZ_OK if there is no problem. */ 156 If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
157 157 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
158extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, 158 return UNZ_OK if there is no problem. */
159 unz_global_info *pglobal_info)); 159
160/* 160extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
161 Write info about the ZipFile in the *pglobal_info structure. 161 unz_global_info *pglobal_info));
162 No preparation of the structure is needed 162/*
163 return UNZ_OK if there is no problem. */ 163 Write info about the ZipFile in the *pglobal_info structure.
164 164 No preparation of the structure is needed
165 165 return UNZ_OK if there is no problem. */
166extern int ZEXPORT unzGetGlobalComment OF((unzFile file, 166
167 char *szComment, 167
168 uLong uSizeBuf)); 168extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
169/* 169 char *szComment,
170 Get the global comment string of the ZipFile, in the szComment buffer. 170 uLong uSizeBuf));
171 uSizeBuf is the size of the szComment buffer. 171/*
172 return the number of byte copied or an error code <0 172 Get the global comment string of the ZipFile, in the szComment buffer.
173*/ 173 uSizeBuf is the size of the szComment buffer.
174 174 return the number of byte copied or an error code <0
175 175*/
176/***************************************************************************/ 176
177/* Unzip package allow you browse the directory of the zipfile */ 177
178 178/***************************************************************************/
179extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); 179/* Unzip package allow you browse the directory of the zipfile */
180/* 180
181 Set the current file of the zipfile to the first file. 181extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
182 return UNZ_OK if there is no problem 182/*
183*/ 183 Set the current file of the zipfile to the first file.
184 184 return UNZ_OK if there is no problem
185extern int ZEXPORT unzGoToNextFile OF((unzFile file)); 185*/
186/* 186
187 Set the current file of the zipfile to the next file. 187extern int ZEXPORT unzGoToNextFile OF((unzFile file));
188 return UNZ_OK if there is no problem 188/*
189 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. 189 Set the current file of the zipfile to the next file.
190*/ 190 return UNZ_OK if there is no problem
191 191 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
192extern int ZEXPORT unzLocateFile OF((unzFile file, 192*/
193 const char *szFileName, 193
194 int iCaseSensitivity)); 194extern int ZEXPORT unzLocateFile OF((unzFile file,
195/* 195 const char *szFileName,
196 Try locate the file szFileName in the zipfile. 196 int iCaseSensitivity));
197 For the iCaseSensitivity signification, see unzStringFileNameCompare 197/*
198 198 Try locate the file szFileName in the zipfile.
199 return value : 199 For the iCaseSensitivity signification, see unzStringFileNameCompare
200 UNZ_OK if the file is found. It becomes the current file. 200
201 UNZ_END_OF_LIST_OF_FILE if the file is not found 201 return value :
202*/ 202 UNZ_OK if the file is found. It becomes the current file.
203 203 UNZ_END_OF_LIST_OF_FILE if the file is not found
204 204*/
205/* ****************************************** */ 205
206/* Ryan supplied functions */ 206
207/* unz_file_info contain information about a file in the zipfile */ 207/* ****************************************** */
208typedef struct unz_file_pos_s 208/* Ryan supplied functions */
209{ 209/* unz_file_info contain information about a file in the zipfile */
210 uLong pos_in_zip_directory; /* offset in zip file directory */ 210typedef struct unz_file_pos_s
211 uLong num_of_file; /* # of file */ 211{
212} unz_file_pos; 212 uLong pos_in_zip_directory; /* offset in zip file directory */
213 213 uLong num_of_file; /* # of file */
214extern int ZEXPORT unzGetFilePos( 214} unz_file_pos;
215 unzFile file, 215
216 unz_file_pos* file_pos); 216extern int ZEXPORT unzGetFilePos(
217 217 unzFile file,
218extern int ZEXPORT unzGoToFilePos( 218 unz_file_pos* file_pos);
219 unzFile file, 219
220 unz_file_pos* file_pos); 220extern int ZEXPORT unzGoToFilePos(
221 221 unzFile file,
222/* ****************************************** */ 222 unz_file_pos* file_pos);
223 223
224extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, 224/* ****************************************** */
225 unz_file_info *pfile_info, 225
226 char *szFileName, 226extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
227 uLong fileNameBufferSize, 227 unz_file_info *pfile_info,
228 void *extraField, 228 char *szFileName,
229 uLong extraFieldBufferSize, 229 uLong fileNameBufferSize,
230 char *szComment, 230 void *extraField,
231 uLong commentBufferSize)); 231 uLong extraFieldBufferSize,
232/* 232 char *szComment,
233 Get Info about the current file 233 uLong commentBufferSize));
234 if pfile_info!=NULL, the *pfile_info structure will contain somes info about 234/*
235 the current file 235 Get Info about the current file
236 if szFileName!=NULL, the filemane string will be copied in szFileName 236 if pfile_info!=NULL, the *pfile_info structure will contain somes info about
237 (fileNameBufferSize is the size of the buffer) 237 the current file
238 if extraField!=NULL, the extra field information will be copied in extraField 238 if szFileName!=NULL, the filemane string will be copied in szFileName
239 (extraFieldBufferSize is the size of the buffer). 239 (fileNameBufferSize is the size of the buffer)
240 This is the Central-header version of the extra field 240 if extraField!=NULL, the extra field information will be copied in extraField
241 if szComment!=NULL, the comment string of the file will be copied in szComment 241 (extraFieldBufferSize is the size of the buffer).
242 (commentBufferSize is the size of the buffer) 242 This is the Central-header version of the extra field
243*/ 243 if szComment!=NULL, the comment string of the file will be copied in szComment
244 244 (commentBufferSize is the size of the buffer)
245/***************************************************************************/ 245*/
246/* for reading the content of the current zipfile, you can open it, read data 246
247 from it, and close it (you can close it before reading all the file) 247/***************************************************************************/
248 */ 248/* for reading the content of the current zipfile, you can open it, read data
249 249 from it, and close it (you can close it before reading all the file)
250extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); 250 */
251/* 251
252 Open for reading data the current file in the zipfile. 252extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
253 If there is no error, the return value is UNZ_OK. 253/*
254*/ 254 Open for reading data the current file in the zipfile.
255 255 If there is no error, the return value is UNZ_OK.
256extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, 256*/
257 const char* password)); 257
258/* 258extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
259 Open for reading data the current file in the zipfile. 259 const char* password));
260 password is a crypting password 260/*
261 If there is no error, the return value is UNZ_OK. 261 Open for reading data the current file in the zipfile.
262*/ 262 password is a crypting password
263 263 If there is no error, the return value is UNZ_OK.
264extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, 264*/
265 int* method, 265
266 int* level, 266extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
267 int raw)); 267 int* method,
268/* 268 int* level,
269 Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) 269 int raw));
270 if raw==1 270/*
271 *method will receive method of compression, *level will receive level of 271 Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
272 compression 272 if raw==1
273 note : you can set level parameter as NULL (if you did not want known level, 273 *method will receive method of compression, *level will receive level of
274 but you CANNOT set method parameter as NULL 274 compression
275*/ 275 note : you can set level parameter as NULL (if you did not want known level,
276 276 but you CANNOT set method parameter as NULL
277extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, 277*/
278 int* method, 278
279 int* level, 279extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
280 int raw, 280 int* method,
281 const char* password)); 281 int* level,
282/* 282 int raw,
283 Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) 283 const char* password));
284 if raw==1 284/*
285 *method will receive method of compression, *level will receive level of 285 Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
286 compression 286 if raw==1
287 note : you can set level parameter as NULL (if you did not want known level, 287 *method will receive method of compression, *level will receive level of
288 but you CANNOT set method parameter as NULL 288 compression
289*/ 289 note : you can set level parameter as NULL (if you did not want known level,
290 290 but you CANNOT set method parameter as NULL
291 291*/
292extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); 292
293/* 293
294 Close the file in zip opened with unzOpenCurrentFile 294extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
295 Return UNZ_CRCERROR if all the file was read but the CRC is not good 295/*
296*/ 296 Close the file in zip opened with unzOpenCurrentFile
297 297 Return UNZ_CRCERROR if all the file was read but the CRC is not good
298extern int ZEXPORT unzReadCurrentFile OF((unzFile file, 298*/
299 voidp buf, 299
300 unsigned len)); 300extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
301/* 301 voidp buf,
302 Read bytes from the current file (opened by unzOpenCurrentFile) 302 unsigned len));
303 buf contain buffer where data must be copied 303/*
304 len the size of buf. 304 Read bytes from the current file (opened by unzOpenCurrentFile)
305 305 buf contain buffer where data must be copied
306 return the number of byte copied if somes bytes are copied 306 len the size of buf.
307 return 0 if the end of file was reached 307
308 return <0 with error code if there is an error 308 return the number of byte copied if somes bytes are copied
309 (UNZ_ERRNO for IO error, or zLib error for uncompress error) 309 return 0 if the end of file was reached
310*/ 310 return <0 with error code if there is an error
311 311 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
312extern z_off_t ZEXPORT unztell OF((unzFile file)); 312*/
313/* 313
314 Give the current position in uncompressed data 314extern z_off_t ZEXPORT unztell OF((unzFile file));
315*/ 315/*
316 316 Give the current position in uncompressed data
317extern int ZEXPORT unzeof OF((unzFile file)); 317*/
318/* 318
319 return 1 if the end of file was reached, 0 elsewhere 319extern int ZEXPORT unzeof OF((unzFile file));
320*/ 320/*
321 321 return 1 if the end of file was reached, 0 elsewhere
322extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, 322*/
323 voidp buf, 323
324 unsigned len)); 324extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
325/* 325 voidp buf,
326 Read extra field from the current file (opened by unzOpenCurrentFile) 326 unsigned len));
327 This is the local-header version of the extra field (sometimes, there is 327/*
328 more info in the local-header version than in the central-header) 328 Read extra field from the current file (opened by unzOpenCurrentFile)
329 329 This is the local-header version of the extra field (sometimes, there is
330 if buf==NULL, it return the size of the local extra field 330 more info in the local-header version than in the central-header)
331 331
332 if buf!=NULL, len is the size of the buffer, the extra header is copied in 332 if buf==NULL, it return the size of the local extra field
333 buf. 333
334 the return value is the number of bytes copied in buf, or (if <0) 334 if buf!=NULL, len is the size of the buffer, the extra header is copied in
335 the error code 335 buf.
336*/ 336 the return value is the number of bytes copied in buf, or (if <0)
337 337 the error code
338/***************************************************************************/ 338*/
339 339
340/* Get the current file offset */ 340/***************************************************************************/
341extern uLong ZEXPORT unzGetOffset (unzFile file); 341
342 342/* Get the current file offset */
343/* Set the current file offset */ 343extern uLong ZEXPORT unzGetOffset (unzFile file);
344extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); 344
345 345/* Set the current file offset */
346 346extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
347 347
348#ifdef __cplusplus 348
349} 349
350#endif 350#ifdef __cplusplus
351 351}
352#endif /* _unz_H */ 352#endif
353
354#endif /* _unz_H */
diff --git a/contrib/minizip/zip.c b/contrib/minizip/zip.c
index 2ccd7fd..400e2ba 100644
--- a/contrib/minizip/zip.c
+++ b/contrib/minizip/zip.c
@@ -1,1188 +1,1219 @@
1/* zip.c -- IO on .zip files using zlib 1/* zip.c -- IO on .zip files using zlib
2 Version 1.01, May 8th, 2004 2 Version 1.01e, February 12th, 2005
3 3
4 Copyright (C) 1998-2004 Gilles Vollant 4 27 Dec 2004 Rolf Kalbermatter
5 5 Modification to zipOpen2 to support globalComment retrieval.
6 Read zip.h for more info 6
7*/ 7 Copyright (C) 1998-2005 Gilles Vollant
8 8
9 9 Read zip.h for more info
10#include <stdio.h> 10*/
11#include <stdlib.h> 11
12#include <string.h> 12
13#include <time.h> 13#include <stdio.h>
14#include "zlib.h" 14#include <stdlib.h>
15#include "zip.h" 15#include <string.h>
16 16#include <time.h>
17#ifdef STDC 17#include "zlib.h"
18# include <stddef.h> 18#include "zip.h"
19# include <string.h> 19
20# include <stdlib.h> 20#ifdef STDC
21#endif 21# include <stddef.h>
22#ifdef NO_ERRNO_H 22# include <string.h>
23 extern int errno; 23# include <stdlib.h>
24#else 24#endif
25# include <errno.h> 25#ifdef NO_ERRNO_H
26#endif 26 extern int errno;
27 27#else
28 28# include <errno.h>
29#ifndef local 29#endif
30# define local static 30
31#endif 31
32/* compile with -Dlocal if your debugger can't find static symbols */ 32#ifndef local
33 33# define local static
34#ifndef VERSIONMADEBY 34#endif
35# define VERSIONMADEBY (0x0) /* platform depedent */ 35/* compile with -Dlocal if your debugger can't find static symbols */
36#endif 36
37 37#ifndef VERSIONMADEBY
38#ifndef Z_BUFSIZE 38# define VERSIONMADEBY (0x0) /* platform depedent */
39#define Z_BUFSIZE (16384) 39#endif
40#endif 40
41 41#ifndef Z_BUFSIZE
42#ifndef Z_MAXFILENAMEINZIP 42#define Z_BUFSIZE (16384)
43#define Z_MAXFILENAMEINZIP (256) 43#endif
44#endif 44
45 45#ifndef Z_MAXFILENAMEINZIP
46#ifndef ALLOC 46#define Z_MAXFILENAMEINZIP (256)
47# define ALLOC(size) (malloc(size)) 47#endif
48#endif 48
49#ifndef TRYFREE 49#ifndef ALLOC
50# define TRYFREE(p) {if (p) free(p);} 50# define ALLOC(size) (malloc(size))
51#endif 51#endif
52 52#ifndef TRYFREE
53/* 53# define TRYFREE(p) {if (p) free(p);}
54#define SIZECENTRALDIRITEM (0x2e) 54#endif
55#define SIZEZIPLOCALHEADER (0x1e) 55
56*/ 56/*
57 57#define SIZECENTRALDIRITEM (0x2e)
58/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ 58#define SIZEZIPLOCALHEADER (0x1e)
59 59*/
60#ifndef SEEK_CUR 60
61#define SEEK_CUR 1 61/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
62#endif 62
63 63#ifndef SEEK_CUR
64#ifndef SEEK_END 64#define SEEK_CUR 1
65#define SEEK_END 2 65#endif
66#endif 66
67 67#ifndef SEEK_END
68#ifndef SEEK_SET 68#define SEEK_END 2
69#define SEEK_SET 0 69#endif
70#endif 70
71 71#ifndef SEEK_SET
72#ifndef DEF_MEM_LEVEL 72#define SEEK_SET 0
73#if MAX_MEM_LEVEL >= 8 73#endif
74# define DEF_MEM_LEVEL 8 74
75#else 75#ifndef DEF_MEM_LEVEL
76# define DEF_MEM_LEVEL MAX_MEM_LEVEL 76#if MAX_MEM_LEVEL >= 8
77#endif 77# define DEF_MEM_LEVEL 8
78#endif 78#else
79const char zip_copyright[] = 79# define DEF_MEM_LEVEL MAX_MEM_LEVEL
80 " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; 80#endif
81 81#endif
82 82const char zip_copyright[] =
83#define SIZEDATA_INDATABLOCK (4096-(4*4)) 83 " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
84 84
85#define LOCALHEADERMAGIC (0x04034b50) 85
86#define CENTRALHEADERMAGIC (0x02014b50) 86#define SIZEDATA_INDATABLOCK (4096-(4*4))
87#define ENDHEADERMAGIC (0x06054b50) 87
88 88#define LOCALHEADERMAGIC (0x04034b50)
89#define FLAG_LOCALHEADER_OFFSET (0x06) 89#define CENTRALHEADERMAGIC (0x02014b50)
90#define CRC_LOCALHEADER_OFFSET (0x0e) 90#define ENDHEADERMAGIC (0x06054b50)
91 91
92#define SIZECENTRALHEADER (0x2e) /* 46 */ 92#define FLAG_LOCALHEADER_OFFSET (0x06)
93 93#define CRC_LOCALHEADER_OFFSET (0x0e)
94typedef struct linkedlist_datablock_internal_s 94
95{ 95#define SIZECENTRALHEADER (0x2e) /* 46 */
96 struct linkedlist_datablock_internal_s* next_datablock; 96
97 uLong avail_in_this_block; 97typedef struct linkedlist_datablock_internal_s
98 uLong filled_in_this_block; 98{
99 uLong unused; /* for future use and alignement */ 99 struct linkedlist_datablock_internal_s* next_datablock;
100 unsigned char data[SIZEDATA_INDATABLOCK]; 100 uLong avail_in_this_block;
101} linkedlist_datablock_internal; 101 uLong filled_in_this_block;
102 102 uLong unused; /* for future use and alignement */
103typedef struct linkedlist_data_s 103 unsigned char data[SIZEDATA_INDATABLOCK];
104{ 104} linkedlist_datablock_internal;
105 linkedlist_datablock_internal* first_block; 105
106 linkedlist_datablock_internal* last_block; 106typedef struct linkedlist_data_s
107} linkedlist_data; 107{
108 108 linkedlist_datablock_internal* first_block;
109 109 linkedlist_datablock_internal* last_block;
110typedef struct 110} linkedlist_data;
111{ 111
112 z_stream stream; /* zLib stream structure for inflate */ 112
113 int stream_initialised; /* 1 is stream is initialised */ 113typedef struct
114 uInt pos_in_buffered_data; /* last written byte in buffered_data */ 114{
115 115 z_stream stream; /* zLib stream structure for inflate */
116 uLong pos_local_header; /* offset of the local header of the file 116 int stream_initialised; /* 1 is stream is initialised */
117 currenty writing */ 117 uInt pos_in_buffered_data; /* last written byte in buffered_data */
118 char* central_header; /* central header data for the current file */ 118
119 uLong size_centralheader; /* size of the central header for cur file */ 119 uLong pos_local_header; /* offset of the local header of the file
120 uLong flag; /* flag of the file currently writing */ 120 currenty writing */
121 121 char* central_header; /* central header data for the current file */
122 int method; /* compression method of file currenty wr.*/ 122 uLong size_centralheader; /* size of the central header for cur file */
123 int raw; /* 1 for directly writing raw data */ 123 uLong flag; /* flag of the file currently writing */
124 Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ 124
125 uLong dosDate; 125 int method; /* compression method of file currenty wr.*/
126 uLong crc32; 126 int raw; /* 1 for directly writing raw data */
127 int encrypt; 127 Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
128#ifndef NOCRYPT 128 uLong dosDate;
129 unsigned long keys[3]; /* keys defining the pseudo-random sequence */ 129 uLong crc32;
130 const unsigned long* pcrc_32_tab; 130 int encrypt;
131 int crypt_header_size; 131#ifndef NOCRYPT
132#endif 132 unsigned long keys[3]; /* keys defining the pseudo-random sequence */
133} curfile_info; 133 const unsigned long* pcrc_32_tab;
134 134 int crypt_header_size;
135typedef struct 135#endif
136{ 136} curfile_info;
137 zlib_filefunc_def z_filefunc; 137
138 voidpf filestream; /* io structore of the zipfile */ 138typedef struct
139 linkedlist_data central_dir;/* datablock with central dir in construction*/ 139{
140 int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ 140 zlib_filefunc_def z_filefunc;
141 curfile_info ci; /* info on the file curretly writing */ 141 voidpf filestream; /* io structore of the zipfile */
142 142 linkedlist_data central_dir;/* datablock with central dir in construction*/
143 uLong begin_pos; /* position of the beginning of the zipfile */ 143 int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
144 uLong add_position_when_writting_offset; 144 curfile_info ci; /* info on the file curretly writing */
145 uLong number_entry; 145
146} zip_internal; 146 uLong begin_pos; /* position of the beginning of the zipfile */
147 147 uLong add_position_when_writting_offset;
148 148 uLong number_entry;
149 149#ifndef NO_ADDFILEINEXISTINGZIP
150#ifndef NOCRYPT 150 char *globalcomment;
151#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED 151#endif
152#include "crypt.h" 152} zip_internal;
153#endif 153
154 154
155local linkedlist_datablock_internal* allocate_new_datablock() 155
156{ 156#ifndef NOCRYPT
157 linkedlist_datablock_internal* ldi; 157#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
158 ldi = (linkedlist_datablock_internal*) 158#include "crypt.h"
159 ALLOC(sizeof(linkedlist_datablock_internal)); 159#endif
160 if (ldi!=NULL) 160
161 { 161local linkedlist_datablock_internal* allocate_new_datablock()
162 ldi->next_datablock = NULL ; 162{
163 ldi->filled_in_this_block = 0 ; 163 linkedlist_datablock_internal* ldi;
164 ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; 164 ldi = (linkedlist_datablock_internal*)
165 } 165 ALLOC(sizeof(linkedlist_datablock_internal));
166 return ldi; 166 if (ldi!=NULL)
167} 167 {
168 168 ldi->next_datablock = NULL ;
169local void free_datablock(ldi) 169 ldi->filled_in_this_block = 0 ;
170 linkedlist_datablock_internal* ldi; 170 ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
171{ 171 }
172 while (ldi!=NULL) 172 return ldi;
173 { 173}
174 linkedlist_datablock_internal* ldinext = ldi->next_datablock; 174
175 TRYFREE(ldi); 175local void free_datablock(ldi)
176 ldi = ldinext; 176 linkedlist_datablock_internal* ldi;
177 } 177{
178} 178 while (ldi!=NULL)
179 179 {
180local void init_linkedlist(ll) 180 linkedlist_datablock_internal* ldinext = ldi->next_datablock;
181 linkedlist_data* ll; 181 TRYFREE(ldi);
182{ 182 ldi = ldinext;
183 ll->first_block = ll->last_block = NULL; 183 }
184} 184}
185 185
186local void free_linkedlist(ll) 186local void init_linkedlist(ll)
187 linkedlist_data* ll; 187 linkedlist_data* ll;
188{ 188{
189 free_datablock(ll->first_block); 189 ll->first_block = ll->last_block = NULL;
190 ll->first_block = ll->last_block = NULL; 190}
191} 191
192 192local void free_linkedlist(ll)
193 193 linkedlist_data* ll;
194local int add_data_in_datablock(ll,buf,len) 194{
195 linkedlist_data* ll; 195 free_datablock(ll->first_block);
196 const void* buf; 196 ll->first_block = ll->last_block = NULL;
197 uLong len; 197}
198{ 198
199 linkedlist_datablock_internal* ldi; 199
200 const unsigned char* from_copy; 200local int add_data_in_datablock(ll,buf,len)
201 201 linkedlist_data* ll;
202 if (ll==NULL) 202 const void* buf;
203 return ZIP_INTERNALERROR; 203 uLong len;
204 204{
205 if (ll->last_block == NULL) 205 linkedlist_datablock_internal* ldi;
206 { 206 const unsigned char* from_copy;
207 ll->first_block = ll->last_block = allocate_new_datablock(); 207
208 if (ll->first_block == NULL) 208 if (ll==NULL)
209 return ZIP_INTERNALERROR; 209 return ZIP_INTERNALERROR;
210 } 210
211 211 if (ll->last_block == NULL)
212 ldi = ll->last_block; 212 {
213 from_copy = (unsigned char*)buf; 213 ll->first_block = ll->last_block = allocate_new_datablock();
214 214 if (ll->first_block == NULL)
215 while (len>0) 215 return ZIP_INTERNALERROR;
216 { 216 }
217 uInt copy_this; 217
218 uInt i; 218 ldi = ll->last_block;
219 unsigned char* to_copy; 219 from_copy = (unsigned char*)buf;
220 220
221 if (ldi->avail_in_this_block==0) 221 while (len>0)
222 { 222 {
223 ldi->next_datablock = allocate_new_datablock(); 223 uInt copy_this;
224 if (ldi->next_datablock == NULL) 224 uInt i;
225 return ZIP_INTERNALERROR; 225 unsigned char* to_copy;
226 ldi = ldi->next_datablock ; 226
227 ll->last_block = ldi; 227 if (ldi->avail_in_this_block==0)
228 } 228 {
229 229 ldi->next_datablock = allocate_new_datablock();
230 if (ldi->avail_in_this_block < len) 230 if (ldi->next_datablock == NULL)
231 copy_this = (uInt)ldi->avail_in_this_block; 231 return ZIP_INTERNALERROR;
232 else 232 ldi = ldi->next_datablock ;
233 copy_this = (uInt)len; 233 ll->last_block = ldi;
234 234 }
235 to_copy = &(ldi->data[ldi->filled_in_this_block]); 235
236 236 if (ldi->avail_in_this_block < len)
237 for (i=0;i<copy_this;i++) 237 copy_this = (uInt)ldi->avail_in_this_block;
238 *(to_copy+i)=*(from_copy+i); 238 else
239 239 copy_this = (uInt)len;
240 ldi->filled_in_this_block += copy_this; 240
241 ldi->avail_in_this_block -= copy_this; 241 to_copy = &(ldi->data[ldi->filled_in_this_block]);
242 from_copy += copy_this ; 242
243 len -= copy_this; 243 for (i=0;i<copy_this;i++)
244 } 244 *(to_copy+i)=*(from_copy+i);
245 return ZIP_OK; 245
246} 246 ldi->filled_in_this_block += copy_this;
247 247 ldi->avail_in_this_block -= copy_this;
248 248 from_copy += copy_this ;
249 249 len -= copy_this;
250/****************************************************************************/ 250 }
251 251 return ZIP_OK;
252#ifndef NO_ADDFILEINEXISTINGZIP 252}
253/* =========================================================================== 253
254 Inputs a long in LSB order to the given file 254
255 nbByte == 1, 2 or 4 (byte, short or long) 255
256*/ 256/****************************************************************************/
257 257
258local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def, 258#ifndef NO_ADDFILEINEXISTINGZIP
259 voidpf filestream, uLong x, int nbByte)); 259/* ===========================================================================
260local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte) 260 Inputs a long in LSB order to the given file
261 const zlib_filefunc_def* pzlib_filefunc_def; 261 nbByte == 1, 2 or 4 (byte, short or long)
262 voidpf filestream; 262*/
263 uLong x; 263
264 int nbByte; 264local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def,
265{ 265 voidpf filestream, uLong x, int nbByte));
266 unsigned char buf[4]; 266local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte)
267 int n; 267 const zlib_filefunc_def* pzlib_filefunc_def;
268 for (n = 0; n < nbByte; n++) 268 voidpf filestream;
269 { 269 uLong x;
270 buf[n] = (unsigned char)(x & 0xff); 270 int nbByte;
271 x >>= 8; 271{
272 } 272 unsigned char buf[4];
273 if (x != 0) 273 int n;
274 { /* data overflow - hack for ZIP64 (X Roche) */ 274 for (n = 0; n < nbByte; n++)
275 for (n = 0; n < nbByte; n++) 275 {
276 { 276 buf[n] = (unsigned char)(x & 0xff);
277 buf[n] = 0xff; 277 x >>= 8;
278 } 278 }
279 } 279 if (x != 0)
280 280 { /* data overflow - hack for ZIP64 (X Roche) */
281 if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) 281 for (n = 0; n < nbByte; n++)
282 return ZIP_ERRNO; 282 {
283 else 283 buf[n] = 0xff;
284 return ZIP_OK; 284 }
285} 285 }
286 286
287local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte)); 287 if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
288local void ziplocal_putValue_inmemory (dest, x, nbByte) 288 return ZIP_ERRNO;
289 void* dest; 289 else
290 uLong x; 290 return ZIP_OK;
291 int nbByte; 291}
292{ 292
293 unsigned char* buf=(unsigned char*)dest; 293local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte));
294 int n; 294local void ziplocal_putValue_inmemory (dest, x, nbByte)
295 for (n = 0; n < nbByte; n++) { 295 void* dest;
296 buf[n] = (unsigned char)(x & 0xff); 296 uLong x;
297 x >>= 8; 297 int nbByte;
298 } 298{
299 299 unsigned char* buf=(unsigned char*)dest;
300 if (x != 0) 300 int n;
301 { /* data overflow - hack for ZIP64 */ 301 for (n = 0; n < nbByte; n++) {
302 for (n = 0; n < nbByte; n++) 302 buf[n] = (unsigned char)(x & 0xff);
303 { 303 x >>= 8;
304 buf[n] = 0xff; 304 }
305 } 305
306 } 306 if (x != 0)
307} 307 { /* data overflow - hack for ZIP64 */
308 308 for (n = 0; n < nbByte; n++)
309/****************************************************************************/ 309 {
310 310 buf[n] = 0xff;
311 311 }
312local uLong ziplocal_TmzDateToDosDate(ptm,dosDate) 312 }
313 const tm_zip* ptm; 313}
314 uLong dosDate; 314
315{ 315/****************************************************************************/
316 uLong year = (uLong)ptm->tm_year; 316
317 if (year>1980) 317
318 year-=1980; 318local uLong ziplocal_TmzDateToDosDate(ptm,dosDate)
319 else if (year>80) 319 const tm_zip* ptm;
320 year-=80; 320 uLong dosDate;
321 return 321{
322 (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | 322 uLong year = (uLong)ptm->tm_year;
323 ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); 323 if (year>1980)
324} 324 year-=1980;
325 325 else if (year>80)
326 326 year-=80;
327/****************************************************************************/ 327 return
328 328 (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
329local int ziplocal_getByte OF(( 329 ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
330 const zlib_filefunc_def* pzlib_filefunc_def, 330}
331 voidpf filestream, 331
332 int *pi)); 332
333 333/****************************************************************************/
334local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi) 334
335 const zlib_filefunc_def* pzlib_filefunc_def; 335local int ziplocal_getByte OF((
336 voidpf filestream; 336 const zlib_filefunc_def* pzlib_filefunc_def,
337 int *pi; 337 voidpf filestream,
338{ 338 int *pi));
339 unsigned char c; 339
340 int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1); 340local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi)
341 if (err==1) 341 const zlib_filefunc_def* pzlib_filefunc_def;
342 { 342 voidpf filestream;
343 *pi = (int)c; 343 int *pi;
344 return ZIP_OK; 344{
345 } 345 unsigned char c;
346 else 346 int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
347 { 347 if (err==1)
348 if (ZERROR(*pzlib_filefunc_def,filestream)) 348 {
349 return ZIP_ERRNO; 349 *pi = (int)c;
350 else 350 return ZIP_OK;
351 return ZIP_EOF; 351 }
352 } 352 else
353} 353 {
354 354 if (ZERROR(*pzlib_filefunc_def,filestream))
355 355 return ZIP_ERRNO;
356/* =========================================================================== 356 else
357 Reads a long in LSB order from the given gz_stream. Sets 357 return ZIP_EOF;
358*/ 358 }
359local int ziplocal_getShort OF(( 359}
360 const zlib_filefunc_def* pzlib_filefunc_def, 360
361 voidpf filestream, 361
362 uLong *pX)); 362/* ===========================================================================
363 363 Reads a long in LSB order from the given gz_stream. Sets
364local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX) 364*/
365 const zlib_filefunc_def* pzlib_filefunc_def; 365local int ziplocal_getShort OF((
366 voidpf filestream; 366 const zlib_filefunc_def* pzlib_filefunc_def,
367 uLong *pX; 367 voidpf filestream,
368{ 368 uLong *pX));
369 uLong x ; 369
370 int i; 370local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX)
371 int err; 371 const zlib_filefunc_def* pzlib_filefunc_def;
372 372 voidpf filestream;
373 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); 373 uLong *pX;
374 x = (uLong)i; 374{
375 375 uLong x ;
376 if (err==ZIP_OK) 376 int i;
377 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); 377 int err;
378 x += ((uLong)i)<<8; 378
379 379 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
380 if (err==ZIP_OK) 380 x = (uLong)i;
381 *pX = x; 381
382 else 382 if (err==ZIP_OK)
383 *pX = 0; 383 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
384 return err; 384 x += ((uLong)i)<<8;
385} 385
386 386 if (err==ZIP_OK)
387local int ziplocal_getLong OF(( 387 *pX = x;
388 const zlib_filefunc_def* pzlib_filefunc_def, 388 else
389 voidpf filestream, 389 *pX = 0;
390 uLong *pX)); 390 return err;
391 391}
392local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX) 392
393 const zlib_filefunc_def* pzlib_filefunc_def; 393local int ziplocal_getLong OF((
394 voidpf filestream; 394 const zlib_filefunc_def* pzlib_filefunc_def,
395 uLong *pX; 395 voidpf filestream,
396{ 396 uLong *pX));
397 uLong x ; 397
398 int i; 398local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX)
399 int err; 399 const zlib_filefunc_def* pzlib_filefunc_def;
400 400 voidpf filestream;
401 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); 401 uLong *pX;
402 x = (uLong)i; 402{
403 403 uLong x ;
404 if (err==ZIP_OK) 404 int i;
405 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); 405 int err;
406 x += ((uLong)i)<<8; 406
407 407 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
408 if (err==ZIP_OK) 408 x = (uLong)i;
409 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); 409
410 x += ((uLong)i)<<16; 410 if (err==ZIP_OK)
411 411 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
412 if (err==ZIP_OK) 412 x += ((uLong)i)<<8;
413 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); 413
414 x += ((uLong)i)<<24; 414 if (err==ZIP_OK)
415 415 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
416 if (err==ZIP_OK) 416 x += ((uLong)i)<<16;
417 *pX = x; 417
418 else 418 if (err==ZIP_OK)
419 *pX = 0; 419 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
420 return err; 420 x += ((uLong)i)<<24;
421} 421
422 422 if (err==ZIP_OK)
423#ifndef BUFREADCOMMENT 423 *pX = x;
424#define BUFREADCOMMENT (0x400) 424 else
425#endif 425 *pX = 0;
426/* 426 return err;
427 Locate the Central directory of a zipfile (at the end, just before 427}
428 the global comment) 428
429*/ 429#ifndef BUFREADCOMMENT
430local uLong ziplocal_SearchCentralDir OF(( 430#define BUFREADCOMMENT (0x400)
431 const zlib_filefunc_def* pzlib_filefunc_def, 431#endif
432 voidpf filestream)); 432/*
433 433 Locate the Central directory of a zipfile (at the end, just before
434local uLong ziplocal_SearchCentralDir(pzlib_filefunc_def,filestream) 434 the global comment)
435 const zlib_filefunc_def* pzlib_filefunc_def; 435*/
436 voidpf filestream; 436local uLong ziplocal_SearchCentralDir OF((
437{ 437 const zlib_filefunc_def* pzlib_filefunc_def,
438 unsigned char* buf; 438 voidpf filestream));
439 uLong uSizeFile; 439
440 uLong uBackRead; 440local uLong ziplocal_SearchCentralDir(pzlib_filefunc_def,filestream)
441 uLong uMaxBack=0xffff; /* maximum size of global comment */ 441 const zlib_filefunc_def* pzlib_filefunc_def;
442 uLong uPosFound=0; 442 voidpf filestream;
443 443{
444 if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) 444 unsigned char* buf;
445 return 0; 445 uLong uSizeFile;
446 446 uLong uBackRead;
447 447 uLong uMaxBack=0xffff; /* maximum size of global comment */
448 uSizeFile = ZTELL(*pzlib_filefunc_def,filestream); 448 uLong uPosFound=0;
449 449
450 if (uMaxBack>uSizeFile) 450 if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
451 uMaxBack = uSizeFile; 451 return 0;
452 452
453 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); 453
454 if (buf==NULL) 454 uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
455 return 0; 455
456 456 if (uMaxBack>uSizeFile)
457 uBackRead = 4; 457 uMaxBack = uSizeFile;
458 while (uBackRead<uMaxBack) 458
459 { 459 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
460 uLong uReadSize,uReadPos ; 460 if (buf==NULL)
461 int i; 461 return 0;
462 if (uBackRead+BUFREADCOMMENT>uMaxBack) 462
463 uBackRead = uMaxBack; 463 uBackRead = 4;
464 else 464 while (uBackRead<uMaxBack)
465 uBackRead+=BUFREADCOMMENT; 465 {
466 uReadPos = uSizeFile-uBackRead ; 466 uLong uReadSize,uReadPos ;
467 467 int i;
468 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? 468 if (uBackRead+BUFREADCOMMENT>uMaxBack)
469 (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); 469 uBackRead = uMaxBack;
470 if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) 470 else
471 break; 471 uBackRead+=BUFREADCOMMENT;
472 472 uReadPos = uSizeFile-uBackRead ;
473 if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) 473
474 break; 474 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
475 475 (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
476 for (i=(int)uReadSize-3; (i--)>0;) 476 if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
477 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && 477 break;
478 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) 478
479 { 479 if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
480 uPosFound = uReadPos+i; 480 break;
481 break; 481
482 } 482 for (i=(int)uReadSize-3; (i--)>0;)
483 483 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
484 if (uPosFound!=0) 484 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
485 break; 485 {
486 } 486 uPosFound = uReadPos+i;
487 TRYFREE(buf); 487 break;
488 return uPosFound; 488 }
489} 489
490#endif /* !NO_ADDFILEINEXISTINGZIP*/ 490 if (uPosFound!=0)
491 491 break;
492/************************************************************/ 492 }
493extern zipFile ZEXPORT zipOpen2 (pathname, append, globalcomment, pzlib_filefunc_def) 493 TRYFREE(buf);
494 const char *pathname; 494 return uPosFound;
495 int append; 495}
496 zipcharpc* globalcomment; 496#endif /* !NO_ADDFILEINEXISTINGZIP*/
497 zlib_filefunc_def* pzlib_filefunc_def; 497
498{ 498/************************************************************/
499 zip_internal ziinit; 499extern zipFile ZEXPORT zipOpen2 (pathname, append, globalcomment, pzlib_filefunc_def)
500 zip_internal* zi; 500 const char *pathname;
501 int err=ZIP_OK; 501 int append;
502 502 zipcharpc* globalcomment;
503 503 zlib_filefunc_def* pzlib_filefunc_def;
504 if (pzlib_filefunc_def==NULL) 504{
505 fill_fopen_filefunc(&ziinit.z_filefunc); 505 zip_internal ziinit;
506 else 506 zip_internal* zi;
507 ziinit.z_filefunc = *pzlib_filefunc_def; 507 int err=ZIP_OK;
508 508
509 ziinit.filestream = (*(ziinit.z_filefunc.zopen_file)) 509
510 (ziinit.z_filefunc.opaque, 510 if (pzlib_filefunc_def==NULL)
511 pathname, 511 fill_fopen_filefunc(&ziinit.z_filefunc);
512 (append == APPEND_STATUS_CREATE) ? 512 else
513 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : 513 ziinit.z_filefunc = *pzlib_filefunc_def;
514 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); 514
515 515 ziinit.filestream = (*(ziinit.z_filefunc.zopen_file))
516 if (ziinit.filestream == NULL) 516 (ziinit.z_filefunc.opaque,
517 return NULL; 517 pathname,
518 ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream); 518 (append == APPEND_STATUS_CREATE) ?
519 ziinit.in_opened_file_inzip = 0; 519 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
520 ziinit.ci.stream_initialised = 0; 520 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
521 ziinit.number_entry = 0; 521
522 ziinit.add_position_when_writting_offset = 0; 522 if (ziinit.filestream == NULL)
523 init_linkedlist(&(ziinit.central_dir)); 523 return NULL;
524 524 ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream);
525 525 ziinit.in_opened_file_inzip = 0;
526 zi = (zip_internal*)ALLOC(sizeof(zip_internal)); 526 ziinit.ci.stream_initialised = 0;
527 if (zi==NULL) 527 ziinit.number_entry = 0;
528 { 528 ziinit.add_position_when_writting_offset = 0;
529 ZCLOSE(ziinit.z_filefunc,ziinit.filestream); 529 init_linkedlist(&(ziinit.central_dir));
530 return NULL; 530
531 } 531
532 532 zi = (zip_internal*)ALLOC(sizeof(zip_internal));
533 /* now we add file in a zipfile */ 533 if (zi==NULL)
534# ifndef NO_ADDFILEINEXISTINGZIP 534 {
535 if (append == APPEND_STATUS_ADDINZIP) 535 ZCLOSE(ziinit.z_filefunc,ziinit.filestream);
536 { 536 return NULL;
537 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ 537 }
538 538
539 uLong size_central_dir; /* size of the central directory */ 539 /* now we add file in a zipfile */
540 uLong offset_central_dir; /* offset of start of central directory */ 540# ifndef NO_ADDFILEINEXISTINGZIP
541 uLong central_pos,uL; 541 ziinit.globalcomment = NULL;
542 542 if (append == APPEND_STATUS_ADDINZIP)
543 uLong number_disk; /* number of the current dist, used for 543 {
544 spaning ZIP, unsupported, always 0*/ 544 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
545 uLong number_disk_with_CD; /* number the the disk with central dir, used 545
546 for spaning ZIP, unsupported, always 0*/ 546 uLong size_central_dir; /* size of the central directory */
547 uLong number_entry; 547 uLong offset_central_dir; /* offset of start of central directory */
548 uLong number_entry_CD; /* total number of entries in 548 uLong central_pos,uL;
549 the central dir 549
550 (same than number_entry on nospan) */ 550 uLong number_disk; /* number of the current dist, used for
551 uLong size_comment; 551 spaning ZIP, unsupported, always 0*/
552 552 uLong number_disk_with_CD; /* number the the disk with central dir, used
553 central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream); 553 for spaning ZIP, unsupported, always 0*/
554 if (central_pos==0) 554 uLong number_entry;
555 err=ZIP_ERRNO; 555 uLong number_entry_CD; /* total number of entries in
556 556 the central dir
557 if (ZSEEK(ziinit.z_filefunc, ziinit.filestream, 557 (same than number_entry on nospan) */
558 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) 558 uLong size_comment;
559 err=ZIP_ERRNO; 559
560 560 central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream);
561 /* the signature, already checked */ 561 if (central_pos==0)
562 if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK) 562 err=ZIP_ERRNO;
563 err=ZIP_ERRNO; 563
564 564 if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
565 /* number of this disk */ 565 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
566 if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK) 566 err=ZIP_ERRNO;
567 err=ZIP_ERRNO; 567
568 568 /* the signature, already checked */
569 /* number of the disk with the start of the central directory */ 569 if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK)
570 if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK) 570 err=ZIP_ERRNO;
571 err=ZIP_ERRNO; 571
572 572 /* number of this disk */
573 /* total number of entries in the central dir on this disk */ 573 if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK)
574 if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK) 574 err=ZIP_ERRNO;
575 err=ZIP_ERRNO; 575
576 576 /* number of the disk with the start of the central directory */
577 /* total number of entries in the central dir */ 577 if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK)
578 if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK) 578 err=ZIP_ERRNO;
579 err=ZIP_ERRNO; 579
580 580 /* total number of entries in the central dir on this disk */
581 if ((number_entry_CD!=number_entry) || 581 if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK)
582 (number_disk_with_CD!=0) || 582 err=ZIP_ERRNO;
583 (number_disk!=0)) 583
584 err=ZIP_BADZIPFILE; 584 /* total number of entries in the central dir */
585 585 if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK)
586 /* size of the central directory */ 586 err=ZIP_ERRNO;
587 if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK) 587
588 err=ZIP_ERRNO; 588 if ((number_entry_CD!=number_entry) ||
589 589 (number_disk_with_CD!=0) ||
590 /* offset of start of central directory with respect to the 590 (number_disk!=0))
591 starting disk number */ 591 err=ZIP_BADZIPFILE;
592 if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK) 592
593 err=ZIP_ERRNO; 593 /* size of the central directory */
594 594 if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK)
595 /* zipfile comment length */ 595 err=ZIP_ERRNO;
596 if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK) 596
597 err=ZIP_ERRNO; 597 /* offset of start of central directory with respect to the
598 598 starting disk number */
599 if ((central_pos<offset_central_dir+size_central_dir) && 599 if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK)
600 (err==ZIP_OK)) 600 err=ZIP_ERRNO;
601 err=ZIP_BADZIPFILE; 601
602 602 /* zipfile global comment length */
603 if (err!=ZIP_OK) 603 if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK)
604 { 604 err=ZIP_ERRNO;
605 ZCLOSE(ziinit.z_filefunc, ziinit.filestream); 605
606 return NULL; 606 if ((central_pos<offset_central_dir+size_central_dir) &&
607 } 607 (err==ZIP_OK))
608 608 err=ZIP_BADZIPFILE;
609 byte_before_the_zipfile = central_pos - 609
610 (offset_central_dir+size_central_dir); 610 if (err!=ZIP_OK)
611 ziinit.add_position_when_writting_offset = byte_before_the_zipfile ; 611 {
612 612 ZCLOSE(ziinit.z_filefunc, ziinit.filestream);
613 { 613 return NULL;
614 uLong size_central_dir_to_read = size_central_dir; 614 }
615 size_t buf_size = SIZEDATA_INDATABLOCK; 615
616 void* buf_read = (void*)ALLOC(buf_size); 616 if (size_comment>0)
617 if (ZSEEK(ziinit.z_filefunc, ziinit.filestream, 617 {
618 offset_central_dir + byte_before_the_zipfile, 618 ziinit.globalcomment = ALLOC(size_comment+1);
619 ZLIB_FILEFUNC_SEEK_SET) != 0) 619 if (ziinit.globalcomment)
620 err=ZIP_ERRNO; 620 {
621 621 size_comment = ZREAD(ziinit.z_filefunc, ziinit.filestream,ziinit.globalcomment,size_comment);
622 while ((size_central_dir_to_read>0) && (err==ZIP_OK)) 622 ziinit.globalcomment[size_comment]=0;
623 { 623 }
624 uLong read_this = SIZEDATA_INDATABLOCK; 624 }
625 if (read_this > size_central_dir_to_read) 625
626 read_this = size_central_dir_to_read; 626 byte_before_the_zipfile = central_pos -
627 if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this) 627 (offset_central_dir+size_central_dir);
628 err=ZIP_ERRNO; 628 ziinit.add_position_when_writting_offset = byte_before_the_zipfile;
629 629
630 if (err==ZIP_OK) 630 {
631 err = add_data_in_datablock(&ziinit.central_dir,buf_read, 631 uLong size_central_dir_to_read = size_central_dir;
632 (uLong)read_this); 632 size_t buf_size = SIZEDATA_INDATABLOCK;
633 size_central_dir_to_read-=read_this; 633 void* buf_read = (void*)ALLOC(buf_size);
634 } 634 if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
635 TRYFREE(buf_read); 635 offset_central_dir + byte_before_the_zipfile,
636 } 636 ZLIB_FILEFUNC_SEEK_SET) != 0)
637 ziinit.begin_pos = byte_before_the_zipfile; 637 err=ZIP_ERRNO;
638 ziinit.number_entry = number_entry_CD; 638
639 639 while ((size_central_dir_to_read>0) && (err==ZIP_OK))
640 if (ZSEEK(ziinit.z_filefunc, ziinit.filestream, 640 {
641 offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) 641 uLong read_this = SIZEDATA_INDATABLOCK;
642 err=ZIP_ERRNO; 642 if (read_this > size_central_dir_to_read)
643 } 643 read_this = size_central_dir_to_read;
644# endif /* !NO_ADDFILEINEXISTINGZIP*/ 644 if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this)
645 645 err=ZIP_ERRNO;
646 if (err != ZIP_OK) 646
647 { 647 if (err==ZIP_OK)
648 TRYFREE(zi); 648 err = add_data_in_datablock(&ziinit.central_dir,buf_read,
649 return NULL; 649 (uLong)read_this);
650 } 650 size_central_dir_to_read-=read_this;
651 else 651 }
652 { 652 TRYFREE(buf_read);
653 *zi = ziinit; 653 }
654 return (zipFile)zi; 654 ziinit.begin_pos = byte_before_the_zipfile;
655 } 655 ziinit.number_entry = number_entry_CD;
656} 656
657 657 if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
658extern zipFile ZEXPORT zipOpen (pathname, append) 658 offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
659 const char *pathname; 659 err=ZIP_ERRNO;
660 int append; 660 }
661{ 661
662 return zipOpen2(pathname,append,NULL,NULL); 662 if (globalcomment)
663} 663 {
664 664 *globalcomment = ziinit.globalcomment;
665extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi, 665 }
666 extrafield_local, size_extrafield_local, 666# endif /* !NO_ADDFILEINEXISTINGZIP*/
667 extrafield_global, size_extrafield_global, 667
668 comment, method, level, raw, 668 if (err != ZIP_OK)
669 windowBits, memLevel, strategy, 669 {
670 password, crcForCrypting) 670# ifndef NO_ADDFILEINEXISTINGZIP
671 zipFile file; 671 TRYFREE(ziinit.globalcomment);
672 const char* filename; 672# endif /* !NO_ADDFILEINEXISTINGZIP*/
673 const zip_fileinfo* zipfi; 673 TRYFREE(zi);
674 const void* extrafield_local; 674 return NULL;
675 uInt size_extrafield_local; 675 }
676 const void* extrafield_global; 676 else
677 uInt size_extrafield_global; 677 {
678 const char* comment; 678 *zi = ziinit;
679 int method; 679 return (zipFile)zi;
680 int level; 680 }
681 int raw; 681}
682 int windowBits; 682
683 int memLevel; 683extern zipFile ZEXPORT zipOpen (pathname, append)
684 int strategy; 684 const char *pathname;
685 const char* password; 685 int append;
686 uLong crcForCrypting; 686{
687{ 687 return zipOpen2(pathname,append,NULL,NULL);
688 zip_internal* zi; 688}
689 uInt size_filename; 689
690 uInt size_comment; 690extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi,
691 uInt i; 691 extrafield_local, size_extrafield_local,
692 int err = ZIP_OK; 692 extrafield_global, size_extrafield_global,
693 693 comment, method, level, raw,
694# ifdef NOCRYPT 694 windowBits, memLevel, strategy,
695 if (password != NULL) 695 password, crcForCrypting)
696 return ZIP_PARAMERROR; 696 zipFile file;
697# endif 697 const char* filename;
698 698 const zip_fileinfo* zipfi;
699 if (file == NULL) 699 const void* extrafield_local;
700 return ZIP_PARAMERROR; 700 uInt size_extrafield_local;
701 if ((method!=0) && (method!=Z_DEFLATED)) 701 const void* extrafield_global;
702 return ZIP_PARAMERROR; 702 uInt size_extrafield_global;
703 703 const char* comment;
704 zi = (zip_internal*)file; 704 int method;
705 705 int level;
706 if (zi->in_opened_file_inzip == 1) 706 int raw;
707 { 707 int windowBits;
708 err = zipCloseFileInZip (file); 708 int memLevel;
709 if (err != ZIP_OK) 709 int strategy;
710 return err; 710 const char* password;
711 } 711 uLong crcForCrypting;
712 712{
713 713 zip_internal* zi;
714 if (filename==NULL) 714 uInt size_filename;
715 filename="-"; 715 uInt size_comment;
716 716 uInt i;
717 if (comment==NULL) 717 int err = ZIP_OK;
718 size_comment = 0; 718
719 else 719# ifdef NOCRYPT
720 size_comment = (uInt)strlen(comment); 720 if (password != NULL)
721 721 return ZIP_PARAMERROR;
722 size_filename = (uInt)strlen(filename); 722# endif
723 723
724 if (zipfi == NULL) 724 if (file == NULL)
725 zi->ci.dosDate = 0; 725 return ZIP_PARAMERROR;
726 else 726 if ((method!=0) && (method!=Z_DEFLATED))
727 { 727 return ZIP_PARAMERROR;
728 if (zipfi->dosDate != 0) 728
729 zi->ci.dosDate = zipfi->dosDate; 729 zi = (zip_internal*)file;
730 else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate); 730
731 } 731 if (zi->in_opened_file_inzip == 1)
732 732 {
733 zi->ci.flag = 0; 733 err = zipCloseFileInZip (file);
734 if ((level==8) || (level==9)) 734 if (err != ZIP_OK)
735 zi->ci.flag |= 2; 735 return err;
736 if ((level==2)) 736 }
737 zi->ci.flag |= 4; 737
738 if ((level==1)) 738
739 zi->ci.flag |= 6; 739 if (filename==NULL)
740 if (password != NULL) 740 filename="-";
741 zi->ci.flag |= 1; 741
742 742 if (comment==NULL)
743 zi->ci.crc32 = 0; 743 size_comment = 0;
744 zi->ci.method = method; 744 else
745 zi->ci.encrypt = 0; 745 size_comment = (uInt)strlen(comment);
746 zi->ci.stream_initialised = 0; 746
747 zi->ci.pos_in_buffered_data = 0; 747 size_filename = (uInt)strlen(filename);
748 zi->ci.raw = raw; 748
749 zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ; 749 if (zipfi == NULL)
750 zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + 750 zi->ci.dosDate = 0;
751 size_extrafield_global + size_comment; 751 else
752 zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader); 752 {
753 753 if (zipfi->dosDate != 0)
754 ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); 754 zi->ci.dosDate = zipfi->dosDate;
755 /* version info */ 755 else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate);
756 ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2); 756 }
757 ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2); 757
758 ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); 758 zi->ci.flag = 0;
759 ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); 759 if ((level==8) || (level==9))
760 ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); 760 zi->ci.flag |= 2;
761 ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ 761 if ((level==2))
762 ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ 762 zi->ci.flag |= 4;
763 ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ 763 if ((level==1))
764 ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); 764 zi->ci.flag |= 6;
765 ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); 765 if (password != NULL)
766 ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); 766 zi->ci.flag |= 1;
767 ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ 767
768 768 zi->ci.crc32 = 0;
769 if (zipfi==NULL) 769 zi->ci.method = method;
770 ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); 770 zi->ci.encrypt = 0;
771 else 771 zi->ci.stream_initialised = 0;
772 ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); 772 zi->ci.pos_in_buffered_data = 0;
773 773 zi->ci.raw = raw;
774 if (zipfi==NULL) 774 zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ;
775 ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); 775 zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename +
776 else 776 size_extrafield_global + size_comment;
777 ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); 777 zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader);
778 778
779 ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4); 779 ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
780 780 /* version info */
781 for (i=0;i<size_filename;i++) 781 ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2);
782 *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i); 782 ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
783 783 ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
784 for (i=0;i<size_extrafield_global;i++) 784 ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
785 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) = 785 ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
786 *(((const char*)extrafield_global)+i); 786 ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
787 787 ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
788 for (i=0;i<size_comment;i++) 788 ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
789 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+ 789 ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
790 size_extrafield_global+i) = *(comment+i); 790 ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
791 if (zi->ci.central_header == NULL) 791 ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
792 return ZIP_INTERNALERROR; 792 ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
793 793
794 /* write the local header */ 794 if (zipfi==NULL)
795 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4); 795 ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
796 796 else
797 if (err==ZIP_OK) 797 ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
798 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */ 798
799 if (err==ZIP_OK) 799 if (zipfi==NULL)
800 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2); 800 ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
801 801 else
802 if (err==ZIP_OK) 802 ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
803 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2); 803
804 804 ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4);
805 if (err==ZIP_OK) 805
806 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); 806 for (i=0;i<size_filename;i++)
807 807 *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
808 if (err==ZIP_OK) 808
809 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ 809 for (i=0;i<size_extrafield_global;i++)
810 if (err==ZIP_OK) 810 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
811 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */ 811 *(((const char*)extrafield_global)+i);
812 if (err==ZIP_OK) 812
813 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */ 813 for (i=0;i<size_comment;i++)
814 814 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
815 if (err==ZIP_OK) 815 size_extrafield_global+i) = *(comment+i);
816 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2); 816 if (zi->ci.central_header == NULL)
817 817 return ZIP_INTERNALERROR;
818 if (err==ZIP_OK) 818
819 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2); 819 /* write the local header */
820 820 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4);
821 if ((err==ZIP_OK) && (size_filename>0)) 821
822 if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename) 822 if (err==ZIP_OK)
823 err = ZIP_ERRNO; 823 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
824 824 if (err==ZIP_OK)
825 if ((err==ZIP_OK) && (size_extrafield_local>0)) 825 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
826 if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local) 826
827 !=size_extrafield_local) 827 if (err==ZIP_OK)
828 err = ZIP_ERRNO; 828 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
829 829
830 zi->ci.stream.avail_in = (uInt)0; 830 if (err==ZIP_OK)
831 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; 831 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
832 zi->ci.stream.next_out = zi->ci.buffered_data; 832
833 zi->ci.stream.total_in = 0; 833 if (err==ZIP_OK)
834 zi->ci.stream.total_out = 0; 834 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
835 835 if (err==ZIP_OK)
836 if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) 836 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
837 { 837 if (err==ZIP_OK)
838 zi->ci.stream.zalloc = (alloc_func)0; 838 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
839 zi->ci.stream.zfree = (free_func)0; 839
840 zi->ci.stream.opaque = (voidpf)0; 840 if (err==ZIP_OK)
841 841 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
842 if (windowBits>0) 842
843 windowBits = -windowBits; 843 if (err==ZIP_OK)
844 844 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2);
845 err = deflateInit2(&zi->ci.stream, level, 845
846 Z_DEFLATED, windowBits, memLevel, strategy); 846 if ((err==ZIP_OK) && (size_filename>0))
847 847 if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
848 if (err==Z_OK) 848 err = ZIP_ERRNO;
849 zi->ci.stream_initialised = 1; 849
850 } 850 if ((err==ZIP_OK) && (size_extrafield_local>0))
851# ifndef NOCRYPT 851 if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local)
852 zi->ci.crypt_header_size = 0; 852 !=size_extrafield_local)
853 if ((err==Z_OK) && (password != NULL)) 853 err = ZIP_ERRNO;
854 { 854
855 unsigned char bufHead[RAND_HEAD_LEN]; 855 zi->ci.stream.avail_in = (uInt)0;
856 unsigned int sizeHead; 856 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
857 zi->ci.encrypt = 1; 857 zi->ci.stream.next_out = zi->ci.buffered_data;
858 zi->ci.pcrc_32_tab = get_crc_table(); 858 zi->ci.stream.total_in = 0;
859 /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ 859 zi->ci.stream.total_out = 0;
860 860
861 sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); 861 if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
862 zi->ci.crypt_header_size = sizeHead; 862 {
863 863 zi->ci.stream.zalloc = (alloc_func)0;
864 if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) 864 zi->ci.stream.zfree = (free_func)0;
865 err = ZIP_ERRNO; 865 zi->ci.stream.opaque = (voidpf)0;
866 } 866
867# endif 867 if (windowBits>0)
868 868 windowBits = -windowBits;
869 if (err==Z_OK) 869
870 zi->in_opened_file_inzip = 1; 870 err = deflateInit2(&zi->ci.stream, level,
871 return err; 871 Z_DEFLATED, windowBits, memLevel, strategy);
872} 872
873 873 if (err==Z_OK)
874extern int ZEXPORT zipOpenNewFileInZip2(file, filename, zipfi, 874 zi->ci.stream_initialised = 1;
875 extrafield_local, size_extrafield_local, 875 }
876 extrafield_global, size_extrafield_global, 876# ifndef NOCRYPT
877 comment, method, level, raw) 877 zi->ci.crypt_header_size = 0;
878 zipFile file; 878 if ((err==Z_OK) && (password != NULL))
879 const char* filename; 879 {
880 const zip_fileinfo* zipfi; 880 unsigned char bufHead[RAND_HEAD_LEN];
881 const void* extrafield_local; 881 unsigned int sizeHead;
882 uInt size_extrafield_local; 882 zi->ci.encrypt = 1;
883 const void* extrafield_global; 883 zi->ci.pcrc_32_tab = get_crc_table();
884 uInt size_extrafield_global; 884 /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
885 const char* comment; 885
886 int method; 886 sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
887 int level; 887 zi->ci.crypt_header_size = sizeHead;
888 int raw; 888
889{ 889 if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
890 return zipOpenNewFileInZip3 (file, filename, zipfi, 890 err = ZIP_ERRNO;
891 extrafield_local, size_extrafield_local, 891 }
892 extrafield_global, size_extrafield_global, 892# endif
893 comment, method, level, raw, 893
894 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, 894 if (err==Z_OK)
895 NULL, 0); 895 zi->in_opened_file_inzip = 1;
896} 896 return err;
897 897}
898extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi, 898
899 extrafield_local, size_extrafield_local, 899extern int ZEXPORT zipOpenNewFileInZip2(file, filename, zipfi,
900 extrafield_global, size_extrafield_global, 900 extrafield_local, size_extrafield_local,
901 comment, method, level) 901 extrafield_global, size_extrafield_global,
902 zipFile file; 902 comment, method, level, raw)
903 const char* filename; 903 zipFile file;
904 const zip_fileinfo* zipfi; 904 const char* filename;
905 const void* extrafield_local; 905 const zip_fileinfo* zipfi;
906 uInt size_extrafield_local; 906 const void* extrafield_local;
907 const void* extrafield_global; 907 uInt size_extrafield_local;
908 uInt size_extrafield_global; 908 const void* extrafield_global;
909 const char* comment; 909 uInt size_extrafield_global;
910 int method; 910 const char* comment;
911 int level; 911 int method;
912{ 912 int level;
913 return zipOpenNewFileInZip2 (file, filename, zipfi, 913 int raw;
914 extrafield_local, size_extrafield_local, 914{
915 extrafield_global, size_extrafield_global, 915 return zipOpenNewFileInZip3 (file, filename, zipfi,
916 comment, method, level, 0); 916 extrafield_local, size_extrafield_local,
917} 917 extrafield_global, size_extrafield_global,
918 918 comment, method, level, raw,
919local int zipFlushWriteBuffer(zi) 919 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
920 zip_internal* zi; 920 NULL, 0);
921{ 921}
922 int err=ZIP_OK; 922
923 923extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi,
924 if (zi->ci.encrypt != 0) 924 extrafield_local, size_extrafield_local,
925 { 925 extrafield_global, size_extrafield_global,
926#ifndef NOCRYPT 926 comment, method, level)
927 uInt i; 927 zipFile file;
928 int t; 928 const char* filename;
929 for (i=0;i<zi->ci.pos_in_buffered_data;i++) 929 const zip_fileinfo* zipfi;
930 zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, 930 const void* extrafield_local;
931 zi->ci.buffered_data[i],t); 931 uInt size_extrafield_local;
932#endif 932 const void* extrafield_global;
933 } 933 uInt size_extrafield_global;
934 if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) 934 const char* comment;
935 !=zi->ci.pos_in_buffered_data) 935 int method;
936 err = ZIP_ERRNO; 936 int level;
937 zi->ci.pos_in_buffered_data = 0; 937{
938 return err; 938 return zipOpenNewFileInZip2 (file, filename, zipfi,
939} 939 extrafield_local, size_extrafield_local,
940 940 extrafield_global, size_extrafield_global,
941extern int ZEXPORT zipWriteInFileInZip (file, buf, len) 941 comment, method, level, 0);
942 zipFile file; 942}
943 const void* buf; 943
944 unsigned len; 944local int zipFlushWriteBuffer(zi)
945{ 945 zip_internal* zi;
946 zip_internal* zi; 946{
947 int err=ZIP_OK; 947 int err=ZIP_OK;
948 948
949 if (file == NULL) 949 if (zi->ci.encrypt != 0)
950 return ZIP_PARAMERROR; 950 {
951 zi = (zip_internal*)file; 951#ifndef NOCRYPT
952 952 uInt i;
953 if (zi->in_opened_file_inzip == 0) 953 int t;
954 return ZIP_PARAMERROR; 954 for (i=0;i<zi->ci.pos_in_buffered_data;i++)
955 955 zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab,
956 zi->ci.stream.next_in = (void*)buf; 956 zi->ci.buffered_data[i],t);
957 zi->ci.stream.avail_in = len; 957#endif
958 zi->ci.crc32 = crc32(zi->ci.crc32,buf,len); 958 }
959 959 if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data)
960 while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) 960 !=zi->ci.pos_in_buffered_data)
961 { 961 err = ZIP_ERRNO;
962 if (zi->ci.stream.avail_out == 0) 962 zi->ci.pos_in_buffered_data = 0;
963 { 963 return err;
964 if (zipFlushWriteBuffer(zi) == ZIP_ERRNO) 964}
965 err = ZIP_ERRNO; 965
966 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; 966extern int ZEXPORT zipWriteInFileInZip (file, buf, len)
967 zi->ci.stream.next_out = zi->ci.buffered_data; 967 zipFile file;
968 } 968 const void* buf;
969 969 unsigned len;
970 970{
971 if(err != ZIP_OK) 971 zip_internal* zi;
972 break; 972 int err=ZIP_OK;
973 973
974 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) 974 if (file == NULL)
975 { 975 return ZIP_PARAMERROR;
976 uLong uTotalOutBefore = zi->ci.stream.total_out; 976 zi = (zip_internal*)file;
977 err=deflate(&zi->ci.stream, Z_NO_FLUSH); 977
978 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; 978 if (zi->in_opened_file_inzip == 0)
979 979 return ZIP_PARAMERROR;
980 } 980
981 else 981 zi->ci.stream.next_in = (void*)buf;
982 { 982 zi->ci.stream.avail_in = len;
983 uInt copy_this,i; 983 zi->ci.crc32 = crc32(zi->ci.crc32,buf,len);
984 if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) 984
985 copy_this = zi->ci.stream.avail_in; 985 while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
986 else 986 {
987 copy_this = zi->ci.stream.avail_out; 987 if (zi->ci.stream.avail_out == 0)
988 for (i=0;i<copy_this;i++) 988 {
989 *(((char*)zi->ci.stream.next_out)+i) = 989 if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
990 *(((const char*)zi->ci.stream.next_in)+i); 990 err = ZIP_ERRNO;
991 { 991 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
992 zi->ci.stream.avail_in -= copy_this; 992 zi->ci.stream.next_out = zi->ci.buffered_data;
993 zi->ci.stream.avail_out-= copy_this; 993 }
994 zi->ci.stream.next_in+= copy_this; 994
995 zi->ci.stream.next_out+= copy_this; 995
996 zi->ci.stream.total_in+= copy_this; 996 if(err != ZIP_OK)
997 zi->ci.stream.total_out+= copy_this; 997 break;
998 zi->ci.pos_in_buffered_data += copy_this; 998
999 } 999 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1000 } 1000 {
1001 } 1001 uLong uTotalOutBefore = zi->ci.stream.total_out;
1002 1002 err=deflate(&zi->ci.stream, Z_NO_FLUSH);
1003 return err; 1003 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
1004} 1004
1005 1005 }
1006extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32) 1006 else
1007 zipFile file; 1007 {
1008 uLong uncompressed_size; 1008 uInt copy_this,i;
1009 uLong crc32; 1009 if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
1010{ 1010 copy_this = zi->ci.stream.avail_in;
1011 zip_internal* zi; 1011 else
1012 uLong compressed_size; 1012 copy_this = zi->ci.stream.avail_out;
1013 int err=ZIP_OK; 1013 for (i=0;i<copy_this;i++)
1014 1014 *(((char*)zi->ci.stream.next_out)+i) =
1015 if (file == NULL) 1015 *(((const char*)zi->ci.stream.next_in)+i);
1016 return ZIP_PARAMERROR; 1016 {
1017 zi = (zip_internal*)file; 1017 zi->ci.stream.avail_in -= copy_this;
1018 1018 zi->ci.stream.avail_out-= copy_this;
1019 if (zi->in_opened_file_inzip == 0) 1019 zi->ci.stream.next_in+= copy_this;
1020 return ZIP_PARAMERROR; 1020 zi->ci.stream.next_out+= copy_this;
1021 zi->ci.stream.avail_in = 0; 1021 zi->ci.stream.total_in+= copy_this;
1022 1022 zi->ci.stream.total_out+= copy_this;
1023 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) 1023 zi->ci.pos_in_buffered_data += copy_this;
1024 while (err==ZIP_OK) 1024 }
1025 { 1025 }
1026 uLong uTotalOutBefore; 1026 }
1027 if (zi->ci.stream.avail_out == 0) 1027
1028 { 1028 return err;
1029 if (zipFlushWriteBuffer(zi) == ZIP_ERRNO) 1029}
1030 err = ZIP_ERRNO; 1030
1031 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; 1031extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32)
1032 zi->ci.stream.next_out = zi->ci.buffered_data; 1032 zipFile file;
1033 } 1033 uLong uncompressed_size;
1034 uTotalOutBefore = zi->ci.stream.total_out; 1034 uLong crc32;
1035 err=deflate(&zi->ci.stream, Z_FINISH); 1035{
1036 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; 1036 zip_internal* zi;
1037 } 1037 uLong compressed_size;
1038 1038 int err=ZIP_OK;
1039 if (err==Z_STREAM_END) 1039
1040 err=ZIP_OK; /* this is normal */ 1040 if (file == NULL)
1041 1041 return ZIP_PARAMERROR;
1042 if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) 1042 zi = (zip_internal*)file;
1043 if (zipFlushWriteBuffer(zi)==ZIP_ERRNO) 1043
1044 err = ZIP_ERRNO; 1044 if (zi->in_opened_file_inzip == 0)
1045 1045 return ZIP_PARAMERROR;
1046 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) 1046 zi->ci.stream.avail_in = 0;
1047 { 1047
1048 err=deflateEnd(&zi->ci.stream); 1048 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1049 zi->ci.stream_initialised = 0; 1049 while (err==ZIP_OK)
1050 } 1050 {
1051 1051 uLong uTotalOutBefore;
1052 if (!zi->ci.raw) 1052 if (zi->ci.stream.avail_out == 0)
1053 { 1053 {
1054 crc32 = (uLong)zi->ci.crc32; 1054 if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
1055 uncompressed_size = (uLong)zi->ci.stream.total_in; 1055 err = ZIP_ERRNO;
1056 } 1056 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
1057 compressed_size = (uLong)zi->ci.stream.total_out; 1057 zi->ci.stream.next_out = zi->ci.buffered_data;
1058# ifndef NOCRYPT 1058 }
1059 compressed_size += zi->ci.crypt_header_size; 1059 uTotalOutBefore = zi->ci.stream.total_out;
1060# endif 1060 err=deflate(&zi->ci.stream, Z_FINISH);
1061 1061 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
1062 ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ 1062 }
1063 ziplocal_putValue_inmemory(zi->ci.central_header+20, 1063
1064 compressed_size,4); /*compr size*/ 1064 if (err==Z_STREAM_END)
1065 if (zi->ci.stream.data_type == Z_ASCII) 1065 err=ZIP_OK; /* this is normal */
1066 ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); 1066
1067 ziplocal_putValue_inmemory(zi->ci.central_header+24, 1067 if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
1068 uncompressed_size,4); /*uncompr size*/ 1068 if (zipFlushWriteBuffer(zi)==ZIP_ERRNO)
1069 1069 err = ZIP_ERRNO;
1070 if (err==ZIP_OK) 1070
1071 err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header, 1071 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1072 (uLong)zi->ci.size_centralheader); 1072 {
1073 free(zi->ci.central_header); 1073 err=deflateEnd(&zi->ci.stream);
1074 1074 zi->ci.stream_initialised = 0;
1075 if (err==ZIP_OK) 1075 }
1076 { 1076
1077 long cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream); 1077 if (!zi->ci.raw)
1078 if (ZSEEK(zi->z_filefunc,zi->filestream, 1078 {
1079 zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) 1079 crc32 = (uLong)zi->ci.crc32;
1080 err = ZIP_ERRNO; 1080 uncompressed_size = (uLong)zi->ci.stream.total_in;
1081 1081 }
1082 if (err==ZIP_OK) 1082 compressed_size = (uLong)zi->ci.stream.total_out;
1083 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ 1083# ifndef NOCRYPT
1084 1084 compressed_size += zi->ci.crypt_header_size;
1085 if (err==ZIP_OK) /* compressed size, unknown */ 1085# endif
1086 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); 1086
1087 1087 ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
1088 if (err==ZIP_OK) /* uncompressed size, unknown */ 1088 ziplocal_putValue_inmemory(zi->ci.central_header+20,
1089 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); 1089 compressed_size,4); /*compr size*/
1090 1090 if (zi->ci.stream.data_type == Z_ASCII)
1091 if (ZSEEK(zi->z_filefunc,zi->filestream, 1091 ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
1092 cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) 1092 ziplocal_putValue_inmemory(zi->ci.central_header+24,
1093 err = ZIP_ERRNO; 1093 uncompressed_size,4); /*uncompr size*/
1094 } 1094
1095 1095 if (err==ZIP_OK)
1096 zi->number_entry ++; 1096 err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header,
1097 zi->in_opened_file_inzip = 0; 1097 (uLong)zi->ci.size_centralheader);
1098 1098 free(zi->ci.central_header);
1099 return err; 1099
1100} 1100 if (err==ZIP_OK)
1101 1101 {
1102extern int ZEXPORT zipCloseFileInZip (file) 1102 long cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
1103 zipFile file; 1103 if (ZSEEK(zi->z_filefunc,zi->filestream,
1104{ 1104 zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
1105 return zipCloseFileInZipRaw (file,0,0); 1105 err = ZIP_ERRNO;
1106} 1106
1107 1107 if (err==ZIP_OK)
1108extern int ZEXPORT zipClose (file, global_comment) 1108 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
1109 zipFile file; 1109
1110 const char* global_comment; 1110 if (err==ZIP_OK) /* compressed size, unknown */
1111{ 1111 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
1112 zip_internal* zi; 1112
1113 int err = 0; 1113 if (err==ZIP_OK) /* uncompressed size, unknown */
1114 uLong size_centraldir = 0; 1114 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
1115 uLong centraldir_pos_inzip ; 1115
1116 uInt size_global_comment; 1116 if (ZSEEK(zi->z_filefunc,zi->filestream,
1117 if (file == NULL) 1117 cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
1118 return ZIP_PARAMERROR; 1118 err = ZIP_ERRNO;
1119 zi = (zip_internal*)file; 1119 }
1120 1120
1121 if (zi->in_opened_file_inzip == 1) 1121 zi->number_entry ++;
1122 { 1122 zi->in_opened_file_inzip = 0;
1123 err = zipCloseFileInZip (file); 1123
1124 } 1124 return err;
1125 1125}
1126 if (global_comment==NULL) 1126
1127 size_global_comment = 0; 1127extern int ZEXPORT zipCloseFileInZip (file)
1128 else 1128 zipFile file;
1129 size_global_comment = (uInt)strlen(global_comment); 1129{
1130 1130 return zipCloseFileInZipRaw (file,0,0);
1131 1131}
1132 centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream); 1132
1133 if (err==ZIP_OK) 1133extern int ZEXPORT zipClose (file, global_comment)
1134 { 1134 zipFile file;
1135 linkedlist_datablock_internal* ldi = zi->central_dir.first_block ; 1135 const char* global_comment;
1136 while (ldi!=NULL) 1136{
1137 { 1137 zip_internal* zi;
1138 if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) 1138 int err = 0;
1139 if (ZWRITE(zi->z_filefunc,zi->filestream, 1139 uLong size_centraldir = 0;
1140 ldi->data,ldi->filled_in_this_block) 1140 uLong centraldir_pos_inzip;
1141 !=ldi->filled_in_this_block ) 1141 uInt size_global_comment;
1142 err = ZIP_ERRNO; 1142 if (file == NULL)
1143 1143 return ZIP_PARAMERROR;
1144 size_centraldir += ldi->filled_in_this_block; 1144 zi = (zip_internal*)file;
1145 ldi = ldi->next_datablock; 1145
1146 } 1146 if (zi->in_opened_file_inzip == 1)
1147 } 1147 {
1148 free_datablock(zi->central_dir.first_block); 1148 err = zipCloseFileInZip (file);
1149 1149 }
1150 if (err==ZIP_OK) /* Magic End */ 1150
1151 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); 1151#ifndef NO_ADDFILEINEXISTINGZIP
1152 1152 if (global_comment==NULL)
1153 if (err==ZIP_OK) /* number of this disk */ 1153 global_comment = zi->globalcomment;
1154 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); 1154#endif
1155 1155 if (global_comment==NULL)
1156 if (err==ZIP_OK) /* number of the disk with the start of the central directory */ 1156 size_global_comment = 0;
1157 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); 1157 else
1158 1158 size_global_comment = (uInt)strlen(global_comment);
1159 if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ 1159
1160 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); 1160 centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
1161 1161 if (err==ZIP_OK)
1162 if (err==ZIP_OK) /* total number of entries in the central dir */ 1162 {
1163 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); 1163 linkedlist_datablock_internal* ldi = zi->central_dir.first_block ;
1164 1164 while (ldi!=NULL)
1165 if (err==ZIP_OK) /* size of the central directory */ 1165 {
1166 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4); 1166 if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
1167 1167 if (ZWRITE(zi->z_filefunc,zi->filestream,
1168 if (err==ZIP_OK) /* offset of start of central directory with respect to the 1168 ldi->data,ldi->filled_in_this_block)
1169 starting disk number */ 1169 !=ldi->filled_in_this_block )
1170 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream, 1170 err = ZIP_ERRNO;
1171 (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4); 1171
1172 1172 size_centraldir += ldi->filled_in_this_block;
1173 if (err==ZIP_OK) /* zipfile comment length */ 1173 ldi = ldi->next_datablock;
1174 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); 1174 }
1175 1175 }
1176 if ((err==ZIP_OK) && (size_global_comment>0)) 1176 free_datablock(zi->central_dir.first_block);
1177 if (ZWRITE(zi->z_filefunc,zi->filestream, 1177
1178 global_comment,size_global_comment) != size_global_comment) 1178 if (err==ZIP_OK) /* Magic End */
1179 err = ZIP_ERRNO; 1179 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
1180 1180
1181 if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0) 1181 if (err==ZIP_OK) /* number of this disk */
1182 if (err == ZIP_OK) 1182 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
1183 err = ZIP_ERRNO; 1183
1184 1184 if (err==ZIP_OK) /* number of the disk with the start of the central directory */
1185 TRYFREE(zi); 1185 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
1186 1186
1187 return err; 1187 if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
1188} 1188 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
1189
1190 if (err==ZIP_OK) /* total number of entries in the central dir */
1191 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
1192
1193 if (err==ZIP_OK) /* size of the central directory */
1194 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
1195
1196 if (err==ZIP_OK) /* offset of start of central directory with respect to the
1197 starting disk number */
1198 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,
1199 (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
1200
1201 if (err==ZIP_OK) /* zipfile comment length */
1202 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
1203
1204 if ((err==ZIP_OK) && (size_global_comment>0))
1205 if (ZWRITE(zi->z_filefunc,zi->filestream,
1206 global_comment,size_global_comment) != size_global_comment)
1207 err = ZIP_ERRNO;
1208
1209 if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0)
1210 if (err == ZIP_OK)
1211 err = ZIP_ERRNO;
1212
1213#ifndef NO_ADDFILEINEXISTINGZIP
1214 TRYFREE(zi->globalcomment);
1215#endif
1216 TRYFREE(zi);
1217
1218 return err;
1219}
diff --git a/contrib/minizip/zip.h b/contrib/minizip/zip.h
index d5112c4..cd38b67 100644
--- a/contrib/minizip/zip.h
+++ b/contrib/minizip/zip.h
@@ -1,234 +1,235 @@
1/* zip.h -- IO for compress .zip files using zlib 1/* zip.h -- IO for compress .zip files using zlib
2 Version 1.01, May 8th, 2004 2 Version 1.01e, February 12th, 2005
3 3
4 Copyright (C) 1998-2004 Gilles Vollant 4 Copyright (C) 1998-2005 Gilles Vollant
5 5
6 This unzip package allow creates .ZIP file, compatible with PKZip 2.04g 6 This unzip package allow creates .ZIP file, compatible with PKZip 2.04g
7 WinZip, InfoZip tools and compatible. 7 WinZip, InfoZip tools and compatible.
8 Encryption and multi volume ZipFile (span) are not supported. 8 Multi volume ZipFile (span) are not supported.
9 Old compressions used by old PKZip 1.x are not supported 9 Encryption compatible with pkzip 2.04g only supported
10 10 Old compressions used by old PKZip 1.x are not supported
11 For uncompress .zip file, look at unzip.h 11
12 12 For uncompress .zip file, look at unzip.h
13 13
14 I WAIT FEEDBACK at mail info@winimage.com 14
15 Visit also http://www.winimage.com/zLibDll/unzip.html for evolution 15 I WAIT FEEDBACK at mail info@winimage.com
16 16 Visit also http://www.winimage.com/zLibDll/unzip.html for evolution
17 Condition of use and distribution are the same than zlib : 17
18 18 Condition of use and distribution are the same than zlib :
19 This software is provided 'as-is', without any express or implied 19
20 warranty. In no event will the authors be held liable for any damages 20 This software is provided 'as-is', without any express or implied
21 arising from the use of this software. 21 warranty. In no event will the authors be held liable for any damages
22 22 arising from the use of this software.
23 Permission is granted to anyone to use this software for any purpose, 23
24 including commercial applications, and to alter it and redistribute it 24 Permission is granted to anyone to use this software for any purpose,
25 freely, subject to the following restrictions: 25 including commercial applications, and to alter it and redistribute it
26 26 freely, subject to the following restrictions:
27 1. The origin of this software must not be misrepresented; you must not 27
28 claim that you wrote the original software. If you use this software 28 1. The origin of this software must not be misrepresented; you must not
29 in a product, an acknowledgment in the product documentation would be 29 claim that you wrote the original software. If you use this software
30 appreciated but is not required. 30 in a product, an acknowledgment in the product documentation would be
31 2. Altered source versions must be plainly marked as such, and must not be 31 appreciated but is not required.
32 misrepresented as being the original software. 32 2. Altered source versions must be plainly marked as such, and must not be
33 3. This notice may not be removed or altered from any source distribution. 33 misrepresented as being the original software.
34 34 3. This notice may not be removed or altered from any source distribution.
35 35
36*/ 36
37 37*/
38/* for more info about .ZIP format, see 38
39 http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip 39/* for more info about .ZIP format, see
40 http://www.info-zip.org/pub/infozip/doc/ 40 http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip
41 PkWare has also a specification at : 41 http://www.info-zip.org/pub/infozip/doc/
42 ftp://ftp.pkware.com/probdesc.zip 42 PkWare has also a specification at :
43*/ 43 ftp://ftp.pkware.com/probdesc.zip
44 44*/
45#ifndef _zip_H 45
46#define _zip_H 46#ifndef _zip_H
47 47#define _zip_H
48#ifdef __cplusplus 48
49extern "C" { 49#ifdef __cplusplus
50#endif 50extern "C" {
51 51#endif
52#ifndef _ZLIB_H 52
53#include "zlib.h" 53#ifndef _ZLIB_H
54#endif 54#include "zlib.h"
55 55#endif
56#ifndef _ZLIBIOAPI_H 56
57#include "ioapi.h" 57#ifndef _ZLIBIOAPI_H
58#endif 58#include "ioapi.h"
59 59#endif
60#if defined(STRICTZIP) || defined(STRICTZIPUNZIP) 60
61/* like the STRICT of WIN32, we define a pointer that cannot be converted 61#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
62 from (void*) without cast */ 62/* like the STRICT of WIN32, we define a pointer that cannot be converted
63typedef struct TagzipFile__ { int unused; } zipFile__; 63 from (void*) without cast */
64typedef zipFile__ *zipFile; 64typedef struct TagzipFile__ { int unused; } zipFile__;
65#else 65typedef zipFile__ *zipFile;
66typedef voidp zipFile; 66#else
67#endif 67typedef voidp zipFile;
68 68#endif
69#define ZIP_OK (0) 69
70#define ZIP_EOF (0) 70#define ZIP_OK (0)
71#define ZIP_ERRNO (Z_ERRNO) 71#define ZIP_EOF (0)
72#define ZIP_PARAMERROR (-102) 72#define ZIP_ERRNO (Z_ERRNO)
73#define ZIP_BADZIPFILE (-103) 73#define ZIP_PARAMERROR (-102)
74#define ZIP_INTERNALERROR (-104) 74#define ZIP_BADZIPFILE (-103)
75 75#define ZIP_INTERNALERROR (-104)
76#ifndef DEF_MEM_LEVEL 76
77# if MAX_MEM_LEVEL >= 8 77#ifndef DEF_MEM_LEVEL
78# define DEF_MEM_LEVEL 8 78# if MAX_MEM_LEVEL >= 8
79# else 79# define DEF_MEM_LEVEL 8
80# define DEF_MEM_LEVEL MAX_MEM_LEVEL 80# else
81# endif 81# define DEF_MEM_LEVEL MAX_MEM_LEVEL
82#endif 82# endif
83/* default memLevel */ 83#endif
84 84/* default memLevel */
85/* tm_zip contain date/time info */ 85
86typedef struct tm_zip_s 86/* tm_zip contain date/time info */
87{ 87typedef struct tm_zip_s
88 uInt tm_sec; /* seconds after the minute - [0,59] */ 88{
89 uInt tm_min; /* minutes after the hour - [0,59] */ 89 uInt tm_sec; /* seconds after the minute - [0,59] */
90 uInt tm_hour; /* hours since midnight - [0,23] */ 90 uInt tm_min; /* minutes after the hour - [0,59] */
91 uInt tm_mday; /* day of the month - [1,31] */ 91 uInt tm_hour; /* hours since midnight - [0,23] */
92 uInt tm_mon; /* months since January - [0,11] */ 92 uInt tm_mday; /* day of the month - [1,31] */
93 uInt tm_year; /* years - [1980..2044] */ 93 uInt tm_mon; /* months since January - [0,11] */
94} tm_zip; 94 uInt tm_year; /* years - [1980..2044] */
95 95} tm_zip;
96typedef struct 96
97{ 97typedef struct
98 tm_zip tmz_date; /* date in understandable format */ 98{
99 uLong dosDate; /* if dos_date == 0, tmu_date is used */ 99 tm_zip tmz_date; /* date in understandable format */
100/* uLong flag; */ /* general purpose bit flag 2 bytes */ 100 uLong dosDate; /* if dos_date == 0, tmu_date is used */
101 101/* uLong flag; */ /* general purpose bit flag 2 bytes */
102 uLong internal_fa; /* internal file attributes 2 bytes */ 102
103 uLong external_fa; /* external file attributes 4 bytes */ 103 uLong internal_fa; /* internal file attributes 2 bytes */
104} zip_fileinfo; 104 uLong external_fa; /* external file attributes 4 bytes */
105 105} zip_fileinfo;
106typedef const char* zipcharpc; 106
107 107typedef const char* zipcharpc;
108 108
109#define APPEND_STATUS_CREATE (0) 109
110#define APPEND_STATUS_CREATEAFTER (1) 110#define APPEND_STATUS_CREATE (0)
111#define APPEND_STATUS_ADDINZIP (2) 111#define APPEND_STATUS_CREATEAFTER (1)
112 112#define APPEND_STATUS_ADDINZIP (2)
113extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append)); 113
114/* 114extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));
115 Create a zipfile. 115/*
116 pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on 116 Create a zipfile.
117 an Unix computer "zlib/zlib113.zip". 117 pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on
118 if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip 118 an Unix computer "zlib/zlib113.zip".
119 will be created at the end of the file. 119 if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip
120 (useful if the file contain a self extractor code) 120 will be created at the end of the file.
121 if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will 121 (useful if the file contain a self extractor code)
122 add files in existing zip (be sure you don't add file that doesn't exist) 122 if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will
123 If the zipfile cannot be opened, the return value is NULL. 123 add files in existing zip (be sure you don't add file that doesn't exist)
124 Else, the return value is a zipFile Handle, usable with other function 124 If the zipfile cannot be opened, the return value is NULL.
125 of this zip package. 125 Else, the return value is a zipFile Handle, usable with other function
126*/ 126 of this zip package.
127 127*/
128/* Note : there is no delete function into a zipfile. 128
129 If you want delete file into a zipfile, you must open a zipfile, and create another 129/* Note : there is no delete function into a zipfile.
130 Of couse, you can use RAW reading and writing to copy the file you did not want delte 130 If you want delete file into a zipfile, you must open a zipfile, and create another
131*/ 131 Of couse, you can use RAW reading and writing to copy the file you did not want delte
132 132*/
133extern zipFile ZEXPORT zipOpen2 OF((const char *pathname, 133
134 int append, 134extern zipFile ZEXPORT zipOpen2 OF((const char *pathname,
135 zipcharpc* globalcomment, 135 int append,
136 zlib_filefunc_def* pzlib_filefunc_def)); 136 zipcharpc* globalcomment,
137 137 zlib_filefunc_def* pzlib_filefunc_def));
138extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, 138
139 const char* filename, 139extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
140 const zip_fileinfo* zipfi, 140 const char* filename,
141 const void* extrafield_local, 141 const zip_fileinfo* zipfi,
142 uInt size_extrafield_local, 142 const void* extrafield_local,
143 const void* extrafield_global, 143 uInt size_extrafield_local,
144 uInt size_extrafield_global, 144 const void* extrafield_global,
145 const char* comment, 145 uInt size_extrafield_global,
146 int method, 146 const char* comment,
147 int level)); 147 int method,
148/* 148 int level));
149 Open a file in the ZIP for writing. 149/*
150 filename : the filename in zip (if NULL, '-' without quote will be used 150 Open a file in the ZIP for writing.
151 *zipfi contain supplemental information 151 filename : the filename in zip (if NULL, '-' without quote will be used
152 if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local 152 *zipfi contain supplemental information
153 contains the extrafield data the the local header 153 if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local
154 if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global 154 contains the extrafield data the the local header
155 contains the extrafield data the the local header 155 if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
156 if comment != NULL, comment contain the comment string 156 contains the extrafield data the the local header
157 method contain the compression method (0 for store, Z_DEFLATED for deflate) 157 if comment != NULL, comment contain the comment string
158 level contain the level of compression (can be Z_DEFAULT_COMPRESSION) 158 method contain the compression method (0 for store, Z_DEFLATED for deflate)
159*/ 159 level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
160 160*/
161 161
162extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, 162
163 const char* filename, 163extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,
164 const zip_fileinfo* zipfi, 164 const char* filename,
165 const void* extrafield_local, 165 const zip_fileinfo* zipfi,
166 uInt size_extrafield_local, 166 const void* extrafield_local,
167 const void* extrafield_global, 167 uInt size_extrafield_local,
168 uInt size_extrafield_global, 168 const void* extrafield_global,
169 const char* comment, 169 uInt size_extrafield_global,
170 int method, 170 const char* comment,
171 int level, 171 int method,
172 int raw)); 172 int level,
173 173 int raw));
174/* 174
175 Same than zipOpenNewFileInZip, except if raw=1, we write raw file 175/*
176 */ 176 Same than zipOpenNewFileInZip, except if raw=1, we write raw file
177 177 */
178extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, 178
179 const char* filename, 179extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,
180 const zip_fileinfo* zipfi, 180 const char* filename,
181 const void* extrafield_local, 181 const zip_fileinfo* zipfi,
182 uInt size_extrafield_local, 182 const void* extrafield_local,
183 const void* extrafield_global, 183 uInt size_extrafield_local,
184 uInt size_extrafield_global, 184 const void* extrafield_global,
185 const char* comment, 185 uInt size_extrafield_global,
186 int method, 186 const char* comment,
187 int level, 187 int method,
188 int raw, 188 int level,
189 int windowBits, 189 int raw,
190 int memLevel, 190 int windowBits,
191 int strategy, 191 int memLevel,
192 const char* password, 192 int strategy,
193 uLong crcForCtypting)); 193 const char* password,
194 194 uLong crcForCtypting));
195/* 195
196 Same than zipOpenNewFileInZip2, except 196/*
197 windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 197 Same than zipOpenNewFileInZip2, except
198 password : crypting password (NULL for no crypting) 198 windowBits,memLevel,,strategy : see parameter strategy in deflateInit2
199 crcForCtypting : crc of file to compress (needed for crypting) 199 password : crypting password (NULL for no crypting)
200 */ 200 crcForCtypting : crc of file to compress (needed for crypting)
201 201 */
202 202
203extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, 203
204 const void* buf, 204extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,
205 unsigned len)); 205 const void* buf,
206/* 206 unsigned len));
207 Write data in the zipfile 207/*
208*/ 208 Write data in the zipfile
209 209*/
210extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); 210
211/* 211extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
212 Close the current file in the zipfile 212/*
213*/ 213 Close the current file in the zipfile
214 214*/
215extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, 215
216 uLong uncompressed_size, 216extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,
217 uLong crc32)); 217 uLong uncompressed_size,
218/* 218 uLong crc32));
219 Close the current file in the zipfile, for fiel opened with 219/*
220 parameter raw=1 in zipOpenNewFileInZip2 220 Close the current file in the zipfile, for fiel opened with
221 uncompressed_size and crc32 are value for the uncompressed size 221 parameter raw=1 in zipOpenNewFileInZip2
222*/ 222 uncompressed_size and crc32 are value for the uncompressed size
223 223*/
224extern int ZEXPORT zipClose OF((zipFile file, 224
225 const char* global_comment)); 225extern int ZEXPORT zipClose OF((zipFile file,
226/* 226 const char* global_comment));
227 Close the zipfile 227/*
228*/ 228 Close the zipfile
229 229*/
230#ifdef __cplusplus 230
231} 231#ifdef __cplusplus
232#endif 232}
233 233#endif
234#endif /* _zip_H */ 234
235#endif /* _zip_H */
diff --git a/contrib/testzlib/rdtsc64.asm b/contrib/testzlib/rdtsc64.asm
new file mode 100644
index 0000000..6b78a8b
--- /dev/null
+++ b/contrib/testzlib/rdtsc64.asm
@@ -0,0 +1,18 @@
1; rdtsc64.asm
2;
3; unsigned _int64 myrdtsc();
4;
5; return the performance rdtsc value, on AMD64/Intel EM64T
6;
7; compile with :
8; ml64.exe" /Flrdtsc64 /c /Zi rdtsc64.asm
9;
10.code
11myrdtsc PROC
12 rdtsc
13 shl rdx,32
14 or rax,rdx
15 ret
16myrdtsc ENDP
17
18END
diff --git a/contrib/testzlib/rdtsc64.obj b/contrib/testzlib/rdtsc64.obj
new file mode 100644
index 0000000..7905142
--- /dev/null
+++ b/contrib/testzlib/rdtsc64.obj
Binary files differ
diff --git a/contrib/testzlib/testzlib.c b/contrib/testzlib/testzlib.c
index fdabc5c..6c3ff9f 100644
--- a/contrib/testzlib/testzlib.c
+++ b/contrib/testzlib/testzlib.c
@@ -1,149 +1,258 @@
1 1
2#include <stdio.h> 2#include <stdio.h>
3#include <stdlib.h> 3#include <stdlib.h>
4#include <windows.h> 4#include <windows.h>
5#include "zlib.h" 5#include "zlib.h"
6 6
7int ReadFileMemory(const char* filename,long* plFileSize,void** pFilePtr) 7
8{ 8void MyDoMinus64(LARGE_INTEGER *R,LARGE_INTEGER A,LARGE_INTEGER B)
9 FILE* stream; 9{
10 void* ptr; 10 R->HighPart = A.HighPart - B.HighPart;
11 int retVal=1; 11 if (A.LowPart >= B.LowPart)
12 stream=fopen(filename, "rb"); 12 R->LowPart = A.LowPart - B.LowPart;
13 if (stream==NULL) 13 else
14 return 0; 14 {
15 15 R->LowPart = A.LowPart - B.LowPart;
16 fseek(stream,0,SEEK_END); 16 R->HighPart --;
17 17 }
18 *plFileSize=ftell(stream); 18}
19 fseek(stream,0,SEEK_SET); 19
20 ptr=malloc((*plFileSize)+1); 20#ifdef _AMD64_
21 if (ptr==NULL) 21unsigned _int64 myrdtsc();
22 retVal=0; 22void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)
23 else 23{
24 { 24 // printf("rdtsc = %I64x\n",myrdtsc());
25 if (fread(ptr, 1, *plFileSize,stream) != (*plFileSize)) 25 pbeginTime64->QuadPart=myrdtsc();
26 retVal=0; 26}
27 } 27
28 fclose(stream); 28LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
29 *pFilePtr=ptr; 29{
30 return retVal; 30 LARGE_INTEGER LIres;
31} 31 unsigned _int64 res=myrdtsc()-((unsigned _int64)(beginTime64.QuadPart));
32 32 LIres.QuadPart=res;
33int main(int argc, char *argv[]) 33 // printf("rdtsc = %I64x\n",myrdtsc());
34{ 34 return LIres;
35 int BlockSizeCompress=0x8000; 35}
36 int BlockSizeUncompress=0x8000; 36#else
37 int cprLevel=Z_DEFAULT_COMPRESSION ; 37void myGetRDTSC32(LARGE_INTEGER * pbeginTime64)
38 long lFileSize; 38{
39 unsigned char* FilePtr; 39 DWORD dwEdx,dwEax;
40 long lBufferSizeCpr; 40 _asm
41 long lBufferSizeUncpr; 41 {
42 long lCompressedSize=0; 42 rdtsc
43 unsigned char* CprPtr; 43 mov dwEax,eax
44 unsigned char* UncprPtr; 44 mov dwEdx,edx
45 long lSizeCpr,lSizeUncpr; 45 }
46 DWORD dwGetTick; 46 pbeginTime64->LowPart=dwEax;
47 47 pbeginTime64->HighPart=dwEdx;
48 if (argc<=1) 48}
49 { 49
50 printf("run TestZlib <File> [BlockSizeCompress] [BlockSizeUncompress] [compres. level]\n"); 50void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)
51 return 0; 51{
52 } 52 myGetRDTSC32(pbeginTime64);
53 53}
54 if (ReadFileMemory(argv[1],&lFileSize,&FilePtr)==0) 54
55 { 55LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
56 printf("error reading %s\n",argv[1]); 56{
57 return 1; 57 LARGE_INTEGER LIres,endTime64;
58 } 58 myGetRDTSC32(&endTime64);
59 else printf("file %s read, %u bytes\n",argv[1],lFileSize); 59
60 60 LIres.LowPart=LIres.HighPart=0;
61 if (argc>=3) 61 MyDoMinus64(&LIres,endTime64,beginTime64);
62 BlockSizeCompress=atol(argv[2]); 62 return LIres;
63 63}
64 if (argc>=4) 64#endif
65 BlockSizeUncompress=atol(argv[3]); 65
66 66
67 if (argc>=5) 67void BeginCountPerfCounter(LARGE_INTEGER * pbeginTime64,BOOL fComputeTimeQueryPerf)
68 cprLevel=(int)atol(argv[4]); 68{
69 69 if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(pbeginTime64)))
70 lBufferSizeCpr = lFileSize + (lFileSize/0x10) + 0x200; 70 {
71 lBufferSizeUncpr = lBufferSizeCpr; 71 pbeginTime64->LowPart = GetTickCount();
72 72 pbeginTime64->HighPart = 0;
73 CprPtr=(unsigned char*)malloc(lBufferSizeCpr + BlockSizeCompress); 73 }
74 UncprPtr=(unsigned char*)malloc(lBufferSizeUncpr + BlockSizeUncompress); 74}
75 75
76 dwGetTick=GetTickCount(); 76DWORD GetMsecSincePerfCounter(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
77 { 77{
78 z_stream zcpr; 78 LARGE_INTEGER endTime64,ticksPerSecond,ticks;
79 int ret=Z_OK; 79 DWORDLONG ticksShifted,tickSecShifted;
80 long lOrigToDo = lFileSize; 80 DWORD dwLog=16+0;
81 long lOrigDone = 0; 81 DWORD dwRet;
82 int step=0; 82 if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(&endTime64)))
83 memset(&zcpr,0,sizeof(z_stream)); 83 dwRet = (GetTickCount() - beginTime64.LowPart)*1;
84 deflateInit(&zcpr,cprLevel); 84 else
85 85 {
86 zcpr.next_in = FilePtr; 86 MyDoMinus64(&ticks,endTime64,beginTime64);
87 zcpr.next_out = CprPtr; 87 QueryPerformanceFrequency(&ticksPerSecond);
88 88
89 89
90 do 90 {
91 { 91 ticksShifted = Int64ShrlMod32(*(DWORDLONG*)&ticks,dwLog);
92 long all_read_before = zcpr.total_in; 92 tickSecShifted = Int64ShrlMod32(*(DWORDLONG*)&ticksPerSecond,dwLog);
93 zcpr.avail_in = min(lOrigToDo,BlockSizeCompress); 93
94 zcpr.avail_out = BlockSizeCompress; 94 }
95 ret=deflate(&zcpr,(zcpr.avail_in==lOrigToDo) ? Z_FINISH : Z_SYNC_FLUSH); 95
96 lOrigDone += (zcpr.total_in-all_read_before); 96 dwRet = (DWORD)((((DWORD)ticksShifted)*1000)/(DWORD)(tickSecShifted));
97 lOrigToDo -= (zcpr.total_in-all_read_before); 97 dwRet *=1;
98 step++; 98 }
99 } while (ret==Z_OK); 99 return dwRet;
100 100}
101 lSizeCpr=zcpr.total_out; 101
102 deflateEnd(&zcpr); 102int ReadFileMemory(const char* filename,long* plFileSize,void** pFilePtr)
103 dwGetTick=GetTickCount()-dwGetTick; 103{
104 printf("total compress size = %u, in %u step\n",lSizeCpr,step); 104 FILE* stream;
105 printf("time = %u msec = %f sec\n\n",dwGetTick,dwGetTick/(double)1000.); 105 void* ptr;
106 } 106 int retVal=1;
107 107 stream=fopen(filename, "rb");
108 dwGetTick=GetTickCount(); 108 if (stream==NULL)
109 { 109 return 0;
110 z_stream zcpr; 110
111 int ret=Z_OK; 111 fseek(stream,0,SEEK_END);
112 long lOrigToDo = lSizeCpr; 112
113 long lOrigDone = 0; 113 *plFileSize=ftell(stream);
114 int step=0; 114 fseek(stream,0,SEEK_SET);
115 memset(&zcpr,0,sizeof(z_stream)); 115 ptr=malloc((*plFileSize)+1);
116 inflateInit(&zcpr); 116 if (ptr==NULL)
117 117 retVal=0;
118 zcpr.next_in = CprPtr; 118 else
119 zcpr.next_out = UncprPtr; 119 {
120 120 if (fread(ptr, 1, *plFileSize,stream) != (*plFileSize))
121 121 retVal=0;
122 do 122 }
123 { 123 fclose(stream);
124 long all_read_before = zcpr.total_in; 124 *pFilePtr=ptr;
125 zcpr.avail_in = min(lOrigToDo,BlockSizeUncompress); 125 return retVal;
126 zcpr.avail_out = BlockSizeUncompress; 126}
127 ret=inflate(&zcpr,Z_SYNC_FLUSH); 127
128 lOrigDone += (zcpr.total_in-all_read_before); 128int main(int argc, char *argv[])
129 lOrigToDo -= (zcpr.total_in-all_read_before); 129{
130 step++; 130 int BlockSizeCompress=0x8000;
131 } while (ret==Z_OK); 131 int BlockSizeUncompress=0x8000;
132 132 int cprLevel=Z_DEFAULT_COMPRESSION ;
133 lSizeUncpr=zcpr.total_out; 133 long lFileSize;
134 inflateEnd(&zcpr); 134 unsigned char* FilePtr;
135 dwGetTick=GetTickCount()-dwGetTick; 135 long lBufferSizeCpr;
136 printf("total uncompress size = %u, in %u step\n",lSizeUncpr,step); 136 long lBufferSizeUncpr;
137 printf("time = %u msec = %f sec\n\n",dwGetTick,dwGetTick/(double)1000.); 137 long lCompressedSize=0;
138 } 138 unsigned char* CprPtr;
139 139 unsigned char* UncprPtr;
140 if (lSizeUncpr==lFileSize) 140 long lSizeCpr,lSizeUncpr;
141 { 141 DWORD dwGetTick,dwMsecQP;
142 if (memcmp(FilePtr,UncprPtr,lFileSize)==0) 142 LARGE_INTEGER li_qp,li_rdtsc,dwResRdtsc;
143 printf("compare ok\n"); 143
144 144 if (argc<=1)
145 } 145 {
146 146 printf("run TestZlib <File> [BlockSizeCompress] [BlockSizeUncompress] [compres. level]\n");
147 return 0; 147 return 0;
148 148 }
149} 149
150 if (ReadFileMemory(argv[1],&lFileSize,&FilePtr)==0)
151 {
152 printf("error reading %s\n",argv[1]);
153 return 1;
154 }
155 else printf("file %s read, %u bytes\n",argv[1],lFileSize);
156
157 if (argc>=3)
158 BlockSizeCompress=atol(argv[2]);
159
160 if (argc>=4)
161 BlockSizeUncompress=atol(argv[3]);
162
163 if (argc>=5)
164 cprLevel=(int)atol(argv[4]);
165
166 lBufferSizeCpr = lFileSize + (lFileSize/0x10) + 0x200;
167 lBufferSizeUncpr = lBufferSizeCpr;
168
169 CprPtr=(unsigned char*)malloc(lBufferSizeCpr + BlockSizeCompress);
170
171 BeginCountPerfCounter(&li_qp,TRUE);
172 dwGetTick=GetTickCount();
173 BeginCountRdtsc(&li_rdtsc);
174 {
175 z_stream zcpr;
176 int ret=Z_OK;
177 long lOrigToDo = lFileSize;
178 long lOrigDone = 0;
179 int step=0;
180 memset(&zcpr,0,sizeof(z_stream));
181 deflateInit(&zcpr,cprLevel);
182
183 zcpr.next_in = FilePtr;
184 zcpr.next_out = CprPtr;
185
186
187 do
188 {
189 long all_read_before = zcpr.total_in;
190 zcpr.avail_in = min(lOrigToDo,BlockSizeCompress);
191 zcpr.avail_out = BlockSizeCompress;
192 ret=deflate(&zcpr,(zcpr.avail_in==lOrigToDo) ? Z_FINISH : Z_SYNC_FLUSH);
193 lOrigDone += (zcpr.total_in-all_read_before);
194 lOrigToDo -= (zcpr.total_in-all_read_before);
195 step++;
196 } while (ret==Z_OK);
197
198 lSizeCpr=zcpr.total_out;
199 deflateEnd(&zcpr);
200 dwGetTick=GetTickCount()-dwGetTick;
201 dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE);
202 dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE);
203 printf("total compress size = %u, in %u step\n",lSizeCpr,step);
204 printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.);
205 printf("defcpr time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.);
206 printf("defcpr result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart);
207 }
208
209 CprPtr=(unsigned char*)realloc(CprPtr,lSizeCpr);
210 UncprPtr=(unsigned char*)malloc(lBufferSizeUncpr + BlockSizeUncompress);
211
212 BeginCountPerfCounter(&li_qp,TRUE);
213 dwGetTick=GetTickCount();
214 BeginCountRdtsc(&li_rdtsc);
215 {
216 z_stream zcpr;
217 int ret=Z_OK;
218 long lOrigToDo = lSizeCpr;
219 long lOrigDone = 0;
220 int step=0;
221 memset(&zcpr,0,sizeof(z_stream));
222 inflateInit(&zcpr);
223
224 zcpr.next_in = CprPtr;
225 zcpr.next_out = UncprPtr;
226
227
228 do
229 {
230 long all_read_before = zcpr.total_in;
231 zcpr.avail_in = min(lOrigToDo,BlockSizeUncompress);
232 zcpr.avail_out = BlockSizeUncompress;
233 ret=inflate(&zcpr,Z_SYNC_FLUSH);
234 lOrigDone += (zcpr.total_in-all_read_before);
235 lOrigToDo -= (zcpr.total_in-all_read_before);
236 step++;
237 } while (ret==Z_OK);
238
239 lSizeUncpr=zcpr.total_out;
240 inflateEnd(&zcpr);
241 dwGetTick=GetTickCount()-dwGetTick;
242 dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE);
243 dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE);
244 printf("total uncompress size = %u, in %u step\n",lSizeUncpr,step);
245 printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.);
246 printf("uncpr time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.);
247 printf("uncpr result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart);
248 }
249
250 if (lSizeUncpr==lFileSize)
251 {
252 if (memcmp(FilePtr,UncprPtr,lFileSize)==0)
253 printf("compare ok\n");
254
255 }
256
257 return 0;
258}
diff --git a/contrib/testzlib/testzlib.txt b/contrib/testzlib/testzlib.txt
new file mode 100644
index 0000000..62258f1
--- /dev/null
+++ b/contrib/testzlib/testzlib.txt
@@ -0,0 +1,10 @@
1To build testzLib with Visual Studio 2005:
2
3copy to a directory file from :
4- root of zLib tree
5- contrib/testzlib
6- contrib/masmx86
7- contrib/masmx64
8- contrib/vstudio/vc7
9
10and open testzlib8.sln \ No newline at end of file
diff --git a/contrib/testzlib/testzlib8.sln b/contrib/testzlib/testzlib8.sln
new file mode 100644
index 0000000..794f72d
--- /dev/null
+++ b/contrib/testzlib/testzlib8.sln
@@ -0,0 +1,32 @@
1
2Microsoft Visual Studio Solution File, Format Version 9.00
3# Visual Studio 2005
4Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib8", "testzlib8.vcproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"
5EndProject
6Global
7 GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 Debug|Win32 = Debug|Win32
9 Debug|Win64 (AMD64) = Debug|Win64 (AMD64)
10 Release|Win32 = Release|Win32
11 Release|Win64 (AMD64) = Release|Win64 (AMD64)
12 ReleaseAsm|Win32 = ReleaseAsm|Win32
13 ReleaseAsm|Win64 (AMD64) = ReleaseAsm|Win64 (AMD64)
14 EndGlobalSection
15 GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32
17 {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32
18 {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win64 (AMD64).ActiveCfg = Debug|Win64 (AMD64)
19 {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win64 (AMD64).Build.0 = Debug|Win64 (AMD64)
20 {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32
21 {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32
22 {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win64 (AMD64).ActiveCfg = Release|Win64 (AMD64)
23 {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win64 (AMD64).Build.0 = Release|Win64 (AMD64)
24 {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseAsm|Win32.ActiveCfg = ReleaseAsm|Win32
25 {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseAsm|Win32.Build.0 = ReleaseAsm|Win32
26 {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseAsm|Win64 (AMD64).ActiveCfg = ReleaseAsm|Win64 (AMD64)
27 {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseAsm|Win64 (AMD64).Build.0 = ReleaseAsm|Win64 (AMD64)
28 EndGlobalSection
29 GlobalSection(SolutionProperties) = preSolution
30 HideSolutionNode = FALSE
31 EndGlobalSection
32EndGlobal
diff --git a/contrib/testzlib/testzlib8.vcproj b/contrib/testzlib/testzlib8.vcproj
new file mode 100644
index 0000000..3cab776
--- /dev/null
+++ b/contrib/testzlib/testzlib8.vcproj
@@ -0,0 +1,638 @@
1<?xml version="1.0" encoding="Windows-1252"?>
2<VisualStudioProject
3 ProjectType="Visual C++"
4 Version="8,00"
5 Name="testzlib8"
6 ProjectGUID="{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"
7 Keyword="Win32Proj"
8 >
9 <Platforms>
10 <Platform
11 Name="Win32"
12 />
13 <Platform
14 Name="Win64 (AMD64)"
15 />
16 </Platforms>
17 <ToolFiles>
18 <DefaultToolFile
19 FileName="masm.tool"
20 />
21 </ToolFiles>
22 <Configurations>
23 <Configuration
24 Name="Debug|Win32"
25 OutputDirectory="x86\$(ConfigurationName)"
26 IntermediateDirectory="x86\$(ConfigurationName)"
27 ConfigurationType="1"
28 CharacterSet="2"
29 >
30 <Tool
31 Name="VCPreBuildEventTool"
32 />
33 <Tool
34 Name="VCCustomBuildTool"
35 />
36 <Tool
37 Name="MASM"
38 />
39 <Tool
40 Name="VCXMLDataGeneratorTool"
41 />
42 <Tool
43 Name="VCWebServiceProxyGeneratorTool"
44 />
45 <Tool
46 Name="VCMIDLTool"
47 />
48 <Tool
49 Name="VCCLCompilerTool"
50 Optimization="0"
51 PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
52 MinimalRebuild="TRUE"
53 BasicRuntimeChecks="3"
54 RuntimeLibrary="1"
55 UsePrecompiledHeader="0"
56 AssemblerOutput="4"
57 WarningLevel="3"
58 Detect64BitPortabilityProblems="TRUE"
59 DebugInformationFormat="4"
60 />
61 <Tool
62 Name="VCManagedResourceCompilerTool"
63 />
64 <Tool
65 Name="VCResourceCompilerTool"
66 />
67 <Tool
68 Name="VCPreLinkEventTool"
69 />
70 <Tool
71 Name="VCLinkerTool"
72 AdditionalDependencies="gvmat32.obj inffas32.obj"
73 OutputFile="$(OutDir)/testzlib.exe"
74 LinkIncremental="2"
75 GenerateDebugInformation="TRUE"
76 ProgramDatabaseFile="$(OutDir)/testzlib.pdb"
77 SubSystem="1"
78 TargetMachine="1"
79 />
80 <Tool
81 Name="VCALinkTool"
82 />
83 <Tool
84 Name="VCManifestTool"
85 />
86 <Tool
87 Name="VCXDCMakeTool"
88 />
89 <Tool
90 Name="VCBscMakeTool"
91 />
92 <Tool
93 Name="VCAppVerifierTool"
94 />
95 <Tool
96 Name="VCWebDeploymentTool"
97 />
98 <Tool
99 Name="VCPostBuildEventTool"
100 />
101 </Configuration>
102 <Configuration
103 Name="Debug|Win64 (AMD64)"
104 OutputDirectory="amd64\$(ConfigurationName)"
105 IntermediateDirectory="amd64\$(ConfigurationName)"
106 ConfigurationType="1"
107 CharacterSet="2"
108 >
109 <Tool
110 Name="VCPreBuildEventTool"
111 />
112 <Tool
113 Name="VCCustomBuildTool"
114 />
115 <Tool
116 Name="MASM"
117 />
118 <Tool
119 Name="VCXMLDataGeneratorTool"
120 />
121 <Tool
122 Name="VCWebServiceProxyGeneratorTool"
123 />
124 <Tool
125 Name="VCMIDLTool"
126 TargetEnvironment="3"
127 />
128 <Tool
129 Name="VCCLCompilerTool"
130 Optimization="0"
131 PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
132 MinimalRebuild="TRUE"
133 BasicRuntimeChecks="3"
134 RuntimeLibrary="1"
135 UsePrecompiledHeader="0"
136 AssemblerOutput="4"
137 WarningLevel="3"
138 Detect64BitPortabilityProblems="TRUE"
139 DebugInformationFormat="3"
140 />
141 <Tool
142 Name="VCManagedResourceCompilerTool"
143 />
144 <Tool
145 Name="VCResourceCompilerTool"
146 />
147 <Tool
148 Name="VCPreLinkEventTool"
149 CommandLine=""
150 />
151 <Tool
152 Name="VCLinkerTool"
153 AdditionalDependencies="gvmat64.obj inffasx64.obj rdtsc64.obj"
154 OutputFile="$(OutDir)/testzlib.exe"
155 LinkIncremental="2"
156 GenerateDebugInformation="TRUE"
157 ProgramDatabaseFile="$(OutDir)/testzlib.pdb"
158 SubSystem="1"
159 TargetMachine="17"
160 />
161 <Tool
162 Name="VCALinkTool"
163 />
164 <Tool
165 Name="VCManifestTool"
166 />
167 <Tool
168 Name="VCXDCMakeTool"
169 />
170 <Tool
171 Name="VCBscMakeTool"
172 />
173 <Tool
174 Name="VCWebDeploymentTool"
175 />
176 <Tool
177 Name="VCPostBuildEventTool"
178 />
179 </Configuration>
180 <Configuration
181 Name="Release|Win32"
182 OutputDirectory="x86\$(ConfigurationName)"
183 IntermediateDirectory="x86\$(ConfigurationName)"
184 ConfigurationType="1"
185 CharacterSet="2"
186 >
187 <Tool
188 Name="VCPreBuildEventTool"
189 />
190 <Tool
191 Name="VCCustomBuildTool"
192 />
193 <Tool
194 Name="MASM"
195 />
196 <Tool
197 Name="VCXMLDataGeneratorTool"
198 />
199 <Tool
200 Name="VCWebServiceProxyGeneratorTool"
201 />
202 <Tool
203 Name="VCMIDLTool"
204 />
205 <Tool
206 Name="VCCLCompilerTool"
207 Optimization="2"
208 InlineFunctionExpansion="1"
209 OmitFramePointers="TRUE"
210 PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
211 StringPooling="TRUE"
212 RuntimeLibrary="0"
213 EnableFunctionLevelLinking="TRUE"
214 UsePrecompiledHeader="0"
215 WarningLevel="3"
216 Detect64BitPortabilityProblems="TRUE"
217 DebugInformationFormat="3"
218 />
219 <Tool
220 Name="VCManagedResourceCompilerTool"
221 />
222 <Tool
223 Name="VCResourceCompilerTool"
224 />
225 <Tool
226 Name="VCPreLinkEventTool"
227 />
228 <Tool
229 Name="VCLinkerTool"
230 OutputFile="$(OutDir)/testzlib.exe"
231 LinkIncremental="1"
232 GenerateDebugInformation="TRUE"
233 SubSystem="1"
234 OptimizeReferences="2"
235 EnableCOMDATFolding="2"
236 OptimizeForWindows98="1"
237 TargetMachine="1"
238 />
239 <Tool
240 Name="VCALinkTool"
241 />
242 <Tool
243 Name="VCManifestTool"
244 />
245 <Tool
246 Name="VCXDCMakeTool"
247 />
248 <Tool
249 Name="VCBscMakeTool"
250 />
251 <Tool
252 Name="VCAppVerifierTool"
253 />
254 <Tool
255 Name="VCWebDeploymentTool"
256 />
257 <Tool
258 Name="VCPostBuildEventTool"
259 />
260 </Configuration>
261 <Configuration
262 Name="Release|Win64 (AMD64)"
263 OutputDirectory="amd64\$(ConfigurationName)"
264 IntermediateDirectory="amd64\$(ConfigurationName)"
265 ConfigurationType="1"
266 CharacterSet="2"
267 >
268 <Tool
269 Name="VCPreBuildEventTool"
270 />
271 <Tool
272 Name="VCCustomBuildTool"
273 />
274 <Tool
275 Name="MASM"
276 />
277 <Tool
278 Name="VCXMLDataGeneratorTool"
279 />
280 <Tool
281 Name="VCWebServiceProxyGeneratorTool"
282 />
283 <Tool
284 Name="VCMIDLTool"
285 TargetEnvironment="3"
286 />
287 <Tool
288 Name="VCCLCompilerTool"
289 Optimization="2"
290 InlineFunctionExpansion="1"
291 OmitFramePointers="TRUE"
292 PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
293 StringPooling="TRUE"
294 RuntimeLibrary="0"
295 EnableFunctionLevelLinking="TRUE"
296 UsePrecompiledHeader="0"
297 WarningLevel="3"
298 Detect64BitPortabilityProblems="TRUE"
299 DebugInformationFormat="3"
300 />
301 <Tool
302 Name="VCManagedResourceCompilerTool"
303 />
304 <Tool
305 Name="VCResourceCompilerTool"
306 />
307 <Tool
308 Name="VCPreLinkEventTool"
309 />
310 <Tool
311 Name="VCLinkerTool"
312 AdditionalDependencies="rdtsc64.obj"
313 OutputFile="$(OutDir)/testzlib.exe"
314 LinkIncremental="1"
315 GenerateDebugInformation="TRUE"
316 SubSystem="1"
317 OptimizeReferences="2"
318 EnableCOMDATFolding="2"
319 OptimizeForWindows98="1"
320 TargetMachine="17"
321 />
322 <Tool
323 Name="VCALinkTool"
324 />
325 <Tool
326 Name="VCManifestTool"
327 />
328 <Tool
329 Name="VCXDCMakeTool"
330 />
331 <Tool
332 Name="VCBscMakeTool"
333 />
334 <Tool
335 Name="VCWebDeploymentTool"
336 />
337 <Tool
338 Name="VCPostBuildEventTool"
339 />
340 </Configuration>
341 <Configuration
342 Name="ReleaseAsm|Win32"
343 OutputDirectory="x86\$(ConfigurationName)"
344 IntermediateDirectory="x86\$(ConfigurationName)"
345 ConfigurationType="1"
346 CharacterSet="2"
347 >
348 <Tool
349 Name="VCPreBuildEventTool"
350 />
351 <Tool
352 Name="VCCustomBuildTool"
353 />
354 <Tool
355 Name="MASM"
356 />
357 <Tool
358 Name="VCXMLDataGeneratorTool"
359 />
360 <Tool
361 Name="VCWebServiceProxyGeneratorTool"
362 />
363 <Tool
364 Name="VCMIDLTool"
365 />
366 <Tool
367 Name="VCCLCompilerTool"
368 Optimization="2"
369 InlineFunctionExpansion="1"
370 OmitFramePointers="TRUE"
371 PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
372 StringPooling="TRUE"
373 RuntimeLibrary="0"
374 EnableFunctionLevelLinking="TRUE"
375 UsePrecompiledHeader="0"
376 WarningLevel="3"
377 Detect64BitPortabilityProblems="TRUE"
378 DebugInformationFormat="3"
379 />
380 <Tool
381 Name="VCManagedResourceCompilerTool"
382 />
383 <Tool
384 Name="VCResourceCompilerTool"
385 />
386 <Tool
387 Name="VCPreLinkEventTool"
388 />
389 <Tool
390 Name="VCLinkerTool"
391 AdditionalDependencies="gvmat32.obj inffas32.obj"
392 OutputFile="$(OutDir)/testzlib.exe"
393 LinkIncremental="1"
394 GenerateDebugInformation="TRUE"
395 SubSystem="1"
396 OptimizeReferences="2"
397 EnableCOMDATFolding="2"
398 OptimizeForWindows98="1"
399 TargetMachine="1"
400 />
401 <Tool
402 Name="VCALinkTool"
403 />
404 <Tool
405 Name="VCManifestTool"
406 />
407 <Tool
408 Name="VCXDCMakeTool"
409 />
410 <Tool
411 Name="VCBscMakeTool"
412 />
413 <Tool
414 Name="VCAppVerifierTool"
415 />
416 <Tool
417 Name="VCWebDeploymentTool"
418 />
419 <Tool
420 Name="VCPostBuildEventTool"
421 />
422 </Configuration>
423 <Configuration
424 Name="ReleaseAsm|Win64 (AMD64)"
425 OutputDirectory="amd64\$(ConfigurationName)"
426 IntermediateDirectory="amd64\$(ConfigurationName)"
427 ConfigurationType="1"
428 CharacterSet="2"
429 >
430 <Tool
431 Name="VCPreBuildEventTool"
432 CommandLine=""
433 />
434 <Tool
435 Name="VCCustomBuildTool"
436 />
437 <Tool
438 Name="MASM"
439 />
440 <Tool
441 Name="VCXMLDataGeneratorTool"
442 />
443 <Tool
444 Name="VCWebServiceProxyGeneratorTool"
445 />
446 <Tool
447 Name="VCMIDLTool"
448 TargetEnvironment="3"
449 />
450 <Tool
451 Name="VCCLCompilerTool"
452 Optimization="2"
453 InlineFunctionExpansion="1"
454 OmitFramePointers="TRUE"
455 PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
456 StringPooling="TRUE"
457 RuntimeLibrary="0"
458 EnableFunctionLevelLinking="TRUE"
459 UsePrecompiledHeader="0"
460 AssemblerOutput="4"
461 WarningLevel="3"
462 Detect64BitPortabilityProblems="TRUE"
463 DebugInformationFormat="3"
464 />
465 <Tool
466 Name="VCManagedResourceCompilerTool"
467 />
468 <Tool
469 Name="VCResourceCompilerTool"
470 />
471 <Tool
472 Name="VCPreLinkEventTool"
473 CommandLine=""
474 />
475 <Tool
476 Name="VCLinkerTool"
477 AdditionalDependencies="gvmat64.obj inffasx64.obj rdtsc64.obj"
478 OutputFile="$(OutDir)/testzlib.exe"
479 LinkIncremental="1"
480 GenerateDebugInformation="TRUE"
481 SubSystem="1"
482 OptimizeReferences="2"
483 EnableCOMDATFolding="2"
484 OptimizeForWindows98="1"
485 TargetMachine="17"
486 />
487 <Tool
488 Name="VCALinkTool"
489 />
490 <Tool
491 Name="VCManifestTool"
492 />
493 <Tool
494 Name="VCXDCMakeTool"
495 />
496 <Tool
497 Name="VCBscMakeTool"
498 />
499 <Tool
500 Name="VCWebDeploymentTool"
501 />
502 <Tool
503 Name="VCPostBuildEventTool"
504 />
505 </Configuration>
506 </Configurations>
507 <References>
508 </References>
509 <Files>
510 <Filter
511 Name="Source Files"
512 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
513 >
514 <File
515 RelativePath=".\adler32.c"
516 >
517 </File>
518 <File
519 RelativePath=".\compress.c"
520 >
521 </File>
522 <File
523 RelativePath=".\crc32.c"
524 >
525 </File>
526 <File
527 RelativePath=".\deflate.c"
528 >
529 </File>
530 <File
531 RelativePath=".\gvmat32c.c"
532 >
533 <FileConfiguration
534 Name="Debug|Win64 (AMD64)"
535 ExcludedFromBuild="TRUE"
536 >
537 <Tool
538 Name="VCCLCompilerTool"
539 />
540 </FileConfiguration>
541 <FileConfiguration
542 Name="Release|Win64 (AMD64)"
543 ExcludedFromBuild="TRUE"
544 >
545 <Tool
546 Name="VCCLCompilerTool"
547 />
548 </FileConfiguration>
549 <FileConfiguration
550 Name="ReleaseAsm|Win32"
551 >
552 <Tool
553 Name="VCCLCompilerTool"
554 />
555 </FileConfiguration>
556 <FileConfiguration
557 Name="ReleaseAsm|Win64 (AMD64)"
558 ExcludedFromBuild="TRUE"
559 >
560 <Tool
561 Name="VCCLCompilerTool"
562 />
563 </FileConfiguration>
564 </File>
565 <File
566 RelativePath=".\infback.c"
567 >
568 </File>
569 <File
570 RelativePath=".\inffas8664.c"
571 >
572 <FileConfiguration
573 Name="Debug|Win32"
574 ExcludedFromBuild="TRUE"
575 >
576 <Tool
577 Name="VCCLCompilerTool"
578 />
579 </FileConfiguration>
580 <FileConfiguration
581 Name="Release|Win32"
582 >
583 <Tool
584 Name="VCCLCompilerTool"
585 />
586 </FileConfiguration>
587 <FileConfiguration
588 Name="ReleaseAsm|Win32"
589 ExcludedFromBuild="TRUE"
590 >
591 <Tool
592 Name="VCCLCompilerTool"
593 />
594 </FileConfiguration>
595 </File>
596 <File
597 RelativePath=".\inffast.c"
598 >
599 </File>
600 <File
601 RelativePath=".\inflate.c"
602 >
603 </File>
604 <File
605 RelativePath=".\inftrees.c"
606 >
607 </File>
608 <File
609 RelativePath="testzlib.c"
610 >
611 </File>
612 <File
613 RelativePath=".\trees.c"
614 >
615 </File>
616 <File
617 RelativePath=".\uncompr.c"
618 >
619 </File>
620 <File
621 RelativePath=".\zutil.c"
622 >
623 </File>
624 </Filter>
625 <Filter
626 Name="Header Files"
627 Filter="h;hpp;hxx;hm;inl;inc"
628 >
629 </Filter>
630 <Filter
631 Name="Resource Files"
632 Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
633 >
634 </Filter>
635 </Files>
636 <Globals>
637 </Globals>
638</VisualStudioProject>
diff --git a/contrib/vstudio/vc7/gvmat32.obj b/contrib/vstudio/vc7/gvmat32.obj
index 5b2f856..ebb3262 100644
--- a/contrib/vstudio/vc7/gvmat32.obj
+++ b/contrib/vstudio/vc7/gvmat32.obj
Binary files differ
diff --git a/contrib/vstudio/vc7/inffas32.obj b/contrib/vstudio/vc7/inffas32.obj
index a541a5a..bd6664d 100644
--- a/contrib/vstudio/vc7/inffas32.obj
+++ b/contrib/vstudio/vc7/inffas32.obj
Binary files differ
diff --git a/contrib/vstudio/vc7/zlib.rc b/contrib/vstudio/vc7/zlib.rc
index d35cef0..d0651ec 100644
--- a/contrib/vstudio/vc7/zlib.rc
+++ b/contrib/vstudio/vc7/zlib.rc
@@ -2,8 +2,8 @@
2 2
3#define IDR_VERSION1 1 3#define IDR_VERSION1 1
4IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE 4IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
5 FILEVERSION 1,2,2,2 5 FILEVERSION 1,2,2,3
6 PRODUCTVERSION 1,2,2,2 6 PRODUCTVERSION 1,2,2,3
7 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 7 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
8 FILEFLAGS 0 8 FILEFLAGS 0
9 FILEOS VOS_DOS_WINDOWS32 9 FILEOS VOS_DOS_WINDOWS32
@@ -17,7 +17,7 @@ BEGIN
17 17
18 BEGIN 18 BEGIN
19 VALUE "FileDescription", "zlib data compression library\0" 19 VALUE "FileDescription", "zlib data compression library\0"
20 VALUE "FileVersion", "1.2.2.2\0" 20 VALUE "FileVersion", "1.2.2.3\0"
21 VALUE "InternalName", "zlib\0" 21 VALUE "InternalName", "zlib\0"
22 VALUE "OriginalFilename", "zlib.dll\0" 22 VALUE "OriginalFilename", "zlib.dll\0"
23 VALUE "ProductName", "ZLib.DLL\0" 23 VALUE "ProductName", "ZLib.DLL\0"
diff --git a/crc32.c b/crc32.c
index 62b025f..9b1de04 100644
--- a/crc32.c
+++ b/crc32.c
@@ -1,5 +1,5 @@
1/* crc32.c -- compute the CRC-32 of a data stream 1/* crc32.c -- compute the CRC-32 of a data stream
2 * Copyright (C) 1995-2004 Mark Adler 2 * Copyright (C) 1995-2005 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 * 4 *
5 * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster 5 * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
@@ -273,7 +273,7 @@ local unsigned long crc32_little(crc, buf, len)
273 len--; 273 len--;
274 } 274 }
275 275
276 buf4 = (const u4 FAR *)buf; 276 buf4 = (const u4 FAR *)(const void FAR *)buf;
277 while (len >= 32) { 277 while (len >= 32) {
278 DOLIT32; 278 DOLIT32;
279 len -= 32; 279 len -= 32;
@@ -313,7 +313,7 @@ local unsigned long crc32_big(crc, buf, len)
313 len--; 313 len--;
314 } 314 }
315 315
316 buf4 = (const u4 FAR *)buf; 316 buf4 = (const u4 FAR *)(const void FAR *)buf;
317 buf4--; 317 buf4--;
318 while (len >= 32) { 318 while (len >= 32) {
319 DOBIG32; 319 DOBIG32;
diff --git a/deflate.c b/deflate.c
index 159f946..5cd9a92 100644
--- a/deflate.c
+++ b/deflate.c
@@ -1,5 +1,5 @@
1/* deflate.c -- compress data using the deflation algorithm 1/* deflate.c -- compress data using the deflation algorithm
2 * Copyright (C) 1995-2004 Jean-loup Gailly. 2 * Copyright (C) 1995-2005 Jean-loup Gailly.
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
@@ -52,7 +52,7 @@
52#include "deflate.h" 52#include "deflate.h"
53 53
54const char deflate_copyright[] = 54const char deflate_copyright[] =
55 " deflate 1.2.2.2 Copyright 1995-2004 Jean-loup Gailly "; 55 " deflate 1.2.2.3 Copyright 1995-2005 Jean-loup Gailly ";
56/* 56/*
57 If you use the zlib library in a product, an acknowledgment is welcome 57 If you use the zlib library in a product, an acknowledgment is welcome
58 in the documentation of your product. If for some reason you cannot 58 in the documentation of your product. If for some reason you cannot
@@ -334,9 +334,7 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
334 if (length < MIN_MATCH) return Z_OK; 334 if (length < MIN_MATCH) return Z_OK;
335 if (length > MAX_DIST(s)) { 335 if (length > MAX_DIST(s)) {
336 length = MAX_DIST(s); 336 length = MAX_DIST(s);
337#ifndef USE_DICT_HEAD
338 dictionary += dictLength - length; /* use the tail of the dictionary */ 337 dictionary += dictLength - length; /* use the tail of the dictionary */
339#endif
340 } 338 }
341 zmemcpy(s->window, dictionary, length); 339 zmemcpy(s->window, dictionary, length);
342 s->strstart = length; 340 s->strstart = length;
@@ -452,6 +450,25 @@ int ZEXPORT deflateParams(strm, level, strategy)
452 return err; 450 return err;
453} 451}
454 452
453/* ========================================================================= */
454int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
455 z_streamp strm;
456 int good_length;
457 int max_lazy;
458 int nice_length;
459 int max_chain;
460{
461 deflate_state *s;
462
463 if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
464 s = strm->state;
465 s->good_match = good_length;
466 s->max_lazy_match = max_lazy;
467 s->nice_match = nice_length;
468 s->max_chain_length = max_chain;
469 return Z_OK;
470}
471
455/* ========================================================================= 472/* =========================================================================
456 * For the default windowBits of 15 and memLevel of 8, this function returns 473 * For the default windowBits of 15 and memLevel of 8, this function returns
457 * a close to exact, as well as small, upper bound on the compressed size. 474 * a close to exact, as well as small, upper bound on the compressed size.
@@ -986,9 +1003,11 @@ local void lm_init (s)
986 s->match_length = s->prev_length = MIN_MATCH-1; 1003 s->match_length = s->prev_length = MIN_MATCH-1;
987 s->match_available = 0; 1004 s->match_available = 0;
988 s->ins_h = 0; 1005 s->ins_h = 0;
1006#ifndef FASTEST
989#ifdef ASMV 1007#ifdef ASMV
990 match_init(); /* initialize the asm code */ 1008 match_init(); /* initialize the asm code */
991#endif 1009#endif
1010#endif
992} 1011}
993 1012
994#ifndef FASTEST 1013#ifndef FASTEST
diff --git a/examples/README.examples b/examples/README.examples
index 1084525..75e9970 100644
--- a/examples/README.examples
+++ b/examples/README.examples
@@ -4,6 +4,13 @@ fitblk.c
4 compress just enough input to nearly fill a requested output size 4 compress just enough input to nearly fill a requested output size
5 - zlib isn't designed to do this, but fitblk does it anyway 5 - zlib isn't designed to do this, but fitblk does it anyway
6 6
7gun.c
8 uncompress a gzip file
9 - illustrates the use of inflateBack() for high speed file-to-file
10 decompression using call-back functions
11 - is approximately twice as fast as gzip -d
12 - also provides Unix uncompress functionality, again twice as fast
13
7gzappend.c 14gzappend.c
8 append to a gzip file 15 append to a gzip file
9 - illustrates the use of the Z_BLOCK flush parameter for inflate() 16 - illustrates the use of the Z_BLOCK flush parameter for inflate()
@@ -27,3 +34,4 @@ zlib_how.html
27zpipe.c 34zpipe.c
28 reads and writes zlib streams from stdin to stdout 35 reads and writes zlib streams from stdin to stdout
29 - illustrates the proper use of deflate() and inflate() 36 - illustrates the proper use of deflate() and inflate()
37 - deeply commented in zlib_how.html (see above)
diff --git a/examples/gun.c b/examples/gun.c
new file mode 100644
index 0000000..1c0d8e5
--- /dev/null
+++ b/examples/gun.c
@@ -0,0 +1,692 @@
1/* gun.c -- simple gunzip to give an example of the use of inflateBack()
2 * Copyright (C) 2003, 2005 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 Version 1.2 20 March 2005 Mark Adler */
5
6/* Version history:
7 1.0 16 Feb 2003 First version for testing of inflateBack()
8 1.1 21 Feb 2005 Decompress concatenated gzip streams
9 Remove use of "this" variable (C++ keyword)
10 Fix return value for in()
11 Improve allocation failure checking
12 Add typecasting for void * structures
13 Add -h option for command version and usage
14 Add a bunch of comments
15 1.2 20 Mar 2005 Add Unix compress (LZW) decompression
16 Copy file attributes from input file to output file
17 */
18
19/*
20 gun [ -t ] [ name ... ]
21
22 decompresses the data in the named gzip files. If no arguments are given,
23 gun will decompress from stdin to stdout. The names must end in .gz, -gz,
24 .z, -z, _z, or .Z. The uncompressed data will be written to a file name
25 with the suffix stripped. On success, the original file is deleted. On
26 failure, the output file is deleted. For most failures, the command will
27 continue to process the remaining names on the command line. A memory
28 allocation failure will abort the command. If -t is specified, then the
29 listed files or stdin will be tested as gzip files for integrity (without
30 checking for a proper suffix), no output will be written, and no files
31 will be deleted.
32
33 Like gzip, gun allows concatenated gzip streams and will decompress them,
34 writing all of the uncompressed data to the output. Unlike gzip, gun allows
35 an empty file on input, and will produce no error writing an empty output
36 file.
37
38 gun will also decompress files made by Unix compress, which uses LZW
39 compression. These files are automatically detected by virtue of their
40 magic header bytes. Since the end of Unix compress stream is marked by the
41 end-of-file, they cannot be concantenated. If a Unix compress stream is
42 encountered in an input file, it is the last stream in that file.
43
44 Like gunzip and uncompress, the file attributes of the orignal compressed
45 file are maintained in the final uncompressed file, to the extent that the
46 user permissions allow it.
47
48 On my Mac OS X PowerPC G4, gun is almost twice as fast as gunzip (version
49 1.2.4) is on the same file, when gun is linked with zlib 1.2.2. Also the
50 LZW decompression provided by gun is about twice as fast as the standard
51 Unix uncompress command.
52 */
53
54/* external functions and related types and constants */
55#include <stdio.h> /* fprintf() */
56#include <stdlib.h> /* malloc(), free() */
57#include <string.h> /* strerror(), strcmp(), strlen(), memcpy() */
58#include <errno.h> /* errno */
59#include <fcntl.h> /* open() */
60#include <unistd.h> /* read(), write(), close(), chown(), unlink() */
61#include <sys/types.h>
62#include <sys/stat.h> /* stat(), chmod() */
63#include <utime.h> /* utime() */
64#include "zlib.h" /* inflateBackInit(), inflateBack(), */
65 /* inflateBackEnd(), crc32() */
66
67/* function declaration */
68#define local static
69
70/* buffer constants */
71#define SIZE 32768U /* input and output buffer sizes */
72#define PIECE 16384 /* limits i/o chunks for 16-bit int case */
73
74/* structure for infback() to pass to input function in() -- it maintains the
75 input file and a buffer of size SIZE */
76struct ind {
77 int infile;
78 unsigned char *inbuf;
79};
80
81/* Load input buffer, assumed to be empty, and return bytes loaded and a
82 pointer to them. read() is called until the buffer is full, or until it
83 returns end-of-file or error. Return 0 on error. */
84local unsigned in(void *in_desc, unsigned char **buf)
85{
86 int ret;
87 unsigned len;
88 unsigned char *next;
89 struct ind *me = (struct ind *)in_desc;
90
91 next = me->inbuf;
92 *buf = next;
93 len = 0;
94 do {
95 ret = PIECE;
96 if ((unsigned)ret > SIZE - len)
97 ret = (int)(SIZE - len);
98 ret = (int)read(me->infile, next, ret);
99 if (ret == -1) {
100 len = 0;
101 break;
102 }
103 next += ret;
104 len += ret;
105 } while (ret != 0 && len < SIZE);
106 return len;
107}
108
109/* structure for infback() to pass to output function out() -- it maintains the
110 output file, a running CRC-32 check on the output and the total number of
111 bytes output, both for checking against the gzip trailer. (The length in
112 the gzip trailer is stored modulo 2^32, so it's ok if a long is 32 bits and
113 the output is greater than 4 GB.) */
114struct outd {
115 int outfile;
116 int check; /* true if checking crc and total */
117 unsigned long crc;
118 unsigned long total;
119};
120
121/* Write output buffer and update the CRC-32 and total bytes written. write()
122 is called until all of the output is written or an error is encountered.
123 On success out() returns 0. For a write failure, out() returns 1. If the
124 output file descriptor is -1, then nothing is written.
125 */
126local int out(void *out_desc, unsigned char *buf, unsigned len)
127{
128 int ret;
129 struct outd *me = (struct outd *)out_desc;
130
131 if (me->check) {
132 me->crc = crc32(me->crc, buf, len);
133 me->total += len;
134 }
135 if (me->outfile != -1)
136 do {
137 ret = PIECE;
138 if ((unsigned)ret > len)
139 ret = (int)len;
140 ret = (int)write(me->outfile, buf, ret);
141 if (ret == -1)
142 return 1;
143 buf += ret;
144 len -= ret;
145 } while (len != 0);
146 return 0;
147}
148
149/* next input byte macro for use inside lunpipe() and gunpipe() */
150#define NEXT() (have ? 0 : (have = in(indp, &next)), \
151 last = have ? (have--, (int)(*next++)) : -1)
152
153/* memory for gunpipe() and lunpipe() --
154 the first 256 entries of prefix[] and suffix[] are never used, could
155 have offset the index, but it's faster to waste the memory */
156unsigned char inbuf[SIZE]; /* input buffer */
157unsigned char outbuf[SIZE]; /* output buffer */
158unsigned short prefix[65536]; /* index to LZW prefix string */
159unsigned char suffix[65536]; /* one-character LZW suffix */
160unsigned char match[65280 + 2]; /* buffer for reversed match or gzip
161 32K sliding window */
162
163/* throw out what's left in the current bits byte buffer (this is a vestigial
164 aspect of the compressed data format derived from an implementation that
165 made use of a special VAX machine instruction!) */
166#define FLUSHCODE() \
167 do { \
168 left = 0; \
169 rem = 0; \
170 if (chunk > have) { \
171 chunk -= have; \
172 have = 0; \
173 if (NEXT() == -1) \
174 break; \
175 chunk--; \
176 if (chunk > have) { \
177 chunk = have = 0; \
178 break; \
179 } \
180 } \
181 have -= chunk; \
182 next += chunk; \
183 chunk = 0; \
184 } while (0)
185
186/* Decompress a compress (LZW) file from indp to outfile. The compress magic
187 header (two bytes) has already been read and verified. There are have bytes
188 of buffered input at next. strm is used for passing error information back
189 to gunpipe().
190
191 lunpipe() will return Z_OK on success, Z_BUF_ERROR for an unexpected end of
192 file, read error, or write error (a write error indicated by strm->next_in
193 not equal to Z_NULL), or Z_DATA_ERROR for invalid input.
194 */
195local int lunpipe(unsigned have, unsigned char *next, struct ind *indp,
196 int outfile, z_stream *strm)
197{
198 int last; /* last byte read by NEXT(), or -1 if EOF */
199 int chunk; /* bytes left in current chunk */
200 int left; /* bits left in rem */
201 unsigned rem; /* unused bits from input */
202 int bits; /* current bits per code */
203 unsigned code; /* code, table traversal index */
204 unsigned mask; /* mask for current bits codes */
205 int max; /* maximum bits per code for this stream */
206 int flags; /* compress flags, then block compress flag */
207 unsigned end; /* last valid entry in prefix/suffix tables */
208 unsigned temp; /* current code */
209 unsigned prev; /* previous code */
210 unsigned final; /* last character written for previous code */
211 unsigned stack; /* next position for reversed string */
212 unsigned outcnt; /* bytes in output buffer */
213 struct outd outd; /* output structure */
214
215 /* set up output */
216 outd.outfile = outfile;
217 outd.check = 0;
218
219 /* process remainder of compress header -- a flags byte */
220 flags = NEXT();
221 if (last == -1)
222 return Z_BUF_ERROR;
223 if (flags & 0x60) {
224 strm->msg = "unknown lzw flags set";
225 return Z_DATA_ERROR;
226 }
227 max = flags & 0x1f;
228 if (max < 9 || max > 16) {
229 strm->msg = "lzw bits out of range";
230 return Z_DATA_ERROR;
231 }
232 if (max == 9) /* 9 doesn't really mean 9 */
233 max = 10;
234 flags &= 0x80; /* true if block compress */
235
236 /* clear table */
237 bits = 9;
238 mask = 0x1ff;
239 end = flags ? 256 : 255;
240
241 /* set up: get first 9-bit code, which is the first decompressed byte, but
242 don't create a table entry until the next code */
243 if (NEXT() == -1) /* no compressed data is ok */
244 return Z_OK;
245 final = prev = (unsigned)last; /* low 8 bits of code */
246 if (NEXT() == -1) /* missing a bit */
247 return Z_BUF_ERROR;
248 if (last & 1) { /* code must be < 256 */
249 strm->msg = "invalid lzw code";
250 return Z_DATA_ERROR;
251 }
252 rem = (unsigned)last >> 1; /* remaining 7 bits */
253 left = 7;
254 chunk = bits - 2; /* 7 bytes left in this chunk */
255 outbuf[0] = (unsigned char)final; /* write first decompressed byte */
256 outcnt = 1;
257
258 /* decode codes */
259 stack = 0;
260 for (;;) {
261 /* if the table will be full after this, increment the code size */
262 if (end >= mask && bits < max) {
263 FLUSHCODE();
264 bits++;
265 mask <<= 1;
266 mask++;
267 }
268
269 /* get a code of length bits */
270 if (chunk == 0) /* decrement chunk modulo bits */
271 chunk = bits;
272 code = rem; /* low bits of code */
273 if (NEXT() == -1) { /* EOF is end of compressed data */
274 /* write remaining buffered output */
275 if (outcnt && out(&outd, outbuf, outcnt)) {
276 strm->next_in = outbuf; /* signal write error */
277 return Z_BUF_ERROR;
278 }
279 return Z_OK;
280 }
281 code += (unsigned)last << left; /* middle (or high) bits of code */
282 left += 8;
283 chunk--;
284 if (bits > left) { /* need more bits */
285 if (NEXT() == -1) /* can't end in middle of code */
286 return Z_BUF_ERROR;
287 code += (unsigned)last << left; /* high bits of code */
288 left += 8;
289 chunk--;
290 }
291 code &= mask; /* mask to current code length */
292 left -= bits; /* number of unused bits */
293 rem = (unsigned)last >> (8 - left); /* unused bits from last byte */
294
295 /* process clear code (256) */
296 if (code == 256 && flags) {
297 FLUSHCODE();
298 bits = 9; /* initialize bits and mask */
299 mask = 0x1ff;
300 end = 255; /* empty table */
301 continue; /* get next code */
302 }
303
304 /* special code to reuse last match */
305 temp = code; /* save the current code */
306 if (code > end) {
307 /* Be picky on the allowed code here, and make sure that the code
308 we drop through (prev) will be a valid index so that random
309 input does not cause an exception. The code != end + 1 check is
310 empirically derived, and not checked in the original uncompress
311 code. If this ever causes a problem, that check could be safely
312 removed. Leaving this check in greatly improves gun's ability
313 to detect random or corrupted input after a compress header.
314 In any case, the prev > end check must be retained. */
315 if (code != end + 1 || prev > end) {
316 strm->msg = "invalid lzw code";
317 return Z_DATA_ERROR;
318 }
319 match[stack++] = (unsigned char)final;
320 code = prev;
321 }
322
323 /* walk through linked list to generate output in reverse order */
324 while (code >= 256) {
325 match[stack++] = suffix[code];
326 code = prefix[code];
327 }
328 match[stack++] = (unsigned char)code;
329 final = code;
330
331 /* link new table entry */
332 if (end < mask) {
333 end++;
334 prefix[end] = (unsigned short)prev;
335 suffix[end] = (unsigned char)final;
336 }
337
338 /* set previous code for next iteration */
339 prev = temp;
340
341 /* write output in forward order */
342 while (stack > SIZE - outcnt) {
343 while (outcnt < SIZE)
344 outbuf[outcnt++] = match[--stack];
345 if (out(&outd, outbuf, outcnt)) {
346 strm->next_in = outbuf; /* signal write error */
347 return Z_BUF_ERROR;
348 }
349 outcnt = 0;
350 }
351 do {
352 outbuf[outcnt++] = match[--stack];
353 } while (stack);
354
355 /* loop for next code with final and prev as the last match, rem and
356 left provide the first 0..7 bits of the next code, end is the last
357 valid table entry */
358 }
359}
360
361/* Decompress a gzip file from infile to outfile. strm is assumed to have been
362 successfully initialized with inflateBackInit(). The input file may consist
363 of a series of gzip streams, in which case all of them will be decompressed
364 to the output file. If outfile is -1, then the gzip stream(s) integrity is
365 checked and nothing is written.
366
367 The return value is a zlib error code: Z_MEM_ERROR if out of memory,
368 Z_DATA_ERROR if the header or the compressed data is invalid, or if the
369 trailer CRC-32 check or length doesn't match, Z_BUF_ERROR if the input ends
370 prematurely or a write error occurs, or Z_ERRNO if junk (not a another gzip
371 stream) follows a valid gzip stream.
372 */
373local int gunpipe(z_stream *strm, int infile, int outfile)
374{
375 int ret, first, last;
376 unsigned have, flags, len;
377 unsigned char *next;
378 struct ind ind, *indp;
379 struct outd outd;
380
381 /* setup input buffer */
382 ind.infile = infile;
383 ind.inbuf = inbuf;
384 indp = &ind;
385
386 /* decompress concatenated gzip streams */
387 have = 0; /* no input data read in yet */
388 first = 1; /* looking for first gzip header */
389 strm->next_in = Z_NULL; /* so Z_BUF_ERROR means EOF */
390 for (;;) {
391 /* look for the two magic header bytes for a gzip stream */
392 if (NEXT() == -1) {
393 ret = Z_OK;
394 break; /* empty gzip stream is ok */
395 }
396 if (last != 31 || (NEXT() != 139 && last != 157)) {
397 strm->msg = "incorrect header check";
398 ret = first ? Z_DATA_ERROR : Z_ERRNO;
399 break; /* not a gzip or compress header */
400 }
401 first = 0; /* next non-header is junk */
402
403 /* process a compress (LZW) file -- can't be concatenated after this */
404 if (last == 157) {
405 ret = lunpipe(have, next, indp, outfile, strm);
406 break;
407 }
408
409 /* process remainder of gzip header */
410 ret = Z_BUF_ERROR;
411 if (NEXT() != 8) { /* only deflate method allowed */
412 if (last == -1) break;
413 strm->msg = "unknown compression method";
414 ret = Z_DATA_ERROR;
415 break;
416 }
417 flags = NEXT(); /* header flags */
418 NEXT(); /* discard mod time, xflgs, os */
419 NEXT();
420 NEXT();
421 NEXT();
422 NEXT();
423 NEXT();
424 if (last == -1) break;
425 if (flags & 0xe0) {
426 strm->msg = "unknown header flags set";
427 ret = Z_DATA_ERROR;
428 break;
429 }
430 if (flags & 4) { /* extra field */
431 len = NEXT();
432 len += (unsigned)(NEXT()) << 8;
433 if (last == -1) break;
434 while (len > have) {
435 len -= have;
436 have = 0;
437 if (NEXT() == -1) break;
438 len--;
439 }
440 if (last == -1) break;
441 have -= len;
442 next += len;
443 }
444 if (flags & 8) /* file name */
445 while (NEXT() != 0 && last != -1)
446 ;
447 if (flags & 16) /* comment */
448 while (NEXT() != 0 && last != -1)
449 ;
450 if (flags & 2) { /* header crc */
451 NEXT();
452 NEXT();
453 }
454 if (last == -1) break;
455
456 /* set up output */
457 outd.outfile = outfile;
458 outd.check = 1;
459 outd.crc = crc32(0L, Z_NULL, 0);
460 outd.total = 0;
461
462 /* decompress data to output */
463 strm->next_in = next;
464 strm->avail_in = have;
465 ret = inflateBack(strm, in, indp, out, &outd);
466 if (ret != Z_STREAM_END) break;
467 next = strm->next_in;
468 have = strm->avail_in;
469 strm->next_in = Z_NULL; /* so Z_BUF_ERROR means EOF */
470
471 /* check trailer */
472 ret = Z_BUF_ERROR;
473 if (NEXT() != (outd.crc & 0xff) ||
474 NEXT() != ((outd.crc >> 8) & 0xff) ||
475 NEXT() != ((outd.crc >> 16) & 0xff) ||
476 NEXT() != ((outd.crc >> 24) & 0xff)) {
477 /* crc error */
478 if (last != -1) {
479 strm->msg = "incorrect data check";
480 ret = Z_DATA_ERROR;
481 }
482 break;
483 }
484 if (NEXT() != (outd.total & 0xff) ||
485 NEXT() != ((outd.total >> 8) & 0xff) ||
486 NEXT() != ((outd.total >> 16) & 0xff) ||
487 NEXT() != ((outd.total >> 24) & 0xff)) {
488 /* length error */
489 if (last != -1) {
490 strm->msg = "incorrect length check";
491 ret = Z_DATA_ERROR;
492 }
493 break;
494 }
495
496 /* go back and look for another gzip stream */
497 }
498
499 /* clean up and return */
500 return ret;
501}
502
503/* Copy file attributes, from -> to, as best we can. This is best effort, so
504 no errors are reported. The mode bits, including suid, sgid, and the sticky
505 bit are copied (if allowed), the owner's user id and group id are copied
506 (again if allowed), and the access and modify times are copied. */
507local void copymeta(char *from, char *to)
508{
509 struct stat was;
510 struct utimbuf when;
511
512 /* get all of from's Unix meta data, return if not a regular file */
513 if (stat(from, &was) != 0 || (was.st_mode & S_IFMT) != S_IFREG)
514 return;
515
516 /* set to's mode bits, ignore errors */
517 (void)chmod(to, was.st_mode & 07777);
518
519 /* copy owner's user and group, ignore errors */
520 (void)chown(to, was.st_uid, was.st_gid);
521
522 /* copy access and modify times, ignore errors */
523 when.actime = was.st_atime;
524 when.modtime = was.st_mtime;
525 (void)utime(to, &when);
526}
527
528/* Decompress the file inname to the file outnname, of if test is true, just
529 decompress without writing and check the gzip trailer for integrity. If
530 inname is NULL or an empty string, read from stdin. If outname is NULL or
531 an empty string, write to stdout. strm is a pre-initialized inflateBack
532 structure. When appropriate, copy the file attributes from inname to
533 outname.
534
535 gunzip() returns 1 if there is an out-of-memory error or an unexpected
536 return code from gunpipe(). Otherwise it returns 0.
537 */
538local int gunzip(z_stream *strm, char *inname, char *outname, int test)
539{
540 int ret;
541 int infile, outfile;
542
543 /* open files */
544 if (inname == NULL || *inname == 0) {
545 inname = "-";
546 infile = 0; /* stdin */
547 }
548 else {
549 infile = open(inname, O_RDONLY, 0);
550 if (infile == -1) {
551 fprintf(stderr, "gun cannot open %s\n", inname);
552 return 0;
553 }
554 }
555 if (test)
556 outfile = -1;
557 else if (outname == NULL || *outname == 0) {
558 outname = "-";
559 outfile = 1; /* stdout */
560 }
561 else {
562 outfile = open(outname, O_CREAT | O_TRUNC | O_WRONLY, 0666);
563 if (outfile == -1) {
564 close(infile);
565 fprintf(stderr, "gun cannot create %s\n", outname);
566 return 0;
567 }
568 }
569 errno = 0;
570
571 /* decompress */
572 ret = gunpipe(strm, infile, outfile);
573 if (outfile > 2) close(outfile);
574 if (infile > 2) close(infile);
575
576 /* interpret result */
577 switch (ret) {
578 case Z_OK:
579 case Z_ERRNO:
580 if (infile > 2 && outfile > 2) {
581 copymeta(inname, outname); /* copy attributes */
582 unlink(inname);
583 }
584 if (ret == Z_ERRNO)
585 fprintf(stderr, "gun warning: trailing garbage ignored in %s\n",
586 inname);
587 break;
588 case Z_DATA_ERROR:
589 if (outfile > 2) unlink(outname);
590 fprintf(stderr, "gun data error on %s: %s\n", inname, strm->msg);
591 break;
592 case Z_MEM_ERROR:
593 if (outfile > 2) unlink(outname);
594 fprintf(stderr, "gun out of memory error--aborting\n");
595 return 1;
596 case Z_BUF_ERROR:
597 if (outfile > 2) unlink(outname);
598 if (strm->next_in != Z_NULL) {
599 fprintf(stderr, "gun write error on %s: %s\n",
600 outname, strerror(errno));
601 }
602 else if (errno) {
603 fprintf(stderr, "gun read error on %s: %s\n",
604 inname, strerror(errno));
605 }
606 else {
607 fprintf(stderr, "gun unexpected end of file on %s\n",
608 inname);
609 }
610 break;
611 default:
612 if (outfile > 2) unlink(outname);
613 fprintf(stderr, "gun internal error--aborting\n");
614 return 1;
615 }
616 return 0;
617}
618
619/* Process the gun command line arguments. See the command syntax near the
620 beginning of this source file. */
621int main(int argc, char **argv)
622{
623 int ret, len, test;
624 char *outname;
625 unsigned char *window;
626 z_stream strm;
627
628 /* initialize inflateBack state for repeated use */
629 window = match; /* reuse LZW match buffer */
630 strm.zalloc = Z_NULL;
631 strm.zfree = Z_NULL;
632 strm.opaque = Z_NULL;
633 ret = inflateBackInit(&strm, 15, window);
634 if (ret != Z_OK) {
635 fprintf(stderr, "gun out of memory error--aborting\n");
636 return 1;
637 }
638
639 /* decompress each file to the same name with the suffix removed */
640 argc--;
641 argv++;
642 test = 0;
643 if (argc && strcmp(*argv, "-h") == 0) {
644 fprintf(stderr, "gun 1.2 (20 Mar 2005)\n");
645 fprintf(stderr, "Copyright (c) 2005 Mark Adler\n");
646 fprintf(stderr, "usage: gun [-t] [file1.gz [file2.Z ...]]\n");
647 return 0;
648 }
649 if (argc && strcmp(*argv, "-t") == 0) {
650 test = 1;
651 argc--;
652 argv++;
653 }
654 if (argc)
655 do {
656 if (test)
657 outname = NULL;
658 else {
659 len = (int)strlen(*argv);
660 if (strcmp(*argv + len - 3, ".gz") == 0 ||
661 strcmp(*argv + len - 3, "-gz") == 0)
662 len -= 3;
663 else if (strcmp(*argv + len - 2, ".z") == 0 ||
664 strcmp(*argv + len - 2, "-z") == 0 ||
665 strcmp(*argv + len - 2, "_z") == 0 ||
666 strcmp(*argv + len - 2, ".Z") == 0)
667 len -= 2;
668 else {
669 fprintf(stderr, "gun error: no gz type on %s--skipping\n",
670 *argv);
671 continue;
672 }
673 outname = malloc(len + 1);
674 if (outname == NULL) {
675 fprintf(stderr, "gun out of memory error--aborting\n");
676 ret = 1;
677 break;
678 }
679 memcpy(outname, *argv, len);
680 outname[len] = 0;
681 }
682 ret = gunzip(&strm, *argv, outname, test);
683 if (outname != NULL) free(outname);
684 if (ret) break;
685 } while (argv++, --argc);
686 else
687 ret = gunzip(&strm, NULL, NULL, test);
688
689 /* clean up */
690 inflateBackEnd(&strm);
691 return ret;
692}
diff --git a/examples/zlib_how.html b/examples/zlib_how.html
index b2bda6b..40998db 100644
--- a/examples/zlib_how.html
+++ b/examples/zlib_how.html
@@ -420,10 +420,11 @@ The output of <tt>inflate()</tt> is handled identically to that of <tt>deflate()
420 } 420 }
421</b></pre> 421</b></pre>
422The inner <tt>do</tt>-loop ends when <tt>inflate()</tt> has no more output as indicated 422The inner <tt>do</tt>-loop ends when <tt>inflate()</tt> has no more output as indicated
423by not filling the output buffer, just as for <tt>deflate()</tt>. 423by not filling the output buffer, just as for <tt>deflate()</tt>. In this case, we cannot
424assert that <tt>strm.avail_in</tt> will be zero, since the deflate stream may end before the file
425does.
424<pre><b> 426<pre><b>
425 } while (strm.avail_out == 0); 427 } while (strm.avail_out == 0);
426 assert(strm.avail_in == 0); /* all input will be used */
427</b></pre><!-- --> 428</b></pre><!-- -->
428The outer <tt>do</tt>-loop ends when <tt>inflate()</tt> reports that it has reached the 429The outer <tt>do</tt>-loop ends when <tt>inflate()</tt> reports that it has reached the
429end of the input <em>zlib</em> stream, has completed the decompression and integrity 430end of the input <em>zlib</em> stream, has completed the decompression and integrity
diff --git a/examples/zpipe.c b/examples/zpipe.c
index a602d59..26abb56 100644
--- a/examples/zpipe.c
+++ b/examples/zpipe.c
@@ -7,6 +7,7 @@
7 1.1 8 Nov 2004 Add void casting for unused return values 7 1.1 8 Nov 2004 Add void casting for unused return values
8 Use switch statement for inflate() return values 8 Use switch statement for inflate() return values
9 1.2 9 Nov 2004 Add assertions to document zlib guarantees 9 1.2 9 Nov 2004 Add assertions to document zlib guarantees
10 1.3 6 Apr 2005 Remove incorrect assertion in inf()
10 */ 11 */
11 12
12#include <stdio.h> 13#include <stdio.h>
@@ -127,7 +128,6 @@ int inf(FILE *source, FILE *dest)
127 return Z_ERRNO; 128 return Z_ERRNO;
128 } 129 }
129 } while (strm.avail_out == 0); 130 } while (strm.avail_out == 0);
130 assert(strm.avail_in == 0); /* all input will be used */
131 131
132 /* done when inflate() says it's done */ 132 /* done when inflate() says it's done */
133 } while (ret != Z_STREAM_END); 133 } while (ret != Z_STREAM_END);
diff --git a/gzio.c b/gzio.c
index 217a4cc..b069b7a 100644
--- a/gzio.c
+++ b/gzio.c
@@ -1,5 +1,5 @@
1/* gzio.c -- IO on .gz files 1/* gzio.c -- IO on .gz files
2 * Copyright (C) 1995-2004 Jean-loup Gailly. 2 * Copyright (C) 1995-2005 Jean-loup Gailly.
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 * 4 *
5 * Compile this file with -DNO_GZCOMPRESS to avoid the compression code. 5 * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
@@ -264,7 +264,7 @@ local int get_byte(s)
264 if (s->z_eof) return EOF; 264 if (s->z_eof) return EOF;
265 if (s->stream.avail_in == 0) { 265 if (s->stream.avail_in == 0) {
266 errno = 0; 266 errno = 0;
267 s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); 267 s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
268 if (s->stream.avail_in == 0) { 268 if (s->stream.avail_in == 0) {
269 s->z_eof = 1; 269 s->z_eof = 1;
270 if (ferror(s->file)) s->z_err = Z_ERRNO; 270 if (ferror(s->file)) s->z_err = Z_ERRNO;
@@ -300,7 +300,7 @@ local void check_header(s)
300 if (len < 2) { 300 if (len < 2) {
301 if (len) s->inbuf[0] = s->stream.next_in[0]; 301 if (len) s->inbuf[0] = s->stream.next_in[0];
302 errno = 0; 302 errno = 0;
303 len = fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file); 303 len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
304 if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO; 304 if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
305 s->stream.avail_in += len; 305 s->stream.avail_in += len;
306 s->stream.next_in = s->inbuf; 306 s->stream.next_in = s->inbuf;
@@ -415,6 +415,7 @@ int ZEXPORT gzread (file, buf, len)
415 s->stream.avail_out--; 415 s->stream.avail_out--;
416 s->back = EOF; 416 s->back = EOF;
417 s->out++; 417 s->out++;
418 start++;
418 if (s->last) { 419 if (s->last) {
419 s->z_err = Z_STREAM_END; 420 s->z_err = Z_STREAM_END;
420 return 1; 421 return 1;
@@ -436,8 +437,8 @@ int ZEXPORT gzread (file, buf, len)
436 s->stream.avail_in -= n; 437 s->stream.avail_in -= n;
437 } 438 }
438 if (s->stream.avail_out > 0) { 439 if (s->stream.avail_out > 0) {
439 s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out, 440 s->stream.avail_out -=
440 s->file); 441 (uInt)fread(next_out, 1, s->stream.avail_out, s->file);
441 } 442 }
442 len -= s->stream.avail_out; 443 len -= s->stream.avail_out;
443 s->in += len; 444 s->in += len;
@@ -448,17 +449,13 @@ int ZEXPORT gzread (file, buf, len)
448 if (s->stream.avail_in == 0 && !s->z_eof) { 449 if (s->stream.avail_in == 0 && !s->z_eof) {
449 450
450 errno = 0; 451 errno = 0;
451 s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); 452 s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
452 if (s->stream.avail_in == 0) { 453 if (s->stream.avail_in == 0) {
453 s->z_eof = 1; 454 s->z_eof = 1;
454 if (ferror(s->file)) { 455 if (ferror(s->file)) {
455 s->z_err = Z_ERRNO; 456 s->z_err = Z_ERRNO;
456 break; 457 break;
457 } 458 }
458 if (feof(s->file)) { /* avoid error for empty file */
459 s->z_err = Z_STREAM_END;
460 break;
461 }
462 } 459 }
463 s->stream.next_in = s->inbuf; 460 s->stream.next_in = s->inbuf;
464 } 461 }
@@ -903,6 +900,18 @@ int ZEXPORT gzeof (file)
903} 900}
904 901
905/* =========================================================================== 902/* ===========================================================================
903 Returns 1 if reading and doing so transparently, otherwise zero.
904*/
905int ZEXPORT gzdirect (file)
906 gzFile file;
907{
908 gz_stream *s = (gz_stream*)file;
909
910 if (s == NULL || s->mode != 'r') return 0;
911 return s->transparent;
912}
913
914/* ===========================================================================
906 Outputs a long in LSB order to the given file 915 Outputs a long in LSB order to the given file
907*/ 916*/
908local void putLong (file, x) 917local void putLong (file, x)
diff --git a/inflate.c b/inflate.c
index 5733437..7dccc9d 100644
--- a/inflate.c
+++ b/inflate.c
@@ -1,5 +1,5 @@
1/* inflate.c -- zlib decompression 1/* inflate.c -- zlib decompression
2 * Copyright (C) 1995-2004 Mark Adler 2 * Copyright (C) 1995-2005 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
@@ -1334,11 +1334,15 @@ z_streamp source;
1334 /* copy state */ 1334 /* copy state */
1335 zmemcpy(dest, source, sizeof(z_stream)); 1335 zmemcpy(dest, source, sizeof(z_stream));
1336 zmemcpy(copy, state, sizeof(struct inflate_state)); 1336 zmemcpy(copy, state, sizeof(struct inflate_state));
1337 copy->lencode = copy->codes + (state->lencode - state->codes); 1337 if (state->lencode >= state->codes &&
1338 copy->distcode = copy->codes + (state->distcode - state->codes); 1338 state->lencode <= state->codes + ENOUGH - 1)
1339 {
1340 copy->lencode = copy->codes + (state->lencode - state->codes);
1341 copy->distcode = copy->codes + (state->distcode - state->codes);
1342 }
1339 copy->next = copy->codes + (state->next - state->codes); 1343 copy->next = copy->codes + (state->next - state->codes);
1340 if (window != Z_NULL) 1344 if (window != Z_NULL)
1341 zmemcpy(window, state->window, 1U << state->wbits); 1345 zmemcpy(window, state->window, (uInt)(1U << state->wbits));
1342 copy->window = window; 1346 copy->window = window;
1343 dest->state = (voidpf)copy; 1347 dest->state = (voidpf)copy;
1344 return Z_OK; 1348 return Z_OK;
diff --git a/inftrees.c b/inftrees.c
index 72c5b75..471f735 100644
--- a/inftrees.c
+++ b/inftrees.c
@@ -1,5 +1,5 @@
1/* inftrees.c -- generate Huffman trees for efficient decoding 1/* inftrees.c -- generate Huffman trees for efficient decoding
2 * Copyright (C) 1995-2004 Mark Adler 2 * Copyright (C) 1995-2005 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
@@ -9,7 +9,7 @@
9#define MAXBITS 15 9#define MAXBITS 15
10 10
11const char inflate_copyright[] = 11const char inflate_copyright[] =
12 " inflate 1.2.2.2 Copyright 1995-2004 Mark Adler "; 12 " inflate 1.2.2.3 Copyright 1995-2005 Mark Adler ";
13/* 13/*
14 If you use the zlib library in a product, an acknowledgment is welcome 14 If you use the zlib library in a product, an acknowledgment is welcome
15 in the documentation of your product. If for some reason you cannot 15 in the documentation of your product. If for some reason you cannot
@@ -62,7 +62,7 @@ unsigned short FAR *work;
62 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; 62 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
63 static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 63 static const unsigned short lext[31] = { /* Length codes 257..285 extra */
64 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 64 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
65 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 199}; 65 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 66, 71};
66 static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 66 static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
67 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 67 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
68 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 68 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
@@ -262,7 +262,7 @@ unsigned short FAR *work;
262 drop = root; 262 drop = root;
263 263
264 /* increment past last table */ 264 /* increment past last table */
265 next += 1U << curr; 265 next += (unsigned)(1U << curr);
266 266
267 /* determine length of next table */ 267 /* determine length of next table */
268 curr = len - drop; 268 curr = len - drop;
diff --git a/minigzip.c b/minigzip.c
index 4ba5e50..4524b96 100644
--- a/minigzip.c
+++ b/minigzip.c
@@ -1,5 +1,5 @@
1/* minigzip.c -- simulate gzip using the zlib compression library 1/* minigzip.c -- simulate gzip using the zlib compression library
2 * Copyright (C) 1995-2004 Jean-loup Gailly. 2 * Copyright (C) 1995-2005 Jean-loup Gailly.
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
@@ -295,6 +295,8 @@ int main(argc, argv)
295 break; 295 break;
296 argc--, argv++; 296 argc--, argv++;
297 } 297 }
298 if (outmode[3] == ' ')
299 outmode[3] = 0;
298 if (argc == 0) { 300 if (argc == 0) {
299 SET_BINARY_MODE(stdin); 301 SET_BINARY_MODE(stdin);
300 SET_BINARY_MODE(stdout); 302 SET_BINARY_MODE(stdout);
diff --git a/qnx/package.qpg b/qnx/package.qpg
index 03cd351..b08778d 100644
--- a/qnx/package.qpg
+++ b/qnx/package.qpg
@@ -25,10 +25,10 @@
25 <QPG:Files> 25 <QPG:Files>
26 <QPG:Add file="../zconf.h" install="/opt/include/" user="root:sys" permission="644"/> 26 <QPG:Add file="../zconf.h" install="/opt/include/" user="root:sys" permission="644"/>
27 <QPG:Add file="../zlib.h" install="/opt/include/" user="root:sys" permission="644"/> 27 <QPG:Add file="../zlib.h" install="/opt/include/" user="root:sys" permission="644"/>
28 <QPG:Add file="../libz.so.1.2.2.2" install="/opt/lib/" user="root:bin" permission="644"/> 28 <QPG:Add file="../libz.so.1.2.2.3" install="/opt/lib/" user="root:bin" permission="644"/>
29 <QPG:Add file="libz.so" install="/opt/lib/" component="dev" filetype="symlink" linkto="libz.so.1.2.2.2"/> 29 <QPG:Add file="libz.so" install="/opt/lib/" component="dev" filetype="symlink" linkto="libz.so.1.2.2.3"/>
30 <QPG:Add file="libz.so.1" install="/opt/lib/" filetype="symlink" linkto="libz.so.1.2.2.2"/> 30 <QPG:Add file="libz.so.1" install="/opt/lib/" filetype="symlink" linkto="libz.so.1.2.2.3"/>
31 <QPG:Add file="../libz.so.1.2.2.2" install="/opt/lib/" component="slib"/> 31 <QPG:Add file="../libz.so.1.2.2.3" install="/opt/lib/" component="slib"/>
32 </QPG:Files> 32 </QPG:Files>
33 33
34 <QPG:PackageFilter> 34 <QPG:PackageFilter>
@@ -63,7 +63,7 @@
63 </QPM:ProductDescription> 63 </QPM:ProductDescription>
64 64
65 <QPM:ReleaseDescription> 65 <QPM:ReleaseDescription>
66 <QPM:ReleaseVersion>1.2.2.2</QPM:ReleaseVersion> 66 <QPM:ReleaseVersion>1.2.2.3</QPM:ReleaseVersion>
67 <QPM:ReleaseUrgency>Medium</QPM:ReleaseUrgency> 67 <QPM:ReleaseUrgency>Medium</QPM:ReleaseUrgency>
68 <QPM:ReleaseStability>Stable</QPM:ReleaseStability> 68 <QPM:ReleaseStability>Stable</QPM:ReleaseStability>
69 <QPM:ReleaseNoteMinor></QPM:ReleaseNoteMinor> 69 <QPM:ReleaseNoteMinor></QPM:ReleaseNoteMinor>
diff --git a/win32/zlib1.rc b/win32/zlib1.rc
index 1d37694..e49a81c 100644
--- a/win32/zlib1.rc
+++ b/win32/zlib1.rc
@@ -5,8 +5,8 @@ VS_VERSION_INFO VERSIONINFO
5#else 5#else
6VS_VERSION_INFO VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE 6VS_VERSION_INFO VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
7#endif 7#endif
8 FILEVERSION 1,2,2,2 8 FILEVERSION 1,2,2,3
9 PRODUCTVERSION 1,2,2,2 9 PRODUCTVERSION 1,2,2,3
10 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 10 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
11#ifdef _DEBUG 11#ifdef _DEBUG
12 FILEFLAGS 1 12 FILEFLAGS 1
@@ -23,12 +23,12 @@ BEGIN
23 //language ID = U.S. English, char set = Windows, Multilingual 23 //language ID = U.S. English, char set = Windows, Multilingual
24 BEGIN 24 BEGIN
25 VALUE "FileDescription", "zlib data compression library\0" 25 VALUE "FileDescription", "zlib data compression library\0"
26 VALUE "FileVersion", "1.2.2.2\0" 26 VALUE "FileVersion", "1.2.2.3\0"
27 VALUE "InternalName", "zlib1.dll\0" 27 VALUE "InternalName", "zlib1.dll\0"
28 VALUE "LegalCopyright", "(C) 1995-2004 Jean-loup Gailly & Mark Adler\0" 28 VALUE "LegalCopyright", "(C) 1995-2004 Jean-loup Gailly & Mark Adler\0"
29 VALUE "OriginalFilename", "zlib1.dll\0" 29 VALUE "OriginalFilename", "zlib1.dll\0"
30 VALUE "ProductName", "zlib\0" 30 VALUE "ProductName", "zlib\0"
31 VALUE "ProductVersion", "1.2.2.2\0" 31 VALUE "ProductVersion", "1.2.2.3\0"
32 VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" 32 VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
33 END 33 END
34 END 34 END
diff --git a/zconf.h b/zconf.h
index 6897bf0..03a9431 100644
--- a/zconf.h
+++ b/zconf.h
@@ -1,5 +1,5 @@
1/* zconf.h -- configuration of the zlib compression library 1/* zconf.h -- configuration of the zlib compression library
2 * Copyright (C) 1995-2004 Jean-loup Gailly. 2 * Copyright (C) 1995-2005 Jean-loup Gailly.
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
@@ -68,8 +68,10 @@
68#if defined(_WINDOWS) && !defined(WINDOWS) 68#if defined(_WINDOWS) && !defined(WINDOWS)
69# define WINDOWS 69# define WINDOWS
70#endif 70#endif
71#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) 71#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
72# define WIN32 72# ifndef WIN32
73# define WIN32
74# endif
73#endif 75#endif
74#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) 76#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
75# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) 77# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
diff --git a/zconf.in.h b/zconf.in.h
index 6897bf0..03a9431 100644
--- a/zconf.in.h
+++ b/zconf.in.h
@@ -1,5 +1,5 @@
1/* zconf.h -- configuration of the zlib compression library 1/* zconf.h -- configuration of the zlib compression library
2 * Copyright (C) 1995-2004 Jean-loup Gailly. 2 * Copyright (C) 1995-2005 Jean-loup Gailly.
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
@@ -68,8 +68,10 @@
68#if defined(_WINDOWS) && !defined(WINDOWS) 68#if defined(_WINDOWS) && !defined(WINDOWS)
69# define WINDOWS 69# define WINDOWS
70#endif 70#endif
71#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) 71#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
72# define WIN32 72# ifndef WIN32
73# define WIN32
74# endif
73#endif 75#endif
74#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) 76#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
75# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) 77# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
diff --git a/zlib.3 b/zlib.3
index 17491cc..41e5fed 100644
--- a/zlib.3
+++ b/zlib.3
@@ -1,4 +1,4 @@
1.TH ZLIB 3 "30 December 2004" 1.TH ZLIB 3 "27 May 2005"
2.SH NAME 2.SH NAME
3zlib \- compression/decompression library 3zlib \- compression/decompression library
4.SH SYNOPSIS 4.SH SYNOPSIS
@@ -133,7 +133,7 @@ before asking for help.
133Send questions and/or comments to zlib@gzip.org, 133Send questions and/or comments to zlib@gzip.org,
134or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). 134or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
135.SH AUTHORS 135.SH AUTHORS
136Version 1.2.2.2 136Version 1.2.2.3
137Copyright (C) 1995-2004 Jean-loup Gailly (jloup@gzip.org) 137Copyright (C) 1995-2004 Jean-loup Gailly (jloup@gzip.org)
138and Mark Adler (madler@alumni.caltech.edu). 138and Mark Adler (madler@alumni.caltech.edu).
139.LP 139.LP
diff --git a/zlib.h b/zlib.h
index b13ca6f..9bb6931 100644
--- a/zlib.h
+++ b/zlib.h
@@ -1,7 +1,7 @@
1/* zlib.h -- interface of the 'zlib' general purpose compression library 1/* zlib.h -- interface of the 'zlib' general purpose compression library
2 version 1.2.2.2, December 30th, 2004 2 version 1.2.2.3, May 27th, 2005
3 3
4 Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler 4 Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
5 5
6 This software is provided 'as-is', without any express or implied 6 This software is provided 'as-is', without any express or implied
7 warranty. In no event will the authors be held liable for any damages 7 warranty. In no event will the authors be held liable for any damages
@@ -37,8 +37,8 @@
37extern "C" { 37extern "C" {
38#endif 38#endif
39 39
40#define ZLIB_VERSION "1.2.2.2" 40#define ZLIB_VERSION "1.2.2.3"
41#define ZLIB_VERNUM 0x1222 41#define ZLIB_VERNUM 0x1223
42 42
43/* 43/*
44 The 'zlib' compression library provides in-memory compression and 44 The 'zlib' compression library provides in-memory compression and
@@ -556,7 +556,9 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
556 deflateInit or deflateInit2, a part of the dictionary may in effect be 556 deflateInit or deflateInit2, a part of the dictionary may in effect be
557 discarded, for example if the dictionary is larger than the window size in 557 discarded, for example if the dictionary is larger than the window size in
558 deflate or deflate2. Thus the strings most likely to be useful should be 558 deflate or deflate2. Thus the strings most likely to be useful should be
559 put at the end of the dictionary, not at the front. 559 put at the end of the dictionary, not at the front. In addition, the
560 current implementation of deflate will use at most the window size minus
561 262 bytes of the provided dictionary.
560 562
561 Upon return of this function, strm->adler is set to the adler32 value 563 Upon return of this function, strm->adler is set to the adler32 value
562 of the dictionary; the decompressor may later use this value to determine 564 of the dictionary; the decompressor may later use this value to determine
@@ -622,6 +624,23 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
622 if strm->avail_out was zero. 624 if strm->avail_out was zero.
623*/ 625*/
624 626
627ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
628 int good_length,
629 int max_lazy,
630 int nice_length,
631 int max_chain));
632/*
633 Fine tune deflate's internal compression parameters. This should only be
634 used by someone who understands the algorithm used by zlib's deflate for
635 searching for the best matching string, and even then only by the most
636 fanatic optimizer trying to squeeze out the last compressed bit for their
637 specific input data. Read the deflate.c source code for the meaning of the
638 max_lazy, good_length, nice_length, and max_chain parameters.
639
640 deflateTune() can be called after deflateInit() or deflateInit2(), and
641 returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
642 */
643
625ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, 644ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
626 uLong sourceLen)); 645 uLong sourceLen));
627/* 646/*
@@ -703,7 +722,7 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
703 windowBits can also be greater than 15 for optional gzip decoding. Add 722 windowBits can also be greater than 15 for optional gzip decoding. Add
704 32 to windowBits to enable zlib and gzip decoding with automatic header 723 32 to windowBits to enable zlib and gzip decoding with automatic header
705 detection, or add 16 to decode only the gzip format (the zlib format will 724 detection, or add 16 to decode only the gzip format (the zlib format will
706 return a Z_DATA_ERROR. If a gzip stream is being decoded, strm->adler is 725 return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
707 a crc32 instead of an adler32. 726 a crc32 instead of an adler32.
708 727
709 inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough 728 inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
@@ -1185,6 +1204,12 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file));
1185 input stream, otherwise zero. 1204 input stream, otherwise zero.
1186*/ 1205*/
1187 1206
1207ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
1208/*
1209 Returns 1 if file is being read directly without decompression, otherwise
1210 zero.
1211*/
1212
1188ZEXTERN int ZEXPORT gzclose OF((gzFile file)); 1213ZEXTERN int ZEXPORT gzclose OF((gzFile file));
1189/* 1214/*
1190 Flushes all pending output if necessary, closes the compressed file 1215 Flushes all pending output if necessary, closes the compressed file
diff --git a/zutil.h b/zutil.h
index 5209d65..c800fab 100644
--- a/zutil.h
+++ b/zutil.h
@@ -1,5 +1,5 @@
1/* zutil.h -- internal interface and configuration of the compression library 1/* zutil.h -- internal interface and configuration of the compression library
2 * Copyright (C) 1995-2004 Jean-loup Gailly. 2 * Copyright (C) 1995-2005 Jean-loup Gailly.
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
@@ -17,7 +17,9 @@
17#include "zlib.h" 17#include "zlib.h"
18 18
19#ifdef STDC 19#ifdef STDC
20# include <stddef.h> 20# ifndef _WIN32_WCE
21# include <stddef.h>
22# endif
21# include <string.h> 23# include <string.h>
22# include <stdlib.h> 24# include <stdlib.h>
23#endif 25#endif
@@ -32,7 +34,9 @@
32# endif 34# endif
33 extern int errno; 35 extern int errno;
34#else 36#else
35# include <errno.h> 37# ifndef _WIN32_WCE
38# include <errno.h>
39# endif
36#endif 40#endif
37 41
38#ifndef local 42#ifndef local