aboutsummaryrefslogtreecommitdiff
path: root/gzwrite.c
diff options
context:
space:
mode:
authorMark Adler <madler@alumni.caltech.edu>2016-12-04 18:29:43 -0800
committerMark Adler <madler@alumni.caltech.edu>2016-12-04 18:47:34 -0800
commit77bc4f8944c0e1a1fd4689eddbcead6e93bef58a (patch)
tree4de4ee562e63d8ec74878d58041b53a291ffc443 /gzwrite.c
parent44dfd831d24f9b627ab666cf0973b0dce98fabba (diff)
downloadzlib-77bc4f8944c0e1a1fd4689eddbcead6e93bef58a.tar.gz
zlib-77bc4f8944c0e1a1fd4689eddbcead6e93bef58a.tar.bz2
zlib-77bc4f8944c0e1a1fd4689eddbcead6e93bef58a.zip
Add gzfwrite(), duplicating the interface of fwrite().
Diffstat (limited to 'gzwrite.c')
-rw-r--r--gzwrite.c138
1 files changed, 98 insertions, 40 deletions
diff --git a/gzwrite.c b/gzwrite.c
index eb73d9c..2420514 100644
--- a/gzwrite.c
+++ b/gzwrite.c
@@ -9,6 +9,7 @@
9local int gz_init OF((gz_statep)); 9local int gz_init OF((gz_statep));
10local int gz_comp OF((gz_statep, int)); 10local int gz_comp OF((gz_statep, int));
11local int gz_zero OF((gz_statep, z_off64_t)); 11local int gz_zero OF((gz_statep, z_off64_t));
12local z_size_t gz_write OF((gz_statep, voidpc, z_size_t));
12 13
13/* Initialize state for writing a gzip file. Mark initialization by setting 14/* Initialize state for writing a gzip file. Mark initialization by setting
14 state->size to non-zero. Return -1 on a memory allocation failure, or 0 on 15 state->size to non-zero. Return -1 on a memory allocation failure, or 0 on
@@ -170,32 +171,14 @@ local int gz_zero(state, len)
170 return 0; 171 return 0;
171} 172}
172 173
173/* -- see zlib.h -- */ 174/* Write len bytes from buf to file. Return the number of bytes written. If
174int ZEXPORT gzwrite(file, buf, len) 175 the returned value is less than len, then there was an error. */
175 gzFile file; 176local z_size_t gz_write(state, buf, len)
177 gz_statep state;
176 voidpc buf; 178 voidpc buf;
177 unsigned len; 179 z_size_t len;
178{ 180{
179 unsigned put = len; 181 z_size_t put = len;
180 gz_statep state;
181 z_streamp strm;
182
183 /* get internal structure */
184 if (file == NULL)
185 return 0;
186 state = (gz_statep)file;
187 strm = &(state->strm);
188
189 /* check that we're writing and that there's no error */
190 if (state->mode != GZ_WRITE || state->err != Z_OK)
191 return 0;
192
193 /* since an int is returned, make sure len fits in one, otherwise return
194 with an error (this avoids the flaw in the interface) */
195 if ((int)len < 0) {
196 gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
197 return 0;
198 }
199 182
200 /* if len is zero, avoid unnecessary operations */ 183 /* if len is zero, avoid unnecessary operations */
201 if (len == 0) 184 if (len == 0)
@@ -218,14 +201,15 @@ int ZEXPORT gzwrite(file, buf, len)
218 do { 201 do {
219 unsigned have, copy; 202 unsigned have, copy;
220 203
221 if (strm->avail_in == 0) 204 if (state->strm.avail_in == 0)
222 strm->next_in = state->in; 205 state->strm.next_in = state->in;
223 have = (unsigned)((strm->next_in + strm->avail_in) - state->in); 206 have = (unsigned)((state->strm.next_in + state->strm.avail_in) -
207 state->in);
224 copy = state->size - have; 208 copy = state->size - have;
225 if (copy > len) 209 if (copy > len)
226 copy = len; 210 copy = len;
227 memcpy(state->in + have, buf, copy); 211 memcpy(state->in + have, buf, copy);
228 strm->avail_in += copy; 212 state->strm.avail_in += copy;
229 state->x.pos += copy; 213 state->x.pos += copy;
230 buf = (const char *)buf + copy; 214 buf = (const char *)buf + copy;
231 len -= copy; 215 len -= copy;
@@ -235,19 +219,83 @@ int ZEXPORT gzwrite(file, buf, len)
235 } 219 }
236 else { 220 else {
237 /* consume whatever's left in the input buffer */ 221 /* consume whatever's left in the input buffer */
238 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) 222 if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
239 return 0; 223 return 0;
240 224
241 /* directly compress user buffer to file */ 225 /* directly compress user buffer to file */
242 strm->avail_in = len; 226 state->strm.next_in = (z_const Bytef *)buf;
243 strm->next_in = (z_const Bytef *)buf; 227 do {
244 state->x.pos += len; 228 unsigned n = -1;
245 if (gz_comp(state, Z_NO_FLUSH) == -1) 229 if (n > len)
246 return 0; 230 n = len;
231 state->strm.avail_in = n;
232 state->x.pos += n;
233 if (gz_comp(state, Z_NO_FLUSH) == -1)
234 return 0;
235 len -= n;
236 } while (len);
237 }
238
239 /* input was all buffered or compressed */
240 return put;
241}
242
243/* -- see zlib.h -- */
244int ZEXPORT gzwrite(file, buf, len)
245 gzFile file;
246 voidpc buf;
247 unsigned len;
248{
249 gz_statep state;
250
251 /* get internal structure */
252 if (file == NULL)
253 return 0;
254 state = (gz_statep)file;
255
256 /* check that we're writing and that there's no error */
257 if (state->mode != GZ_WRITE || state->err != Z_OK)
258 return 0;
259
260 /* since an int is returned, make sure len fits in one, otherwise return
261 with an error (this avoids a flaw in the interface) */
262 if ((int)len < 0) {
263 gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
264 return 0;
265 }
266
267 /* write len bytes from buf (the return value will fit in an int) */
268 return (int)gz_write(state, buf, len);
269}
270
271/* -- see zlib.h -- */
272z_size_t ZEXPORT gzfwrite(buf, size, nitems, file)
273 voidpc buf;
274 z_size_t size;
275 z_size_t nitems;
276 gzFile file;
277{
278 z_size_t len;
279 gz_statep state;
280
281 /* get internal structure */
282 if (file == NULL)
283 return 0;
284 state = (gz_statep)file;
285
286 /* check that we're writing and that there's no error */
287 if (state->mode != GZ_WRITE || state->err != Z_OK)
288 return 0;
289
290 /* compute bytes to read -- error on overflow */
291 len = nitems * size;
292 if (size && len / size != nitems) {
293 gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
294 return 0;
247 } 295 }
248 296
249 /* input was all buffered or compressed (put will fit in int) */ 297 /* write len bytes to buf, return the number of full items written */
250 return (int)put; 298 return len ? gz_write(state, buf, len) / size : 0;
251} 299}
252 300
253/* -- see zlib.h -- */ 301/* -- see zlib.h -- */
@@ -293,7 +341,7 @@ int ZEXPORT gzputc(file, c)
293 341
294 /* no room in buffer or not initialized, use gz_write() */ 342 /* no room in buffer or not initialized, use gz_write() */
295 buf[0] = (unsigned char)c; 343 buf[0] = (unsigned char)c;
296 if (gzwrite(file, buf, 1) != 1) 344 if (gz_write(state, buf, 1) != 1)
297 return -1; 345 return -1;
298 return c & 0xff; 346 return c & 0xff;
299} 347}
@@ -304,11 +352,21 @@ int ZEXPORT gzputs(file, str)
304 const char *str; 352 const char *str;
305{ 353{
306 int ret; 354 int ret;
307 unsigned len; 355 z_size_t len;
356 gz_statep state;
357
358 /* get internal structure */
359 if (file == NULL)
360 return -1;
361 state = (gz_statep)file;
362
363 /* check that we're writing and that there's no error */
364 if (state->mode != GZ_WRITE || state->err != Z_OK)
365 return -1;
308 366
309 /* write string */ 367 /* write string */
310 len = (unsigned)strlen(str); 368 len = strlen(str);
311 ret = gzwrite(file, str, len); 369 ret = gz_write(state, str, len);
312 return ret == 0 && len != 0 ? -1 : ret; 370 return ret == 0 && len != 0 ? -1 : ret;
313} 371}
314 372