1 /* gzwrite.c -- zlib functions for writing gzip files
2 * Copyright (C) 2004, 2005, 2010 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
9 #if TARGET_MSDOS == 16 && defined(SMALL_MEDIUM) && defined(__WATCOMC__)
14 local int gz_init OF((gz_statep));
15 local int gz_comp OF((gz_statep, int));
16 local int gz_zero OF((gz_statep, z_off64_t));
18 /* Initialize state for writing a gzip file. Mark initialization by setting
19 state->size to non-zero. Return -1 on failure or 0 on success. */
20 local int gz_init(state)
24 z_streamp strm = &(state->strm);
26 /* allocate input and output buffers */
27 #if TARGET_MSDOS == 16 && (defined(__SMALL__) || defined(__MEDIUM__))
28 state->in = _fmalloc(state->want);
29 state->out = _fmalloc(state->want);
31 state->in = malloc(state->want);
32 state->out = malloc(state->want);
34 if (state->in == NULL || state->out == NULL) {
35 fprintf(stderr,"Unable to malloc(%u x 2 = %lu)\n",
37 (unsigned long)state->want * 2UL);
38 #if TARGET_MSDOS == 16 && (defined(__SMALL__) || defined(__MEDIUM__))
39 if (state->out != NULL)
41 if (state->in != NULL)
44 if (state->out != NULL)
46 if (state->in != NULL)
49 gz_error(state, Z_MEM_ERROR, "out of memory");
53 /* allocate deflate memory, set up for gzip compression */
54 strm->zalloc = Z_NULL;
56 strm->opaque = Z_NULL;
57 ret = deflateInit2(strm, state->level, Z_DEFLATED,
58 15 + 16, 8, state->strategy);
60 #if TARGET_MSDOS == 16 && (defined(__SMALL__) || defined(__MEDIUM__))
65 gz_error(state, Z_MEM_ERROR, "out of memory");
69 /* mark state as initialized */
70 state->size = state->want;
72 /* initialize write buffer */
73 strm->avail_out = state->size;
74 strm->next_out = state->out;
75 state->next = strm->next_out;
79 /* Compress whatever is at avail_in and next_in and write to the output file.
80 Return -1 if there is an error writing to the output file, otherwise 0.
81 flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH,
82 then the deflate() state is reset to start a new gzip stream. */
83 local int gz_comp(state, flush)
89 z_streamp strm = &(state->strm);
91 /* allocate memory if this is the first time through */
92 if (state->size == 0 && gz_init(state) == -1)
95 /* run deflate() on provided input until it produces no more output */
98 /* write out current buffer contents if full, or if flushing, but if
99 doing Z_FINISH then don't write until we get to Z_STREAM_END */
100 if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
101 (flush != Z_FINISH || ret == Z_STREAM_END))) {
102 have = (unsigned)(strm->next_out - state->next);
103 #if TARGET_MSDOS == 16 && defined(SMALL_MEDIUM) && defined(__WATCOMC__)
105 if (have && (_dos_write(state->fd, state->next, have, (unsigned*)(&got)) != 0 ||
106 (unsigned)got != have)) {
108 if (have && ((got = write(state->fd, state->next, have)) < 0 ||
109 (unsigned)got != have)) {
111 gz_error(state, Z_ERRNO, zstrerror());
114 if (strm->avail_out == 0) {
115 strm->avail_out = state->size;
116 strm->next_out = state->out;
118 state->next = strm->next_out;
122 have = strm->avail_out;
123 ret = deflate(strm, flush);
124 if (ret == Z_STREAM_ERROR) {
125 gz_error(state, Z_STREAM_ERROR,
126 "internal error: deflate stream corrupt");
129 have -= strm->avail_out;
132 /* if that completed a deflate stream, allow another to start */
133 if (flush == Z_FINISH)
136 /* all done, no errors */
140 /* Compress len zeros to output. Return -1 on error, 0 on success. */
141 local int gz_zero(state, len)
147 z_streamp strm = &(state->strm);
149 /* consume whatever's left in the input buffer */
150 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
153 /* compress len zeros (len guaranteed > 0) */
156 n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
157 (unsigned)len : state->size;
159 zmemzero(state->in, n);
163 strm->next_in = state->in;
165 if (gz_comp(state, Z_NO_FLUSH) == -1)
172 /* -- see zlib.h -- */
173 int ZEXPORT gzwrite(file, buf, len)
183 /* get internal structure */
186 state = (gz_statep)file;
187 strm = &(state->strm);
189 /* check that we're writing and that there's no error */
190 if (state->mode != GZ_WRITE || state->err != Z_OK)
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) */
196 gz_error(state, Z_BUF_ERROR, "requested length does not fit in int");
200 /* if len is zero, avoid unnecessary operations */
204 /* allocate memory if this is the first time through */
205 if (state->size == 0 && gz_init(state) == -1)
208 /* check for seek request */
211 if (gz_zero(state, state->skip) == -1)
215 /* for small len, copy to input buffer, otherwise compress directly */
216 if (len < state->size) {
217 /* copy to input buffer, compress when full */
219 if (strm->avail_in == 0)
220 strm->next_in = state->in;
221 n = state->size - strm->avail_in;
224 zmemcpy(strm->next_in + strm->avail_in, buf, n);
227 buf = (char *)buf + n;
229 if (len && gz_comp(state, Z_NO_FLUSH) == -1)
234 /* consume whatever's left in the input buffer */
235 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
238 /* directly compress user buffer to file */
239 strm->avail_in = len;
240 strm->next_in = (voidp)buf;
242 if (gz_comp(state, Z_NO_FLUSH) == -1)
246 /* input was all buffered or compressed (put will fit in int) */
250 /* -- see zlib.h -- */
251 int ZEXPORT gzputc(file, c)
255 unsigned char buf[1];
259 /* get internal structure */
262 state = (gz_statep)file;
263 strm = &(state->strm);
265 /* check that we're writing and that there's no error */
266 if (state->mode != GZ_WRITE || state->err != Z_OK)
269 /* check for seek request */
272 if (gz_zero(state, state->skip) == -1)
276 /* try writing to input buffer for speed (state->size == 0 if buffer not
278 if (strm->avail_in < state->size) {
279 if (strm->avail_in == 0)
280 strm->next_in = state->in;
281 strm->next_in[strm->avail_in++] = c;
286 /* no room in buffer or not initialized, use gz_write() */
288 if (gzwrite(file, buf, 1) != 1)
293 /* -- see zlib.h -- */
294 int ZEXPORT gzputs(file, str)
302 len = (unsigned)strlen(str);
303 ret = gzwrite(file, str, len);
304 return ret == 0 && len != 0 ? -1 : ret;
310 #if TARGET_MSDOS == 16 && (defined(__SMALL__) || defined(__MEDIUM__))
311 static unsigned char __gzprintf_buffer[1024];
314 /* -- see zlib.h -- */
315 int ZEXPORTVA gzprintf (gzFile file, const char *format, ...)
322 /* get internal structure */
325 state = (gz_statep)file;
326 strm = &(state->strm);
328 /* check that we're writing and that there's no error */
329 if (state->mode != GZ_WRITE || state->err != Z_OK)
332 /* make sure we have some buffer space */
333 if (state->size == 0 && gz_init(state) == -1)
336 /* check for seek request */
339 if (gz_zero(state, state->skip) == -1)
343 /* consume whatever's left in the input buffer */
344 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
347 /* do the printf() into the input buffer, put length in len */
348 size = (int)(state->size);
349 state->in[size - 1] = 0;
350 va_start(va, format);
351 #if TARGET_MSDOS == 16 && (defined(__SMALL__) || defined(__MEDIUM__))
352 /* there is no vsprintf() that writes to a FAR pointer, so we have to vsprintf to a temp buffer */
353 len = vsnprintf((char*)__gzprintf_buffer,sizeof(__gzprintf_buffer),format,va);
354 if (len != 0) _fmemcpy(state->in,__gzprintf_buffer,len);
358 # ifdef HAS_vsprintf_void
359 (void)vsprintf(state->in, format, va);
361 for (len = 0; len < size; len++)
362 if (state->in[len] == 0) break;
364 len = vsprintf(state->in, format, va);
368 # ifdef HAS_vsnprintf_void
369 (void)vsnprintf(state->in, size, format, va);
371 len = strlen(state->in);
373 len = vsnprintf((char *)(state->in), size, format, va);
379 /* check that printf() results fit in buffer */
380 if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
383 /* update buffer and position, defer compression until needed */
384 strm->avail_in = (unsigned)len;
385 strm->next_in = state->in;
392 /* -- see zlib.h -- */
393 int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
394 a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
397 int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
398 a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
404 /* get internal structure */
407 state = (gz_statep)file;
408 strm = &(state->strm);
410 /* check that we're writing and that there's no error */
411 if (state->mode != GZ_WRITE || state->err != Z_OK)
414 /* make sure we have some buffer space */
415 if (state->size == 0 && gz_init(state) == -1)
418 /* check for seek request */
421 if (gz_zero(state, state->skip) == -1)
425 /* consume whatever's left in the input buffer */
426 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
429 /* do the printf() into the input buffer, put length in len */
430 size = (int)(state->size);
431 state->in[size - 1] = 0;
433 # ifdef HAS_sprintf_void
434 sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8,
435 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
436 for (len = 0; len < size; len++)
437 if (state->in[len] == 0) break;
439 len = sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8,
440 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
443 # ifdef HAS_snprintf_void
444 snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8,
445 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
446 len = strlen(state->in);
448 len = snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8,
449 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
453 /* check that printf() results fit in buffer */
454 if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
457 /* update buffer and position, defer compression until needed */
458 strm->avail_in = (unsigned)len;
459 strm->next_in = state->in;
466 /* -- see zlib.h -- */
467 int ZEXPORT gzflush(file, flush)
473 /* get internal structure */
476 state = (gz_statep)file;
478 /* check that we're writing and that there's no error */
479 if (state->mode != GZ_WRITE || state->err != Z_OK)
480 return Z_STREAM_ERROR;
482 /* check flush parameter */
483 if (flush < 0 || flush > Z_FINISH)
484 return Z_STREAM_ERROR;
486 /* check for seek request */
489 if (gz_zero(state, state->skip) == -1)
493 /* compress remaining data with requested flush */
494 gz_comp(state, flush);
498 /* -- see zlib.h -- */
499 int ZEXPORT gzsetparams(file, level, strategy)
507 /* get internal structure */
509 return Z_STREAM_ERROR;
510 state = (gz_statep)file;
511 strm = &(state->strm);
513 /* check that we're writing and that there's no error */
514 if (state->mode != GZ_WRITE || state->err != Z_OK)
515 return Z_STREAM_ERROR;
517 /* if no change is requested, then do nothing */
518 if (level == state->level && strategy == state->strategy)
521 /* check for seek request */
524 if (gz_zero(state, state->skip) == -1)
528 /* change compression parameters for subsequent input */
530 /* flush previous input with previous parameters before changing */
531 if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1)
533 deflateParams(strm, level, strategy);
535 state->level = level;
536 state->strategy = strategy;
540 /* -- see zlib.h -- */
541 int ZEXPORT gzclose_w(file)
547 /* get internal structure */
549 return Z_STREAM_ERROR;
550 state = (gz_statep)file;
552 /* check that we're writing */
553 if (state->mode != GZ_WRITE)
554 return Z_STREAM_ERROR;
556 /* check for seek request */
559 ret += gz_zero(state, state->skip);
562 /* flush, free memory, and close file */
563 ret += gz_comp(state, Z_FINISH);
564 (void)deflateEnd(&(state->strm));
565 #if TARGET_MSDOS == 16 && defined(SMALL_MEDIUM) && defined(__WATCOMC__)
572 gz_error(state, Z_OK, NULL);
574 ret += close(state->fd);
576 return ret ? Z_ERRNO : Z_OK;