2 * zlib wrappers to make sure we don't silently miss errors
7 static const char *zerr_to_string(int status
)
11 return "out of memory";
13 return "wrong version";
15 return "needs dictionary";
17 return "data stream error";
19 return "stream consistency error";
21 return "unknown error";
26 * avail_in and avail_out in zlib are counted in uInt, which typically
27 * limits the size of the buffer we can use to 4GB when interacting
28 * with zlib in a single call to inflate/deflate.
30 /* #define ZLIB_BUF_MAX ((uInt)-1) */
31 #define ZLIB_BUF_MAX ((uInt) 1024 * 1024 * 1024) /* 1GB */
32 static inline uInt
zlib_buf_cap(unsigned long len
)
34 return (ZLIB_BUF_MAX
< len
) ? ZLIB_BUF_MAX
: len
;
37 static void zlib_pre_call(git_zstream
*s
)
39 s
->z
.next_in
= s
->next_in
;
40 s
->z
.next_out
= s
->next_out
;
41 s
->z
.total_in
= s
->total_in
;
42 s
->z
.total_out
= s
->total_out
;
43 s
->z
.avail_in
= zlib_buf_cap(s
->avail_in
);
44 s
->z
.avail_out
= zlib_buf_cap(s
->avail_out
);
47 static void zlib_post_call(git_zstream
*s
)
49 unsigned long bytes_consumed
;
50 unsigned long bytes_produced
;
52 bytes_consumed
= s
->z
.next_in
- s
->next_in
;
53 bytes_produced
= s
->z
.next_out
- s
->next_out
;
54 if (s
->z
.total_out
!= s
->total_out
+ bytes_produced
)
55 die("BUG: total_out mismatch");
56 if (s
->z
.total_in
!= s
->total_in
+ bytes_consumed
)
57 die("BUG: total_in mismatch");
59 s
->total_out
= s
->z
.total_out
;
60 s
->total_in
= s
->z
.total_in
;
61 s
->next_in
= s
->z
.next_in
;
62 s
->next_out
= s
->z
.next_out
;
63 s
->avail_in
-= bytes_consumed
;
64 s
->avail_out
-= bytes_produced
;
67 void git_inflate_init(git_zstream
*strm
)
72 status
= inflateInit(&strm
->z
);
76 die("inflateInit: %s (%s)", zerr_to_string(status
),
77 strm
->z
.msg
? strm
->z
.msg
: "no message");
80 void git_inflate_init_gzip_only(git_zstream
*strm
)
83 * Use default 15 bits, +16 is to accept only gzip and to
84 * yield Z_DATA_ERROR when fed zlib format.
86 const int windowBits
= 15 + 16;
90 status
= inflateInit2(&strm
->z
, windowBits
);
94 die("inflateInit2: %s (%s)", zerr_to_string(status
),
95 strm
->z
.msg
? strm
->z
.msg
: "no message");
98 void git_inflate_end(git_zstream
*strm
)
103 status
= inflateEnd(&strm
->z
);
104 zlib_post_call(strm
);
107 error("inflateEnd: %s (%s)", zerr_to_string(status
),
108 strm
->z
.msg
? strm
->z
.msg
: "no message");
111 int git_inflate(git_zstream
*strm
, int flush
)
117 /* Never say Z_FINISH unless we are feeding everything */
118 status
= inflate(&strm
->z
,
119 (strm
->z
.avail_in
!= strm
->avail_in
)
121 if (status
== Z_MEM_ERROR
)
122 die("inflate: out of memory");
123 zlib_post_call(strm
);
126 * Let zlib work another round, while we can still
129 if ((strm
->avail_out
&& !strm
->z
.avail_out
) &&
130 (status
== Z_OK
|| status
== Z_BUF_ERROR
))
136 /* Z_BUF_ERROR: normal, needs more space in the output buffer */
144 error("inflate: %s (%s)", zerr_to_string(status
),
145 strm
->z
.msg
? strm
->z
.msg
: "no message");
149 #if defined(NO_DEFLATE_BOUND) || ZLIB_VERNUM < 0x1200
150 #define deflateBound(c,s) ((s) + (((s) + 7) >> 3) + (((s) + 63) >> 6) + 11)
153 unsigned long git_deflate_bound(git_zstream
*strm
, unsigned long size
)
155 return deflateBound(&strm
->z
, size
);
158 void git_deflate_init(git_zstream
*strm
, int level
)
163 status
= deflateInit(&strm
->z
, level
);
164 zlib_post_call(strm
);
167 die("deflateInit: %s (%s)", zerr_to_string(status
),
168 strm
->z
.msg
? strm
->z
.msg
: "no message");
171 void git_deflate_init_gzip(git_zstream
*strm
, int level
)
174 * Use default 15 bits, +16 is to generate gzip header/trailer
175 * instead of the zlib wrapper.
177 const int windowBits
= 15 + 16;
181 status
= deflateInit2(&strm
->z
, level
,
182 Z_DEFLATED
, windowBits
,
183 8, Z_DEFAULT_STRATEGY
);
184 zlib_post_call(strm
);
187 die("deflateInit2: %s (%s)", zerr_to_string(status
),
188 strm
->z
.msg
? strm
->z
.msg
: "no message");
191 int git_deflate_abort(git_zstream
*strm
)
196 status
= deflateEnd(&strm
->z
);
197 zlib_post_call(strm
);
201 void git_deflate_end(git_zstream
*strm
)
203 int status
= git_deflate_abort(strm
);
207 error("deflateEnd: %s (%s)", zerr_to_string(status
),
208 strm
->z
.msg
? strm
->z
.msg
: "no message");
211 int git_deflate_end_gently(git_zstream
*strm
)
216 status
= deflateEnd(&strm
->z
);
217 zlib_post_call(strm
);
221 int git_deflate(git_zstream
*strm
, int flush
)
228 /* Never say Z_FINISH unless we are feeding everything */
229 status
= deflate(&strm
->z
,
230 (strm
->z
.avail_in
!= strm
->avail_in
)
232 if (status
== Z_MEM_ERROR
)
233 die("deflate: out of memory");
234 zlib_post_call(strm
);
237 * Let zlib work another round, while we can still
240 if ((strm
->avail_out
&& !strm
->z
.avail_out
) &&
241 (status
== Z_OK
|| status
== Z_BUF_ERROR
))
247 /* Z_BUF_ERROR: normal, needs more space in the output buffer */
255 error("deflate: %s (%s)", zerr_to_string(status
),
256 strm
->z
.msg
? strm
->z
.msg
: "no message");